Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How do you use DrawProcedural with an index buffer?

Discussion in 'General Graphics' started by RaphByrneTitanium, Jul 20, 2021.

  1. RaphByrneTitanium

    RaphByrneTitanium

    Joined:
    Jul 1, 2019
    Posts:
    4
    I've been experimenting with DrawProcedural to draw large amount of vertices from a common buffer. There are overloads of DrawProcedural and DrawProcedural indirect e.g.

    Code (CSharp):
    1. DrawProcedural(GraphicsBuffer indexBuffer, Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, int indexCount);
    I did some debugging with RenderDoc which reports the D3D11 calls made to try and see what's happening at a lower level. From that you can see that there is a IASetIndexBuffer call and an IASetVertexBuffers call but the vertex buffer is null or unassigned. This matches what the docs say: "DrawProcedural does a draw call on the GPU, without a vertex buffer." From looking at the debug output of the vertex program I can indeed see that the indices are being submitted but I can't seem to find how I would actually access them in the vertex program.

    I only have a rough understanding here but it seems like without a vertex buffer the index buffer is totally pointless. The indices are not passed through to later shader stages and so if they aren't used to retrieve vertices then they don't really do anything. The input assembler stage has already completed and all you get in the vertex program is the SV_VertexID. There doesn't appear to be any way to offset this value as it is generated as part of the input assembler stage and so can't really be used as an index in the same way.


    What is the advantage of using this version over the non-index buffer version?

    Is there any way to use the data from the index buffer in the vertex program?

    I haven't tried this yet but I'm guess that doing a DrawMesh variant would set the vertex buffer. Is there some other way to get Unity to call the relevant API to set a vertex buffer without using a Mesh? I know there has been some recent development in the lower level graphics APIs that are heading in this direction (e.g. GraphicsBuffer).
     
    DragonCoder likes this.
  2. blindgr

    blindgr

    Joined:
    Jul 17, 2021
    Posts:
    4
  3. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,240
    It allows the vertex cache to be utilised for a performance boost. So if you draw a quad consisting of 2 triangles you can do it 2 ways:

    1. 6 vertices, with logic in your vertex shader to figure out if you’re in the first or second triangle.

    2. a quad only has 4 vertices, so if you add an index buffer with 0,1,2,0,2,3, and draw 6 indices with that, the gpu now knows that it can run the vertex shader only 4 times, instead of 6, and re-use the results for the 2 duplicated vertices.
     
  4. RaphByrneTitanium

    RaphByrneTitanium

    Joined:
    Jul 1, 2019
    Posts:
    4
    Thanks! That clears things up a lot.

    So it seems like my options in this version of Unity are use the SV_VertexID or provide vertex data out of a mesh? It would be really cool to be able to set an arbitrary vertex and index buffer as a part of the draw rather than use the Mesh API but it seems like the Graphics API is heading in that direction so maybe I'll only have to wait a few versions.
     
    richardkettlewell likes this.