400: Validate bind group layouts by value r=kvark a=yanchith

This PR widens the comparisons done between two bind group layouts to also consider them equivalent if their vectors of `BindGroupLayoutBinding`s are equal. 

Tested on various modifications of the cube example from wgpu-rs. https://gist.github.com/yanchith/56e15fe35658b14587ff9bfcbd53116f

Fixes #335 

Co-authored-by: yanchith <yanchi.toth@gmail.com>
This commit is contained in:
bors[bot] 2019-12-17 17:37:39 +00:00 committed by GitHub
commit 6a963892b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 5 deletions

View File

@ -7,6 +7,7 @@ use crate::{
resource::TextureViewDimension, resource::TextureViewDimension,
track::{DUMMY_SELECTOR, TrackerSet}, track::{DUMMY_SELECTOR, TrackerSet},
BufferAddress, BufferAddress,
FastHashMap,
LifeGuard, LifeGuard,
RefCount, RefCount,
Stored, Stored,
@ -41,7 +42,7 @@ pub enum BindingType {
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug, Hash)] #[derive(Clone, Debug, Hash, PartialEq)]
pub struct BindGroupLayoutBinding { pub struct BindGroupLayoutBinding {
pub binding: u32, pub binding: u32,
pub visibility: ShaderStage, pub visibility: ShaderStage,
@ -61,7 +62,7 @@ pub struct BindGroupLayoutDescriptor {
#[derive(Debug)] #[derive(Debug)]
pub struct BindGroupLayout<B: hal::Backend> { pub struct BindGroupLayout<B: hal::Backend> {
pub(crate) raw: B::DescriptorSetLayout, pub(crate) raw: B::DescriptorSetLayout,
pub(crate) bindings: Vec<BindGroupLayoutBinding>, pub(crate) bindings: FastHashMap<u32, BindGroupLayoutBinding>,
pub(crate) desc_ranges: DescriptorRanges, pub(crate) desc_ranges: DescriptorRanges,
pub(crate) dynamic_count: usize, pub(crate) dynamic_count: usize,
} }

View File

@ -1181,6 +1181,23 @@ impl<F: IdentityFilter<BindGroupLayoutId>> Global<F> {
let mut token = Token::root(); let mut token = Token::root();
let hub = B::hub(self); let hub = B::hub(self);
let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) }; let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) };
let bindings_map: FastHashMap<_, _> = bindings
.iter()
.cloned()
.map(|b| (b.binding, b))
.collect();
{
let (bind_group_layout_guard, _) = hub.bind_group_layouts.read(&mut token);
let bind_group_layout =
bind_group_layout_guard
.iter(device_id.backend())
.find(|(_, bgl)| bgl.bindings == bindings_map);
if let Some((id, _)) = bind_group_layout {
return id;
}
}
let raw_bindings = bindings let raw_bindings = bindings
.iter() .iter()
@ -1203,7 +1220,7 @@ impl<F: IdentityFilter<BindGroupLayoutId>> Global<F> {
let layout = binding_model::BindGroupLayout { let layout = binding_model::BindGroupLayout {
raw, raw,
bindings: bindings.to_vec(), bindings: bindings_map,
desc_ranges: DescriptorRanges::from_bindings(&raw_bindings), desc_ranges: DescriptorRanges::from_bindings(&raw_bindings),
dynamic_count: bindings.iter().filter(|b| b.dynamic).count(), dynamic_count: bindings.iter().filter(|b| b.dynamic).count(),
}; };
@ -1299,7 +1316,9 @@ impl<F: IdentityFilter<BindGroupId>> Global<F> {
//TODO: group writes into contiguous sections //TODO: group writes into contiguous sections
let mut writes = Vec::new(); let mut writes = Vec::new();
for (b, decl) in bindings.iter().zip(&bind_group_layout.bindings) { for b in bindings.iter() {
let decl = bind_group_layout.bindings.get(&b.binding)
.expect("Failed to find binding declaration for binding");
let descriptor = match b.resource { let descriptor = match b.resource {
binding_model::BindingResource::Buffer(ref bb) => { binding_model::BindingResource::Buffer(ref bb) => {
let (alignment, usage) = match decl.ty { let (alignment, usage) = match decl.ty {

View File

@ -136,8 +136,15 @@ impl<T, I: TypedId> Storage<T, I> {
value value
}) })
} }
}
pub fn iter(&self, backend: Backend) -> impl Iterator<Item = (I, &T)> {
self.map
.iter()
.map(move |(index, (value, storage_epoch))| {
(I::zip(index as Index, *storage_epoch, backend), value)
})
}
}
/// Type system for enforcing the lock order on shared HUB structures. /// Type system for enforcing the lock order on shared HUB structures.
/// If type A implements `Access<B>`, that means we are allowed to proceed /// If type A implements `Access<B>`, that means we are allowed to proceed