Search Unity

Issue with typed UAV load on Vulkan

Discussion in 'Shaders' started by kamkolak, Jan 13, 2020.

  1. kamkolak

    kamkolak

    Joined:
    Nov 15, 2019
    Posts:
    4
    I have a problem with typed UAV loads in compute shader when using Vulkan API. To somehow give a quick description - it looks like even a simple copy between two RGBAFloat textures modifies alpha channel when RGB channels are unused.

    A snippet of the simplified test case I'm using:

    Code (CSharp):
    1. #pragma kernel CopyFull
    2. #pragma kernel CopyAlpha ALPHA_ONLY
    3.  
    4. RWTexture2D<float4> _CopySource;
    5. RWTexture2D<float4> _CopyTarget;
    6.  
    7. void CopyImpl(uint3 id)
    8. {
    9.     uint w, h;
    10.     _CopySource.GetDimensions(w, h);
    11.  
    12.     if (id.x >= w || id.y >= h)
    13.         return;
    14.  
    15.     float4 value = _CopySource.Load(uint3(id.xy, 0));
    16.  
    17. #ifdef ALPHA_ONLY
    18.     _CopyTarget[id.xy] = float4(0, 0, 0, value.a);
    19. #else
    20.     _CopyTarget[id.xy] = value;
    21. #endif
    22. }
    23.  
    24. [numthreads(8,8,1)]
    25. void CopyFull(uint3 id : SV_DispatchThreadID)
    26. {
    27.     CopyImpl(id);
    28. }
    29.  
    30. [numthreads(8,8,1)]
    31. void CopyAlpha(uint3 id : SV_DispatchThreadID)
    32. {
    33.     CopyImpl(id);
    34. }
    Note the section defined by ALPHA_ONLY keyword - the only difference is that in one case all 4 channels are copied, in the other I'm only leaving alpha.

    Alpha channel on the _CopyTarget when using DX11 is exactly the same in both cases and matches _CopySource. When using Vulkan, alpha output is correct if all channels are copied, but it changes if I want to only use alpha (gets zeroed in this case, but seems to be modified in a different way in more complex scenarios).
    (edit: this happens only for B and A channels - if I use R or G everywhere instead, it works fine)

    One thing that I also tested was changing _CopySource to simple Texture2D<float4>. In this case everything works as expected, hence my assumption that this has something to do with typed UAV loads.

    Is there any kind of dependency between texture channels in this case that I'm not aware of? Is what I'm doing actually invalid in this context? Any help would be appreciated.

    P.S.
    In case anyone wants to take a better look at the code, I'm attaching unity package with what I believe is enough to reproduce the issue. Just open the scene inside and toggle copy mode in TestRenderer script attached to Main Camera. Make sure you're using Vulkan as graphics API.
    "All Channels" copy should display a gradient, while "Alpha Only" will result in black output. Both cases should work properly on DX11. Tested on 2019.1 and 2019.3.
     

    Attached Files:

    Last edited: Jan 13, 2020