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:
- Pass the first buffer (containing the number 1) to the shader.
- Dispatch the shader to copy data from the input to the output. At this stage, the output buffer should contain the number 1.
- Pass the second buffer (containing the number 2) to the shader.
- 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];
}