Track stencil reference

This commit is contained in:
Dzmitry Malyshau 2019-05-14 11:51:12 -04:00
parent 6a1dcb9565
commit f024758e07
5 changed files with 50 additions and 18 deletions

View File

@ -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,

View File

@ -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<B: hal::Backend> {
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<B: hal::Backend> RenderPass<B> {
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<B: hal::Backend> RenderPass<B> {
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);

View File

@ -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 {

View File

@ -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;
}
}

View File

@ -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,