浏览代码

add non-uniform dynamic indexing option to dynamic resources uniform indexing test (#4428)

* add non-uniform dynamic indexing option to dynamic resources uniform indexing test

* assign non-uniform results to different result indices, reduce thread count to 2, use NonUniformResourceIndex correctly

* add non-uniform indexing for samplers, add a definition option in the test, and update the fallback path.

* fixed global variable names, made some simplifications

* unified testing, hardcode 0 for fallback case

* checkpoint, some concerns were addressed

* change test name, make result arrays separate depending on non-uniformity, other fixes

* swapped loops, simplified verification function, fixed 2 fields that weren't reset, other stuff

* variable changes and condition clarity
Joshua Batista 3 年之前
父节点
当前提交
5ebfae414c
共有 2 个文件被更改,包括 255 次插入148 次删除
  1. 125 85
      tools/clang/test/HLSL/ShaderOpArith.xml
  2. 130 63
      tools/clang/unittests/HLSL/ExecutionTest.cpp

+ 125 - 85
tools/clang/test/HLSL/ShaderOpArith.xml

@@ -3494,10 +3494,10 @@ void MSMain(uint GID : SV_GroupIndex,
     </Shader>
   </ShaderOp>
 
-  <ShaderOp Name="DynamicResourcesUniformIndexing" CS="CS66" VS="VS66" PS="PS66">
+  <ShaderOp Name="DynamicResourcesDynamicIndexing" CS="CS66" VS="VS66" PS="PS66">
 
     <Resource Name="ConstantBuffer" Dimension="BUFFER" Width="256" InitialResourceState="COPY_DEST" Init="FromBytes" ReadBack="true">
-      { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u }
+      { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u}
     </Resource>
     
     <Resource Name="T0"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" >
@@ -3508,18 +3508,38 @@ void MSMain(uint GID : SV_GroupIndex,
       11.0
     </Resource>
 
-    <Resource Name="T2"            Dimension="Texture2D"  Width="4" Height="4"  InitialResourceState="COPY_DEST" Init="FromBytes" Format="R32_FLOAT">
-      12.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+    <Resource Name="T2"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" >
+      12.0
+    </Resource>
+
+    <Resource Name="T3"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" >
+      13.0
+    </Resource>
+
+    <Resource Name="T4"            Dimension="Texture2D"  Width="4" Height="4"  InitialResourceState="COPY_DEST" Init="FromBytes" Format="R32_FLOAT">
+      14.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+    </Resource>
+    <Resource Name="T5"            Dimension="Texture2D"  Width="4" Height="4"  InitialResourceState="COPY_DEST" Init="FromBytes" Format="R32_FLOAT">
+      15.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+    </Resource>
+    
+    <Resource Name="U0"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS">
+      20.0
+    </Resource>
+    <Resource Name="U1"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS">
+      21.0
     </Resource>
     
+    <Resource Name="U2"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS">
+      22.0
+    </Resource>
     <Resource Name="U3"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS">
       23.0
     </Resource>
     
-    <Resource Name="U4"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS">
-      24.0
+    <Resource Name="U4"            Dimension="TEXTURE1D"  Width="4"             InitialResourceState="COPY_DEST" Init="FromBytes" Flags="ALLOW_UNORDERED_ACCESS" Format="R32_FLOAT" TransitionTo="UNORDERED_ACCESS">
+      24.0 0 0 0
     </Resource>
-    
     <Resource Name="U5"            Dimension="TEXTURE1D"  Width="4"             InitialResourceState="COPY_DEST" Init="FromBytes" Flags="ALLOW_UNORDERED_ACCESS" Format="R32_FLOAT" TransitionTo="UNORDERED_ACCESS">
       25.0 0 0 0
     </Resource>
@@ -3533,28 +3553,36 @@ void MSMain(uint GID : SV_GroupIndex,
     { 1.0f, -1.0f, 0.0f },
     </Resource>
     
-    <Resource Name="g_result"      Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="ZERO"      Flags="ALLOW_UNORDERED_ACCESS" ReadBack="true"  TransitionTo="UNORDERED_ACCESS"/>
-    <Resource Name="g_resultPS"    Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="ZERO"      Flags="ALLOW_UNORDERED_ACCESS" ReadBack="true"  TransitionTo="UNORDERED_ACCESS"/>
-    <Resource Name="g_resultVS"    Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="ZERO"      Flags="ALLOW_UNORDERED_ACCESS" ReadBack="true"  TransitionTo="UNORDERED_ACCESS"/>
+    <Resource Name="g_result"      Dimension="BUFFER"     Width="64"            InitialResourceState="COPY_DEST" Init="ZERO"      Flags="ALLOW_UNORDERED_ACCESS" ReadBack="true"  TransitionTo="UNORDERED_ACCESS"/>
+    <Resource Name="g_resultPS"    Dimension="BUFFER"     Width="64"            InitialResourceState="COPY_DEST" Init="ZERO"      Flags="ALLOW_UNORDERED_ACCESS" ReadBack="true"  TransitionTo="UNORDERED_ACCESS"/>
+    <Resource Name="g_resultVS"    Dimension="BUFFER"     Width="64"            InitialResourceState="COPY_DEST" Init="ZERO"      Flags="ALLOW_UNORDERED_ACCESS" ReadBack="true"  TransitionTo="UNORDERED_ACCESS"/>
     
     <Resource Name="RTarget" Dimension="TEXTURE2D" Width="16" Height="16" Format="R32G32B32A32_FLOAT" Flags="ALLOW_RENDER_TARGET" InitialResourceState="COPY_DEST" ReadBack="true"/>
 
     <DescriptorHeap Name="ResourceDescriptorHeap" Type="CBV_SRV_UAV">
       <Descriptor Name="T0" Kind="SRV" Flags='RAW' NumElements="1" Format="R32_TYPELESS"/>
-      <Descriptor Name="T1" Kind="SRV" NumElements="1" StructureByteStride="4"/>
-      <Descriptor Name="T2" Kind="SRV" />
-      <Descriptor Name="U3" Kind="UAV" Flags='RAW' NumElements="1" Format="R32_TYPELESS"/>
-      <Descriptor Name="U4" Kind="UAV" NumElements="1" StructureByteStride="4"/>
+      <Descriptor Name="T1" Kind="SRV" Flags='RAW' NumElements="1" Format="R32_TYPELESS"/>
+      <Descriptor Name="T2" Kind="SRV" NumElements="1" StructureByteStride="4"/>
+      <Descriptor Name="T3" Kind="SRV" NumElements="1" StructureByteStride="4"/>
+      <Descriptor Name="T4" Kind="SRV" />
+      <Descriptor Name="T5" Kind="SRV" />
+      <Descriptor Name="U0" Kind="UAV" Flags='RAW' NumElements="1" Format="R32_TYPELESS"/>
+      <Descriptor Name="U1" Kind="UAV" Flags='RAW' NumElements="1" Format="R32_TYPELESS"/>
+      <Descriptor Name="U2" Kind="UAV" NumElements="1" StructureByteStride="4"/>
+      <Descriptor Name="U3" Kind="UAV" NumElements="1" StructureByteStride="4"/>
+      <Descriptor Name="U4" Kind="UAV" Dimension="TEXTURE1D" Format="R32_FLOAT"/>
       <Descriptor Name="U5" Kind="UAV" Dimension="TEXTURE1D" Format="R32_FLOAT"/>
       <Descriptor Name="ConstantBuffer" Kind="CBV"/>
-      <Descriptor Name="g_result"   NumElements="8" Kind="UAV"  StructureByteStride="4"/>
-      <Descriptor Name="g_resultVS" NumElements="8" Kind="UAV"  StructureByteStride="4"/>
-      <Descriptor Name="g_resultPS" NumElements="8" Kind="UAV"  StructureByteStride="4"/>
+      <Descriptor Name="g_result"   NumElements="16" Kind="UAV"  StructureByteStride="4"/>
+      <Descriptor Name="g_resultVS" NumElements="16" Kind="UAV"  StructureByteStride="4"/>
+      <Descriptor Name="g_resultPS" NumElements="16" Kind="UAV"  StructureByteStride="4"/>
     </DescriptorHeap>
 
     <DescriptorHeap Name="SamplerDescriptorHeap" Type="SAMPLER">
-      <Descriptor Kind="SAMPLER" AddressU="BORDER" AddressV="BORDER" BorderColorR="1.0" />
-      <Descriptor Kind="SAMPLER" AddressU="BORDER" AddressV="BORDER" BorderColorR="1.0" ComparisonFunc="EQUAL"/>
+      <Descriptor Kind="SAMPLER" AddressU="BORDER" AddressV="BORDER" BorderColorR="30.0" />
+      <Descriptor Kind="SAMPLER" AddressU="BORDER" AddressV="BORDER" BorderColorR="31.0" />
+      <Descriptor Kind="SAMPLER" AddressU="BORDER" AddressV="BORDER" BorderColorR="32.0" ComparisonFunc="EQUAL"/>
+      <Descriptor Kind="SAMPLER" AddressU="BORDER" AddressV="BORDER" BorderColorR="33.0" ComparisonFunc="EQUAL"/>
     </DescriptorHeap>
     
     <DescriptorHeap Name="RtvHeap" NumDescriptors="1" Type="RTV">
@@ -3576,77 +3604,104 @@ void MSMain(uint GID : SV_GroupIndex,
     <Shader Name="CS66" Target="cs_6_6" EntryPoint="main" Text="@MAIN"/> 
     <!-- -->
     
-    <!-- FALLBACK BEGINS ->
+    <!-- This root value is only applied in the fallback case -->
     <RootValues>
-      <RootValue HeapName="ResourceDescriptorHeap" />
+      <RootValue HeapName="ResourceDescriptorHeap" Index="0" />
+      <RootValue HeapName="SamplerDescriptorHeap"  Index="1" />
     </RootValues>
-    <Shader Name="PS66" Target="ps_6_0" EntryPoint="PSMain" Text="@MAIN" Arguments="/DFALLBACK=1"/>
-    <Shader Name="VS66" Target="vs_6_0" EntryPoint="VSMain" Text="@MAIN" Arguments="/DFALLBACK=1"/>
-    <Shader Name="CS66" Target="cs_6_0" EntryPoint="main" Text="@MAIN" Arguments="/DFALLBACK=1"/>
-    <!- FALLBACK ENDS -->
 
     <Shader Name="MAIN" Target="cs_6_6" EntryPoint="main">
       <![CDATA[
     struct Constants
     {
-      uint idx0, idx1, idx2, idx3, idx4, idx5, idx6, idx7;
+      uint idx0, idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9, idx10;
     };
+    
+    // globally declare these so that non-fallback won't throw an unknown identifier error
+    
+    #ifndef NON_UNIFORM
+    #define INDEXER(idx,ix) idx
+    #else
+    #define INDEXER(idx,ix) NonUniformResourceIndex(idx + ix%2)
+    #endif
 
-    #ifdef FALLBACK
 
-    #define ROOT_SIG [RootSignature("RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), DescriptorTable( SRV(t0), SRV(t1), SRV(t2), UAV(u3), UAV(u4), UAV(u5), CBV(b6), UAV(u7,numDescriptors=3) ), StaticSampler(s0, addressU = TEXTURE_ADDRESS_BORDER, addressV = TEXTURE_ADDRESS_BORDER, borderColor=STATIC_BORDER_COLOR_OPAQUE_WHITE), StaticSampler(s1, addressU = TEXTURE_ADDRESS_BORDER, addressV = TEXTURE_ADDRESS_BORDER, borderColor=STATIC_BORDER_COLOR_OPAQUE_WHITE, comparisonFunc=COMPARISON_EQUAL)")]
+    #ifdef FALLBACK
 
-    ConstantBuffer<Constants> CB : register(b6);
+    #define ROOT_SIG [RootSignature("RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), DescriptorTable( SRV(t0, numDescriptors=6), UAV(u6, numDescriptors=6), CBV(b12), UAV(u13,numDescriptors=3) ), \
+    DescriptorTable(Sampler(s0, numDescriptors=2), Sampler(s2, numDescriptors=2))")]
+    
+    ByteAddressBuffer g_fallback_rawBuf[2]              : register(t0);
+    StructuredBuffer<float> g_fallback_structBuf[2]     : register(t2);
+    Texture2D<float> g_fallback_tex[2]                  : register(t4);
+    RWByteAddressBuffer g_fallback_rwRawBuf[2]          : register(u6);
+    RWStructuredBuffer<float> g_fallback_rwStructBuf[2] : register(u8);
+    RWTexture1D<float> g_fallback_rwTex[2]              : register(u10);
 
-    ByteAddressBuffer g_rawBuf : register(t0);
-    StructuredBuffer<float> g_structBuf : register(t1);
-    Texture2D<float> g_tex : register(t2);
-    RWByteAddressBuffer g_rwRawBuf : register(u3);
-    RWStructuredBuffer<float> g_rwStructBuf : register(u4);
-    RWTexture1D<float> g_rwTex : register(u5);
+    SamplerState g_fallback_samp[2]              : register(s0);
+    SamplerComparisonState g_fallback_sampCmp[2] : register(s2);
 
+    ConstantBuffer<Constants> CB               : register(b12);
     // Result buffers
-    RWBuffer<float> g_result : register(u7);
-    RWBuffer<float> g_resultVS : register(u8);
-    RWBuffer<float> g_resultPS : register(u9);
-
-    SamplerState g_samp : register(s0);
-    SamplerComparisonState g_sampCmp : register(s1);
-
+    RWStructuredBuffer <float> g_result   : register(u13);
+    RWStructuredBuffer <float> g_resultVS : register(u14);
+    RWStructuredBuffer <float> g_resultPS : register(u15);
+    
     #else // NO FALLBACK
 
     #define ROOT_SIG [RootSignature("RootFlags(CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED | SAMPLER_HEAP_DIRECTLY_INDEXED | ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT)")]
-
-    static ConstantBuffer<Constants> CB = ResourceDescriptorHeap[6];
-
-    static ByteAddressBuffer g_rawBuf = ResourceDescriptorHeap[CB.idx0];
-    static StructuredBuffer<float> g_structBuf = ResourceDescriptorHeap[CB.idx1];
-    static Texture2D<float> g_tex = ResourceDescriptorHeap[CB.idx2];
-    static RWByteAddressBuffer g_rwRawBuf = ResourceDescriptorHeap[CB.idx3];
-    static RWStructuredBuffer<float> g_rwStructBuf = ResourceDescriptorHeap[CB.idx4];
-    static RWTexture1D<float> g_rwTex = ResourceDescriptorHeap[CB.idx5];
+    
+    static const int CBIndex = 12;
+    static ConstantBuffer<Constants> CB = ResourceDescriptorHeap[CBIndex];
 
     // Result buffers
-    static RWStructuredBuffer<float> g_result = ResourceDescriptorHeap[7];
-    static RWStructuredBuffer<float> g_resultVS = ResourceDescriptorHeap[8];
-    static RWStructuredBuffer<float> g_resultPS = ResourceDescriptorHeap[9];
+    static RWStructuredBuffer<float> g_result   = ResourceDescriptorHeap[CBIndex+1];
+    static RWStructuredBuffer<float> g_resultVS = ResourceDescriptorHeap[CBIndex+2];
+    static RWStructuredBuffer<float> g_resultPS = ResourceDescriptorHeap[CBIndex+3];
     
-    static SamplerState g_samp = SamplerDescriptorHeap[CB.idx0];
-    static SamplerComparisonState g_sampCmp = SamplerDescriptorHeap[CB.idx1];
-
     #endif // FALLBACK
+    
+    
+    void TestResources(RWStructuredBuffer<float> result, uint ix) {
+        
+    #ifndef FALLBACK
+        ByteAddressBuffer rawBuf = ResourceDescriptorHeap[INDEXER(CB.idx0,ix)];
+        StructuredBuffer<float> structBuf = ResourceDescriptorHeap[INDEXER(CB.idx2,ix)];
+        Texture2D<float> tex = ResourceDescriptorHeap[INDEXER(CB.idx4,ix)];
+        RWByteAddressBuffer rwRawBuf = ResourceDescriptorHeap[INDEXER(CB.idx6,ix)];
+        RWStructuredBuffer<float> rwStructBuf = ResourceDescriptorHeap[INDEXER(CB.idx8,ix)];
+        RWTexture1D<float> rwTex = ResourceDescriptorHeap[INDEXER(CB.idx10,ix)];
+        
+        static SamplerState g_samp = SamplerDescriptorHeap[INDEXER(CB.idx0, ix)];
+        static SamplerComparisonState g_sampCmp  = SamplerDescriptorHeap[INDEXER(CB.idx2, ix)];
+    #endif
+    
+    #ifdef FALLBACK
+        ByteAddressBuffer rawBuf = g_fallback_rawBuf[INDEXER(0,ix)];
+        StructuredBuffer<float> structBuf = g_fallback_structBuf[INDEXER(0,ix)];
+        Texture2D<float> tex = g_fallback_tex[INDEXER(0,ix)];
+        RWByteAddressBuffer rwRawBuf = g_fallback_rwRawBuf[INDEXER(0,ix)];
+        RWStructuredBuffer<float> rwStructBuf = g_fallback_rwStructBuf[INDEXER(0,ix)];
+        RWTexture1D<float> rwTex = g_fallback_rwTex[INDEXER(0,ix)];
+        
+        static SamplerState g_samp = g_fallback_samp[INDEXER(0, ix)];
+        static SamplerComparisonState g_sampCmp = g_fallback_sampCmp[INDEXER(0, ix)];
+   #endif
+
+        result[0*2 + ix%2] = rawBuf.Load<float>(0);
+        result[1*2 + ix%2] = structBuf.Load(0);
+        result[2*2 + ix%2] = tex.Load(0);
+        result[3*2 + ix%2] = rwRawBuf.Load<float>(0);
+        result[4*2 + ix%2] = rwStructBuf.Load(0);
+        result[5*2 + ix%2] = rwTex.Load(0);
+        result[6*2 + ix%2] = tex.SampleLevel(g_samp, -0.5, 0);
+        result[7*2 + ix%2] = tex.SampleCmpLevelZero(g_sampCmp, -0.5, (float)INDEXER(32, ix)) ? (float)INDEXER(32, ix) : 0.0;
+    }
 
     ROOT_SIG
-    [NumThreads(1, 1, 1)]
+    [NumThreads(2, 2, 1)]
     void main(uint ix : SV_GroupIndex) {
-        g_result[0] = g_rawBuf.Load<float>(0);
-        g_result[1] = g_structBuf.Load(0);
-        g_result[2] = g_tex.Load(0);
-        g_result[3] = g_rwRawBuf.Load<float>(0);
-        g_result[4] = g_rwStructBuf.Load(0);
-        g_result[5] = g_rwTex.Load(0);
-        g_result[6] = g_tex.SampleLevel(g_samp, -0.5, 0) ? 30.0 : 0.0;;
-        g_result[7] = g_tex.SampleCmpLevelZero(g_sampCmp, -0.5, 1.0) ? 31.0 : 0.0;
+        TestResources(g_result, ix);
     }
     
     struct PSInput {
@@ -3655,30 +3710,15 @@ void MSMain(uint GID : SV_GroupIndex,
 
     ROOT_SIG
     float4 PSMain(PSInput input) : SV_TARGET {
-        
-        g_resultPS[0] = g_rawBuf.Load<float>(0);
-        g_resultPS[1] = g_structBuf.Load(0);
-        g_resultPS[2] = g_tex.Load(0);
-        g_resultPS[3] = g_rwRawBuf.Load<float>(0);
-        g_resultPS[4] = g_rwStructBuf.Load(0);
-        g_resultPS[5] = g_rwTex.Load(0);
-        g_resultPS[6] = g_tex.SampleLevel(g_samp, -0.5, 0) == 1.0 ? 30.0 : 0.0;
-        g_resultPS[7] = g_tex.SampleCmpLevelZero(g_sampCmp, -0.5, 1.0) ? 31.0 : 0.0;
-        
+        int ix = WaveGetLaneIndex();
+        TestResources(g_resultPS, ix);      
         // This output doesn't actually matter
         return input.position;
     }
     
     ROOT_SIG
-    PSInput VSMain(float3 pos : POSITION) {
-        g_resultVS[0] = g_rawBuf.Load<float>(0);
-        g_resultVS[1] = g_structBuf.Load(0);
-        g_resultVS[2] = g_tex.Load(0);
-        g_resultVS[3] = g_rwRawBuf.Load<float>(0);
-        g_resultVS[4] = g_rwStructBuf.Load(0);
-        g_resultVS[5] = g_rwTex.Load(0);
-        g_resultVS[6] = g_tex.SampleLevel(g_samp, -0.5, 0) == 1.0 ? 30.0 : 0.0;
-        g_resultVS[7] = g_tex.SampleCmpLevelZero(g_sampCmp, -0.5, 1.0) ? 31.0 : 0.0;
+    PSInput VSMain(float3 pos : POSITION, uint ix : SV_VertexID) {
+        TestResources(g_resultVS, ix);
         PSInput r;
         r.position = float4(pos, 1); 
         return r;

+ 130 - 63
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -319,7 +319,7 @@ public:
   TEST_METHOD(HelperLaneTestWave);
   TEST_METHOD(SignatureResourcesTest)
   TEST_METHOD(DynamicResourcesTest)
-  TEST_METHOD(DynamicResourcesUniformIndexingTest)
+  TEST_METHOD(DynamicResourcesDynamicIndexingTest)
 
   TEST_METHOD(QuadReadTest)
   TEST_METHOD(QuadAnyAll);
@@ -1407,6 +1407,13 @@ public:
 #endif
   }
 
+  bool IsFallbackPathEnabled(){
+    // Enable fallback paths with: /p:"EnableFallback=1"
+    UINT EnableFallbackValue = 0;
+    WEX::TestExecution::RuntimeParameters::TryGetValue(L"EnableFallback", EnableFallbackValue);
+    return EnableFallbackValue != 0;
+  }
+
 #ifndef _HLK_CONF
   void DXBCFromText(LPCSTR pText, LPCWSTR pEntryPoint, LPCWSTR pTargetProfile, ID3DBlob **ppBlob) {
     CW2A pEntryPointA(pEntryPoint, CP_UTF8);
@@ -9816,7 +9823,15 @@ void EnableShaderBasedValidation() {
   spDebugController1->SetEnableGPUBasedValidation(true);
 }
 
-TEST_F(ExecutionTest, DynamicResourcesUniformIndexingTest) {
+void VerifyFloatArraysAreEqual(const float* resultFloats, float *expectedResults, int expectedResultsSize)
+{
+  for (int j = 0; j < expectedResultsSize; j++)
+  {
+    VERIFY_ARE_EQUAL(resultFloats[j], expectedResults[j]);
+  } 
+}
+
+TEST_F(ExecutionTest, DynamicResourcesDynamicIndexingTest) {
   //EnableShaderBasedValidation();
   WEX::TestExecution::SetVerifyOutput verifySettings(
       WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
@@ -9827,14 +9842,41 @@ TEST_F(ExecutionTest, DynamicResourcesUniformIndexingTest) {
       std::make_shared<st::ShaderOpSet>();
   st::ParseShaderOpSetFromStream(pStream, ShaderOpSet.get());
   st::ShaderOp *pShaderOp =
-      ShaderOpSet->GetShaderOp("DynamicResourcesUniformIndexing");
+      ShaderOpSet->GetShaderOp("DynamicResourcesDynamicIndexing");
+  vector<st::ShaderOpRootValue> fallbackRootValues = pShaderOp->RootValues;
 
   bool Skipped = true;
 
   //D3D_SHADER_MODEL TestShaderModels[] = {D3D_SHADER_MODEL_6_0}; // FALLBACK
-  D3D_SHADER_MODEL TestShaderModels[] = {D3D_SHADER_MODEL_6_6};
-
-  for (unsigned i = 0; i < _countof(TestShaderModels); i++) {
+  D3D_SHADER_MODEL TestShaderModels[] = {D3D_SHADER_MODEL_6_6, D3D_SHADER_MODEL_6_0};
+
+  const int expectedResultsSize = 16;
+  float expectedResultsUniform[expectedResultsSize] = {
+    10.0, 10.0, 
+    12.0, 12.0,
+    14.0, 14.0, 
+    20.0, 20.0, 
+    22.0, 22.0,
+    24.0, 24.0, 
+    30.0, 30.0, 
+    32.0, 32.0};
+
+  float expectedResultsNonUniform[expectedResultsSize] = {
+    10.0, 11.0, 
+    12.0, 13.0,
+    14.0, 15.0, 
+    20.0, 21.0, 
+    22.0, 23.0,
+    24.0, 25.0, 
+    30.0, 31.0, 
+    32.0, 33.0};
+    
+  // TestShaderModels will be an array, where the first x models are "non-fallback", and the rest of the models
+  // are "fallback". If TestShaderModels has length y, and a test loops through all shader models, a convention
+  // to test based on whether fallback is enabled or not is to limit the loop like this:
+  // unsigned num_models_to_test = ExecutionTest::IsFallbackPathEnabled() ? y : x;
+  unsigned num_models_to_test = ExecutionTest::IsFallbackPathEnabled() ? 2 : 1;
+  for (unsigned i = 0; i < num_models_to_test; i++) {
     D3D_SHADER_MODEL sm = TestShaderModels[i];
     LogCommentFmt(L"\r\nVerifying Dynamic Resources Uniform Indexing in shader "
                   L"model 6.%1u",
@@ -9847,7 +9889,7 @@ TEST_F(ExecutionTest, DynamicResourcesUniformIndexingTest) {
     D3D12_FEATURE_DATA_D3D12_OPTIONS devOptions;
     VERIFY_SUCCEEDED(
         pDevice->CheckFeatureSupport((D3D12_FEATURE)D3D12_FEATURE_D3D12_OPTIONS,
-                                     &devOptions, sizeof(devOptions)));
+                                      &devOptions, sizeof(devOptions)));
     if (devOptions.ResourceBindingTier < D3D12_RESOURCE_BINDING_TIER_3) {
       WEX::Logging::Log::Comment(
           L"Device does not support Resource Binding Tier 3");
@@ -9855,71 +9897,96 @@ TEST_F(ExecutionTest, DynamicResourcesUniformIndexingTest) {
       return;
     }
 
-    // Test Compute shader
-    {
-      pShaderOp->CS = pShaderOp->GetString("CS66");
-      std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTestAfterParse(
-          pDevice, m_support, "DynamicResourcesUniformIndexing", nullptr,
-          ShaderOpSet);
+    for (unsigned int non_uniform_bit = 0; non_uniform_bit < 2; non_uniform_bit++) {
+      float *expectedResults = non_uniform_bit ? expectedResultsNonUniform : expectedResultsUniform;
 
-      MappedData resultData;
-      test->Test->GetReadBackData("g_result", &resultData);
-      const float *resultFloats = (float *)resultData.data();
+      LogCommentFmt(L"Testing %s Resource Indexing.", non_uniform_bit ? L"NonUniform" : L"Uniform");
 
-      VERIFY_ARE_EQUAL(resultFloats[0], 10.0F);
-      VERIFY_ARE_EQUAL(resultFloats[1], 11.0F);
-      VERIFY_ARE_EQUAL(resultFloats[2], 12.0F);
-      VERIFY_ARE_EQUAL(resultFloats[3], 23.0F);
-      VERIFY_ARE_EQUAL(resultFloats[4], 24.0F);
-      VERIFY_ARE_EQUAL(resultFloats[5], 25.0F);
-      VERIFY_ARE_EQUAL(resultFloats[6], 30.0F);
-      VERIFY_ARE_EQUAL(resultFloats[7], 31.0F);
-    }
+      // Add compile options
+      std::string compilerOptions = "";
+      if (sm==D3D_SHADER_MODEL_6_0)
+        compilerOptions += " -D FALLBACK=1";
+      if (non_uniform_bit)
+        compilerOptions += " -D NON_UNIFORM=1";
 
-    // Test Vertex + Pixel shader
-    {
-      pShaderOp->CS = nullptr;
-      pShaderOp->VS = pShaderOp->GetString("VS66");
-      pShaderOp->PS = pShaderOp->GetString("PS66");
-      std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTestAfterParse(
-          pDevice, m_support, "DynamicResourcesUniformIndexing", nullptr,
-          ShaderOpSet);
-
-      MappedData resultVSData;
-      MappedData resultPSData;
-      test->Test->GetReadBackData("g_resultVS", &resultVSData);
-      test->Test->GetReadBackData("g_resultPS", &resultPSData);
-      const float *resultVSFloats = (float *)resultVSData.data();
-      const float *resultPSFloats = (float *)resultPSData.data();
-      D3D12_QUERY_DATA_PIPELINE_STATISTICS Stats;
-      test->Test->GetPipelineStats(&Stats);
-
-
-      // VS
-      VERIFY_ARE_EQUAL(resultVSFloats[0], 10.0F);
-      VERIFY_ARE_EQUAL(resultVSFloats[1], 11.0F);
-      VERIFY_ARE_EQUAL(resultVSFloats[2], 12.0F);
-      VERIFY_ARE_EQUAL(resultVSFloats[3], 23.0F);
-      VERIFY_ARE_EQUAL(resultVSFloats[4], 24.0F);
-      VERIFY_ARE_EQUAL(resultVSFloats[5], 25.0F);
-      VERIFY_ARE_EQUAL(resultVSFloats[6], 30.0F);
-      VERIFY_ARE_EQUAL(resultVSFloats[7], 31.0F);
+      // by default a root value is added.
+      // remove the root value if this is the non-fallback path
+      if (sm==D3D_SHADER_MODEL_6_6)
+      {
+        pShaderOp->RootValues.clear();
+      }
+      else
+      {
+         pShaderOp->RootValues = fallbackRootValues;
+      }
 
-      // PS
-      VERIFY_ARE_EQUAL(resultPSFloats[0], 10.0F);
-      VERIFY_ARE_EQUAL(resultPSFloats[1], 11.0F);
-      VERIFY_ARE_EQUAL(resultPSFloats[2], 12.0F);
-      VERIFY_ARE_EQUAL(resultPSFloats[3], 23.0F);
-      VERIFY_ARE_EQUAL(resultPSFloats[4], 24.0F);
-      VERIFY_ARE_EQUAL(resultPSFloats[5], 25.0F);
-      VERIFY_ARE_EQUAL(resultPSFloats[6], 30.0F);
-      VERIFY_ARE_EQUAL(resultPSFloats[7], 31.0F);
+      // Update shader target in xml.
+      for (st::ShaderOpShader &S : pShaderOp->Shaders){
+        S.Arguments = NULL;
+        if (!compilerOptions.empty()){
+          S.Arguments = pShaderOp->GetString(compilerOptions.c_str());
+        }        
+        // Set the target correctly. Setting here permanently overwrites
+        // the Target string even in future iterations.
+        if (sm==D3D_SHADER_MODEL_6_0){
+          std::string Target(S.Target);
+          Target[Target.length() - 1] = '0';
+          S.Target = pShaderOp->GetString(Target.c_str());
+        }
+        else if (sm==D3D_SHADER_MODEL_6_6){
+          std::string Target(S.Target);
+          Target[Target.length() - 1] = '6';
+          S.Target = pShaderOp->GetString(Target.c_str());
+        }
+      }
+
+      // Test Compute shader
+      {
+        pShaderOp->CS = pShaderOp->GetString("CS66");
+        std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTestAfterParse(
+            pDevice, m_support, "DynamicResourcesDynamicIndexing", nullptr,
+            ShaderOpSet);
+
+        MappedData resultData;
+        test->Test->GetReadBackData("g_result", &resultData);
+        const float *resultCSFloats = (float *)resultData.data();
+
+        VerifyFloatArraysAreEqual(resultCSFloats, expectedResults, expectedResultsSize);
+      }
+
+      // Test Vertex + Pixel shader
+      {
+        pShaderOp->CS = nullptr;
+        pShaderOp->VS = pShaderOp->GetString("VS66");
+        pShaderOp->PS = pShaderOp->GetString("PS66");
+        std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTestAfterParse(
+            pDevice, m_support, "DynamicResourcesDynamicIndexing", nullptr,
+            ShaderOpSet);
+
+        MappedData resultVSData;
+        MappedData resultPSData;
+        test->Test->GetReadBackData("g_resultVS", &resultVSData);
+        test->Test->GetReadBackData("g_resultPS", &resultPSData);
+        const float *resultVSFloats = (float *)resultVSData.data();
+        const float *resultPSFloats = (float *)resultPSData.data();
+        D3D12_QUERY_DATA_PIPELINE_STATISTICS Stats;
+        test->Test->GetPipelineStats(&Stats);
+
+
+        // VS
+        VerifyFloatArraysAreEqual(resultVSFloats, expectedResults, expectedResultsSize);
+
+        // PS
+        VerifyFloatArraysAreEqual(resultPSFloats, expectedResults, expectedResultsSize);
+      }
+      Skipped = false;
     }
-    Skipped = false;
   }
+
   if (Skipped) {
     WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
   }
+  
 }
 
 #define MAX_WAVESIZE 128