mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Validate bind group layouts
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>(
|
||||
|
||||
Reference in New Issue
Block a user