SPIR-V 中哪些类型不允许作为类型别名?

Which types in SPIR-V are not allowed to be type aliases?

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.

这到底是什么意思?

#version 400

void main()
{
  uint a = 4;
  uint b = 5;
}

使用 glslang 编译此着色器导致

; 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

这里%uint = OpTypeInt 32 0用了几次,%_ptr_Function_uint也用了两次

这条规则甚至适用于什么地方?

我的猜测是该验证规则的措辞很不幸并且指的是这个 (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.)

但还是有区别的。例如。 "non-aggregate"(即非结构+非数组)vs "non-structure".

因此,这意味着您不能执行以下操作: 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

我没有发现在您的人类可读 SPIR-V 示例中违反了这条规则。