Bug? `SetComputeVectorParam` Updates Lagging a Frame Behind in Compute Shaders

Hi All,

I’ve encountered a peculiar behavior when using SetComputeVectorParam to update a global parameter in a compute shader. The issue manifests as the parameter value being one frame behind when accessed in the compute shader.

Steps:

  1. In the CPU code, I set a Vector4 parameter using SetComputeVectorParam:
  2. At the same time, I write the same data into a ComputeBuffer and use it in the shader.
Vector2 cachedPositionOffset = m_positionOffset;
var debugComputeBuffer = new ComputeBuffer(2, sizeof(float));
debugComputeBuffer.SetData(new []{cachedPositionOffset.x, cachedPositionOffset.y});

using var commandBuffer = CommandBufferPool.Get();
commandBuffer.SetComputeVectorParam(computeShader, "_PositionOffset", new Vector4(cachedPositionOffset.x, cachedPositionOffset.y, 0, 0));
commandBuffer.SetComputeBufferParam(computeShader, 0, "_debugBuffer", debugComputeBuffer);
commandBuffer.DispatchCompute(computeShader, 0, m_numThreads, 1, 1);
Graphics.ExecuteCommandBuffer(commandBuffer);
  1. I use the compute shader to write the _PositionOffset value to an output texture for debugging.
float4 _PositionOffset;
StructuredBuffer<float> _debugBuffer;
RWTexture2D<float4> _Result;
void Compute(uint3 id : SV_DispatchThreadID) 
{
float4 debugColor = float4(_PositionOffset.x, _PositionOffset.y, _debugBuffer[0], _debugBuffer[1]);
_Result[int2(0, 0)] = debugColor;
}

Expectations:

The _PositionOffset parameter and the ComputeBuffer value should be identical within the same dispatch. Observed: The value from SetComputeVectorParam lags one frame behind, while the value from the ComputeBuffer is correct and up-to-date.

Findings:

  • Switching to a ComputeBuffer for _PositionOffset completely resolved the issue.
  • It seems that SetComputeVectorParam updates may not always propagate in time for the compute shader dispatch within the same frame.
  • The input values visible in Unity FrameDebugger appear to be up-to-date, however, upon also supplying a RenderCount id Integer, I realized it would just re-draw the whole thing when looked at in the Debugger, so its not the actual original drawcall.
  • With RenderDoc I managed to capture the output Texture, where the values of the debugColor pixel would indeed not always be the exact same.

Environment:

  • Unity Version: 2020.3.20f1
  • Target Platform: Windows
  • Rendering Pipeline: URP

Suggestions/Questions:

  1. Is this expected behavior due to Unity’s internal GPU queuing, or is it a bug in the parameter propagation pipeline?
  2. If this is expected, should SetComputeVectorParam include a note in the documentation warning about potential frame-lagging behavior?
  3. Is there a best practice to ensure real-time updates when using SetComputeXXXParam, can it be trusted to be up-to-date or should I avoid it entirely in favor of ComputeBuffers?

Hi!
Please report a bug so that relevant people can investigate this.
Thank you!