2
0
Эх сурвалжийг харах

Add 2D quads to ComputeSample test (#3420)

Change test to represent both 1D and 2D quad layout options
Greg Roth 4 жил өмнө
parent
commit
f069cc9649

+ 71 - 29
tools/clang/test/HLSL/ShaderOpArith.xml

@@ -355,15 +355,15 @@
       { { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f } },
       { { 1.0f, -1.0f, 0.0f }, { 1.0f, 1.0f } }
     </Resource>
-    <Resource Name="T0" Dimension="Texture2D" Width="64" Height="64" MipLevels="7" InitialResourceState="COPY_DEST" Init="ByName" Format="R32_FLOAT" />
-    <Resource Name="RTarget" Dimension="TEXTURE2D" Width="8" Height="8" Format="R32G32B32A32_FLOAT" Flags="ALLOW_RENDER_TARGET" InitialResourceState="COPY_DEST" />
-    <Resource Name="U0" Dimension="BUFFER" Width="1920"
+    <Resource Name="T0" Dimension="Texture2D" Width="1008" Height="1008" MipLevels="7" InitialResourceState="COPY_DEST" Init="ByName" Format="R32_FLOAT" />
+    <Resource Name="RTarget" Dimension="TEXTURE2D" Width="84" Height="4" Format="R32G32B32A32_FLOAT" Flags="ALLOW_RENDER_TARGET" InitialResourceState="COPY_DEST" />
+    <Resource Name="U0" Dimension="BUFFER" Width="16384"
               Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST"
               Init="Zero" ReadBack="true" />
-    <Resource Name="U1" Dimension="BUFFER" Width="1920"
+    <Resource Name="U1" Dimension="BUFFER" Width="2048"
               Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST"
               Init="Zero" ReadBack="true" />
-    <Resource Name="U2" Dimension="BUFFER" Width="1920"
+    <Resource Name="U2" Dimension="BUFFER" Width="2048"
               Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST"
               Init="Zero" ReadBack="true" />
 
@@ -373,11 +373,11 @@
     <DescriptorHeap Name="ResHeap" Type="CBV_SRV_UAV">
       <Descriptor Name='T0' Kind='SRV' ResName='T0' />
       <Descriptor Name='U0' Kind='UAV' ResName='U0'
-                  NumElements="64" StructureByteStride="16" />
+                  NumElements="1008" StructureByteStride="16" />
       <Descriptor Name='U1' Kind='UAV' ResName='U1'
-                  NumElements="64" StructureByteStride="16" />
+                  NumElements="128" StructureByteStride="16" />
       <Descriptor Name='U2' Kind='UAV' ResName='U2'
-                  NumElements="64" StructureByteStride="16" />
+                  NumElements="128" StructureByteStride="16" />
     </DescriptorHeap>
     <DescriptorHeap Name="RtvHeap" NumDescriptors="1" Type="RTV">
       <Descriptor Name="RTarget" Kind="RTV"/>
@@ -390,9 +390,12 @@
     <RenderTargets>
       <RenderTarget Name="RTarget"/>
     </RenderTargets>
-    <Shader Name="CS" Target="cs_6_6" EntryPoint="CSMain" Text="@PS"/>
-    <Shader Name="AS" Target="as_6_6" EntryPoint="ASMain" Text="@PS"/>
-    <Shader Name="MS" Target="ms_6_6" EntryPoint="MSMain" Text="@PS"/>
+    <Shader Name="CS" Target="cs_6_6" EntryPoint="CSMain1D" Text="@PS"/>
+    <Shader Name="AS" Target="as_6_6" EntryPoint="ASMain1D" Text="@PS"/>
+    <Shader Name="MS" Target="ms_6_6" EntryPoint="MSMain1D" Text="@PS"/>
+    <Shader Name="CS2" Target="cs_6_6" EntryPoint="CSMain2D" Text="@PS"/>
+    <Shader Name="AS2" Target="as_6_6" EntryPoint="ASMain2D" Text="@PS"/>
+    <Shader Name="MS2" Target="ms_6_6" EntryPoint="MSMain2D" Text="@PS"/>
     <Shader Name="VS" Target="vs_6_0" EntryPoint="VSMain" Text="@PS"/>
     <Shader Name="PS" Target="ps_6_0" EntryPoint="PSMain">
       <![CDATA[
@@ -415,8 +418,7 @@
 
         SamplerState g_samp : register(s0);
 
-        uint4 DerivTest(uint ix, float left, float right, float top, float bot) {
-          uint iy = ix>>1;
+        uint4 DerivTest(uint ix, uint iy, float left, float right, float top, float bot) {
           return uint4(g_tex.CalculateLevelOfDetail(g_samp, float2(left, 0.5)) * (~ix&1) +
                        g_tex.CalculateLevelOfDetail(g_samp, float2(right, 0.5)) * (ix&1),
                        g_tex.Sample(g_samp, float2(left, 0.5)) * (~ix&1) +
@@ -429,10 +431,10 @@
 
         // To avoid conditionals, two samples are performed one for left one for right
         // They are step functioned on or off depending
-        uint4 DerivTest(uint ix) {
+        uint4 DerivTest(uint ix, float threadCt) {
           uint iy = ix>>1;
-          return DerivTest(ix, ((ix^1)/64.0)*(ix&1), (ix/64.0)*(ix&1),
-                               ((ix^2)/64.0)*(iy&1), (ix/64.0)*(iy&1));
+          return DerivTest(ix, iy, ((ix^1)/threadCt)*(ix&1), (ix/threadCt)*(ix&1),
+                                   ((ix^2)/threadCt)*(iy&1), (ix/threadCt)*(iy&1));
         }
 
         static float4 g_Verts[6] = {
@@ -457,17 +459,37 @@
           uint nothing;
         };
 
-        [NumThreads(8, 8, 1)]
-        void ASMain(uint ix : SV_GroupIndex) {
+        uint convert2Dto1D(uint x, uint y, uint width) {
+          // Convert 2D coords to 1D for testing
+          // All completed rows of quads
+          uint prevRows = (y/2)*2*width;
+          // All previous full quads on this quad row
+          uint prevQuads = (x/2)*4;
+          // index into current quad
+          uint quadIx = (y&1)*2 + (x&1);
+          return prevRows + prevQuads + quadIx;
+        }
+
+        [NumThreads(116, 1, 1)]
+        void ASMain1D(uint ix : SV_GroupIndex) {
           Payload payload;
-          g_bufAmp[ix] = DerivTest(ix);
+          g_bufAmp[ix] = DerivTest(ix, 116);
+          payload.nothing = 0;
+          DispatchMesh(1, 1, 1, payload);
+        }
+
+        [NumThreads(42, 2, 1)]
+        void ASMain2D(uint3 id : SV_GroupThreadID) {
+          Payload payload;
+          uint ix = convert2Dto1D(id.x, id.y, 42);
+          g_bufAmp[ix] = DerivTest(ix, 42*2);
           payload.nothing = 0;
           DispatchMesh(1, 1, 1, payload);
         }
 
-        [NumThreads(8, 8, 1)]
+        [NumThreads(116, 1, 1)]
         [OutputTopology("triangle")]
-        void MSMain(
+        void MSMain1D(
           uint ix : SV_GroupIndex,
           in payload Payload payload,
           out vertices PSInput verts[6],
@@ -477,19 +499,39 @@
             verts[ix%6].position = g_Verts[ix%6];
             verts[ix%6].uv = g_UV[ix%6];
             tris[ix&1] = uint3((ix&1)*3, (ix&1)*3 + 1, (ix&1)*3 + 2);
-            g_bufMesh[ix] = DerivTest(ix);
+            g_bufMesh[ix] = DerivTest(ix, 116);
+        }
+
+        [NumThreads(42, 2, 1)]
+        [OutputTopology("triangle")]
+        void MSMain2D(
+          uint3 id : SV_GroupThreadID,
+          in payload Payload payload,
+          out vertices PSInput verts[6],
+          out indices uint3 tris[2]) {
+            SetMeshOutputCounts(6, 2);
+            uint ix = convert2Dto1D(id.x, id.y, 42);
+            // Assign static fullscreen 2 tri quad
+            verts[ix%6].position = g_Verts[ix%6];
+            verts[ix%6].uv = g_UV[ix%6];
+            tris[ix&1] = uint3((ix&1)*3, (ix&1)*3 + 1, (ix&1)*3 + 2);
+            g_bufMesh[ix] = DerivTest(ix, 42*2);
         }
 
         float4 PSMain(PSInput input) : SV_TARGET {
-          int ix = int(input.uv.y * 8) * 8 + int(input.uv.x * 8);
-          // Contort the linear index into quad order by rotating relevant middle bits
-          ix = (ix&~0xE)|((ix&0x8)>>2)|((ix&0x6)<<1);
-          g_bufMain[ix] = DerivTest(ix);
+          uint ix = convert2Dto1D(input.uv.x, input.uv.y, 84);
+          g_bufMain[ix] = DerivTest(ix, 84*4*3);
           return 1;
         }
-        [NumThreads(8, 8, 1)]
-        void CSMain(uint ix : SV_GroupIndex) {
-          g_bufMain[ix] = DerivTest(ix);
+        [NumThreads(1008, 1, 1)]
+        void CSMain1D(uint ix : SV_GroupIndex) {
+          g_bufMain[ix] = DerivTest(ix, 1008);
+        }
+
+        [NumThreads(84, 4, 3)]
+        void CSMain2D(uint3 id : SV_GroupThreadID) {
+          uint ix = convert2Dto1D(id.x, id.y, 84);
+          g_bufMain[ix] = DerivTest(ix, 84*4*3);
         }
 
       ]]>

+ 48 - 7
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -3305,7 +3305,7 @@ TEST_F(ExecutionTest, QuadReadTest) {
   }
 }
 
-void VerifySampleResults(const UINT *pPixels) {
+void VerifySampleResults(const UINT *pPixels, UINT width) {
   UINT xlod = 0;
   UINT ylod = 0;
   // Each pixel contains 4 samples and 4 LOD calculations.
@@ -3323,7 +3323,7 @@ void VerifySampleResults(const UINT *pPixels) {
   // in both directions might result in different levels for different locations
   // in the quad. So only comparisons between sample results and LOD calculations
   // and ensuring that the LOD increased and reaches the max can be tested reliably.
-  for (unsigned i = 0; i < 64; i++) {
+  for (unsigned i = 0; i < width; i++) {
     // CalculateLOD and Sample from texture with mip levels containing LOD index should match
     VERIFY_ARE_EQUAL(pPixels[4*i + 0], pPixels[4*i + 1]);
     VERIFY_ARE_EQUAL(pPixels[4*i + 2], pPixels[4*i + 3]);
@@ -3353,14 +3353,13 @@ TEST_F(ExecutionTest, ComputeSampleTest) {
 
   st::ShaderOp *pShaderOp = ShaderOpSet->GetShaderOp("ComputeSample");
 
-  D3D12_RESOURCE_DESC &texDesc = pShaderOp->GetResourceByName("T0")->Desc;
-  UINT texWidth = (UINT)texDesc.Width;
-  UINT texHeight = (UINT)texDesc.Height;
-
   // Initialize texture with the LOD number in each corresponding mip level
   auto SampleInitFn = [&](LPCSTR Name, std::vector<BYTE> &Data, st::ShaderOp *pShaderOp) {
                         UNREFERENCED_PARAMETER(pShaderOp);
                         VERIFY_ARE_EQUAL(0, _stricmp(Name, "T0"));
+                        D3D12_RESOURCE_DESC &texDesc = pShaderOp->GetResourceByName("T0")->Desc;
+                        UINT texWidth = (UINT)texDesc.Width;
+                        UINT texHeight = (UINT)texDesc.Height;
                         size_t size = sizeof(float) * texWidth * texHeight * 2;
                         Data.resize(size);
                         float *pPrimitives = (float *)Data.data();
@@ -3379,17 +3378,59 @@ TEST_F(ExecutionTest, ComputeSampleTest) {
                           texWidth >>= 1;
                         }
                       };
+  LPCSTR CS2 = nullptr, AS2 = nullptr, MS2 = nullptr;
+  for (st::ShaderOpShader &S : pShaderOp->Shaders) {
+    if (!strcmp(S.Name, "CS2")) CS2 = S.Name;
+    if (!strcmp(S.Name, "AS2")) AS2 = S.Name;
+    if (!strcmp(S.Name, "MS2")) MS2 = S.Name;
+  }
+
+  // Test 1D compute shader
   std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTestAfterParse(pDevice, m_support, "ComputeSample", SampleInitFn, ShaderOpSet);
   MappedData data;
 
   test->Test->GetReadBackData("U0", &data);
   const UINT *pPixels = (UINT *)data.data();
 
-  VerifySampleResults(pPixels);
+  VerifySampleResults(pPixels, 1008);
+
+  // Test 2D compute shader
+  pShaderOp->CS = CS2;
+
+  test = RunShaderOpTestAfterParse(pDevice, m_support, "ComputeSample", SampleInitFn, ShaderOpSet);
+
+  test->Test->GetReadBackData("U0", &data);
+  pPixels = (UINT *)data.data();
+
+  VerifySampleResults(pPixels, 1008);
+
+
   if (DoesDeviceSupportMeshAmpDerivatives(pDevice)) {
     // Disable CS so mesh goes forward
     pShaderOp->CS = nullptr;
     test = RunShaderOpTestAfterParse(pDevice, m_support, "ComputeSample", SampleInitFn, ShaderOpSet);
+    test->Test->GetReadBackData("U1", &data);
+    pPixels = (UINT *)data.data();
+
+    VerifySampleResults(pPixels, 116);
+
+    test->Test->GetReadBackData("U2", &data);
+    pPixels = (UINT *)data.data();
+
+    VerifySampleResults(pPixels, 84);
+
+    pShaderOp->AS = AS2;
+    pShaderOp->MS = MS2;
+    test = RunShaderOpTestAfterParse(pDevice, m_support, "ComputeSample", SampleInitFn, ShaderOpSet);
+    test->Test->GetReadBackData("U1", &data);
+    pPixels = (UINT *)data.data();
+
+    VerifySampleResults(pPixels, 116);
+
+    test->Test->GetReadBackData("U2", &data);
+    pPixels = (UINT *)data.data();
+
+    VerifySampleResults(pPixels, 84);
   }
 }