mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
Validate bind group compatibility
This commit is contained in:
parent
332305012c
commit
5923deff6e
@ -8,6 +8,12 @@ pub struct BindGroupPair {
|
||||
group_id: Stored<BindGroupId>,
|
||||
}
|
||||
|
||||
pub enum Expectation {
|
||||
Unchanged,
|
||||
Match(BindGroupId),
|
||||
Mismatch,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BindGroupEntry {
|
||||
expected_layout_id: Option<BindGroupLayoutId>,
|
||||
@ -41,7 +47,7 @@ impl BindGroupEntry {
|
||||
pub fn expect_layout(
|
||||
&mut self,
|
||||
bind_group_layout_id: BindGroupLayoutId,
|
||||
) -> Option<BindGroupId> {
|
||||
) -> Expectation {
|
||||
let some = Some(bind_group_layout_id);
|
||||
if self.expected_layout_id != some {
|
||||
self.expected_layout_id = some;
|
||||
@ -49,13 +55,20 @@ impl BindGroupEntry {
|
||||
Some(BindGroupPair {
|
||||
layout_id,
|
||||
ref group_id,
|
||||
}) if layout_id == bind_group_layout_id => Some(group_id.value),
|
||||
Some(_) | None => None,
|
||||
}) if layout_id == bind_group_layout_id => Expectation::Match(group_id.value),
|
||||
Some(_) | None => Expectation::Mismatch,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
Expectation::Unchanged
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _info(&self) -> (BindGroupLayoutId, Option<(BindGroupLayoutId, BindGroupId)>) {
|
||||
(
|
||||
self.expected_layout_id.unwrap(),
|
||||
self.provided.as_ref().map(|pair| (pair.layout_id, pair.group_id.value)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
command::bind::Binder,
|
||||
command::bind::{Binder, Expectation},
|
||||
hub::HUB,
|
||||
track::{Stitch, TrackerSet},
|
||||
BindGroupId, CommandBuffer, CommandBufferId, ComputePassId, ComputePipelineId, Stored,
|
||||
@ -122,7 +122,7 @@ pub extern "C" fn wgpu_compute_pass_set_pipeline(
|
||||
.zip(&pipeline_layout.bind_group_layout_ids)
|
||||
.enumerate()
|
||||
{
|
||||
if let Some(bg_id) = entry.expect_layout(bgl_id) {
|
||||
if let Expectation::Match(bg_id) = entry.expect_layout(bgl_id) {
|
||||
let desc_set = &bing_group_guard[bg_id].raw;
|
||||
unsafe {
|
||||
pass.raw.bind_compute_descriptor_sets(
|
||||
|
@ -1,6 +1,5 @@
|
||||
|
||||
use crate::{
|
||||
command::bind::Binder,
|
||||
command::bind::{Binder, Expectation},
|
||||
conv,
|
||||
device::RenderPassContext,
|
||||
hub::HUB,
|
||||
@ -15,9 +14,22 @@ use hal::command::RawCommandBuffer;
|
||||
use std::{iter, slice};
|
||||
|
||||
|
||||
type BindGroupMask = u8;
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum BlendColorStatus {
|
||||
Unused,
|
||||
Required,
|
||||
Set,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum DrawError {
|
||||
MissingBlendColor,
|
||||
IncompatibleBindGroup {
|
||||
index: u32,
|
||||
//expected: BindGroupLayoutId,
|
||||
//provided: Option<(BindGroupLayoutId, BindGroupId)>,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct RenderPass<B: hal::Backend> {
|
||||
@ -26,7 +38,8 @@ pub struct RenderPass<B: hal::Backend> {
|
||||
context: RenderPassContext,
|
||||
binder: Binder,
|
||||
trackers: TrackerSet,
|
||||
blend_color_set: i8,
|
||||
incompatible_bind_group_mask: BindGroupMask,
|
||||
blend_color_status: BlendColorStatus,
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> RenderPass<B> {
|
||||
@ -41,14 +54,21 @@ impl<B: hal::Backend> RenderPass<B> {
|
||||
context,
|
||||
binder: Binder::default(),
|
||||
trackers: TrackerSet::new(),
|
||||
blend_color_set: -1,
|
||||
incompatible_bind_group_mask: 0,
|
||||
blend_color_status: BlendColorStatus::Unused,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_ready(&self) -> Result<(), DrawError> {
|
||||
//TODO: vertex buffers
|
||||
//TODO: bind groups
|
||||
if self.blend_color_set == 0 {
|
||||
if self.incompatible_bind_group_mask != 0 {
|
||||
let index = self.incompatible_bind_group_mask.trailing_zeros() as u32;
|
||||
//let (expected, provided) = self.binder.entries[index as usize].info();
|
||||
return Err(DrawError::IncompatibleBindGroup {
|
||||
index,
|
||||
});
|
||||
}
|
||||
if self.blend_color_status == BlendColorStatus::Required {
|
||||
return Err(DrawError::MissingBlendColor)
|
||||
}
|
||||
Ok(())
|
||||
@ -202,6 +222,7 @@ pub extern "C" fn wgpu_render_pass_set_bind_group(
|
||||
pass.binder
|
||||
.provide_entry(index as usize, bind_group_id, bind_group)
|
||||
{
|
||||
pass.incompatible_bind_group_mask &= !(1u8 << index);
|
||||
let pipeline_layout_guard = HUB.pipeline_layouts.read();
|
||||
let pipeline_layout = &pipeline_layout_guard[pipeline_layout_id];
|
||||
unsafe {
|
||||
@ -230,8 +251,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_set < 0 {
|
||||
pass.blend_color_set = 0;
|
||||
if pipeline.flags.contains(PipelineFlags::BLEND_COLOR) && pass.blend_color_status == BlendColorStatus::Unused {
|
||||
pass.blend_color_status = BlendColorStatus::Required;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
@ -246,6 +267,7 @@ pub extern "C" fn wgpu_render_pass_set_pipeline(
|
||||
let pipeline_layout = &pipeline_layout_guard[pipeline.layout_id];
|
||||
let bind_group_guard = HUB.bind_groups.read();
|
||||
|
||||
pass.incompatible_bind_group_mask &= (1u8 << pipeline_layout.bind_group_layout_ids.len()) - 1;
|
||||
pass.binder.pipeline_layout_id = Some(pipeline.layout_id.clone());
|
||||
pass.binder
|
||||
.ensure_length(pipeline_layout.bind_group_layout_ids.len());
|
||||
@ -257,15 +279,22 @@ pub extern "C" fn wgpu_render_pass_set_pipeline(
|
||||
.zip(&pipeline_layout.bind_group_layout_ids)
|
||||
.enumerate()
|
||||
{
|
||||
if let Some(bg_id) = entry.expect_layout(bgl_id) {
|
||||
let desc_set = &bind_group_guard[bg_id].raw;
|
||||
unsafe {
|
||||
pass.raw.bind_graphics_descriptor_sets(
|
||||
&pipeline_layout.raw,
|
||||
index,
|
||||
iter::once(desc_set),
|
||||
&[],
|
||||
);
|
||||
match entry.expect_layout(bgl_id) {
|
||||
Expectation::Unchanged => {}
|
||||
Expectation::Mismatch => {
|
||||
pass.incompatible_bind_group_mask |= 1u8 << index;
|
||||
}
|
||||
Expectation::Match(bg_id) => {
|
||||
pass.incompatible_bind_group_mask &= !(1u8 << index);
|
||||
let desc_set = &bind_group_guard[bg_id].raw;
|
||||
unsafe {
|
||||
pass.raw.bind_graphics_descriptor_sets(
|
||||
&pipeline_layout.raw,
|
||||
index,
|
||||
iter::once(desc_set),
|
||||
&[],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -279,7 +308,7 @@ pub extern "C" fn wgpu_render_pass_set_blend_color(
|
||||
let mut pass_guard = HUB.render_passes.write();
|
||||
let pass = &mut pass_guard[pass_id];
|
||||
|
||||
pass.blend_color_set = 1;
|
||||
pass.blend_color_status = BlendColorStatus::Set;
|
||||
|
||||
unsafe {
|
||||
pass.raw.set_blend_constants(conv::map_color(color));
|
||||
|
Loading…
Reference in New Issue
Block a user