Hello. I'm currently trying to do GPU-driven culling on 6000.3.0f1 (URP, D3D12), and I have some troubles with atomic operations. For context, the indirect buffer holds multiple commands, and one compute dispatch is done per command/draw to cull their instances. The supplied drawID is confirmed to change for each dispatch via Renderdoc shader debugging, and atomic operations using that indexing work on another (non-indirect) structured buffer just fine. For the indirect buffer, only the atomic operations targeting the first command seem to be applied, even with other buffer flag combinations like IndirectArguments|Structured (if it even makes sense). The buffer contents are verified with GraphicsBuffer.GetData() before and after the dispatches, as well as Renderdoc. I'm kinda running out of options, and neither Google or ChatGPT have helped on this one, so here I am. 🙃
Here's the related code:
//=====================
//Setup
//=====================
this.indirectBuffer = new(Target.IndirectArguments,assetCount,IndirectDrawIndexedArgs.size);
...
this.cullShader.SetBuffer(cullKernel,"indirectBuffer",this.indirectBuffer);
//=====================
//Per-frame
//=====================
//Reset data to a saved state before culling.
this.indirectBuffer.SetData(this.indirectData);
...
for(var index = 0;index < this.indirectData.Length;index += 1){
this.cullShader.SetInt("drawID",index);
this.cullShader.Dispatch(cullKernel,Mathf.CeilToInt((float)this.indirectData[index].instanceCount / threadsX),(int)threadsY,(int)threadsZ);
}
...
//=====================
//Compute Shader
//=====================
struct IndirectCommand{
uint indexCountPerInstance;
int instanceCount;
uint startIndex;
uint baseVertexIndex;
uint startInstance;
};
RWStructuredBuffer<IndirectCommand> indirectBuffer;
...
InterlockedAdd(indirectBuffer[drawID].instanceCount,-1);```