Validate bind group layouts

This commit is contained in:
Dzmitry Malyshau
2020-06-04 23:47:02 -04:00
parent 581863a73a
commit f158709dd0
3 changed files with 54 additions and 6 deletions

View File

@@ -263,7 +263,8 @@ impl GlobalExt for wgc::hub::Global<IdentityPassThroughFactory> {
entries_length: entries.len(),
},
id,
);
)
.unwrap();
}
A::DestroyBindGroupLayout(id) => {
self.bind_group_layout_destroy::<B>(id);

View File

@@ -47,6 +47,38 @@ pub struct BindGroupLayoutEntry {
pub storage_texture_format: wgt::TextureFormat,
}
#[derive(Clone, Debug)]
pub enum BindGroupLayoutEntryError {
NoVisibility,
UnexpectedHasDynamicOffset,
UnexpectedMultisampled,
}
impl BindGroupLayoutEntry {
pub(crate) fn validate(&self) -> Result<(), BindGroupLayoutEntryError> {
if self.visibility.is_empty() {
return Err(BindGroupLayoutEntryError::NoVisibility);
}
match self.ty {
BindingType::UniformBuffer | BindingType::StorageBuffer => {}
_ => {
if self.has_dynamic_offset {
return Err(BindGroupLayoutEntryError::UnexpectedHasDynamicOffset);
}
}
}
match self.ty {
BindingType::SampledTexture => {}
_ => {
if self.multisampled {
return Err(BindGroupLayoutEntryError::UnexpectedMultisampled);
}
}
}
Ok(())
}
}
#[repr(C)]
#[derive(Debug)]
pub struct BindGroupLayoutDescriptor {
@@ -55,6 +87,12 @@ pub struct BindGroupLayoutDescriptor {
pub entries_length: usize,
}
#[derive(Clone, Debug)]
pub enum BindGroupLayoutError {
ConflictBinding(u32),
Entry(u32, BindGroupLayoutEntryError),
}
#[derive(Debug)]
pub struct BindGroupLayout<B: hal::Backend> {
pub(crate) raw: B::DescriptorSetLayout,

View File

@@ -1085,12 +1085,21 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
device_id: id::DeviceId,
desc: &binding_model::BindGroupLayoutDescriptor,
id_in: Input<G, id::BindGroupLayoutId>,
) -> id::BindGroupLayoutId {
) -> Result<id::BindGroupLayoutId, binding_model::BindGroupLayoutError> {
let mut token = Token::root();
let hub = B::hub(self);
let entries = unsafe { slice::from_raw_parts(desc.entries, desc.entries_length) };
let entry_map: FastHashMap<_, _> =
entries.iter().cloned().map(|b| (b.binding, b)).collect();
let mut entry_map = FastHashMap::default();
for entry in entries {
if let Err(e) = entry.validate() {
return Err(binding_model::BindGroupLayoutError::Entry(entry.binding, e));
}
if entry_map.insert(entry.binding, entry.clone()).is_some() {
return Err(binding_model::BindGroupLayoutError::ConflictBinding(
entry.binding,
));
}
}
// TODO: deduplicate the bind group layouts at some level.
// We can't do it right here, because in the remote scenario
@@ -1102,7 +1111,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.find(|(_, bgl)| bgl.entries == entry_map);
if let Some((id, _)) = bind_group_layout_id {
return id;
return Ok(id);
}
}
@@ -1157,7 +1166,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}),
None => (),
};
id
Ok(id)
}
pub fn bind_group_layout_destroy<B: GfxBackend>(