Search Unity

Question Compute shader does not work on Vulkan

Discussion in 'Shaders' started by Bovine, Aug 4, 2022.

  1. Bovine

    Bovine

    Joined:
    Oct 13, 2010
    Posts:
    195
    Hi There I have the following compute shader, which basically sorts a series of lights into the nearest 4 for a given 'tile' centre. This works fine in the editor and runs fine on Quest 2 in OpenGL, but something is not right when I build using Vulkan.

    Does anyone have any theory looking at the shader code as to why this might be? I suspect it is the branching but I have not been able to verify that and I've tried various forms of the branching and evne included the [branch] attribute but the results are the same... I don't think it ever goes into any of the IF statements.

    If not the branching then maybe my code, literals or other are a not quite right and this is being tolerated by OpenGL but not Vulkan?

    Code (CSharp):
    1. // Each #kernel tells which function to compile; you can have many kernels
    2. #pragma kernel CSMain
    3.  
    4. // Create a RenderTexture with enableRandomWrite flag and set it
    5. // with cs.SetTexture
    6. RWTexture2D<float4> Lighting;
    7.  
    8. struct csLight
    9. {
    10.     float3 position;
    11.     float intensity;
    12.     float3 colour;
    13.     float overbright;
    14. };
    15.  
    16. struct Important
    17. {
    18.     float index;
    19.     float distance;
    20. };
    21.  
    22. RWStructuredBuffer<csLight> Lights;
    23.  
    24. float LightCount;
    25.  
    26. [numthreads(8,8,1)]
    27. void CSMain (uint3 id : SV_DispatchThreadID)
    28. {
    29.     Important imp[4];
    30.  
    31.     imp[0].index = 0;
    32.     imp[0].distance = 9000000.0f;
    33.  
    34.     imp[1].index = 0;
    35.     imp[1].distance = 9000000.0f;
    36.  
    37.     imp[2].index = 0;
    38.     imp[2].distance = 9000000.0f;
    39.  
    40.     imp[3].index = 0;
    41.     imp[3].distance = 9000000.0f;
    42.  
    43.     float x = id.x;
    44.     float y = id.y;
    45.  
    46.     float3 centre = float3(0.75f + (x * 1.5f), 0.75f, 0.75f + (y * 1.5f));
    47.     int i = 1;
    48.     for (i = 1; i < LightCount; ++i)
    49.     {
    50.         csLight l = Lights[i];
    51.  
    52.         float dist = distance(l.position, centre);
    53.  
    54.         if (imp[0].distance > dist)
    55.         {
    56.             imp[3] = imp[2];
    57.             imp[2] = imp[1];
    58.             imp[1] = imp[0];
    59.  
    60.             imp[0].distance = dist;
    61.             imp[0].index = i;
    62.         }
    63.         else
    64.         {
    65.             if (imp[1].distance > dist)
    66.             {
    67.                 imp[3] = imp[2];
    68.                 imp[2] = imp[1];
    69.  
    70.                 imp[1].distance = dist;
    71.                 imp[1].index = i;
    72.             }
    73.             else
    74.             {
    75.                 if (imp[2].distance > dist)
    76.                 {
    77.                     imp[3] = imp[2];
    78.  
    79.                     imp[2].distance = dist;
    80.                     imp[2].index = i;
    81.                 }
    82.                 else
    83.                 {
    84.                     if (imp[3].distance > dist)
    85.                     {
    86.                         imp[3].distance = dist;
    87.                         imp[3].index = i;
    88.                     }
    89.                 }
    90.             }
    91.         }
    92.     }
    93.  
    94.     Lighting[id.xy] = float4(imp[0].index / 255.0f, imp[1].index / 255.0f, imp[2].index / 255.0f, imp[3].index / 255.0f);
    95. }
    Appreciate that there may be ways to do this with structured buffers, I have yet to explore that but it's up next, hopefully once I have this solved.

    Thanks
    Ian H
     
    Last edited: Aug 4, 2022