mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[spv-out] Emit required decorations on wrapper struct types, too.
Fixes #1810.
This commit is contained in:
@@ -62,7 +62,21 @@ impl crate::AddressSpace {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if the global requires a type decorated with "Block".
|
||||
/// Return true if the global requires a type decorated with `Block`.
|
||||
///
|
||||
/// Vulkan spec v1.3 §15.6.2, "Descriptor Set Interface", says:
|
||||
///
|
||||
/// > Variables identified with the `Uniform` storage class are used to
|
||||
/// > access transparent buffer backed resources. Such variables must
|
||||
/// > be:
|
||||
/// >
|
||||
/// > - typed as `OpTypeStruct`, or an array of this type,
|
||||
/// >
|
||||
/// > - identified with a `Block` or `BufferBlock` decoration, and
|
||||
/// >
|
||||
/// > - laid out explicitly using the `Offset`, `ArrayStride`, and
|
||||
/// > `MatrixStride` decorations as specified in §15.6.4, "Offset
|
||||
/// > and Stride Assignment."
|
||||
// See `back::spv::GlobalVariable::access_id` for details.
|
||||
pub fn global_needs_wrapper(ir_module: &crate::Module, var: &crate::GlobalVariable) -> bool {
|
||||
match var.space {
|
||||
|
||||
@@ -844,50 +844,7 @@ impl Writer {
|
||||
} => {
|
||||
let mut member_ids = Vec::with_capacity(members.len());
|
||||
for (index, member) in members.iter().enumerate() {
|
||||
self.annotations.push(Instruction::member_decorate(
|
||||
id,
|
||||
index as u32,
|
||||
Decoration::Offset,
|
||||
&[member.offset],
|
||||
));
|
||||
|
||||
if self.flags.contains(WriterFlags::DEBUG) {
|
||||
if let Some(ref name) = member.name {
|
||||
self.debugs
|
||||
.push(Instruction::member_name(id, index as u32, name));
|
||||
}
|
||||
}
|
||||
|
||||
// The matrix decorations also go on arrays of matrices,
|
||||
// so lets check this first.
|
||||
let member_array_subty_inner = match arena[member.ty].inner {
|
||||
crate::TypeInner::Array { base, .. } => &arena[base].inner,
|
||||
ref other => other,
|
||||
};
|
||||
if let crate::TypeInner::Matrix {
|
||||
columns: _,
|
||||
rows,
|
||||
width,
|
||||
} = *member_array_subty_inner
|
||||
{
|
||||
let byte_stride = match rows {
|
||||
crate::VectorSize::Bi => 2 * width,
|
||||
crate::VectorSize::Tri | crate::VectorSize::Quad => 4 * width,
|
||||
};
|
||||
self.annotations.push(Instruction::member_decorate(
|
||||
id,
|
||||
index as u32,
|
||||
Decoration::ColMajor,
|
||||
&[],
|
||||
));
|
||||
self.annotations.push(Instruction::member_decorate(
|
||||
id,
|
||||
index as u32,
|
||||
Decoration::MatrixStride,
|
||||
&[byte_stride as u32],
|
||||
));
|
||||
}
|
||||
|
||||
self.decorate_struct_member(id, index, member, arena)?;
|
||||
let member_id = self.get_type_id(LookupType::Handle(member.ty));
|
||||
member_ids.push(member_id);
|
||||
}
|
||||
@@ -1281,12 +1238,14 @@ impl Writer {
|
||||
let wrapper_type_id = self.id_gen.next();
|
||||
|
||||
self.decorate(wrapper_type_id, Decoration::Block, &[]);
|
||||
self.annotations.push(Instruction::member_decorate(
|
||||
wrapper_type_id,
|
||||
0,
|
||||
Decoration::Offset,
|
||||
&[0],
|
||||
));
|
||||
let member = crate::StructMember {
|
||||
name: None,
|
||||
ty: global_variable.ty,
|
||||
binding: None,
|
||||
offset: 0,
|
||||
};
|
||||
self.decorate_struct_member(wrapper_type_id, 0, &member, &ir_module.types)?;
|
||||
|
||||
Instruction::type_struct(wrapper_type_id, &[inner_type_id])
|
||||
.to_words(&mut self.logical_layout.declarations);
|
||||
|
||||
@@ -1311,6 +1270,66 @@ impl Writer {
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
/// Write the necessary decorations for a struct member.
|
||||
///
|
||||
/// Emit decorations for the `index`'th member of the struct type
|
||||
/// designated by `struct_id`, described by `member`.
|
||||
fn decorate_struct_member(
|
||||
&mut self,
|
||||
struct_id: Word,
|
||||
index: usize,
|
||||
member: &crate::StructMember,
|
||||
arena: &UniqueArena<crate::Type>,
|
||||
) -> Result<(), Error> {
|
||||
use spirv::Decoration;
|
||||
|
||||
self.annotations.push(Instruction::member_decorate(
|
||||
struct_id,
|
||||
index as u32,
|
||||
Decoration::Offset,
|
||||
&[member.offset],
|
||||
));
|
||||
|
||||
if self.flags.contains(WriterFlags::DEBUG) {
|
||||
if let Some(ref name) = member.name {
|
||||
self.debugs
|
||||
.push(Instruction::member_name(struct_id, index as u32, name));
|
||||
}
|
||||
}
|
||||
|
||||
// Matrices and arrays of matrices both require decorations,
|
||||
// so "see through" an array to determine if they're needed.
|
||||
let member_array_subty_inner = match arena[member.ty].inner {
|
||||
crate::TypeInner::Array { base, .. } => &arena[base].inner,
|
||||
ref other => other,
|
||||
};
|
||||
if let crate::TypeInner::Matrix {
|
||||
columns: _,
|
||||
rows,
|
||||
width,
|
||||
} = *member_array_subty_inner
|
||||
{
|
||||
let byte_stride = match rows {
|
||||
crate::VectorSize::Bi => 2 * width,
|
||||
crate::VectorSize::Tri | crate::VectorSize::Quad => 4 * width,
|
||||
};
|
||||
self.annotations.push(Instruction::member_decorate(
|
||||
struct_id,
|
||||
index as u32,
|
||||
Decoration::ColMajor,
|
||||
&[],
|
||||
));
|
||||
self.annotations.push(Instruction::member_decorate(
|
||||
struct_id,
|
||||
index as u32,
|
||||
Decoration::MatrixStride,
|
||||
&[byte_stride as u32],
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_function_type(&mut self, lookup_function_type: LookupFunctionType) -> Word {
|
||||
match self
|
||||
.lookup_function_type
|
||||
|
||||
Reference in New Issue
Block a user