1

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?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Maik Klein
  • 15,548
  • 27
  • 101
  • 197
  • 1
    My guess: It means that for example int and uint can not be the same, even though they might be the same size. Even more so for float, you can't treat a float as an int, like in c, float f; int i=*((int*)&f) to get to it's bits. – starmole Jul 20 '17 at 08:34

1 Answers1

1

My guess is that that validation rule is unfortunately worded and refers to this (2.8. Types and Variables of SPIR-V specification):

Two different type <id>s form, by definition, two different types. It is valid to declare multiple aggregate type <id>s having the same opcode and operands. This is to allow multiple instances of aggregate types with the same structure to be decorated differently. (Different decorations are not required; two different aggregate type <id>s are allowed to have identical declarations and decorations, and will still be two different types.) Non-aggregate types are different: It is invalid to declare multiple type <id>s for the same scalar, vector, or matrix type. That is, non-aggregate type declarations must all have different opcodes or operands. (Note that non-aggregate types cannot be decorated in ways that affect their type.)

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.

krOoze
  • 12,301
  • 1
  • 20
  • 34