Compute shader reads from a wrong compute buffer after shader compilation

Hi everyone,

I’m encountering an issue, and I’m not sure if it’s a bug or if I’m doing something wrong.

I have a simple compute shader that copies data from one buffer to another. The setup involves three buffers of size 1: one buffer with the number 1, another with the number 2, and an output buffer.

Steps:

  1. Pass the first buffer (containing the number 1) to the shader.
  2. Dispatch the shader to copy data from the input to the output. At this stage, the output buffer should contain the number 1.
  3. Pass the second buffer (containing the number 2) to the shader.
  4. Dispatch again to overwrite the output with the number 2.

The problem is that after these steps, I sometimes find that the output buffer still contains the number 1 because the second dispatch seems to read from the first buffer (???). This issue occurs specifically when I recompile the shader (Check this video).

I’ve tried manually inserting Graphics.WaitOnAsyncGraphicsFence and buffer.GetData between dispatches, even though this shouldn’t be necessary, but it hasn’t resolved the issue. I also attempted to use a CommandBuffer and Graphics.ExecuteCommandBuffer to perform the same algorithm, but the problem still persists.

Thank you in advance!

Here’s the code:

MonoBehaviour
public class RaceConditionTest : MonoBehaviour
{
    [SerializeField] private ComputeShader _shader;
    private ComputeBuffer _firstInput;
    private ComputeBuffer _secondInput;
    private ComputeBuffer _output;

    private void Start()
    {
        _firstInput = new ComputeBuffer(1, sizeof(int));
        _secondInput = new ComputeBuffer(1, sizeof(int));
        _output = new ComputeBuffer(1, sizeof(int));
        _firstInput.SetData(new[] { 1 });
        _secondInput.SetData(new[] { 2 });
        _shader.SetBuffer(0, "Output", _output);
    }

    private void Update()
    {
        _shader.SetBuffer(0, "Input", _firstInput);
        _shader.Dispatch(0, 1, 1, 1);
    
        _shader.SetBuffer(0, "Input", _secondInput);
        _shader.Dispatch(0, 1, 1, 1);
        
        int[] output = new int[1];
        _output.GetData(output);
        Debug.Log($"Output = {output[0]}");
    }
}
Compute shader
#pragma kernel CSMain
RWStructuredBuffer<int> Input;
RWStructuredBuffer<int> Output;

#define CHANGE_ME_JUST_FOR_RECOMPILE 1

[numthreads(1,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    Output[id.x] = Input[id.x];
}
6 Likes

Hi!
Please submit a bug report.
Thank you!

1 Like