Non-structure types (scalars, vectors, arrays, etc.) with the same operand parameterization cannot be type aliases. For non-structures, two type
<id>
s match if-and-only-if the types match.
What exactly does this mean?
#version 400
void main()
{
uint a = 4;
uint b = 5;
}
Compiling this shader with glslang results in
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 1
; Bound: 12
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main"
OpSource GLSL 400
OpName %main "main"
OpName %a "a"
OpName %b "b"
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
%_ptr_Function_uint = OpTypePointer Function %uint
%uint_4 = OpConstant %uint 4
%uint_5 = OpConstant %uint 5
%main = OpFunction %void None %3
%5 = OpLabel
%a = OpVariable %_ptr_Function_uint Function
%b = OpVariable %_ptr_Function_uint Function
OpStore %a %uint_4
OpStore %b %uint_5
OpReturn
OpFunctionEnd
Here %uint = OpTypeInt 32 0
is used several times and %_ptr_Function_uint
is also used two times.
Where does this rule even apply?
My guess is that that validation rule is unfortunately worded and refers to this (2.8. Types and Variables of SPIR-V specification):
But there are differences. E.g. "non-aggregate"(i.e. non-structure + non-array) vs "non-structure".
So, what it means is you cannot do things like:
OpTypeInt id=1 bits=32 sign=0 // OK OpTypeInt id=1 bits=32 sign=1 // ERROR -- redefined result id OpTypeInt id=2 bits=32 sign=0 // ERROR -- uint32 already defined as id 1 OpTypeInt id=3 bits=32 sign=1 // OK
I don't see this rule violated in your human-readable SPIR-V example.