1

具有相同操作数参数化的非结构类型(标量、向量、数组等)不能是类型别名。对于非结构,两个 type<id>匹配 if-and-only-if 类型匹配。

这到底是什么意思?

#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也用了两次。

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

4

1 回答 1

1

我的猜测是,不幸的是,该验证规则的措辞是指这一点(2.8. SPIR-V 规范的类型和变量):

<id>根据定义,两种不同的类型形成两种不同的类型。声明多个具有相同操作码和操作数的聚合类型是有效的。<id>这是为了允许对具有相同结构的聚合类型的多个实例进行不同的装饰。(不需要不同的修饰;两个不同<id>的聚合类型允许有相同的声明和修饰,仍然是两种不同的类型。)非聚合类型不同:<id>为同一个标量声明多个类型是无效的,向量或矩阵类型。也就是说,非聚合类型声明必须都有不同的操作码或操作数。(请注意,非聚合类型不能以影响其类型的方式进行修饰。)

但也有区别。例如“非聚合”(即非结构+非数组)与“非结构”。

因此,这意味着您不能执行以下操作: 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 示例中,我没有看到这条规则被违反。

于 2017-07-24T14:01:49.960 回答