[Solved] How can I copy a small part of ComputeBuffer without CPU-GPU sync in ComputeShader

I realy don’t know how to correctly name this problem.
Suppose i have a large 2d data stored in ComputeBuffer (1024 * 1024*40float), and a ComputeShader, that process this data on each Dispatch.
How can i copy a small part (a viewport ) of this data in diferent ComputeBuffer without triggering a CPU-GPU sync for larger buffer.
My simplified code now looks like this.

// on each loop
if (!inited)
        {
            // runs once for init. I filling a largeBuffer;
            substanceInputBuffer.SetData(world.substances);
             /// initing a small buffers for viewport
            InitViewportBuffers(((int)tmp.width + border) * (int)(tmp.height + border));
            inited = true;
        }
        // processing data on ComputeShader
        computeShader.Dispatch(kernelCSMain, world.width / (3 * NUM_THREADS) + 1, world.height / (3 * NUM_THREADS) + 1, 3);
        
        // exporting viewport
       
        viewport = GetViewport();

        computeShader.SetInt("_ViewportX", (int)viewport.xMin);
        computeShader.SetInt("_ViewportY", (int)viewport.yMin);
        computeShader.SetInt("_ViewportWidth", (int)viewport.width);
        computeShader.SetInt("_ViewportHeight", (int)viewport.height);
       
        computeShader.Dispatch(kernelViewportExport, (int)viewport.width / NUM_THREADS + 1, (int)viewport.height / NUM_THREADS + 1, 1);

The reason for this manipulation is decreasing amount of data reciving from gpu on each draw call. But for some reason it’s now working as it should be. Like it’s always sync largebuffer.

How did you solved it?

The example they show is essentially how you do it. Their issue may have been related to something else, or mistaking the stall their compute caused for being a sync.

The basic of it is to dispatch a second kernel (compute shader program) that copies a section of one GPU buffer into another GPU buffer.
Now you can use that smaller buffer wherever on the GPU, like in a regular shader or another compute shader. Or readback that smaller buffer to CPU (sysram).

If you’re going to readback data to the CPU, ideally you want to use the AsyncReadback if possible, instead of stalling the pipeline.

1 Like