Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

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.