diff --git a/examples/hello_triangle_c/main.c b/examples/hello_triangle_c/main.c index b1352f46d..c36e01176 100644 --- a/examples/hello_triangle_c/main.c +++ b/examples/hello_triangle_c/main.c @@ -210,7 +210,7 @@ int main() { swap_chain = wgpu_device_create_swap_chain(device, surface, &(WGPUSwapChainDescriptor){ - .usage = WGPUTextureUsageFlags_OUTPUT_ATTACHMENT, + .usage = WGPUTextureUsage_OUTPUT_ATTACHMENT, .format = WGPUTextureFormat_Bgra8Unorm, .width = width, .height = height, diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index ef55ad116..a388a98ac 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -21,15 +21,24 @@ use hal::command::RawCommandBuffer; use std::{iter, slice}; #[derive(Debug, PartialEq)] -enum BlendColorStatus { +enum OptionalState { Unused, Required, Set, } +impl OptionalState { + fn require(&mut self, require: bool) { + if require && *self == OptionalState::Unused { + *self = OptionalState::Required; + } + } +} + #[derive(Debug, PartialEq)] enum DrawError { MissingBlendColor, + MissingStencilReference, IncompatibleBindGroup { index: u32, //expected: BindGroupLayoutId, @@ -49,7 +58,8 @@ pub struct RenderPass { context: RenderPassContext, binder: Binder, trackers: TrackerSet, - blend_color_status: BlendColorStatus, + blend_color_status: OptionalState, + stencil_reference_status: OptionalState, index_state: IndexState, } @@ -66,7 +76,8 @@ impl RenderPass { context, binder: Binder::default(), trackers: TrackerSet::new(), - blend_color_status: BlendColorStatus::Unused, + blend_color_status: OptionalState::Unused, + stencil_reference_status: OptionalState::Unused, index_state, } } @@ -80,9 +91,12 @@ impl RenderPass { index: bind_mask.trailing_zeros() as u32, }); } - if self.blend_color_status == BlendColorStatus::Required { + if self.blend_color_status == OptionalState::Required { return Err(DrawError::MissingBlendColor); } + if self.stencil_reference_status == OptionalState::Required { + return Err(DrawError::MissingStencilReference); + } Ok(()) } } @@ -276,11 +290,8 @@ pub extern "C" fn wgpu_render_pass_set_pipeline( "The render pipeline is not compatible with the pass!" ); - if pipeline.flags.contains(PipelineFlags::BLEND_COLOR) - && pass.blend_color_status == BlendColorStatus::Unused - { - pass.blend_color_status = BlendColorStatus::Required; - } + pass.blend_color_status.require(pipeline.flags.contains(PipelineFlags::BLEND_COLOR)); + pass.stencil_reference_status.require(pipeline.flags.contains(PipelineFlags::STENCIL_REFERENCE)); unsafe { pass.raw.bind_graphics_pipeline(&pipeline.raw); @@ -348,7 +359,7 @@ pub extern "C" fn wgpu_render_pass_set_blend_color(pass_id: RenderPassId, color: let mut pass_guard = HUB.render_passes.write(); let pass = &mut pass_guard[pass_id]; - pass.blend_color_status = BlendColorStatus::Set; + pass.blend_color_status = OptionalState::Set; unsafe { pass.raw.set_blend_constants(conv::map_color(color)); @@ -360,8 +371,7 @@ pub extern "C" fn wgpu_render_pass_set_stencil_reference(pass_id: RenderPassId, let mut pass_guard = HUB.render_passes.write(); let pass = &mut pass_guard[pass_id]; - //TODO - //pass.blend_color_status = BlendColorStatus::Set; + pass.stencil_reference_status = OptionalState::Set; unsafe { pass.raw.set_stencil_reference(hal::pso::Face::all(), value); diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 17b886a6a..4670b8f0b 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -1568,11 +1568,15 @@ pub fn device_create_render_pipeline( }; let mut flags = pipeline::PipelineFlags::empty(); - if color_states - .iter() - .any(|state| state.color_blend.uses_color() | state.alpha_blend.uses_color()) - { - flags |= pipeline::PipelineFlags::BLEND_COLOR; + for state in color_states { + if state.color_blend.uses_color() | state.alpha_blend.uses_color() { + flags |= pipeline::PipelineFlags::BLEND_COLOR; + } + } + if let Some(ds) = depth_stencil_state { + if ds.needs_stencil_reference() { + flags |= pipeline::PipelineFlags::STENCIL_REFERENCE; + } } pipeline::RenderPipeline { diff --git a/wgpu-native/src/pipeline.rs b/wgpu-native/src/pipeline.rs index 60c02a960..a4651eadd 100644 --- a/wgpu-native/src/pipeline.rs +++ b/wgpu-native/src/pipeline.rs @@ -122,6 +122,13 @@ pub struct DepthStencilStateDescriptor { pub stencil_write_mask: u32, } +impl DepthStencilStateDescriptor { + pub fn needs_stencil_reference(&self) -> bool { + !self.stencil_front.compare.is_trivial() || + !self.stencil_back.compare.is_trivial() + } +} + #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] pub enum IndexFormat { @@ -269,6 +276,7 @@ bitflags! { #[repr(transparent)] pub struct PipelineFlags: u32 { const BLEND_COLOR = 1; + const STENCIL_REFERENCE = 2; } } diff --git a/wgpu-native/src/resource.rs b/wgpu-native/src/resource.rs index 431fd8991..5e8059942 100644 --- a/wgpu-native/src/resource.rs +++ b/wgpu-native/src/resource.rs @@ -280,6 +280,16 @@ pub enum CompareFunction { Always = 7, } +impl CompareFunction { + pub fn is_trivial(&self) -> bool { + match *self { + CompareFunction::Never | + CompareFunction::Always => true, + _ => false, + } + } +} + #[repr(C)] pub struct SamplerDescriptor { pub address_mode_u: AddressMode,