mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
Fix and refine the generation of readonly
descriptor attribute (#1534)
* Vulkano-shaders: Improve handling of readonly descriptors * Changelog * Fixed image readonly detection for real this time
This commit is contained in:
parent
bba6a0e776
commit
1af922a607
@ -4,6 +4,7 @@
|
|||||||
Breaking changes should be listed first, before other changes, and should be preceded by - **Breaking**.
|
Breaking changes should be listed first, before other changes, and should be preceded by - **Breaking**.
|
||||||
-->
|
-->
|
||||||
- The deprecated `cause` trait function on Vulkano error types is replaced with `source`.
|
- The deprecated `cause` trait function on Vulkano error types is replaced with `source`.
|
||||||
|
- Vulkano-shaders: Fixed and refined the generation of the `readonly` descriptor attribute. It should now correctly mark uniforms and sampled images as read-only, but storage buffers and images only if explicitly marked as `readonly` in the shader.
|
||||||
|
|
||||||
# Version 0.22.0 (2021-03-31)
|
# Version 0.22.0 (2021-03-31)
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ use crate::parse::{Instruction, Spirv};
|
|||||||
use crate::{spirv_search, TypesMeta};
|
use crate::{spirv_search, TypesMeta};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct Descriptor {
|
struct Descriptor {
|
||||||
set: u32,
|
set: u32,
|
||||||
binding: u32,
|
binding: u32,
|
||||||
@ -177,6 +178,10 @@ fn find_descriptors(doc: &Spirv, entrypoint_id: u32, interface: &[u32]) -> Vec<D
|
|||||||
.get_decoration_params(variable_id, Decoration::DecorationBinding)
|
.get_decoration_params(variable_id, Decoration::DecorationBinding)
|
||||||
.unwrap()[0];
|
.unwrap()[0];
|
||||||
|
|
||||||
|
let nonwritable = doc
|
||||||
|
.get_decoration_params(variable_id, Decoration::DecorationNonWritable)
|
||||||
|
.is_some();
|
||||||
|
|
||||||
// Find information about the kind of binding for this descriptor.
|
// Find information about the kind of binding for this descriptor.
|
||||||
let (desc_ty, readonly, array_count) =
|
let (desc_ty, readonly, array_count) =
|
||||||
descriptor_infos(doc, pointed_ty, storage_class, false).expect(&format!(
|
descriptor_infos(doc, pointed_ty, storage_class, false).expect(&format!(
|
||||||
@ -188,7 +193,7 @@ fn find_descriptors(doc: &Spirv, entrypoint_id: u32, interface: &[u32]) -> Vec<D
|
|||||||
set,
|
set,
|
||||||
binding,
|
binding,
|
||||||
array_count,
|
array_count,
|
||||||
readonly,
|
readonly: nonwritable || readonly,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,26 +394,23 @@ fn descriptor_infos(
|
|||||||
decoration_block ^ decoration_buffer_block,
|
decoration_block ^ decoration_buffer_block,
|
||||||
"Structs in shader interface are expected to be decorated with one of Block or BufferBlock"
|
"Structs in shader interface are expected to be decorated with one of Block or BufferBlock"
|
||||||
);
|
);
|
||||||
let is_ssbo = pointer_storage == StorageClass::StorageClassStorageBuffer;
|
|
||||||
|
|
||||||
// Determine whether there's a NonWritable decoration.
|
// false -> VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
||||||
let readonly = {
|
// true -> VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
|
||||||
let mut readonly = vec![false; member_types.len()];
|
let storage = pointer_storage == StorageClass::StorageClassStorageBuffer;
|
||||||
for i in doc.instructions.iter() {
|
|
||||||
if let Instruction::MemberDecorate { target_id, member, decoration, .. } = i {
|
// Determine whether all members have a NonWritable decoration.
|
||||||
if *target_id == *result_id && *decoration == Decoration::DecorationNonWritable {
|
let nonwritable = (0..member_types.len() as u32).all(|i| {
|
||||||
assert!(!readonly[*member as usize]);
|
doc.get_member_decoration_params(pointed_ty, i, Decoration::DecorationNonWritable).is_some()
|
||||||
readonly[*member as usize] = true;
|
});
|
||||||
}
|
|
||||||
}
|
// Uniforms are never writable.
|
||||||
}
|
let readonly = !storage || nonwritable;
|
||||||
readonly.iter().all(|x| *x)
|
|
||||||
};
|
|
||||||
|
|
||||||
let desc = quote! {
|
let desc = quote! {
|
||||||
DescriptorDescTy::Buffer(DescriptorBufferDesc {
|
DescriptorDescTy::Buffer(DescriptorBufferDesc {
|
||||||
dynamic: None,
|
dynamic: None,
|
||||||
storage: #is_ssbo,
|
storage: #storage,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -435,7 +437,7 @@ fn descriptor_infos(
|
|||||||
|
|
||||||
match dim {
|
match dim {
|
||||||
Dim::DimSubpassData => {
|
Dim::DimSubpassData => {
|
||||||
// We are an input attachment.
|
// VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
|
||||||
assert!(
|
assert!(
|
||||||
!force_combined_image_sampled,
|
!force_combined_image_sampled,
|
||||||
"An OpTypeSampledImage can't point to \
|
"An OpTypeSampledImage can't point to \
|
||||||
@ -459,25 +461,32 @@ fn descriptor_infos(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((desc, true, 1))
|
Some((desc, true, 1)) // Never writable.
|
||||||
}
|
}
|
||||||
Dim::DimBuffer => {
|
Dim::DimBuffer => {
|
||||||
// We are a texel buffer.
|
// false -> VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|
||||||
let not_sampled = !sampled;
|
// true -> VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
|
||||||
|
let storage = !sampled;
|
||||||
let desc = quote! {
|
let desc = quote! {
|
||||||
DescriptorDescTy::TexelBuffer {
|
DescriptorDescTy::TexelBuffer {
|
||||||
storage: #not_sampled,
|
storage: #storage,
|
||||||
format: None, // TODO: specify format if known
|
format: None, // TODO: specify format if known
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((desc, true, 1))
|
Some((desc, !storage, 1)) // Uniforms are never writable.
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// We are a sampled or storage image.
|
let (ty, readonly) = match force_combined_image_sampled {
|
||||||
let ty = match force_combined_image_sampled {
|
// VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
|
||||||
true => quote! { DescriptorDescTy::CombinedImageSampler },
|
// Never writable.
|
||||||
false => quote! { DescriptorDescTy::Image },
|
true => (quote! { DescriptorDescTy::CombinedImageSampler }, true),
|
||||||
|
false => {
|
||||||
|
// false -> VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
|
||||||
|
// true -> VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
|
||||||
|
let storage = !sampled;
|
||||||
|
(quote! { DescriptorDescTy::Image }, !storage) // Sampled images are never writable.
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let dim = match *dim {
|
let dim = match *dim {
|
||||||
Dim::Dim1D => {
|
Dim::Dim1D => {
|
||||||
@ -504,7 +513,7 @@ fn descriptor_infos(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((desc, true, 1))
|
Some((desc, readonly, 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user