Skip to content

Commit d2d7351

Browse files
committed
Generate reflect::is_type() directly in the spirv header
We've had a *lot* of bugs surfacing from the fact that the manual `rspirv::grammar::reflect` module required hand-adding various `spirv` ops to `match` statements to let the code behave, despite being able to very trivially autogenerate this based on the SPIR-V grammar. By doing so we find quite a few more `OpType` instructions that weren't handled by the hand-written table: - spirv::Op::TypePipeStorage - spirv::Op::TypeNamedBarrier - spirv::Op::TypeUntypedPointerKHR - spirv::Op::TypeNodePayloadArrayAMDX - spirv::Op::TypeHitObjectNV - spirv::Op::TypeCooperativeVectorNV - spirv::Op::TypeCooperativeMatrixNV - spirv::Op::TypeTensorLayoutNV - spirv::Op::TypeTensorViewNV - spirv::Op::TypeBufferSurfaceINTEL - spirv::Op::TypeStructContinuedINTEL
1 parent 89ce4d0 commit d2d7351

File tree

5 files changed

+68
-47
lines changed

5 files changed

+68
-47
lines changed

autogen/src/header.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,16 +291,21 @@ pub fn gen_spirv_header(grammar: &structs::Grammar) -> TokenStream {
291291
// Use associated constants for these aliases.
292292
let mut aliases = vec![];
293293
let mut variants = vec![];
294+
let mut types = vec![];
294295

295296
// Get the instruction table.
296297
for inst in &grammar.instructions {
297298
let opname = as_ident(inst.opname.strip_prefix("Op").unwrap());
298299
let opcode = inst.opcode;
299300
for alias in &inst.aliases {
300301
let alias = as_ident(alias.strip_prefix("Op").unwrap());
301-
aliases.push(quote! { pub const #alias: Op = Op::#opname; });
302+
aliases.push(quote! { pub const #alias: Self = Self::#opname; });
302303
}
303304
variants.push((opcode, opname.clone()));
305+
306+
if inst.class == Some(structs::Class::Type) {
307+
types.push(quote!(Self::#opname));
308+
}
304309
}
305310

306311
let the_enum = generate_enum(
@@ -325,6 +330,14 @@ pub fn gen_spirv_header(grammar: &structs::Grammar) -> TokenStream {
325330
#[allow(non_upper_case_globals)]
326331
impl Op {
327332
#(#aliases)*
333+
334+
/// Returns true if the given opcode is for a type-declaring instruction.
335+
pub fn is_type(self) -> bool {
336+
matches!(
337+
self,
338+
#(#types)|*
339+
)
340+
}
328341
}
329342
}
330343
}

rspirv/binary/tracker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl TypeTracker {
3838

3939
pub fn track(&mut self, inst: &dr::Instruction) {
4040
if let Some(rid) = inst.result_id {
41-
if grammar::reflect::is_type(inst.class.opcode) {
41+
if inst.class.opcode.is_type() {
4242
match inst.class.opcode {
4343
spirv::Op::TypeInt => {
4444
if let (

rspirv/dr/loader.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,7 @@ impl binary::Consumer for Loader {
151151
}
152152
}
153153
opcode if grammar::reflect::is_annotation(opcode) => self.module.annotations.push(inst),
154-
opcode
155-
if grammar::reflect::is_type(opcode) || grammar::reflect::is_constant(opcode) =>
156-
{
154+
opcode if opcode.is_type() || grammar::reflect::is_constant(opcode) => {
157155
self.module.types_global_values.push(inst)
158156
}
159157
spirv::Op::Variable if self.function.is_none() => {

rspirv/grammar/reflect.rs

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,37 +39,6 @@ pub fn is_annotation(opcode: spirv::Op) -> bool {
3939
)
4040
}
4141

42-
/// Returns true if the given opcode is for a type-declaring instruction.
43-
pub fn is_type(opcode: spirv::Op) -> bool {
44-
matches!(
45-
opcode,
46-
spirv::Op::TypeVoid
47-
| spirv::Op::TypeBool
48-
| spirv::Op::TypeInt
49-
| spirv::Op::TypeFloat
50-
| spirv::Op::TypeVector
51-
| spirv::Op::TypeMatrix
52-
| spirv::Op::TypeImage
53-
| spirv::Op::TypeSampler
54-
| spirv::Op::TypeSampledImage
55-
| spirv::Op::TypeArray
56-
| spirv::Op::TypeRuntimeArray
57-
| spirv::Op::TypeStruct
58-
| spirv::Op::TypeOpaque
59-
| spirv::Op::TypePointer
60-
| spirv::Op::TypeFunction
61-
| spirv::Op::TypeEvent
62-
| spirv::Op::TypeDeviceEvent
63-
| spirv::Op::TypeReserveId
64-
| spirv::Op::TypeQueue
65-
| spirv::Op::TypePipe
66-
| spirv::Op::TypeAccelerationStructureKHR
67-
| spirv::Op::TypeRayQueryKHR
68-
| spirv::Op::TypeForwardPointer
69-
| spirv::Op::TypeCooperativeMatrixKHR
70-
)
71-
}
72-
7342
/// Returns true if the given opcode is for a constant-defining instruction.
7443
pub fn is_constant(opcode: spirv::Op) -> bool {
7544
matches!(

spirv/autogen_spirv.rs

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4199,17 +4199,58 @@ impl Op {
41994199
#[allow(clippy::upper_case_acronyms)]
42004200
#[allow(non_upper_case_globals)]
42014201
impl Op {
4202-
pub const SDotKHR: Op = Op::SDot;
4203-
pub const UDotKHR: Op = Op::UDot;
4204-
pub const SUDotKHR: Op = Op::SUDot;
4205-
pub const SDotAccSatKHR: Op = Op::SDotAccSat;
4206-
pub const UDotAccSatKHR: Op = Op::UDotAccSat;
4207-
pub const SUDotAccSatKHR: Op = Op::SUDotAccSat;
4208-
pub const ReportIntersectionNV: Op = Op::ReportIntersectionKHR;
4209-
pub const TypeAccelerationStructureNV: Op = Op::TypeAccelerationStructureKHR;
4210-
pub const DemoteToHelperInvocationEXT: Op = Op::DemoteToHelperInvocation;
4211-
pub const DecorateStringGOOGLE: Op = Op::DecorateString;
4212-
pub const MemberDecorateStringGOOGLE: Op = Op::MemberDecorateString;
4202+
pub const SDotKHR: Self = Self::SDot;
4203+
pub const UDotKHR: Self = Self::UDot;
4204+
pub const SUDotKHR: Self = Self::SUDot;
4205+
pub const SDotAccSatKHR: Self = Self::SDotAccSat;
4206+
pub const UDotAccSatKHR: Self = Self::UDotAccSat;
4207+
pub const SUDotAccSatKHR: Self = Self::SUDotAccSat;
4208+
pub const ReportIntersectionNV: Self = Self::ReportIntersectionKHR;
4209+
pub const TypeAccelerationStructureNV: Self = Self::TypeAccelerationStructureKHR;
4210+
pub const DemoteToHelperInvocationEXT: Self = Self::DemoteToHelperInvocation;
4211+
pub const DecorateStringGOOGLE: Self = Self::DecorateString;
4212+
pub const MemberDecorateStringGOOGLE: Self = Self::MemberDecorateString;
4213+
#[doc = r" Returns true if the given opcode is for a type-declaring instruction."]
4214+
pub fn is_type(self) -> bool {
4215+
matches!(
4216+
self,
4217+
Self::TypeVoid
4218+
| Self::TypeBool
4219+
| Self::TypeInt
4220+
| Self::TypeFloat
4221+
| Self::TypeVector
4222+
| Self::TypeMatrix
4223+
| Self::TypeImage
4224+
| Self::TypeSampler
4225+
| Self::TypeSampledImage
4226+
| Self::TypeArray
4227+
| Self::TypeRuntimeArray
4228+
| Self::TypeStruct
4229+
| Self::TypeOpaque
4230+
| Self::TypePointer
4231+
| Self::TypeFunction
4232+
| Self::TypeEvent
4233+
| Self::TypeDeviceEvent
4234+
| Self::TypeReserveId
4235+
| Self::TypeQueue
4236+
| Self::TypePipe
4237+
| Self::TypeForwardPointer
4238+
| Self::TypePipeStorage
4239+
| Self::TypeNamedBarrier
4240+
| Self::TypeUntypedPointerKHR
4241+
| Self::TypeCooperativeMatrixKHR
4242+
| Self::TypeRayQueryKHR
4243+
| Self::TypeNodePayloadArrayAMDX
4244+
| Self::TypeHitObjectNV
4245+
| Self::TypeCooperativeVectorNV
4246+
| Self::TypeAccelerationStructureKHR
4247+
| Self::TypeCooperativeMatrixNV
4248+
| Self::TypeTensorLayoutNV
4249+
| Self::TypeTensorViewNV
4250+
| Self::TypeBufferSurfaceINTEL
4251+
| Self::TypeStructContinuedINTEL
4252+
)
4253+
}
42134254
}
42144255
#[doc = "[GLSL.std.450](https://www.khronos.org/registry/spir-v/specs/unified1/GLSL.std.450.html) extended instruction opcode"]
42154256
#[repr(u32)]

0 commit comments

Comments
 (0)