Search Unity

Bug ComputeShader not running or not writing to ComputeBuffer

Discussion in 'General Graphics' started by Cracker150, Dec 8, 2022.

  1. Cracker150

    Cracker150

    Joined:
    Jul 25, 2013
    Posts:
    1
    Hello,
    I am testing a simple compute shader I wrote in Unity 2021.1.20f1 (URP) and have encountered an issue. Below is MonoBehaviour and ComputeShader, so I am hoping someone will be able to detect what's wrong.

    Code (CSharp):
    1.  
    2. // MONOBEHAVIOUR
    3. using UnityEngine;
    4.  
    5. public class ComputeShaderTest : MonoBehaviour
    6. {
    7.     [SerializeField] private ComputeShader computeShader;
    8.     [SerializeField] private bool validate = false;
    9.  
    10.     private ComputeBuffer myBuffer;
    11.     private int[] validationArray;
    12.  
    13.     private void Awake()
    14.     {
    15.         validationArray = new int[5];
    16.         myBuffer = new ComputeBuffer(5, sizeof(int), ComputeBufferType.Structured, ComputeBufferMode.SubUpdates);
    17.         var writeBuffer = myBuffer.BeginWrite<int>(0, 5);
    18.         for (int i = 0; i < 5; i++)
    19.         {
    20.             writeBuffer[i] = 0;
    21.         }
    22.         myBuffer.EndWrite<int>(5);
    23.         int kernelIndex = computeShader.FindKernel("Start");
    24.         computeShader.SetBuffer(kernelIndex, "MyBuffer", myBuffer);
    25.     }
    26.  
    27.     private void Update()
    28.     {
    29.         int kernelIndex = computeShader.FindKernel("Start");
    30.         computeShader.Dispatch(kernelIndex, 1, 1, 1);
    31.         if (validate)
    32.         {
    33.             myBuffer.GetData(validationArray);
    34.             for (int i = 0; i < validationArray.Length; i++)
    35.             {
    36.                 Debug.Log(validationArray[i]);
    37.             }
    38.             validate = false;
    39.         }
    40.     }
    41.  
    42.     private void OnDestroy()
    43.     {
    44.         myBuffer.Release();
    45.     }
    46. }
    47.  
    48. //COMPUTE SHADER
    49. #pragma kernel Start
    50.  
    51. RWStructuredBuffer<int> MyBuffer;
    52.  
    53. [numthreads(5,1,1)]
    54. void Start (uint3 id : SV_DispatchThreadID)
    55. {
    56.     MyBuffer[id.x] = 1;
    57. }
    58.  
    ComputeShader does not seem to be dispatched or RWStructuredBuffer is not being written to, because Debug.Log returns 0, which are set at buffer initialization. ComputeShader is running each frame, but no change to data is detected.

    Actual Result: Five 0's are logged to console when validate flag is checked in inspector.
    Expected Result: Five 1's are logged to console indicating successful write operation from compute shader.

    NOTE: ComputeShader/MonoBehaviour does not have any compilation errors, as well as no runtime exceptions.
    NOTE: I am aware of thread count being low, and not efficient on GPU, but optimization is not the issue I am trying to solve.

    Thank you.
     
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,025
    Hi!
    2021.1 is not longer supported. Please update to 2021.3.
     
  3. n3b

    n3b

    Joined:
    Nov 16, 2014
    Posts:
    56
    @aleksandrk it doesn't work neither on 2021.3.19 nor on 2022.2.8, report IN-33394

    either ComputeBufferMode.Dynamic and ComputeBufferMode.SubUpdates are not writeable via shader or they return invalid data via buffer.GetData()

    on 2021.3 Dynamic returns incorrect data right after buffer.SetData(data); buffer.GetData(data);
     
  4. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    674
    ComputeBufferMode.Immutable works but you are right, Dynamic and SubUpdates seem to be broken (you can see the dispatch call in RenderDoc but the RWBuffer isn't bound).

    Strangely enough, ComputeBufferMode.Immutable does not mean that the buffer is immutable on the GPU. It's only immutable on the CPU after the initial upload.
     
  5. n3b

    n3b

    Joined:
    Nov 16, 2014
    Posts:
    56
    GraphicsBuffer with GraphicsBuffer.UsageFlags.LockBufferForWrite are not bound as RWBuffer as well.
    In fact, all these buffer variations are not viable for any cases other than the default ones.