KhronosGroup / SPIRV-Registry

SPIR-V specs
109 stars 72 forks source link

`OpExecutionMode` specification conflicts with `LocalSizeId` specification #157

Closed shangjiaxuan closed 2 years ago

shangjiaxuan commented 2 years ago

OpExecutionMode specification states:

This instruction is only valid if the Mode operand is an execution mode that takes no Extra Operands, or takes Extra Operands that are not <id> operands.

Whereas LocalSizeId as a Mode operand, takes <id> operands:

LocalSizeId Same as the LocalSize Mode, but using <id> operands instead of literals. The operands are consumed as unsigned and each must be an integer type scalar.

Same thing goes for LocalSizeHintId, etc.

Current compilers seem to use WorkgroupSize to achieve this, but that builtin is deprecated in 1.5, and specification recommends LocalSizeId as replacement.

WorkgroupSize Deprecated (use LocalSizeId Execution Mode instead). Work-group size in GLCompute or Kernel Execution Models. See the client API specification for more detail.

Minimal code as illustration:

#version 460

layout(local_size_x_id = 1, local_size_y_id = 2, local_size_z_id = 3) in;
void main(void)
{
}

Code emitted by glslc:

; SPIR-V
; Version: 1.5
; Generator: Google Shaderc over Glslang; 10
; Bound: 12
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main"
               OpExecutionMode %main LocalSize 1 1 1
               OpSource GLSL 460
               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
               OpSourceExtension "GL_GOOGLE_include_directive"
               OpName %main "main"
               OpDecorate %7 SpecId 1
               OpDecorate %8 SpecId 2
               OpDecorate %9 SpecId 3
               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %uint = OpTypeInt 32 0
          %7 = OpSpecConstant %uint 1
          %8 = OpSpecConstant %uint 1
          %9 = OpSpecConstant %uint 1
     %v3uint = OpTypeVector %uint 3
%gl_WorkGroupSize = OpSpecConstantComposite %v3uint %7 %8 %9
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd

The following when assembled and fed to spirv-val results in error:

; SPIR-V
; Version: 1.5
; Generator: Google spiregg; 0
; Bound: 5
; Schema: 0
               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main"
               OpExecutionMode %main LocalSizeId %spec_x_uint %spec_y_uint %spec_z_uint
               OpSource HLSL 670
               OpName %main "main"

               OpDecorate %spec_x_uint SpecId 1
               OpDecorate %spec_y_uint SpecId 2
               OpDecorate %spec_z_uint SpecId 3

       %uint = OpTypeInt 32 0
       %void = OpTypeVoid
     %v3uint = OpTypeVector %uint 3
          %3 = OpTypeFunction %void

%spec_x_uint = OpSpecConstant %uint 1
%spec_y_uint = OpSpecConstant %uint 1
%spec_z_uint = OpSpecConstant %uint 1

       %main = OpFunction %void None %3
          %4 = OpLabel
               OpReturn
               OpFunctionEnd

spirv-val gives following error:

error: line 4: OpExecutionMode is only valid when the Mode operand is an execution mode that takes no Extra Operands, or takes Extra Operands that are not id operands.
  OpExecutionMode %main LocalSizeId %2 %3 %4
shangjiaxuan commented 2 years ago

Just looked closer into spec and realized that there is OpExecutionModeId instruction.