986: [0.6] Allign stencil reference between state setting and pipeline creation r=cwfitzgerald a=kvark

**Connections**
Found this when running Ruffle from #983 

**Description**
There are 2 problems:
  1. setting the stencil reference can't be valid if the pipeline doesn't expect this (d'oh)
  2. our code that created the pipeline used slightly stricter conditions than the code setting the stencil, so these diverged a tiny bit

**Testing**
Tested on Ruffle

Co-authored-by: Dzmitry Malyshau <dmalyshau@mozilla.com>
This commit is contained in:
bors[bot] 2020-10-14 20:56:49 +00:00 committed by GitHub
commit 192dea86ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 15 deletions

View File

@ -1,5 +1,8 @@
# Change Log # Change Log
## wgpu-core-0.6.5 (2020-10-14)
- fix setting the stencil reference on an incompatible pipeline
## wgpu-core-0.6.4 (2020-10-05) ## wgpu-core-0.6.4 (2020-10-05)
- don't request device features that aren't needed - don't request device features that aren't needed
- fix texture depth == 0 checks - fix texture depth == 0 checks

2
Cargo.lock generated
View File

@ -1619,7 +1619,7 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-core" name = "wgpu-core"
version = "0.6.4" version = "0.6.5"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"bitflags", "bitflags",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "wgpu-core" name = "wgpu-core"
version = "0.6.4" version = "0.6.5"
authors = ["wgpu developers"] authors = ["wgpu developers"]
edition = "2018" edition = "2018"
description = "WebGPU core logic on gfx-hal" description = "WebGPU core logic on gfx-hal"

View File

@ -269,9 +269,10 @@ impl VertexState {
#[derive(Debug)] #[derive(Debug)]
struct State { struct State {
pipeline_flags: PipelineFlags,
binder: Binder, binder: Binder,
blend_color: OptionalState, blend_color: OptionalState,
stencil_reference: OptionalState, stencil_reference: u32,
pipeline: OptionalState, pipeline: OptionalState,
index: IndexState, index: IndexState,
vertex: VertexState, vertex: VertexState,
@ -294,9 +295,6 @@ impl State {
if self.blend_color == OptionalState::Required { if self.blend_color == OptionalState::Required {
return Err(DrawError::MissingBlendColor); return Err(DrawError::MissingBlendColor);
} }
if self.stencil_reference == OptionalState::Required {
return Err(DrawError::MissingStencilReference);
}
Ok(()) Ok(())
} }
@ -929,9 +927,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}; };
let mut state = State { let mut state = State {
pipeline_flags: PipelineFlags::empty(),
binder: Binder::new(cmd_buf.limits.max_bind_groups), binder: Binder::new(cmd_buf.limits.max_bind_groups),
blend_color: OptionalState::Unused, blend_color: OptionalState::Unused,
stencil_reference: OptionalState::Unused, stencil_reference: 0,
pipeline: OptionalState::Required, pipeline: OptionalState::Required,
index: IndexState::default(), index: IndexState::default(),
vertex: VertexState::default(), vertex: VertexState::default(),
@ -995,12 +994,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}; };
} }
RenderCommand::SetPipeline(pipeline_id) => { RenderCommand::SetPipeline(pipeline_id) => {
state.pipeline = OptionalState::Set;
let pipeline = trackers let pipeline = trackers
.render_pipes .render_pipes
.use_extend(&*pipeline_guard, pipeline_id, (), ()) .use_extend(&*pipeline_guard, pipeline_id, (), ())
.unwrap(); .unwrap();
state.pipeline = OptionalState::Set;
state.pipeline_flags = pipeline.flags;
if !context.compatible(&pipeline.pass_context) { if !context.compatible(&pipeline.pass_context) {
return Err(RenderCommandError::IncompatiblePipeline.into()); return Err(RenderCommandError::IncompatiblePipeline.into());
} }
@ -1013,14 +1014,20 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
state state
.blend_color .blend_color
.require(pipeline.flags.contains(PipelineFlags::BLEND_COLOR)); .require(pipeline.flags.contains(PipelineFlags::BLEND_COLOR));
state
.stencil_reference
.require(pipeline.flags.contains(PipelineFlags::STENCIL_REFERENCE));
unsafe { unsafe {
raw.bind_graphics_pipeline(&pipeline.raw); raw.bind_graphics_pipeline(&pipeline.raw);
} }
if pipeline.flags.contains(PipelineFlags::STENCIL_REFERENCE) {
unsafe {
raw.set_stencil_reference(
hal::pso::Face::all(),
state.stencil_reference,
);
}
}
// Rebind resource // Rebind resource
if state.binder.pipeline_layout_id != Some(pipeline.layout_id.value) { if state.binder.pipeline_layout_id != Some(pipeline.layout_id.value) {
let pipeline_layout = &pipeline_layout_guard[pipeline.layout_id.value]; let pipeline_layout = &pipeline_layout_guard[pipeline.layout_id.value];
@ -1187,11 +1194,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
} }
} }
RenderCommand::SetStencilReference(value) => { RenderCommand::SetStencilReference(value) => {
state.stencil_reference = OptionalState::Set; state.stencil_reference = value;
if state
.pipeline_flags
.contains(PipelineFlags::STENCIL_REFERENCE)
{
unsafe { unsafe {
raw.set_stencil_reference(hal::pso::Face::all(), value); raw.set_stencil_reference(hal::pso::Face::all(), value);
} }
} }
}
RenderCommand::SetViewport { RenderCommand::SetViewport {
ref rect, ref rect,
depth_min, depth_min,

View File

@ -2928,7 +2928,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
} }
} }
if let Some(ds) = depth_stencil_state.as_ref() { if let Some(ds) = depth_stencil_state.as_ref() {
if ds.stencil.needs_ref_value() { if ds.stencil.is_enabled() && ds.stencil.needs_ref_value() {
flags |= pipeline::PipelineFlags::STENCIL_REFERENCE; flags |= pipeline::PipelineFlags::STENCIL_REFERENCE;
} }
if !ds.is_read_only() { if !ds.is_read_only() {