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

View File

@ -1181,6 +1181,23 @@ impl<F: IdentityFilter<BindGroupLayoutId>> Global<F> {
let mut token = Token::root();
let hub = B::hub(self);
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
.iter()
@ -1203,7 +1220,7 @@ impl<F: IdentityFilter<BindGroupLayoutId>> Global<F> {
let layout = binding_model::BindGroupLayout {
raw,
bindings: bindings.to_vec(),
bindings: bindings_map,
desc_ranges: DescriptorRanges::from_bindings(&raw_bindings),
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
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 {
binding_model::BindingResource::Buffer(ref bb) => {
let (alignment, usage) = match decl.ty {

View File

@ -136,8 +136,15 @@ impl<T, I: TypedId> Storage<T, I> {
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.
/// If type A implements `Access<B>`, that means we are allowed to proceed