Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question IndirectDrawIndexedArgs from compute shader

Discussion in 'General Graphics' started by arkano22, Aug 8, 2023.

  1. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,862
    Hi!

    I'm looking into RenderPrimitivesIndexedIndirect. The whole point of this method is to draw stuff by specifying the amount of mesh indices/instances from a compute shader.

    However the example in the docs writes indirect parameters into the IndirectDrawIndexedArgs struct from the CPU.

    Now, the documentation for IndirectDrawIndexedArgs states:
    So how are we supposed to fill this from a compute shader, if data layout is subject to change between platforms? Old DrawMeshInstancedIndirect allowed you to pass a regular compute buffer formatted this way:

    That is, a buffer that contains 5 integers regardless of platform. This is arguably a lot simpler and cleaner.

    Any solution for using RenderPrimitivesIndexedIndirect for its actual intended purpose? Should we just assume that IndirectDrawIndexedArgs is to be defined like this in HLSL? (tried but didn't work):

    Code (CSharp):
    1.  
    2. struct indirectDrawIndexedArgs
    3. {
    4.     uint baseVertexIndex;
    5.     uint indexCountPerInstance;
    6.     uint instanceCount;
    7.     uint startIndex;
    8.     uint startInstance;
    9. };
    10.  
     
    Last edited: Aug 8, 2023
  2. Rukhanka

    Rukhanka

    Joined:
    Dec 14, 2022
    Posts:
    195
    RenderPrimitivesIndexedIndirect and DrawMeshInstancedIndirect are the same thing under the hood. All indirect rendering is done in GPU so it is graphics API specific what formats and layouts are used for such rendering. Luckily indirect arguments are the same for D3D and Vulkan APIs. They are no subject to change, because it will be huge breaking change for literally every game. You can use same indirect arguments buffer format as before. With IndirectDrawIndexedArgs struct (and whole UnityIndirect.cginc) Unity tries to add level of abstraction around RenderPrimitivesIndexedIndirect call when arguments are given from CPU. When you are take a GPU way, you should know and stick all hardware and platform specifications.
     
  3. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,862
    In case anyone ever gets stumped on this: member order in IndirectDrawIndexedArgs is not as documented, but instead follows the same order used in DrawMeshInstancedIndirect. All your Graphics.RenderPrimitivesIndexedIndirect calls will fail or misbehave if you follow the documentation when declaring the HLSL struct:

    Code (CSharp):
    1.  
    2. struct IndirectDrawIndexedArgs
    3. {
    4.     uint baseVertexIndex;
    5.     uint indexCountPerInstance;
    6.     uint instanceCount;
    7.     uint startIndex;
    8.     uint startInstance;
    9. };
    10.  
    Instead, it should be:

    Code (CSharp):
    1.  
    2. struct IndirectDrawIndexedArgs
    3. {
    4.     uint indexCountPerInstance;
    5.     uint instanceCount;
    6.     uint startIndex;
    7.     uint baseVertexIndex; // baseVertex index is the 4th member, not the first one.
    8.     uint startInstance;
    9. };
    10.  
    See: https://github.com/Unity-Technologi...me/Export/Graphics/GraphicsBuffer.bindings.cs

    What a waste of time. :(
     
    Last edited: Sep 8, 2023
    Goularou, Ian-Snow and c0d3_m0nk3y like this.