mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 00:04:15 +00:00
Fix handling of runtime sized arrays in shaders (#1992)
* Fix handling of runtime sized arrays in shaders * Small fix
This commit is contained in:
parent
137fb9f24b
commit
9a50d6ca56
@ -110,6 +110,10 @@ fn write_descriptor_requirements(
|
||||
let ident = format_ident!("{}", format!("{:?}", ty));
|
||||
quote! { ::vulkano::descriptor_set::layout::DescriptorType::#ident }
|
||||
});
|
||||
let descriptor_count = match descriptor_count {
|
||||
Some(descriptor_count) => quote! { Some(#descriptor_count) },
|
||||
None => quote! { None },
|
||||
};
|
||||
let image_format = match image_format {
|
||||
Some(image_format) => {
|
||||
let ident = format_ident!("{}", format!("{:?}", image_format));
|
||||
|
@ -196,7 +196,7 @@ where
|
||||
#[inline]
|
||||
pub fn new(device: Arc<Device>, usage: BufferUsage) -> CpuBufferPool<T> {
|
||||
assert!(size_of::<T>() > 0);
|
||||
let pool = device.standard_memory_pool().clone();
|
||||
let pool = device.standard_memory_pool();
|
||||
|
||||
CpuBufferPool {
|
||||
device,
|
||||
|
@ -573,10 +573,25 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
elements: &[Option<T>],
|
||||
mut extra_check: impl FnMut(u32, &T) -> Result<(), DescriptorResourceInvalidError>,
|
||||
) -> Result<(), PipelineExecutionError> {
|
||||
for (index, element) in elements[0..reqs.descriptor_count as usize]
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
let elements_to_check = if let Some(descriptor_count) = reqs.descriptor_count {
|
||||
// The shader has a fixed-sized array, so it will never access more than
|
||||
// the first `descriptor_count` elements.
|
||||
elements.get(..descriptor_count as usize).ok_or({
|
||||
// There are less than `descriptor_count` elements in `elements`
|
||||
PipelineExecutionError::DescriptorResourceInvalid {
|
||||
set_num,
|
||||
binding_num,
|
||||
index: elements.len() as u32,
|
||||
error: DescriptorResourceInvalidError::Missing,
|
||||
}
|
||||
})?
|
||||
} else {
|
||||
// The shader has a runtime-sized array, so any element could potentially
|
||||
// be accessed. We must check them all.
|
||||
elements
|
||||
};
|
||||
|
||||
for (index, element) in elements_to_check.iter().enumerate() {
|
||||
let index = index as u32;
|
||||
|
||||
// VUID-vkCmdDispatch-None-02699
|
||||
|
@ -722,8 +722,8 @@ impl DescriptorSetLayoutBinding {
|
||||
&self,
|
||||
descriptor_requirements: &DescriptorRequirements,
|
||||
) -> Result<(), DescriptorRequirementsNotMet> {
|
||||
let DescriptorRequirements {
|
||||
descriptor_types,
|
||||
let &DescriptorRequirements {
|
||||
ref descriptor_types,
|
||||
descriptor_count,
|
||||
image_format: _,
|
||||
image_multisampled: _,
|
||||
@ -746,16 +746,18 @@ impl DescriptorSetLayoutBinding {
|
||||
});
|
||||
}
|
||||
|
||||
if self.descriptor_count < *descriptor_count {
|
||||
if let Some(required) = descriptor_count {
|
||||
if self.descriptor_count < required {
|
||||
return Err(DescriptorRequirementsNotMet::DescriptorCount {
|
||||
required: *descriptor_count,
|
||||
required,
|
||||
obtained: self.descriptor_count,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if !self.stages.contains(stages) {
|
||||
if !self.stages.contains(&stages) {
|
||||
return Err(DescriptorRequirementsNotMet::ShaderStages {
|
||||
required: *stages,
|
||||
required: stages,
|
||||
obtained: self.stages,
|
||||
});
|
||||
}
|
||||
@ -768,7 +770,7 @@ impl From<&DescriptorRequirements> for DescriptorSetLayoutBinding {
|
||||
fn from(reqs: &DescriptorRequirements) -> Self {
|
||||
Self {
|
||||
descriptor_type: reqs.descriptor_types[0],
|
||||
descriptor_count: reqs.descriptor_count,
|
||||
descriptor_count: reqs.descriptor_count.unwrap_or(0),
|
||||
variable_descriptor_count: false,
|
||||
stages: reqs.stages,
|
||||
immutable_samplers: Vec::new(),
|
||||
|
@ -542,7 +542,10 @@ pub struct DescriptorRequirements {
|
||||
|
||||
/// The number of descriptors (array elements) that the shader requires. The descriptor set
|
||||
/// layout can declare more than this, but never less.
|
||||
pub descriptor_count: u32,
|
||||
///
|
||||
/// `None` means that the shader declares this as a runtime-sized array, and could potentially
|
||||
/// access every array element provided in the descriptor set.
|
||||
pub descriptor_count: Option<u32>,
|
||||
|
||||
/// The image format that is required for image views bound to this descriptor. If this is
|
||||
/// `None`, then any image format is allowed.
|
||||
|
@ -711,7 +711,7 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
|
||||
let variable_id_info = spirv.id(variable_id);
|
||||
|
||||
let mut reqs = DescriptorRequirements {
|
||||
descriptor_count: 1,
|
||||
descriptor_count: Some(1),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -878,12 +878,15 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
|
||||
_ => panic!("failed to find array length"),
|
||||
};
|
||||
|
||||
reqs.descriptor_count *= len as u32;
|
||||
if let Some(count) = reqs.descriptor_count.as_mut() {
|
||||
*count *= len as u32
|
||||
}
|
||||
|
||||
Some(element_type)
|
||||
}
|
||||
|
||||
&Instruction::TypeRuntimeArray { element_type, .. } => {
|
||||
reqs.descriptor_count = 0;
|
||||
reqs.descriptor_count = None;
|
||||
Some(element_type)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user