ComputeShader - Append Buffer Problem

Hi, I’m trying to use a compute shader with a “AppendStruturedBuffer” (hlsl) , but i only get a “Number overflow” when I try to get the size of my buffer.

When I get the size of my buffer, it’s a huge negative value ( - 10e9 ) .

What did I do wrong here ?

Here is my C# code with the function to get the count of the append buffer

public static Vector3[] KeyCam(Vector3 key, Vector3 cam, Vector3[] normal) {
            ComputeShader shader = (ComputeShader) Resources.Load("ComputeShader/Normal");
            int _kernel = shader.FindKernel("KeyCam");

            ComputeBuffer inputBuffer = new ComputeBuffer(normal.Length, sizeof(float) * 3);
            inputBuffer.SetData(normal);
            ComputeBuffer outputBuffer = new ComputeBuffer(normal.Length, sizeof(float) * 3, ComputeBufferType.Append);

            shader.SetBuffer(_kernel, "input", inputBuffer);
            shader.SetBuffer(_kernel, "output", outputBuffer);
            shader.SetVector("key", key);
            shader.SetVector("cam", cam);

            shader.Dispatch(_kernel, normal.Length/256, 1, 1);
            int c = GetAppendCount(outputBuffer);
            Debug.Log("Output Count : "+c + " Normal count : " + normal.Length);
//crash here : ofc it can't create a vector with negative size
            Vector3[] output = new Vector3[c];
            outputBuffer.GetData(output);

            inputBuffer.Dispose();
            outputBuffer.Dispose();
            return output;
        }
      //https://sites.google.com/site/aliadevlog/counting-buffers-in-directcompute
        private static int GetAppendCount(ComputeBuffer appendBuffer) {
            ComputeBuffer countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.IndirectArguments);
            ComputeBuffer.CopyCount(appendBuffer, countBuffer, 0);

            Debug.Log("Copy buffer : " + countBuffer.count);
            int[] counter = new int[1] { 0 };
            countBuffer.GetData(counter);
            countBuffer.Dispose();
            return counter[0];
        }
    }

And here my simple ComputeShader

StructuredBuffer<float3> input;
float3 key;
float3 cam;
AppendStructuredBuffer<float3> output;

[numthreads(256,1,1)]
void KeyCam(uint3 id : SV_DispatchThreadID) {
    if (dot(input[id.x], cam) >= 0.0)
        if (dot(input[id.x], key) <= 0.0)
            output.Append(input[id.x]);
}

Thanks

Did you ever find an answer?

This seems to work fine for me in Unity 2019.4. I had to make some changes documented below. First, the shader:

AppendStructuredBuffer<float3> appendBuffer;


[numthreads(1024, 1, 1)]
void DoStuff(uint3 id : SV_DispatchThreadID)
{
    // .... deleted some irrelevant stuff ...

    if (id.x < 100) {
        appendBuffer.Append(float3(id.x, 66, 99));
    }

    //dataBuffer[id.x+1].val = dataBuffer[id.x].val + 1;
}

For the counting function, I had to change the countBuffer to type Raw because otherwise the first time this was called it was giving me a weird value if I used the type IndirectArgument.

private static int GetAppendBufferCount(ComputeBuffer appendBuffer)
        {
            ComputeBuffer countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
            ComputeBuffer.CopyCount(appendBuffer, countBuffer, 0);

            // always size 1 -- Debug.Log("Copy buffer : " + countBuffer.count);
            int[] counter = new int[1] { 0 };
            countBuffer.GetData(counter);
            countBuffer.Dispose();
            return counter[0];
        }

Also, on initializing the buffer I called SetData() I’m not sure if needed, but importantly I also called SetCounterValue(0) to reset it (otherwise the GPU kept counting).

// create the buffer
data = new Vector3[1024 * 1024];
appendBufferGPU = new ComputeBuffer(data.Length, sizeof(float) * 3, ComputeBufferType.Append);
appendBufferGPU.SetData(data);
appendBufferGPU.SetCounterValue(0);

The SetCounterValue() also needs to be manually reset before Dispatch.

1 Like