Enable compute shader by default if the OpenGL version is high enough.

This commit is contained in:
Patrick Walton 2020-05-08 12:16:31 -07:00
parent e766721f37
commit 2421de6616
9 changed files with 62 additions and 31 deletions

View File

@ -803,7 +803,7 @@ impl PFRendererOptions {
None None
}, },
// TODO(pcwalton): Expose this in the C API. // TODO(pcwalton): Expose this in the C API.
use_compute: false, no_compute: false,
} }
} }
} }

View File

@ -137,7 +137,7 @@ impl<W> DemoApp<W> where W: Window {
let mut ui_model = DemoUIModel::new(&options); let mut ui_model = DemoUIModel::new(&options);
let render_options = RendererOptions { let render_options = RendererOptions {
background_color: None, background_color: None,
use_compute: options.compute, no_compute: options.no_compute,
}; };
let filter = build_filter(&ui_model); let filter = build_filter(&ui_model);
@ -625,7 +625,7 @@ pub struct Options {
pub ui: UIVisibility, pub ui: UIVisibility,
pub background_color: BackgroundColor, pub background_color: BackgroundColor,
pub high_performance_gpu: bool, pub high_performance_gpu: bool,
pub compute: bool, pub no_compute: bool,
hidden_field_for_future_proofing: (), hidden_field_for_future_proofing: (),
} }
@ -638,7 +638,7 @@ impl Default for Options {
ui: UIVisibility::All, ui: UIVisibility::All,
background_color: BackgroundColor::Light, background_color: BackgroundColor::Light,
high_performance_gpu: false, high_performance_gpu: false,
compute: false, no_compute: false,
hidden_field_for_future_proofing: (), hidden_field_for_future_proofing: (),
} }
} }
@ -692,10 +692,10 @@ impl Options {
.help("Use the high-performance (discrete) GPU, if available") .help("Use the high-performance (discrete) GPU, if available")
) )
.arg( .arg(
Arg::with_name("compute") Arg::with_name("no-compute")
.short("c") .short("c")
.long("compute") .long("no-compute")
.help("Use compute shaders for certain tasks, if available") .help("Never use compute shaders")
) )
.arg( .arg(
Arg::with_name("INPUT") Arg::with_name("INPUT")
@ -734,8 +734,8 @@ impl Options {
self.high_performance_gpu = true; self.high_performance_gpu = true;
} }
if matches.is_present("compute") { if matches.is_present("no-compute") {
self.compute = true; self.no_compute = true;
} }
if let Some(path) = matches.value_of("INPUT") { if let Some(path) = matches.value_of("INPUT") {

View File

@ -91,7 +91,7 @@ impl<W> DemoApp<W> where W: Window {
}; };
self.renderer.set_options(RendererOptions { self.renderer.set_options(RendererOptions {
background_color: clear_color, background_color: clear_color,
use_compute: self.options.compute, no_compute: self.options.no_compute,
}); });
scene_count scene_count

View File

@ -19,11 +19,11 @@ use half::f16;
use pathfinder_geometry::rect::RectI; use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::Vector2I; use pathfinder_geometry::vector::Vector2I;
use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode, ClearOps}; use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode, ClearOps};
use pathfinder_gpu::{ComputeDimensions, ComputeState, DepthFunc, Device, ImageAccess}; use pathfinder_gpu::{ComputeDimensions, ComputeState, DepthFunc, Device, FeatureLevel};
use pathfinder_gpu::{ImageBinding, Primitive, ProgramKind, RenderOptions, RenderState}; use pathfinder_gpu::{ImageAccess, ImageBinding, Primitive, ProgramKind, RenderOptions};
use pathfinder_gpu::{RenderTarget, ShaderKind, StencilFunc, TextureData, TextureDataRef}; use pathfinder_gpu::{RenderState, RenderTarget, ShaderKind, StencilFunc, TextureData};
use pathfinder_gpu::{TextureFormat, TextureSamplingFlags, UniformData, VertexAttrClass}; use pathfinder_gpu::{TextureDataRef, TextureFormat, TextureSamplingFlags, UniformData};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType}; use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
use pathfinder_resources::ResourceLoader; use pathfinder_resources::ResourceLoader;
use pathfinder_simd::default::F32x4; use pathfinder_simd::default::F32x4;
use std::ffi::CString; use std::ffi::CString;
@ -276,6 +276,13 @@ impl Device for GLDevice {
type VertexArray = GLVertexArray; type VertexArray = GLVertexArray;
type VertexAttr = GLVertexAttr; type VertexAttr = GLVertexAttr;
fn feature_level(&self) -> FeatureLevel {
match self.version {
GLVersion::GL3 | GLVersion::GLES3 => FeatureLevel::D3D10,
GLVersion::GL4 => FeatureLevel::D3D11,
}
}
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> GLTexture { fn create_texture(&self, format: TextureFormat, size: Vector2I) -> GLTexture {
let mut texture = GLTexture { gl_texture: 0, size, format }; let mut texture = GLTexture { gl_texture: 0, size, format };
unsafe { unsafe {

View File

@ -38,6 +38,7 @@ pub trait Device: Sized {
type VertexArray; type VertexArray;
type VertexAttr; type VertexAttr;
fn feature_level(&self) -> FeatureLevel;
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> Self::Texture; fn create_texture(&self, format: TextureFormat, size: Vector2I) -> Self::Texture;
fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef) fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef)
-> Self::Texture; -> Self::Texture;
@ -157,6 +158,14 @@ pub trait Device: Sized {
} }
} }
/// These are rough analogues to D3D versions; don't expect them to represent exactly the feature
/// set of the versions.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum FeatureLevel {
D3D10,
D3D11,
}
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum TextureFormat { pub enum TextureFormat {
R8, R8,

View File

@ -47,10 +47,11 @@ use objc::runtime::{Class, Object};
use pathfinder_geometry::rect::RectI; use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::{Vector2I, vec2i}; use pathfinder_geometry::vector::{Vector2I, vec2i};
use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode}; use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode};
use pathfinder_gpu::{ComputeDimensions, ComputeState, DepthFunc, Device, ImageAccess, Primitive}; use pathfinder_gpu::{ComputeDimensions, ComputeState, DepthFunc, Device, FeatureLevel};
use pathfinder_gpu::{ProgramKind, RenderState, RenderTarget, ShaderKind, StencilFunc, TextureData}; use pathfinder_gpu::{ImageAccess, Primitive, ProgramKind, RenderState, RenderTarget, ShaderKind};
use pathfinder_gpu::{TextureDataRef, TextureFormat, TextureSamplingFlags, UniformData}; use pathfinder_gpu::{StencilFunc, TextureData, TextureDataRef, TextureFormat};
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; use pathfinder_gpu::{TextureSamplingFlags, UniformData, VertexAttrClass};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
use pathfinder_resources::ResourceLoader; use pathfinder_resources::ResourceLoader;
use pathfinder_simd::default::{F32x2, F32x4, I32x2}; use pathfinder_simd::default::{F32x2, F32x4, I32x2};
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
@ -272,6 +273,11 @@ impl Device for MetalDevice {
type VertexArray = MetalVertexArray; type VertexArray = MetalVertexArray;
type VertexAttr = VertexAttribute; type VertexAttr = VertexAttribute;
#[inline]
fn feature_level(&self) -> FeatureLevel {
FeatureLevel::D3D11
}
// TODO: Add texture usage hint. // TODO: Add texture usage hint.
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> MetalTexture { fn create_texture(&self, format: TextureFormat, size: Vector2I) -> MetalTexture {
let descriptor = TextureDescriptor::new(); let descriptor = TextureDescriptor::new();

View File

@ -17,7 +17,7 @@ use pathfinder_gpu::Device;
#[derive(Default)] #[derive(Default)]
pub struct RendererOptions { pub struct RendererOptions {
pub background_color: Option<ColorF>, pub background_color: Option<ColorF>,
pub use_compute: bool, pub no_compute: bool,
} }
#[derive(Clone)] #[derive(Clone)]

View File

@ -11,8 +11,8 @@
use crate::gpu::options::RendererOptions; use crate::gpu::options::RendererOptions;
use crate::gpu::renderer::{MASK_TILES_ACROSS, MASK_TILES_DOWN}; use crate::gpu::renderer::{MASK_TILES_ACROSS, MASK_TILES_DOWN};
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
use pathfinder_gpu::{BufferTarget, BufferUploadMode, ComputeDimensions, Device, VertexAttrClass}; use pathfinder_gpu::{BufferTarget, BufferUploadMode, ComputeDimensions, Device, FeatureLevel};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType}; use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
use pathfinder_resources::ResourceLoader; use pathfinder_resources::ResourceLoader;
// TODO(pcwalton): Replace with `mem::size_of` calls? // TODO(pcwalton): Replace with `mem::size_of` calls?
@ -391,10 +391,13 @@ pub enum FillProgram<D> where D: Device {
impl<D> FillProgram<D> where D: Device { impl<D> FillProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader, options: &RendererOptions) pub fn new(device: &D, resources: &dyn ResourceLoader, options: &RendererOptions)
-> FillProgram<D> { -> FillProgram<D> {
if options.use_compute { match (options.no_compute, device.feature_level()) {
FillProgram::Compute(FillComputeProgram::new(device, resources)) (false, FeatureLevel::D3D11) => {
} else { FillProgram::Compute(FillComputeProgram::new(device, resources))
FillProgram::Raster(FillRasterProgram::new(device, resources)) }
(_, FeatureLevel::D3D10) | (true, _) => {
FillProgram::Raster(FillRasterProgram::new(device, resources))
}
} }
} }
} }

View File

@ -15,11 +15,12 @@ extern crate log;
use pathfinder_geometry::rect::RectI; use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::Vector2I; use pathfinder_geometry::vector::Vector2I;
use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, RenderTarget}; use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode, ClearOps};
use pathfinder_gpu::{BufferUploadMode, ClearOps, ComputeDimensions, ComputeState, DepthFunc, Device, Primitive, ProgramKind}; use pathfinder_gpu::{ComputeDimensions, ComputeState, DepthFunc, Device, FeatureLevel, Primitive};
use pathfinder_gpu::{RenderOptions, RenderState, ShaderKind, StencilFunc, TextureData}; use pathfinder_gpu::{ProgramKind, RenderOptions, RenderState, RenderTarget, ShaderKind};
use pathfinder_gpu::{TextureDataRef, TextureFormat, TextureSamplingFlags, UniformData}; use pathfinder_gpu::{StencilFunc, TextureData, TextureDataRef, TextureFormat};
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; use pathfinder_gpu::{TextureSamplingFlags, UniformData, VertexAttrClass};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
use pathfinder_resources::ResourceLoader; use pathfinder_resources::ResourceLoader;
use std::mem; use std::mem;
use std::str; use std::str;
@ -424,6 +425,11 @@ impl Device for WebGlDevice {
type VertexArray = WebGlVertexArray; type VertexArray = WebGlVertexArray;
type VertexAttr = WebGlVertexAttr; type VertexAttr = WebGlVertexAttr;
#[inline]
fn feature_level(&self) -> FeatureLevel {
FeatureLevel::D3D10
}
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> WebGlTexture { fn create_texture(&self, format: TextureFormat, size: Vector2I) -> WebGlTexture {
let texture = self.context.create_texture().unwrap(); let texture = self.context.create_texture().unwrap();
let texture = WebGlTexture { let texture = WebGlTexture {