Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Compute shader Buffer/RWBuffer vs StructuredBuffer/RWStructuredBuffer

Discussion in 'Shaders' started by TheCelt, Oct 4, 2019.

  1. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    741
    So does unity not support regular RWBuffer?

    I wrote a compute shader using Buffer type because i only need floats yet i get strange outputs. But it works fine for structured buffers but thats more for generics which i don't need and is much slower than regular Buffer....

    Does unity simply not support regular Buffer type?
     
    Last edited: Oct 4, 2019
  2. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    What kind of odd issues were you having?
    RWBuffer<float>
    works fine for me. Even
    RWByteAddressBuffer rwbuffer;
    works well, using the optional
    ComputeBufferType
    parameter in
    new ComputerBuffer()
    creation of
    ComputeBufferType.Raw
    .
     
  3. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    741
    I was using RWBuffer<float4> the data was just random values not the actual values i set the buffer to in C#. When i changed it to structured buffer then it worked.
     
  4. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    Have you tried it since? I was testing it just now and everything seemed fine. Though in 2020.1.0a3, but it should be working fine even in 2017 :S
     
  5. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    741

    Sorry for slow reply here is what i have:

    Code (csharp):
    1.  
    2. RWStructuredBuffer<float2> _buffer;
    3. uniform const uint stride;
    4. void CSMain (uint3 id : SV_DispatchThreadID)
    5. {
    6.      uint index = id.x + id.y * stride;
    7.     _buffer[index] = float2(0.2,0.5);
    8. }
    9.  
    Output:


    And


    Code (csharp):
    1.  
    2. RWBuffer<float2> _buffer;
    3. uniform const uint stride;
    4. void CSMain (uint3 id : SV_DispatchThreadID)
    5. {
    6.      uint index = id.x + id.y * stride;
    7.     _buffer[index] = float2(0.2,0.5);
    8. }
    9.  
    Output:



    Regular buffer acts totally different and i can't figure out why.
     
  6. DHein

    DHein

    Joined:
    Jan 26, 2016
    Posts:
    38
    Any luck with an updated Unity Version? Its the same for me with Unity 2019.1.2f1
     
  7. voxelltech

    voxelltech

    Joined:
    Oct 8, 2019
    Posts:
    44
    is this still not resolved?
     
  8. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,983
    Buffer and RWBuffer support only 32-bit formats: float, int and uint.
     
  9. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    741
    Ah that explains it, couldn't find mention of this in the documentation so that took forever to figure out!
     
  10. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,983
    Hmmm...
    I just double-checked the MS docs - it should work for anything, as long as this anything fits into 4x32-bit. So it should work with float4.
    Can you please report a bug? We'll take a look :)
     
  11. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    I've been happily using Buffer<uint4> and RWBuffer<uint4> in compute shaders on my main NVidia based development PC (using Unity 2020.1.f3). When I run the same app on AMD hardware things are very broken.

    I was just trying to debug using RenderDoc and I can see that in the simplest test where I write out something like uint4(1, 2, 3, 4) the buffer seems to end up containing uint4(1, 0, 0 ,0) ...Basically the YZW fields are always clear.

    Would the issue discussed above explain this? If so, is it going to be fixed? ...I'd really rather not have to switch to Buffer<uint> unless I really have to!
     
  12. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    Oh, and if I switch to StructuredBuffer<uint4> / RWStructuredBuffer<uint4> my uint4 fields *do* show up correctly on AMD so this definitely seems to be the problem.
     
  13. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,983
    @trepan I didn't see any bug reports yet. Can you file a bug report please?
     
  14. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    I just submitted a bug report with a custom sample project.

    To be clear: in my experience I can use multi component compute Buffer/RWBuffer types (e.g. uint4) when using an NVidia GPU but the same code fails on AMD hardware. Switching over to StructuredBuffer/RWStructuredBuffer works fine on both.
     
  15. tvirolai

    tvirolai

    Unity Technologies

    Joined:
    Jan 13, 2020
    Posts:
    79
    Regular Buffers in DirectX are the same as TexelBuffers in Vulkan. They're basically 1D textures. The reason for this is historical, as back in DX10 days the HW didn't really allow any other kind of random access to memory except via the texturing unit so they decided to call what are essentially 1D textures as Buffers.

    StructuredBuffers become SSBO's in Vulkan and are just raw memory loads in both Vulkan and DX. They definitely should not be slower than buffer in any decently modern HW (5 years old or so). Buffer is mostly if you need to use the sampling unit for things like format conversions etc.

    Our API doesn't really seem to support ComputeBuffers as buffers in anycase. As Buffers would require you to specify format, just like with textures, and our constructor doesn't accept it. Nor do we have a ComputeBufferType that would allow it. As an example ComputeBufferType.Default explicitly states that it's for StructuredBuffer https://docs.unity3d.com/2020.2/Documentation/ScriptReference/ComputeBufferType.Default.html
     
    jolix likes this.
  16. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    This is some excellent information. Thank you for posting.