Skip to content

Instantly share code, notes, and snippets.

@AquaGeneral
Last active December 3, 2021 07:58
Show Gist options
  • Select an option

  • Save AquaGeneral/484148d2906f8d0365b96861c5e48a2f to your computer and use it in GitHub Desktop.

Select an option

Save AquaGeneral/484148d2906f8d0365b96861c5e48a2f to your computer and use it in GitHub Desktop.
Code of a test Odin project where I am simply trying to write to a shader resource buffer in OpenGL with SPIR-V binary shaders. It's only working with GLSL shaders, no SPIR-V shader

Odin language project using odin-gl https://github.com/vassvik/odin-gl

Loading and binding in the Odin programming language

path       := path.join(shaderDir, fileName)
shaderComp := dxc.compile_from_file(path, generate_args("../computeshader.hlsl", "cs_6_0"))
shader     := gl.CreateShader(gl.COMPUTE_SHADER)
gl.ShaderBinary(1, &shader, gl.SHADER_BINARY_FORMAT_SPIR_V, shaderComp.bitCode, i32(shaderComp.bitCodeLen / 2))
gl.SpecializeShader(shader, cast(^u8)strings.clone_to_cstring("main"), 0, nil, nil)	
prog       := gl.CreateProgram()
gl.AttachShader(prog, shader)
gl.LinkProgram(prog)

Dispatching the shader every frame

gl.UseProgram(resetBuffersProg)
gl.BindBufferBase(gl.SHADER_STORAGE_BUFFER, 0, digitCountsBuf);
gl.DispatchCompute(32, 1, 1)
gl.MemoryBarrier(gl.SHADER_STORAGE_BARRIER_BIT)
gl.UseProgram(0)
gl.BindBufferBase(gl.SHADER_STORAGE_BUFFER, 0, 0)
// Read the results
gl.BindBuffer(gl.SHADER_STORAGE_BUFFER, digitCountsBuf);
ptr := (^u32)(gl.MapBuffer(gl.SHADER_STORAGE_BUFFER, gl.READ_ONLY));
for i := 0; i < 256; i += 1 {
	outData[i] = (^u32)(mem.ptr_offset((^rawptr)(uintptr(ptr)), i))^
}
gl.UnmapBuffer(gl.SHADER_STORAGE_BUFFER)

for i := 0; i < 256; i += 1 {
	fmt.print(outData[i], ", ") // This prints lots of 0's with a working SPIR-V shader, but 4's with the equivalent GLSL source shader
}

computeshader.hlsl

RWStructuredBuffer<uint> DigitCounts;

[numthreads(64, 1, 1)]
void main(uint d : SV_DispatchThreadID) {
    DigitCounts[d] = 4;
}

Disassembly from dxc HLSL -> SPIR-V

; SPIR-V
; Version: 1.0
; Generator: Google spiregg; 0
; Bound: 20
; Schema: 0
               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
               OpExecutionMode %main LocalSize 64 1 1
               OpSource HLSL 600
               OpName %type_RWStructuredBuffer_uint "type.RWStructuredBuffer.uint"
               OpName %DigitCounts "DigitCounts"
               OpName %main "main"
               OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
               OpDecorate %DigitCounts DescriptorSet 0
               OpDecorate %DigitCounts Binding 0
               OpDecorate %_runtimearr_uint ArrayStride 4
               OpMemberDecorate %type_RWStructuredBuffer_uint 0 Offset 0
               OpDecorate %type_RWStructuredBuffer_uint BufferBlock
       %uint = OpTypeInt 32 0
     %uint_4 = OpConstant %uint 4
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
%_runtimearr_uint = OpTypeRuntimeArray %uint
%type_RWStructuredBuffer_uint = OpTypeStruct %_runtimearr_uint
%_ptr_Uniform_type_RWStructuredBuffer_uint = OpTypePointer Uniform %type_RWStructuredBuffer_uint
     %v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
       %void = OpTypeVoid
         %14 = OpTypeFunction %void
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
%DigitCounts = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_uint Uniform
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
       %main = OpFunction %void None %14
         %16 = OpLabel
         %17 = OpLoad %v3uint %gl_GlobalInvocationID
         %18 = OpCompositeExtract %uint %17 0
         %19 = OpAccessChain %_ptr_Uniform_uint %DigitCounts %int_0 %18
               OpStore %19 %uint_4
               OpReturn
               OpFunctionEnd

GLSL transpiled version of the above shader (this one works straight away!)

#version 450
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;

layout(binding = 0, std430) buffer type_RWStructuredBuffer_uint
{
    uint _m0[];
} DigitCounts;

void main()
{
    DigitCounts._m0[gl_GlobalInvocationID.x] = 4u;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment