Search Unity

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

Discussion in 'General Graphics' started by dotmos, Jun 29, 2022.

  1. dotmos

    dotmos

    Joined:
    Jan 2, 2011
    Posts:
    41
    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:
    Vulkan_BaseVertexOffset.JPG

    SV_InstanceID used to offset objects:
    Vulkan_InstanceID.JPG



    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):
    DX11.JPG

    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):
    DX12.JPG


    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

    Code (CSharp):
    1.  
    2. Shader "CustomShader"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Texture", 2D) = "white" {}
    7.     }
    8.         SubShader
    9.     {
    10.         Tags {
    11.             "LightMode" = "CustomSRP"
    12.             "RenderType" = "Opaque"
    13.         }
    14.         LOD 100
    15.         Pass
    16.         {
    17.             CGPROGRAM
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.             #include "UnityCG.cginc"
    21.  
    22.             //ByteAddressBuffer _VertexPositions;
    23.             StructuredBuffer<float3> _VertexPositions;
    24.  
    25.             struct appdata
    26.             {
    27.                 uint vid : SV_VertexID;
    28.                 uint instID : SV_InstanceID;
    29.             };
    30.             struct v2f
    31.             {
    32.                 float4 vertex : SV_POSITION;
    33.                 float3 debugColor : TEXCOORD0;
    34.             };
    35.  
    36.             sampler2D _MainTex;
    37.             float4 _MainTex_ST;
    38.  
    39.             v2f vert (appdata v)
    40.             {
    41.                 v2f o;
    42.  
    43.                 //v.vid += 1224;
    44.                 o.vertex = UnityObjectToClipPos(float4(_VertexPositions[v.vid] + float3(v.instID*10,0,0), 1));
    45.                 o.debugColor = _VertexPositions[v.vid].xyz;
    46.  
    47.                 return o;
    48.             }
    49.  
    50.             fixed4 frag (v2f i) : SV_Target
    51.             {
    52.                 float4 col = float4(1,1,1,1);
    53.                 col.rgb = i.debugColor.xyz * 0.2f;
    54.  
    55.                 return col;
    56.             }
    57.             ENDCG
    58.         }
    59.     }
    60. }
    61.  
     

    Attached Files:

    Last edited: Jun 29, 2022
  2. dotmos

    dotmos

    Joined:
    Jan 2, 2011
    Posts:
    41
    bump

    Any comment on this from Unity? :)

    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.
     
  3. dotmos

    dotmos

    Joined:
    Jan 2, 2011
    Posts:
    41
    The bug has been confirmed by Unity, but will not be fixed for the time being.

    https://issuetracker.unity3d.com/is...en-using-directx11-directx12-opengl-and-metal

    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.