Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HLSL: the counter created for for AppendStructuredBuffer use the same set and binding as the original buffer #3638

Open
dneto0 opened this issue Jun 29, 2024 · 0 comments

Comments

@dneto0
Copy link
Contributor

dneto0 commented Jun 29, 2024

When Glslang creates a counter for an AppendStructuredBuffer, the additional buffer is placed in the same (set,binding) slot as its associated buffer. I think that's a bug because it's a binding collision. DXC puts the associated counter in the binding right after the associated buffer. Examples below.

(Neither variable gets an Index decoration)

Consider this shader with an AppendStructuredBuffer:

AppendStructuredBuffer<float> outputs;

[numthreads(1,1,1)]
void main() {
  outputs.Append(1.0);
}

Let's say I put it in file x.comp

I compile it to SPIR-V, using : glslang -D -e main -V100 --hlsl-iomap x.comp -o x.spv

I get this SPIR-V:

; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 11
; Bound: 32
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main"
               OpExecutionMode %main LocalSize 1 1 1
               OpSource HLSL 500
               OpName %main "main"
               OpName %outputs "outputs"
               OpMemberName %outputs 0 "@data"
               OpName %outputs_0 "outputs"
               OpName %outputs_count "outputs@count"
               OpMemberName %outputs_count 0 "@count"
               OpName %outputs_count_0 "outputs@count"
               OpDecorate %_runtimearr_float ArrayStride 4
               OpMemberDecorate %outputs 0 Offset 0
               OpDecorate %outputs BufferBlock
               OpDecorate %outputs_0 DescriptorSet 0
               OpDecorate %outputs_0 Binding 0
               OpMemberDecorate %outputs_count 0 Offset 0
               OpDecorate %outputs_count BufferBlock
               OpDecorate %outputs_count_0 DescriptorSet 0
               OpDecorate %outputs_count_0 Binding 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
%_runtimearr_float = OpTypeRuntimeArray %float
    %outputs = OpTypeStruct %_runtimearr_float
%_ptr_Uniform_outputs = OpTypePointer Uniform %outputs
  %outputs_0 = OpVariable %_ptr_Uniform_outputs Uniform
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
       %uint = OpTypeInt 32 0
%outputs_count = OpTypeStruct %uint
%_ptr_Uniform_outputs_count = OpTypePointer Uniform %outputs_count
%outputs_count_0 = OpVariable %_ptr_Uniform_outputs_count Uniform
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
     %uint_1 = OpConstant %uint 1
     %uint_0 = OpConstant %uint 0
    %float_1 = OpConstant %float 1
%_ptr_Uniform_float = OpTypePointer Uniform %float
       %main = OpFunction %void None %3
          %5 = OpLabel
         %29 = OpAccessChain %_ptr_Uniform_uint %outputs_count_0 %int_0
         %30 = OpAtomicIAdd %uint %29 %uint_1 %uint_0 %uint_1
         %31 = OpAccessChain %_ptr_Uniform_float %outputs_0 %int_0 %30
               OpStore %31 %float_1
               OpReturn
               OpFunctionEnd

Note that variable %outputs_0 and its associated counter %outputs_count_0 both get descriptor set 0 and binding 0.
I think this is a bug because they collide.

DXC's SPIR-V output puts the counter in binding 1.
Compile with dxc -spirv -T cs_6_0 -E main x.comp -Fo x.d.spv -fspv-reflect

I get the following. Note that %counter_var_outputs is in set 0, binding 1.

; SPIR-V
; Version: 1.0
; Generator: Google spiregg; 0
; Bound: 24
; Schema: 0
               OpCapability Shader
               OpExtension "SPV_GOOGLE_hlsl_functionality1"
               OpExtension "SPV_GOOGLE_user_type"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main"
               OpExecutionMode %main LocalSize 1 1 1
               OpSource HLSL 600
               OpName %type_AppendStructuredBuffer_float "type.AppendStructuredBuffer.float"
               OpName %outputs "outputs"
               OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
               OpMemberName %type_ACSBuffer_counter 0 "counter"
               OpName %counter_var_outputs "counter.var.outputs"
               OpName %main "main"
               OpDecorateId %outputs CounterBuffer %counter_var_outputs
               OpDecorate %outputs DescriptorSet 0
               OpDecorate %outputs Binding 0
               OpDecorate %counter_var_outputs DescriptorSet 0
               OpDecorate %counter_var_outputs Binding 1
               OpDecorate %_runtimearr_float ArrayStride 4
               OpMemberDecorate %type_AppendStructuredBuffer_float 0 Offset 0
               OpDecorate %type_AppendStructuredBuffer_float BufferBlock
               OpDecorateString %outputs UserTypeGOOGLE "appendstructuredbuffer:<float>"
               OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
               OpDecorate %type_ACSBuffer_counter BufferBlock
       %uint = OpTypeInt 32 0
     %uint_0 = OpConstant %uint 0
        %int = OpTypeInt 32 1
      %int_1 = OpConstant %int 1
      %float = OpTypeFloat 32
    %float_1 = OpConstant %float 1
%_runtimearr_float = OpTypeRuntimeArray %float
%type_AppendStructuredBuffer_float = OpTypeStruct %_runtimearr_float
%_ptr_Uniform_type_AppendStructuredBuffer_float = OpTypePointer Uniform %type_AppendStructuredBuffer_float
%type_ACSBuffer_counter = OpTypeStruct %int
%_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
       %void = OpTypeVoid
         %16 = OpTypeFunction %void
%_ptr_Uniform_int = OpTypePointer Uniform %int
     %uint_1 = OpConstant %uint 1
%_ptr_Uniform_float = OpTypePointer Uniform %float
    %outputs = OpVariable %_ptr_Uniform_type_AppendStructuredBuffer_float Uniform
%counter_var_outputs = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
       %main = OpFunction %void None %16
         %20 = OpLabel
         %21 = OpAccessChain %_ptr_Uniform_int %counter_var_outputs %uint_0
         %22 = OpAtomicIAdd %int %21 %uint_1 %uint_0 %int_1
         %23 = OpAccessChain %_ptr_Uniform_float %outputs %uint_0 %22
               OpStore %23 %float_1
               OpReturn
               OpFunctionEnd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants