DrawIndirect: baseVertexLocation & startInstanceLocation broken on DX11/DX12. Vulkan works fine.

Hi,

I think i found a bug in DrawProceduralIndirect in Unity 2022.1.4.f1

The baseVertexLocation and startInstanceLocation of the argument buffer are not being passed to the shader on DX11 and DX12 when using indirect drawing. It works as intended when switching to Vulkan.

I checked this with the indexBuffer versions of Graphics.DrawProceduralIndirect() and CommandBuffer.DrawProceduralIndirect().

Correct results on Vulkan:

SV_VertexID used to access vertex positions in a single “mesh-atlas” buffer:

SV_InstanceID used to offset objects:

Wrong results when switching the Editor to DX11 or DX12:

DX11 (SV_VertexID & SV_InstanceID are always starting at 0. Their values in the arguments buffer are being ignored / are not being passed to the shader):

DX12 (SV_VertexID & SV_InstanceID are always starting at 0. Their values in the arguments buffer are being ignored / are not being passed to the shader):

Is this a bug or intended behaviour?

Please note that the SV_InstanceID bug (if it is one), was already discussed/displayed in this thread from Feb 2017 in more detail. The SV_VertexID bug is not discussed in that thread though.

[Edit]
The shader that was used for testing

[Edit2]
Uploaded example project

Shader "CustomShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
        SubShader
    {
        Tags {
            "LightMode" = "CustomSRP"
            "RenderType" = "Opaque"
        }
        LOD 100
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            //ByteAddressBuffer _VertexPositions;
            StructuredBuffer<float3> _VertexPositions;

            struct appdata
            {
                uint vid : SV_VertexID;
                uint instID : SV_InstanceID;
            };
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 debugColor : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;

                //v.vid += 1224;
                o.vertex = UnityObjectToClipPos(float4(_VertexPositions[v.vid] + float3(v.instID*10,0,0), 1));
                o.debugColor = _VertexPositions[v.vid].xyz;

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float4 col = float4(1,1,1,1);
                col.rgb = i.debugColor.xyz * 0.2f;
 
                return col;
            }
            ENDCG
        }
    }
}

8240757–1077612–ExampleProject.zip (79.2 KB)

bump

Any comment on this from Unity? :slight_smile:

I updated to 2022.1.10f1 today and the bug is still present.
Works fine on Vulkan. Bugged on DX11 & DX12

I reported the bug ( IN-8761 ) on 29.06.22 and got no comment on it so far.

The bug has been confirmed by Unity, but will not be fixed for the time being.

According to the bug’s page, a feature request has been created to explore how this can be fixed in the future.
Please note that parts of this issue have been reported in 2017 already, so you should probably check if you can use another function or a workaround as it might probably take some time before this gets addressed.

We are using Graphics.RenderMeshIndirect now. Using it, baseVertexIndex and startInstance are now correctly passed to the shader when using DX11, DX12 and Vulkan. See this thread for a quick example.