Search Unity

Question How to avoid race conditions in group shared memory

Discussion in 'Shaders' started by QooPen0815, Jan 8, 2023.

  1. QooPen0815

    QooPen0815

    Joined:
    Sep 4, 2021
    Posts:
    1
    Hi, there.

    I want to use group shared memory in a kernel function of a compute shader, so I tried to test with the following shader. My expectation was that it should return all (100, 0, 0), but the output was (1, 0, 0).

    I think this is due to race conditions, but is there a good solution?

    Code (CSharp):
    1.  
    2. using System.Runtime.InteropServices;
    3. using UnityEngine;
    4.  
    5. public class TestScript : MonoBehaviour
    6. {
    7.     uint _objNum = 10;
    8.  
    9.     ComputeShader _shader;
    10.     GraphicsBuffer _buffer;
    11.  
    12.     void Start()
    13.     {
    14.         _shader = (ComputeShader)Resources.Load("Test");
    15.         _buffer = new GraphicsBuffer(
    16.             GraphicsBuffer.Target.Structured,
    17.             (int)_objNum,
    18.             Marshal.SizeOf(typeof(Vector3)));
    19.  
    20.         DispatchShader(isDebugLog: true);
    21.     }
    22.  
    23.     private void OnDestroy()
    24.     {
    25.         _buffer.Release();
    26.     }
    27.  
    28.     void DispatchShader(bool isDebugLog)
    29.     {
    30.         int kernelID = _shader.FindKernel("CSMain");
    31.         _shader.SetBuffer(kernelID, "test", _buffer);
    32.         _shader.GetKernelThreadGroupSizes(kernelID, out var x, out var y, out var z);
    33.         _shader.Dispatch(kernelID, 1, 1, 1);
    34.  
    35.         if (!isDebugLog) return;
    36.  
    37.         BufferUtils.DebugBuffer<Vector3>(_buffer, (int)_objNum);    // <- same to "Debug.Log()"
    38.     }
    39. }
    40.  
    Code (ComputeShader):
    1.  
    2. #pragma kernel CSMain
    3. #define OBJECT_NUM 10
    4. RWStructuredBuffer<float3> test;
    5. groupshared float3 sharedBuffer[OBJECT_NUM];
    6. [numthreads(10,10,10)]
    7. void CSMain(uint3 groupID : SV_GroupID, uint3 threadID : SV_GroupThreadID, uint3 dispatchID : SV_DispatchThreadID, uint gi : SV_GroupIndex)
    8. {
    9.     const uint ID = dispatchID.x;
    10.     sharedBuffer[threadID.x] = float3(0, 0, 0);
    11.     GroupMemoryBarrierWithGroupSync();
    12.    
    13.     sharedBuffer[threadID.x] += float3(1, 0, 0);
    14.     GroupMemoryBarrierWithGroupSync();
    15.    
    16.     test[threadID.x] = sharedBuffer[threadID.x];
    17. }
    18.  
    upload_2023-1-9_0-11-53.png upload_2023-1-9_0-11-53.png
     
    chadfranklin47 likes this.