Search Unity

ComputeShader - Append Buffer Problem

Discussion in 'Scripting' started by Etherliah, Mar 3, 2017.

  1. Etherliah

    Etherliah

    Joined:
    Mar 3, 2017
    Posts:
    1
    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
    Code (CSharp):
    1.  
    2. public static Vector3[] KeyCam(Vector3 key, Vector3 cam, Vector3[] normal) {
    3.             ComputeShader shader = (ComputeShader) Resources.Load("ComputeShader/Normal");
    4.             int _kernel = shader.FindKernel("KeyCam");
    5.  
    6.             ComputeBuffer inputBuffer = new ComputeBuffer(normal.Length, sizeof(float) * 3);
    7.             inputBuffer.SetData(normal);
    8.             ComputeBuffer outputBuffer = new ComputeBuffer(normal.Length, sizeof(float) * 3, ComputeBufferType.Append);
    9.  
    10.             shader.SetBuffer(_kernel, "input", inputBuffer);
    11.             shader.SetBuffer(_kernel, "output", outputBuffer);
    12.             shader.SetVector("key", key);
    13.             shader.SetVector("cam", cam);
    14.  
    15.             shader.Dispatch(_kernel, normal.Length/256, 1, 1);
    16.             int c = GetAppendCount(outputBuffer);
    17.             Debug.Log("Output Count : "+c + " Normal count : " + normal.Length);
    18. //crash here : ofc it can't create a vector with negative size
    19.             Vector3[] output = new Vector3[c];
    20.             outputBuffer.GetData(output);
    21.  
    22.             inputBuffer.Dispose();
    23.             outputBuffer.Dispose();
    24.             return output;
    25.         }
    26.       //https://sites.google.com/site/aliadevlog/counting-buffers-in-directcompute
    27.         private static int GetAppendCount(ComputeBuffer appendBuffer) {
    28.             ComputeBuffer countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.IndirectArguments);
    29.             ComputeBuffer.CopyCount(appendBuffer, countBuffer, 0);
    30.  
    31.             Debug.Log("Copy buffer : " + countBuffer.count);
    32.             int[] counter = new int[1] { 0 };
    33.             countBuffer.GetData(counter);
    34.             countBuffer.Dispose();
    35.             return counter[0];
    36.         }
    37.     }
    And here my simple ComputeShader
    Code (CSharp):
    1. StructuredBuffer<float3> input;
    2. float3 key;
    3. float3 cam;
    4. AppendStructuredBuffer<float3> output;
    5.  
    6. [numthreads(256,1,1)]
    7. void KeyCam(uint3 id : SV_DispatchThreadID) {
    8.     if (dot(input[id.x], cam) >= 0.0)
    9.         if (dot(input[id.x], key) <= 0.0)
    10.             output.Append(input[id.x]);
    11. }
    Thanks
     
  2. roconn

    roconn

    Joined:
    Sep 4, 2018
    Posts:
    1
    Did you ever find an answer?
     
  3. julesradu

    julesradu

    Joined:
    Nov 9, 2017
    Posts:
    6
    This seems to work fine for me in Unity 2019.4. I had to make some changes documented below. First, the shader:
    Code (CSharp):
    1. AppendStructuredBuffer<float3> appendBuffer;
    2.  
    3.  
    4. [numthreads(1024, 1, 1)]
    5. void DoStuff(uint3 id : SV_DispatchThreadID)
    6. {
    7.     // .... deleted some irrelevant stuff ...
    8.  
    9.     if (id.x < 100) {
    10.         appendBuffer.Append(float3(id.x, 66, 99));
    11.     }
    12.  
    13.     //dataBuffer[id.x+1].val = dataBuffer[id.x].val + 1;
    14. }
    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.

    Code (CSharp):
    1. private static int GetAppendBufferCount(ComputeBuffer appendBuffer)
    2.         {
    3.             ComputeBuffer countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
    4.             ComputeBuffer.CopyCount(appendBuffer, countBuffer, 0);
    5.  
    6.             // always size 1 -- Debug.Log("Copy buffer : " + countBuffer.count);
    7.             int[] counter = new int[1] { 0 };
    8.             countBuffer.GetData(counter);
    9.             countBuffer.Dispose();
    10.             return counter[0];
    11.         }
    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).

    Code (CSharp):
    1.  
    2. // create the buffer
    3. data = new Vector3[1024 * 1024];
    4. appendBufferGPU = new ComputeBuffer(data.Length, sizeof(float) * 3, ComputeBufferType.Append);
    5. appendBufferGPU.SetData(data);
    6. appendBufferGPU.SetCounterValue(0);
    The SetCounterValue() also needs to be manually reset before Dispatch.
     
    Last edited: Oct 10, 2020
    vaendritth likes this.