mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Defer bind group creation to after validation
This commit is contained in:
parent
aee0bead78
commit
962e4dbaf7
@ -62,6 +62,8 @@ pub enum CreateBindGroupError {
|
|||||||
BindingSizeTooSmall { actual: u64, min: u64 },
|
BindingSizeTooSmall { actual: u64, min: u64 },
|
||||||
#[error("number of bindings in bind group descriptor ({actual}) does not match the number of bindings defined in the bind group layout ({expected})")]
|
#[error("number of bindings in bind group descriptor ({actual}) does not match the number of bindings defined in the bind group layout ({expected})")]
|
||||||
BindingsNumMismatch { actual: usize, expected: usize },
|
BindingsNumMismatch { actual: usize, expected: usize },
|
||||||
|
#[error("binding {0} is used at least twice in the descriptor")]
|
||||||
|
DuplicateBinding(u32),
|
||||||
#[error("unable to find a corresponding declaration for the given binding {0}")]
|
#[error("unable to find a corresponding declaration for the given binding {0}")]
|
||||||
MissingBindingDeclaration(u32),
|
MissingBindingDeclaration(u32),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
|||||||
@ -1925,6 +1925,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
.get(desc.layout)
|
.get(desc.layout)
|
||||||
.map_err(|_| CreateBindGroupError::InvalidLayout)?;
|
.map_err(|_| CreateBindGroupError::InvalidLayout)?;
|
||||||
|
|
||||||
|
{
|
||||||
// Check that the number of entries in the descriptor matches
|
// Check that the number of entries in the descriptor matches
|
||||||
// the number of entries in the layout.
|
// the number of entries in the layout.
|
||||||
let actual = desc.entries.len();
|
let actual = desc.entries.len();
|
||||||
@ -1932,34 +1933,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
if actual != expected {
|
if actual != expected {
|
||||||
return Err(CreateBindGroupError::BindingsNumMismatch { expected, actual });
|
return Err(CreateBindGroupError::BindingsNumMismatch { expected, actual });
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut desc_set = {
|
|
||||||
let mut desc_sets = ArrayVec::<[_; 1]>::new();
|
|
||||||
device
|
|
||||||
.desc_allocator
|
|
||||||
.lock()
|
|
||||||
.allocate(
|
|
||||||
&device.raw,
|
|
||||||
&bind_group_layout.raw,
|
|
||||||
&bind_group_layout.desc_counts,
|
|
||||||
1,
|
|
||||||
&mut desc_sets,
|
|
||||||
)
|
|
||||||
.expect("failed to allocate descriptor set");
|
|
||||||
desc_sets.pop().unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set the descriptor set's label for easier debugging.
|
|
||||||
if let Some(label) = desc.label.as_ref() {
|
|
||||||
unsafe {
|
|
||||||
device
|
|
||||||
.raw
|
|
||||||
.set_descriptor_set_name(desc_set.raw_mut(), &label);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Rebind `desc_set` as immutable
|
|
||||||
let desc_set = desc_set;
|
|
||||||
|
|
||||||
// TODO: arrayvec/smallvec
|
// TODO: arrayvec/smallvec
|
||||||
// Record binding info for dynamic offset validation
|
// Record binding info for dynamic offset validation
|
||||||
@ -1967,14 +1941,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
// fill out the descriptors
|
// fill out the descriptors
|
||||||
let mut used = TrackerSet::new(B::VARIANT);
|
let mut used = TrackerSet::new(B::VARIANT);
|
||||||
{
|
let desc_set = {
|
||||||
let (buffer_guard, mut token) = hub.buffers.read(&mut token);
|
let (buffer_guard, mut token) = hub.buffers.read(&mut token);
|
||||||
let (texture_guard, mut token) = hub.textures.read(&mut token); //skip token
|
let (texture_guard, mut token) = hub.textures.read(&mut token); //skip token
|
||||||
let (texture_view_guard, mut token) = hub.texture_views.read(&mut token);
|
let (texture_view_guard, mut token) = hub.texture_views.read(&mut token);
|
||||||
let (sampler_guard, _) = hub.samplers.read(&mut token);
|
let (sampler_guard, _) = hub.samplers.read(&mut token);
|
||||||
|
|
||||||
//TODO: group writes into contiguous sections
|
//TODO: group writes into contiguous sections
|
||||||
let mut writes = Vec::new();
|
let mut write_map =
|
||||||
|
FastHashMap::with_capacity_and_hasher(desc.entries.len(), Default::default());
|
||||||
for entry in desc.entries.iter() {
|
for entry in desc.entries.iter() {
|
||||||
let binding = entry.binding;
|
let binding = entry.binding;
|
||||||
// Find the corresponding declaration in the layout
|
// Find the corresponding declaration in the layout
|
||||||
@ -2217,18 +2192,48 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
.collect::<Result<_, _>>()?
|
.collect::<Result<_, _>>()?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
writes.alloc().init(hal::pso::DescriptorSetWrite {
|
if write_map.insert(binding, descriptors).is_some() {
|
||||||
set: desc_set.raw(),
|
return Err(CreateBindGroupError::DuplicateBinding(binding));
|
||||||
binding,
|
}
|
||||||
array_offset: 0, //TODO
|
|
||||||
descriptors,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut desc_sets = ArrayVec::<[_; 1]>::new();
|
||||||
|
device
|
||||||
|
.desc_allocator
|
||||||
|
.lock()
|
||||||
|
.allocate(
|
||||||
|
&device.raw,
|
||||||
|
&bind_group_layout.raw,
|
||||||
|
&bind_group_layout.desc_counts,
|
||||||
|
1,
|
||||||
|
&mut desc_sets,
|
||||||
|
)
|
||||||
|
.expect("failed to allocate descriptor set");
|
||||||
|
let mut desc_set = desc_sets.pop().unwrap();
|
||||||
|
|
||||||
|
// Set the descriptor set's label for easier debugging.
|
||||||
|
if let Some(label) = desc.label.as_ref() {
|
||||||
|
unsafe {
|
||||||
|
device
|
||||||
|
.raw
|
||||||
|
.set_descriptor_set_name(desc_set.raw_mut(), &label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let writes = write_map
|
||||||
|
.into_iter()
|
||||||
|
.map(|(binding, descriptors)| hal::pso::DescriptorSetWrite {
|
||||||
|
set: desc_set.raw(),
|
||||||
|
binding,
|
||||||
|
array_offset: 0,
|
||||||
|
descriptors,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
unsafe {
|
unsafe {
|
||||||
device.raw.write_descriptor_sets(writes);
|
device.raw.write_descriptor_sets(writes);
|
||||||
}
|
}
|
||||||
}
|
desc_set
|
||||||
|
};
|
||||||
|
|
||||||
let bind_group = binding_model::BindGroup {
|
let bind_group = binding_model::BindGroup {
|
||||||
raw: desc_set,
|
raw: desc_set,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user