Explorar o código

User/jbatista/drui hlk test02 (#4413)

* Made nologo option hidden

* working tests for compute and ps/vs shaders

* working tests for compute and ps/vs shaders

* Fix test and add fallback mode for SM 6.0 to verify test logic

* Correct StructuredBuffer descriptors

* add separate result buffers for each shader, other changes from Tex

* fallback works, add transition to field to uav's

fallback works, add transition to field to uav's. 6_6 still returns all 0's, and there's a message about highest debug layer model supported being 6_5

* fallback works, and on non-fallback, CS works.

* change hardcoded to true rval

* swap root signature and set descriptor heaps so that heaps comes before root

* Remove unnecessary comments, fix indexing to be completely dynamic

* remove extraneous resources in root sig, and use Test_F macro in execution test

Co-authored-by: Tex Riddell <[email protected]>
Joshua Batista %!s(int64=3) %!d(string=hai) anos
pai
achega
72d679ae86

+ 193 - 0
tools/clang/test/HLSL/ShaderOpArith.xml

@@ -3482,4 +3482,197 @@ void MSMain(uint GID : SV_GroupIndex,
 ]]>
     </Shader>
   </ShaderOp>
+
+  <ShaderOp Name="DynamicResourcesUniformIndexing" 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 }
+    </Resource>
+    
+    <Resource Name="T0"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" >
+      10.0
+    </Resource>
+
+    <Resource Name="T1"            Dimension="BUFFER"     Width="32"            InitialResourceState="COPY_DEST" Init="FromBytes" >
+      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>
+    
+    <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>
+    
+    <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>
+    
+    <Resource Name="VBuffer" Dimension="BUFFER" InitialResourceState="COPY_DEST" Init="FromBytes" Topology="TRIANGLELIST">
+    { -1.0f, 1.0f, 0.0f },
+    { 1.0f, 1.0f, 0.0f },
+    { -1.0f, -1.0f, 0.0f },
+    { -1.0f, -1.0f, 0.0f },
+    { 1.0f, 1.0f, 0.0f },
+    { 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="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="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"/>
+    </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"/>
+    </DescriptorHeap>
+    
+    <DescriptorHeap Name="RtvHeap" NumDescriptors="1" Type="RTV">
+      <Descriptor Name="RTarget" Kind="RTV"/>
+    </DescriptorHeap>
+
+    <InputElements>
+      <InputElement SemanticName="POSITION" Format="R32G32B32_FLOAT" AlignedByteOffset="0" />
+    </InputElements>
+    <RenderTargets>
+      <RenderTarget Name="RTarget">
+        <Viewport Width="2.0" Height="2.0" MaxDepth="1.0"/>
+      </RenderTarget>
+    </RenderTargets>
+
+    <!-- -->
+    <Shader Name="PS66" Target="ps_6_6" EntryPoint="PSMain" Text="@MAIN"/> 
+    <Shader Name="VS66" Target="vs_6_6" EntryPoint="VSMain" Text="@MAIN"/>
+    <Shader Name="CS66" Target="cs_6_6" EntryPoint="main" Text="@MAIN"/> 
+    <!-- -->
+    
+    <!-- FALLBACK BEGINS ->
+    <RootValues>
+      <RootValue HeapName="ResourceDescriptorHeap" />
+    </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;
+    };
+
+    #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)")]
+
+    ConstantBuffer<Constants> CB : register(b6);
+
+    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);
+
+    // 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);
+
+    #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];
+
+    // Result buffers
+    static RWStructuredBuffer<float> g_result = ResourceDescriptorHeap[7];
+    static RWStructuredBuffer<float> g_resultVS = ResourceDescriptorHeap[8];
+    static RWStructuredBuffer<float> g_resultPS = ResourceDescriptorHeap[9];
+    
+    static SamplerState g_samp = SamplerDescriptorHeap[CB.idx0];
+    static SamplerComparisonState g_sampCmp = SamplerDescriptorHeap[CB.idx1];
+
+    #endif // FALLBACK
+
+    ROOT_SIG
+    [NumThreads(1, 1, 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;
+    }
+    
+    struct PSInput {
+      float4 position : SV_POSITION;
+    };
+
+    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;
+        
+        // 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 r;
+        r.position = float4(pos, 1); 
+        return r;
+    }
+  ]]>
+    </Shader>
+  </ShaderOp>
 </ShaderOpSet>

+ 118 - 0
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -319,6 +319,8 @@ public:
   TEST_METHOD(HelperLaneTestWave);
   TEST_METHOD(SignatureResourcesTest)
   TEST_METHOD(DynamicResourcesTest)
+  TEST_METHOD(DynamicResourcesUniformIndexingTest)
+
   TEST_METHOD(QuadReadTest)
   TEST_METHOD(QuadAnyAll);
 
@@ -9710,6 +9712,122 @@ TEST_F(ExecutionTest, DynamicResourcesTest) {
   RunResourceTest(pDevice, pShader, L"cs_6_6", /*isDynamic*/true);
 }
 
+//void ExecutionTest::TestComputeShaderDynamicResourcesUniformIndexing()
+
+void EnableShaderBasedValidation() {
+  CComPtr<ID3D12Debug> spDebugController0;
+  CComPtr<ID3D12Debug1> spDebugController1;
+  VERIFY_SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&spDebugController0)));
+  VERIFY_SUCCEEDED(
+      spDebugController0->QueryInterface(IID_PPV_ARGS(&spDebugController1)));
+  spDebugController1->SetEnableGPUBasedValidation(true);
+}
+
+TEST_F(ExecutionTest, DynamicResourcesUniformIndexingTest) {
+  //EnableShaderBasedValidation();
+  WEX::TestExecution::SetVerifyOutput verifySettings(
+      WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
+  CComPtr<IStream> pStream;
+  ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
+
+  std::shared_ptr<st::ShaderOpSet> ShaderOpSet =
+      std::make_shared<st::ShaderOpSet>();
+  st::ParseShaderOpSetFromStream(pStream, ShaderOpSet.get());
+  st::ShaderOp *pShaderOp =
+      ShaderOpSet->GetShaderOp("DynamicResourcesUniformIndexing");
+
+  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 sm = TestShaderModels[i];
+    LogCommentFmt(L"\r\nVerifying Dynamic Resources Uniform Indexing in shader "
+                  L"model 6.%1u",
+                  ((UINT)sm & 0x0f));
+
+    CComPtr<ID3D12Device> pDevice;
+    if (!CreateDevice(&pDevice, sm, false /* skipUnsupported */)) {
+      continue;
+    }
+    D3D12_FEATURE_DATA_D3D12_OPTIONS devOptions;
+    VERIFY_SUCCEEDED(
+        pDevice->CheckFeatureSupport((D3D12_FEATURE)D3D12_FEATURE_D3D12_OPTIONS,
+                                     &devOptions, sizeof(devOptions)));
+    if (devOptions.ResourceBindingTier < D3D12_RESOURCE_BINDING_TIER_3) {
+      WEX::Logging::Log::Comment(
+          L"Device does not support Resource Binding Tier 3");
+      WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+      return;
+    }
+
+    // Test Compute shader
+    {
+      pShaderOp->CS = pShaderOp->GetString("CS66");
+      std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTestAfterParse(
+          pDevice, m_support, "DynamicResourcesUniformIndexing", nullptr,
+          ShaderOpSet);
+
+      MappedData resultData;
+      test->Test->GetReadBackData("g_result", &resultData);
+      const float *resultFloats = (float *)resultData.data();
+
+      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);
+    }
+
+    // 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);
+
+      // 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);
+    }
+    Skipped = false;
+  }
+  if (Skipped) {
+    WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+  }
+}
 
 #define MAX_WAVESIZE 128
 

+ 10 - 2
tools/clang/unittests/HLSL/ShaderOpTest.cpp

@@ -326,6 +326,14 @@ void ShaderOpTest::CreateDescriptorHeaps() {
           ShaderOpResourceData &CounterData = m_ResourceData[D.CounterName];
           pCounterResource = CounterData.Resource;
         }
+        ShaderOpResource *R = m_pShaderOp->GetResourceByName(D.ResName);
+        // Ensure the TransitionTo state is set for UAV's that will be used as UAV's.
+        if (R && R->TransitionTo != D3D12_RESOURCE_STATE_UNORDERED_ACCESS) {
+          ShaderOpLogFmt(L"Resource '%S' used in UAV descriptor, but "
+                         L"TransitionTo not set to 'UNORDERED_ACCESS'",
+                         D.ResName);
+          CHECK_HR(E_FAIL);
+        }
         m_pDevice->CreateUnorderedAccessView(pResource, pCounterResource,
                                              &D.UavDesc, cpuHandle);
       }
@@ -891,15 +899,15 @@ void ShaderOpTest::RunCommandList() {
   ID3D12GraphicsCommandList *pList = m_CommandList.List.p;
   if (m_pShaderOp->IsCompute()) {
     pList->SetPipelineState(m_pPSO);
-    pList->SetComputeRootSignature(m_pRootSignature);
     SetDescriptorHeaps(pList, m_DescriptorHeaps);
+    pList->SetComputeRootSignature(m_pRootSignature);
     SetRootValues(pList, m_pShaderOp->IsCompute());
     pList->Dispatch(m_pShaderOp->DispatchX, m_pShaderOp->DispatchY,
                     m_pShaderOp->DispatchZ);
   } else {
     pList->SetPipelineState(m_pPSO);
-    pList->SetGraphicsRootSignature(m_pRootSignature);
     SetDescriptorHeaps(pList, m_DescriptorHeaps);
+    pList->SetGraphicsRootSignature(m_pRootSignature);
     SetRootValues(pList, m_pShaderOp->IsCompute());
 
     D3D12_VIEWPORT viewport;