Browse Source

Add rawBufferLoad/rawBufferStore tests for the graphics pipeline (#1801)

Add rawBufferLoad/rawBufferStore tests for the graphics pipeline

Covers:
- SRV (Load) and UAV buffers (Load, Store)
- declared in root signature as root values and in a descriptor table
- used as [RW]ByteAddressBuffer and [RW]StructuredBuffer
- data types half, float, double, int16_t, int32_t, int64_t,
- scalar type + vectors with 2 to 4 elements

The 16-bit type tests are temporarily disabled because of a bug in WARP
(set to Priority 2 and not run by hcttest).
Helena Kotas 6 years ago
parent
commit
534ee6d2a7
2 changed files with 387 additions and 127 deletions
  1. 174 9
      tools/clang/test/HLSL/ShaderOpArith.xml
  2. 213 118
      tools/clang/unittests/HLSL/ExecutionTest.cpp

+ 174 - 9
tools/clang/test/HLSL/ShaderOpArith.xml

@@ -666,18 +666,183 @@
     </Shader>
   </ShaderOp>>
 
-  <ShaderOp Name="GraphicsRawBufferLdStI32" PS="PS" VS="VS">
-  </ShaderOp>
-  <ShaderOp Name="GraphicsRawBufferLdStFloat" PS="PS" VS="VS">
-  </ShaderOp>
-  <ShaderOp Name="GraphicsRawBufferLdStI64" PS="PS" VS="VS">
-  </ShaderOp>
-  <ShaderOp Name="GraphicsRawBufferLdStDouble" PS="PS" VS="VS">
+  <ShaderOp Name="GraphicsRawBufferLdSt32Bit" PS="PS" VS="VS">
+    <RootSignature>RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), SRV(t0), SRV(t1), UAV(u0), UAV(u1), DescriptorTable(SRV(t2,numDescriptors=2), UAV(u2,numDescriptors=2))</RootSignature>
+    <Resource Name="SRVBuffer0" Dimension="BUFFER" Width="40"  InitialResourceState="COPY_DEST" Init="ByName" Format="R32_TYPELESS"/>
+    <Resource Name="SRVBuffer1" Dimension="BUFFER" Width="40"  InitialResourceState="COPY_DEST" Init="ByName" />
+    <Resource Name="SRVBuffer2" Dimension="BUFFER" Width="40"  InitialResourceState="COPY_DEST" Init="ByName" Format="R32_TYPELESS"/>
+    <Resource Name="SRVBuffer3" Dimension="BUFFER" Width="40"  InitialResourceState="COPY_DEST" Init="ByName" />
+    <Resource Name="UAVBuffer0" Dimension="BUFFER" Width="120" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" Format="R32_TYPELESS" />
+    <Resource Name="UAVBuffer1" Dimension="BUFFER" Width="120" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <Resource Name="UAVBuffer2" Dimension="BUFFER" Width="120" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" Format="R32_TYPELESS" />
+    <Resource Name="UAVBuffer3" Dimension="BUFFER" Width="120" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <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="RTarget" Dimension="TEXTURE2D" Width="16" Height="16" Format="R32G32B32A32_UINT" Flags="ALLOW_RENDER_TARGET" InitialResourceState="COPY_DEST" ReadBack="true" />
+    <RootValues>
+      <RootValue Index="0" ResName="SRVBuffer0" />
+      <RootValue Index="1" ResName="SRVBuffer1" />
+      <RootValue Index="2" ResName="UAVBuffer0" />
+      <RootValue Index="3" ResName="UAVBuffer1" />
+      <RootValue Index="4" HeapName="ResHeap" />
+    </RootValues>
+    <DescriptorHeap Name="ResHeap" Type="CBV_SRV_UAV">
+      <Descriptor Name='SRVBuffer2' Kind='SRV' ResName='SRVBuffer2' Flags='RAW' NumElements="10" Format="R32_TYPELESS" />
+      <Descriptor Name='SRVBuffer3' Kind='SRV' ResName='SRVBuffer3' NumElements="1" StructureByteStride="40" />
+      <Descriptor Name='UAVBuffer2' Kind='UAV' ResName='UAVBuffer2' Flags='RAW' NumElements="30" Format="R32_TYPELESS" />
+      <Descriptor Name='UAVBuffer3' Kind='UAV' ResName='UAVBuffer3' NumElements="1" StructureByteStride="120" />
+    </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"/>
+    </RenderTargets>
+    <Shader Name="VS" Target="vs_6_2">
+      <![CDATA[
+        struct PSInput {
+          float4 pos : SV_POSITION;
+        };
+        PSInput main(float3 pos : POSITION) {
+          PSInput r;
+          r.pos = float4(pos, 1); 
+          return r;
+        }
+      ]]>
+    </Shader>
+    <Shader Name="PS" Target="ps_6_2">
+      <![CDATA[// Shader source code will be set at runtime]]>
+    </Shader>
   </ShaderOp>
-  <ShaderOp Name="GraphicsRawBufferLdSt16" PS="PS" VS="VS">
+  
+  <ShaderOp Name="GraphicsRawBufferLdSt64Bit" PS="PS" VS="VS">
+    <RootSignature>RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), SRV(t0), SRV(t1), UAV(u0), UAV(u1), DescriptorTable(SRV(t2,numDescriptors=2), UAV(u2,numDescriptors=2))</RootSignature>
+    <Resource Name="SRVBuffer0" Dimension="BUFFER" Width="80"  InitialResourceState="COPY_DEST" Init="ByName" Format="R32_TYPELESS"/>
+    <Resource Name="SRVBuffer1" Dimension="BUFFER" Width="80"  InitialResourceState="COPY_DEST" Init="ByName" />
+    <Resource Name="SRVBuffer2" Dimension="BUFFER" Width="80"  InitialResourceState="COPY_DEST" Init="ByName" Format="R32_TYPELESS"/>
+    <Resource Name="SRVBuffer3" Dimension="BUFFER" Width="80"  InitialResourceState="COPY_DEST" Init="ByName" />
+    <Resource Name="UAVBuffer0" Dimension="BUFFER" Width="240" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" Format="R32_TYPELESS" />
+    <Resource Name="UAVBuffer1" Dimension="BUFFER" Width="240" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <Resource Name="UAVBuffer2" Dimension="BUFFER" Width="240" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" Format="R32_TYPELESS" />
+    <Resource Name="UAVBuffer3" Dimension="BUFFER" Width="240" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <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="RTarget" Dimension="TEXTURE2D" Width="16" Height="16" Format="R32G32B32A32_UINT" Flags="ALLOW_RENDER_TARGET" InitialResourceState="COPY_DEST" ReadBack="true" />
+    <RootValues>
+      <RootValue Index="0" ResName="SRVBuffer0" />
+      <RootValue Index="1" ResName="SRVBuffer1" />
+      <RootValue Index="2" ResName="UAVBuffer0" />
+      <RootValue Index="3" ResName="UAVBuffer1" />
+      <RootValue Index="4" HeapName="ResHeap" />
+    </RootValues>
+    <DescriptorHeap Name="ResHeap" Type="CBV_SRV_UAV">
+      <Descriptor Name='SRVBuffer2' Kind='SRV' ResName='SRVBuffer2' Flags='RAW' NumElements="20" Format="R32_TYPELESS" />
+      <Descriptor Name='SRVBuffer3' Kind='SRV' ResName='SRVBuffer3' NumElements="1" StructureByteStride="80" />
+      <Descriptor Name='UAVBuffer2' Kind='UAV' ResName='UAVBuffer2' Flags='RAW' NumElements="60" Format="R32_TYPELESS" />
+      <Descriptor Name='UAVBuffer3' Kind='UAV' ResName='UAVBuffer3' NumElements="1" StructureByteStride="240" />
+    </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"/>
+    </RenderTargets>
+    <Shader Name="VS" Target="vs_6_2">
+      <![CDATA[
+        struct PSInput {
+          float4 pos : SV_POSITION;
+        };
+        PSInput main(float3 pos : POSITION) {
+          PSInput r;
+          r.pos = float4(pos, 1); 
+          return r;
+        }
+      ]]>
+    </Shader>
+    <Shader Name="PS" Target="ps_6_2">
+      <![CDATA[// Shader source code will be set at runtime]]>
+    </Shader>
   </ShaderOp>
-  <ShaderOp Name="GraphicsRawBufferLdStHalf" PS="PS" VS="VS">
+
+  <ShaderOp Name="GraphicsRawBufferLdSt16Bit" PS="PS" VS="VS">
+    <RootSignature>RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), SRV(t0), SRV(t1), UAV(u0), UAV(u1), DescriptorTable(SRV(t2,numDescriptors=2), UAV(u2,numDescriptors=2))</RootSignature>
+    <Resource Name="SRVBuffer0" Dimension="BUFFER" Width="20"  InitialResourceState="COPY_DEST" Init="ByName" Format="R32_TYPELESS"/>
+    <Resource Name="SRVBuffer1" Dimension="BUFFER" Width="20"  InitialResourceState="COPY_DEST" Init="ByName" />
+    <Resource Name="SRVBuffer2" Dimension="BUFFER" Width="20"  InitialResourceState="COPY_DEST" Init="ByName" Format="R32_TYPELESS"/>
+    <Resource Name="SRVBuffer3" Dimension="BUFFER" Width="20"  InitialResourceState="COPY_DEST" Init="ByName" />
+    <Resource Name="UAVBuffer0" Dimension="BUFFER" Width="60" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" Format="R32_TYPELESS" />
+    <Resource Name="UAVBuffer1" Dimension="BUFFER" Width="60" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <Resource Name="UAVBuffer2" Dimension="BUFFER" Width="60" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" Format="R32_TYPELESS" />
+    <Resource Name="UAVBuffer3" Dimension="BUFFER" Width="60" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <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="RTarget" Dimension="TEXTURE2D" Width="16" Height="16" Format="R32G32B32A32_UINT" Flags="ALLOW_RENDER_TARGET" InitialResourceState="COPY_DEST" ReadBack="true" />
+    <RootValues>
+      <RootValue Index="0" ResName="SRVBuffer0" />
+      <RootValue Index="1" ResName="SRVBuffer1" />
+      <RootValue Index="2" ResName="UAVBuffer0" />
+      <RootValue Index="3" ResName="UAVBuffer1" />
+      <RootValue Index="4" HeapName="ResHeap" />
+    </RootValues>
+    <DescriptorHeap Name="ResHeap" Type="CBV_SRV_UAV">
+      <Descriptor Name='SRVBuffer2' Kind='SRV' ResName='SRVBuffer2' Flags='RAW' NumElements="5" Format="R32_TYPELESS" />
+      <Descriptor Name='SRVBuffer3' Kind='SRV' ResName='SRVBuffer3' NumElements="1" StructureByteStride="20" />
+      <Descriptor Name='UAVBuffer2' Kind='UAV' ResName='UAVBuffer2' Flags='RAW' NumElements="15" Format="R32_TYPELESS" />
+      <Descriptor Name='UAVBuffer3' Kind='UAV' ResName='UAVBuffer3' NumElements="1" StructureByteStride="60" />
+    </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"/>
+    </RenderTargets>
+    <Shader Name="VS" Target="vs_6_2">
+      <![CDATA[
+        struct PSInput {
+          float4 pos : SV_POSITION;
+        };
+        PSInput main(float3 pos : POSITION) {
+          PSInput r;
+          r.pos = float4(pos, 1); 
+          return r;
+        }
+      ]]>
+    </Shader>
+    <Shader Name="PS" Target="ps_6_2">
+      <![CDATA[// Shader source code will be set at runtime]]>
+    </Shader>
   </ShaderOp>
+
   <!--
   TODO: Dynamically index into tables
   -->

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

@@ -437,8 +437,12 @@ public:
     TEST_METHOD_PROPERTY(L"Priority", L"2") // Remove this line once warp supports this feature in Shader Model 6.3
   END_TEST_METHOD()
 
-  TEST_METHOD(GraphicsRawBufferLdStI16);
-  TEST_METHOD(GraphicsRawBufferLdStHalf);
+  BEGIN_TEST_METHOD(GraphicsRawBufferLdStI16)
+    TEST_METHOD_PROPERTY(L"Priority", L"2") // This test is disabled because of a bug in WARP; TODO: enable once the bug is fixed
+  END_TEST_METHOD()
+  BEGIN_TEST_METHOD(GraphicsRawBufferLdStHalf)
+    TEST_METHOD_PROPERTY(L"Priority", L"2") // This test is disabled because of a bug in WARP; TODO: enable once the bug is fixed
+  END_TEST_METHOD()
 
   // This is defined in d3d.h for Windows 10 Anniversary Edition SDK, but we only
   // require the Windows 10 SDK.
@@ -526,8 +530,15 @@ public:
   void RunComputeRawBufferLdStTest(D3D_SHADER_MODEL shaderModel, RawBufferLdStType dataType,
                             const char *shaderOpName, const RawBufferLdStTestData<Ty> &testData);
 
+  template <class Ty>
   void RunGraphicsRawBufferLdStTest(D3D_SHADER_MODEL shaderModel, RawBufferLdStType dataType,
-                            const char *shaderOpName);
+                            const char *shaderOpName, const RawBufferLdStTestData<Ty> &testData);
+
+  template <class Ty>
+  void VerifyRawBufferLdStTestResults(const std::shared_ptr<st::ShaderOpTest> test, const RawBufferLdStTestData<Ty> &testData);
+                                      
+  bool SetupRawBufferLdStTest(D3D_SHADER_MODEL shaderModel, RawBufferLdStType dataType, CComPtr<ID3D12Device> &pDevice, 
+                              CComPtr<IStream> &pStream, char *&sTy, char *&additionalOptions);
 
   template <class Ty>
   void RunBasicShaderModelTest(CComPtr<ID3D12Device> pDevice, const char *pShaderModelStr, const char *pShader, Ty *pInputDataPairs, unsigned inputDataCount);
@@ -5911,7 +5922,7 @@ TEST_F(ExecutionTest, BarycentricsTest) {
     //SavePixelsToFile(pPixels, DXGI_FORMAT_R32G32B32A32_FLOAT, width, height, L"barycentric.bmp");
 }
 
-static const char RawBufferTestComputeShader[] =
+static const char RawBufferTestShaderDeclarations[] =
 "// Note: COMPONENT_TYPE and COMPONENT_SIZE will be defined via compiler option -D\r\n"
 "typedef COMPONENT_TYPE scalar; \r\n"
 "typedef vector<COMPONENT_TYPE, 2> vector2; \r\n"
@@ -5939,11 +5950,9 @@ static const char RawBufferTestComputeShader[] =
 "RWByteAddressBuffer         uav0 : register(u0); \r\n"
 "RWStructuredBuffer<UavData> uav1 : register(u1); \r\n"
 "RWByteAddressBuffer         uav2 : register(u2); \r\n"
-"RWStructuredBuffer<UavData> uav3 : register(u3); \r\n"
-"\r\n"
-"[numthreads(1, 1, 1)]\r\n"
-"void main(uint GI : SV_GroupIndex) {\r\n"
-"\r\n"
+"RWStructuredBuffer<UavData> uav3 : register(u3); \r\n";
+
+static const char RawBufferTestShaderBody[] =
 "  // offset of 'out' in 'UavData'\r\n"
 "  const int out_offset = COMPONENT_SIZE * 10; \r\n"
 "\r\n"
@@ -5994,36 +6003,55 @@ static const char RawBufferTestComputeShader[] =
 "  uav3[0].output.v1 = uav3[0].input.v1; \r\n"
 "  uav3[0].output.v2 = uav3[0].input.v2; \r\n"
 "  uav3[0].output.v3 = uav3[0].input.v3; \r\n"
-"  uav3[0].output.v4 = uav3[0].input.v4; \r\n"
+"  uav3[0].output.v4 = uav3[0].input.v4; \r\n";
+
+
+static const char RawBufferTestComputeShaderTemplate[] =
+"%s\r\n" // <- RawBufferTestShaderDeclarations
+"[numthreads(1, 1, 1)]\r\n"
+"void main(uint GI : SV_GroupIndex) {\r\n"
+"%s\r\n" // <- RawBufferTestShaderBody
+"};";
+
+static const char RawBufferTestGraphicsPixelShaderTemplate[] =
+"%s\r\n" // <- RawBufferTestShaderDeclarations
+"struct PSInput { \r\n"
+"  float4 pos : SV_POSITION; \r\n"
+"}; \r\n"
+"uint4 main(PSInput input) : SV_TARGET{ \r\n"
+"  if (input.pos.x + input.pos.y == 1.0f) { // pixel { 0.5, 0.5, 0 } \r\n"
+"%s\r\n" // <- RawBufferTestShaderBody
+"  } \r\n"
+"  return uint4(1, 2, 3, 4); \r\n"
 "};";
 
 TEST_F(ExecutionTest, ComputeRawBufferLdStI32) {
-  RawBufferLdStTestData<int32_t> data = { { 1 }, { 2, -1 }, { 256, 0, -10517 }, { 465, 13, -89, MAXUINT32 / 2 } };
+  RawBufferLdStTestData<int32_t> data = { { 1 }, { 2, -1 }, { 256, -10517, 980 }, { 465, 13, -89, MAXUINT32 / 2 } };
   RunComputeRawBufferLdStTest<int32_t>(D3D_SHADER_MODEL_6_2, RawBufferLdStType::I32, "ComputeRawBufferLdSt32Bit", data);
 }
 
 TEST_F(ExecutionTest, ComputeRawBufferLdStFloat)  {
-  RawBufferLdStTestData<float> data = { { 3e-10f }, { 1.5f, -1.99988f }, { 256.0f, 0.0f, -105.17f }, { 465.1652f, -1.5694e2f, -0.8543e-2f, 1333.5f } };
+  RawBufferLdStTestData<float> data = { { 3e-10f }, { 1.5f, -1.99988f }, { 256.0f, -105.17f, 980.0f }, { 465.1652f, -1.5694e2f, -0.8543e-2f, 1333.5f } };
   RunComputeRawBufferLdStTest<float>(D3D_SHADER_MODEL_6_2, RawBufferLdStType::Float, "ComputeRawBufferLdSt32Bit", data);
 }
 
 TEST_F(ExecutionTest,  ComputeRawBufferLdStI64)  {
-  RawBufferLdStTestData<int64_t> data = { { 1 }, { 2, -1 }, { 256, 0, -105171532 }, { 465, 13, -89, MAXUINT64 / 2 } };
+  RawBufferLdStTestData<int64_t> data = { { 1 }, { 2, -1 }, { 256, -105171532, 980 }, { 465, 13, -89, MAXUINT64 / 2 } };
   RunComputeRawBufferLdStTest<int64_t>(D3D_SHADER_MODEL_6_3, RawBufferLdStType::I64, "ComputeRawBufferLdSt64Bit", data);
 }
 
 TEST_F(ExecutionTest,  ComputeRawBufferLdStDouble)  {
-  RawBufferLdStTestData<double> data = { { 3e-10 }, { 1.5, -1.99988 }, { 256.0, 0.0, -105.17 }, { 465.1652, -1.5694e2, -0.8543e-2, 1333.5 } };
+  RawBufferLdStTestData<double> data = { { 3e-10 }, { 1.5, -1.99988 }, { 256.0, -105.17, 980.0 }, { 465.1652, -1.5694e2, -0.8543e-2, 1333.5 } };
   RunComputeRawBufferLdStTest<double>(D3D_SHADER_MODEL_6_3, RawBufferLdStType::I64, "ComputeRawBufferLdSt64Bit", data);
 }
 
 TEST_F(ExecutionTest, ComputeRawBufferLdStI16) {
-  RawBufferLdStTestData<int16_t> data = { { 1 }, { 2, -1 }, { 256, 0, -10517 }, { 465, 13, -89, MAXUINT16 / 2 } };
+  RawBufferLdStTestData<int16_t> data = { { 1 }, { 2, -1 }, { 256, -10517, 980 }, { 465, 13, -89, MAXUINT16 / 2 } };
   RunComputeRawBufferLdStTest<int16_t>(D3D_SHADER_MODEL_6_2, RawBufferLdStType::I16, "ComputeRawBufferLdSt16Bit", data);
 }
 
 TEST_F(ExecutionTest,  ComputeRawBufferLdStHalf)  {
-  RawBufferLdStTestData<float> floatData = { { 3e-10f }, { 1.5f, -1.99988f }, { 256.0f, 0.0f, -105.17f }, { 465.1652f, -1.5694e2f, -0.8543e-2f, 1333.5f } };
+  RawBufferLdStTestData<float> floatData = { { 3e-10f }, { 1.5f, -1.99988f }, { 256.0f, 105.17f, 980.0f }, { 465.1652f, -1.5694e2f, -0.8543e-2f, 1333.5f } };
   RawBufferLdStTestData<uint16_t> halfData;
   for (int i = 0; i < sizeof(floatData)/sizeof(float); i++) {
     ((uint16_t*)&halfData)[i] = ConvertFloat32ToFloat16(((float*)&floatData)[i]);
@@ -6032,83 +6060,159 @@ TEST_F(ExecutionTest,  ComputeRawBufferLdStHalf)  {
 }
 
 TEST_F(ExecutionTest,  GraphicsRawBufferLdStI32)  {
-  RunGraphicsRawBufferLdStTest(D3D_SHADER_MODEL_6_2, RawBufferLdStType::I32, "GraphicsRawBufferLdStI32");
+  RawBufferLdStTestData<int32_t> data = { { 1 }, { 2, -1 }, { 256, -10517, 980 }, { 465, 13, -89, MAXUINT32 / 2 } };
+  RunGraphicsRawBufferLdStTest<int32_t>(D3D_SHADER_MODEL_6_2, RawBufferLdStType::I32, "GraphicsRawBufferLdSt32Bit", data);
 }
 
 TEST_F(ExecutionTest,  GraphicsRawBufferLdStFloat)  {
-  RunGraphicsRawBufferLdStTest(D3D_SHADER_MODEL_6_2, RawBufferLdStType::Float, "GraphicsRawBufferLdStFloat");
+  RawBufferLdStTestData<float> data = { { 3e-10f }, { 1.5f, -1.99988f }, { 256.0f, -105.17f, 980.0f }, { 465.1652f, -1.5694e2f, -0.8543e-2f, 1333.5f } };
+  RunGraphicsRawBufferLdStTest<float>(D3D_SHADER_MODEL_6_2, RawBufferLdStType::Float, "GraphicsRawBufferLdSt32Bit", data);
 }
 
 TEST_F(ExecutionTest,  GraphicsRawBufferLdStI64)  {
-  RunGraphicsRawBufferLdStTest(D3D_SHADER_MODEL_6_3, RawBufferLdStType::I64, "GraphicsRawBufferLdStI64");
+  RawBufferLdStTestData<int64_t> data = { { 1 }, { 2, -1 }, { 256, -105171532, 980 }, { 465, 13, -89, MAXUINT64 / 2 } };
+  RunGraphicsRawBufferLdStTest<int64_t>(D3D_SHADER_MODEL_6_3, RawBufferLdStType::I64, "GraphicsRawBufferLdSt64Bit", data);
 }
 
 TEST_F(ExecutionTest,  GraphicsRawBufferLdStDouble)  {
-  RunGraphicsRawBufferLdStTest(D3D_SHADER_MODEL_6_3, RawBufferLdStType::Double, "GraphicsRawBufferLdStDouble");
+  RawBufferLdStTestData<double> data = { { 3e-10 }, { 1.5, -1.99988 }, { 256.0, -105.17, 980.0 }, { 465.1652, -1.5694e2, -0.8543e-2, 1333.5 } };
+  RunGraphicsRawBufferLdStTest<double>(D3D_SHADER_MODEL_6_3, RawBufferLdStType::Double, "GraphicsRawBufferLdSt64Bit", data);
 }
 
 TEST_F(ExecutionTest, GraphicsRawBufferLdStI16) {
-  RunGraphicsRawBufferLdStTest(D3D_SHADER_MODEL_6_2, RawBufferLdStType::I16, "GraphicsRawBufferLdStI16");
+  RawBufferLdStTestData<int16_t> data = { { 1 }, { 2, -1 }, { 256, -10517, 980 }, { 465, 13, -89, MAXUINT16 / 2 } };
+  RunGraphicsRawBufferLdStTest<int16_t>(D3D_SHADER_MODEL_6_2, RawBufferLdStType::I16, "GraphicsRawBufferLdSt16Bit", data);
 }
 
 TEST_F(ExecutionTest, GraphicsRawBufferLdStHalf) {
-  RunGraphicsRawBufferLdStTest(D3D_SHADER_MODEL_6_2, RawBufferLdStType::Half, "GraphicsRawBufferLdStHalf");
+  RawBufferLdStTestData<float> floatData = { { 3e-10f }, { 1.5f, -1.99988f }, { 256.0f, 105.17f, 0.0f }, { 465.1652f, -1.5694e2f, -0.8543e-2f, 1333.5f } };
+  RawBufferLdStTestData<uint16_t> halfData;
+  for (int i = 0; i < sizeof(floatData) / sizeof(float); i++) {
+    ((uint16_t*)&halfData)[i] = ConvertFloat32ToFloat16(((float*)&floatData)[i]);
+  }
+  RunGraphicsRawBufferLdStTest<uint16_t>(D3D_SHADER_MODEL_6_2, RawBufferLdStType::Half, "GraphicsRawBufferLdSt16Bit", halfData);
+}
+
+bool ExecutionTest::SetupRawBufferLdStTest(D3D_SHADER_MODEL shaderModel, RawBufferLdStType dataType,
+                                           CComPtr<ID3D12Device> &pDevice, CComPtr<IStream> &pStream, 
+                                           char *&sTy, char *&additionalOptions) {
+  if (!CreateDevice(&pDevice, shaderModel)) {
+    return false;
+  }
+
+  additionalOptions = "";
+
+  switch (dataType) {
+  case RawBufferLdStType::I64:
+    if (!DoesDeviceSupportInt64(pDevice)) {
+      WEX::Logging::Log::Comment(L"Device does not support int64 operations.");
+      WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+      return false;
+    }
+    sTy = "int64_t";
+    break;
+  case RawBufferLdStType::Double:
+    if (!DoesDeviceSupportDouble(pDevice)) {
+      WEX::Logging::Log::Comment(L"Device does not support double operations.");
+      WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+      return false;
+    }
+    sTy = "double";
+    break;
+  case RawBufferLdStType::I16:
+  case RawBufferLdStType::Half:
+    if (!DoesDeviceSupportNative16bitOps(pDevice)) {
+      WEX::Logging::Log::Comment(L"Device does not support native 16-bit operations.");
+      WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+      return false;
+    }
+    additionalOptions = "-enable-16bit-types";
+    sTy = (dataType == RawBufferLdStType::I16 ? "int16_t" : "half");
+    break;
+  case RawBufferLdStType::I32:
+    sTy = "int32_t";
+    break;
+  case RawBufferLdStType::Float:
+    sTy = "float";
+    break;
+  default:
+    DXASSERT_NOMSG("Invalid RawBufferLdStType");
+  }
+
+  // read shader config
+  ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
+
+  return true;
+}
+
+template <class Ty>
+void ExecutionTest::VerifyRawBufferLdStTestResults(const std::shared_ptr<st::ShaderOpTest> test, const RawBufferLdStTestData<Ty> &testData) {
+  // read buffers back & verify expected values
+  static const int UavBufferCount = 4;
+  char bufferName[11] = "UAVBufferX";
+
+  for (unsigned i = 0; i < UavBufferCount; i++) {
+    MappedData dataUav;
+    RawBufferLdStUavData<Ty> *pOutData;
+
+    bufferName[sizeof(bufferName) - 2] = (char)(i + '0');
+
+    test->GetReadBackData(bufferName, &dataUav);
+    VERIFY_ARE_EQUAL(sizeof(RawBufferLdStUavData<Ty>), dataUav.size());
+    pOutData = (RawBufferLdStUavData<Ty> *)dataUav.data();
+
+    LogCommentFmt(L"Verifying UAVBuffer%d Load -> UAVBuffer%d Store", i, i);
+    // scalar
+    VERIFY_ARE_EQUAL(pOutData->output.v1, testData.v1);
+    // vector 2
+    VERIFY_ARE_EQUAL(pOutData->output.v2[0], testData.v2[0]);
+    VERIFY_ARE_EQUAL(pOutData->output.v2[1], testData.v2[1]);
+    // vector 3
+    VERIFY_ARE_EQUAL(pOutData->output.v3[0], testData.v3[0]);
+    VERIFY_ARE_EQUAL(pOutData->output.v3[1], testData.v3[1]);
+    VERIFY_ARE_EQUAL(pOutData->output.v3[2], testData.v3[2]);
+    // vector 4
+    VERIFY_ARE_EQUAL(pOutData->output.v4[0], testData.v4[0]);
+    VERIFY_ARE_EQUAL(pOutData->output.v4[1], testData.v4[1]);
+    VERIFY_ARE_EQUAL(pOutData->output.v4[2], testData.v4[2]);
+    VERIFY_ARE_EQUAL(pOutData->output.v4[3], testData.v4[3]);
+
+    // verify SRV Store
+    LogCommentFmt(L"Verifying SRVBuffer%d Load -> UAVBuffer%d Store", i, i);
+    // scalar
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v1, testData.v1);
+    // vector 2
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v2[0], testData.v2[0]);
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v2[1], testData.v2[1]);
+    // vector 3
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v3[0], testData.v3[0]);
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v3[1], testData.v3[1]);
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v3[2], testData.v3[2]);
+    // vector 4
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v4[0], testData.v4[0]);
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v4[1], testData.v4[1]);
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v4[2], testData.v4[2]);
+    VERIFY_ARE_EQUAL(pOutData->srvOut.v4[3], testData.v4[3]);
+  }
 }
 
 template <class Ty>
 void ExecutionTest::RunComputeRawBufferLdStTest(D3D_SHADER_MODEL shaderModel, RawBufferLdStType dataType, 
                                                 const char *shaderOpName, const RawBufferLdStTestData<Ty> &testData) {
-   WEX::TestExecution::SetVerifyOutput verifySettings(
-   WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
+   WEX::TestExecution::SetVerifyOutput verifySettings(WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
 
    CComPtr<ID3D12Device> pDevice;
-   if (!CreateDevice(&pDevice, shaderModel)) {
-     return;
-   }
-
-   char *sTy = nullptr;
-   char *additionalOptions = "";
+   CComPtr<IStream> pStream;
+   char *sTy, *additionalOptions;
 
-   switch (dataType) {
-   case RawBufferLdStType::I64:
-     if (!DoesDeviceSupportInt64(pDevice)) {
-       WEX::Logging::Log::Comment(L"Device does not support int64 operations.");
-       WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
-       return;
-     }
-     sTy = "int64_t";
-     break;
-   case RawBufferLdStType::Double:
-     if (!DoesDeviceSupportDouble(pDevice)) {
-       WEX::Logging::Log::Comment(L"Device does not support double operations.");
-       WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
-       return;
-     }
-     sTy = "double";
-     break;
-   case RawBufferLdStType::I16:
-   case RawBufferLdStType::Half:
-     if (!DoesDeviceSupportNative16bitOps(pDevice)) {
-       WEX::Logging::Log::Comment(L"Device does not support native 16-bit operations.");
-       WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
-       return;
-     }
-     additionalOptions = "-enable-16bit-types";
-     sTy = (dataType == RawBufferLdStType::I16 ? "int16_t" : "half");
-     break;
-   case RawBufferLdStType::I32:
-     sTy = "int32_t";
-     break;
-   case RawBufferLdStType::Float:
-     sTy = "float";
-     break;
-   default:
-     DXASSERT_NOMSG("Invalid RawBufferLdStType");
+   if (!SetupRawBufferLdStTest(shaderModel, dataType, pDevice, pStream, sTy, additionalOptions)) {
+     return;
    }
 
-   // read shader config
-   CComPtr<IStream> pStream;
-   ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
+   // format shader source
+   char rawBufferTestShaderText[sizeof(RawBufferTestComputeShaderTemplate) + sizeof(RawBufferTestShaderDeclarations) + sizeof(RawBufferTestShaderBody)];
+   VERIFY_IS_TRUE(sprintf_s(rawBufferTestShaderText, sizeof(rawBufferTestShaderText), 
+                            RawBufferTestComputeShaderTemplate, RawBufferTestShaderDeclarations, RawBufferTestShaderBody) != -1);
 
    // format compiler args
    char compilerOptions[256];
@@ -6120,65 +6224,56 @@ void ExecutionTest::RunComputeRawBufferLdStTest(D3D_SHADER_MODEL shaderModel, Ra
      VERIFY_IS_TRUE(((0 == strncmp(Name, "SRVBuffer", 9)) || (0 == strncmp(Name, "UAVBuffer", 9))) &&
                     (Name[9] >= '0' && Name[9] <= '3'));
      pShaderOp->Shaders.at(0).Arguments = compilerOptions;
-     pShaderOp->Shaders.at(0).Text = RawBufferTestComputeShader;
+     pShaderOp->Shaders.at(0).Text = rawBufferTestShaderText;
 
      VERIFY_IS_TRUE(sizeof(RawBufferLdStTestData<Ty>) <= Data.size());
      RawBufferLdStTestData<Ty> *pInData = (RawBufferLdStTestData<Ty>*)Data.data();
      memcpy(pInData, &testData, sizeof(RawBufferLdStTestData<Ty>));
    });
 
-   // read buffers back & verify expected values
-   static const int UavBufferCount = 4;
-   char bufferName[11] = "UAVBufferX";
-
-   for (unsigned i = 0; i < UavBufferCount; i++) {
-     MappedData dataUav;
-     RawBufferLdStUavData<Ty> *pOutData;
-
-     bufferName[sizeof(bufferName) - 2] = (char)(i + '0');
-     
-     test->Test->GetReadBackData(bufferName, &dataUav);
-     VERIFY_ARE_EQUAL(sizeof(RawBufferLdStUavData<Ty>), dataUav.size());
-     pOutData = (RawBufferLdStUavData<Ty> *)dataUav.data();
-     
-     LogCommentFmt(L"Verifying UAVBuffer%d Load -> UAVBuffer%d Store", i, i);
-     // scalarRunComputeRawBufferLdStTest
-     VERIFY_ARE_EQUAL(pOutData->output.v1,    testData.v1);
-     // vector 2
-     VERIFY_ARE_EQUAL(pOutData->output.v2[0], testData.v2[0]);
-     VERIFY_ARE_EQUAL(pOutData->output.v2[1], testData.v2[1]);
-     // vector 3
-     VERIFY_ARE_EQUAL(pOutData->output.v3[0], testData.v3[0]);
-     VERIFY_ARE_EQUAL(pOutData->output.v3[1], testData.v3[1]);
-     VERIFY_ARE_EQUAL(pOutData->output.v3[2], testData.v3[2]);
-     // vector 4
-     VERIFY_ARE_EQUAL(pOutData->output.v4[0], testData.v4[0]);
-     VERIFY_ARE_EQUAL(pOutData->output.v4[1], testData.v4[1]);
-     VERIFY_ARE_EQUAL(pOutData->output.v4[2], testData.v4[2]);
-     VERIFY_ARE_EQUAL(pOutData->output.v4[3], testData.v4[3]);
-
-     // verify SRV Store
-     LogCommentFmt(L"Verifying SRVBuffer%d Load -> UAVBuffer%d Store", i, i);
-     // scalar
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v1,    testData.v1);
-     // vector 2
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v2[0], testData.v2[0]);
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v2[1], testData.v2[1]);
-     // vector 3
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v3[0], testData.v3[0]);
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v3[1], testData.v3[1]);
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v3[2], testData.v3[2]);
-     // vector 4
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v4[0], testData.v4[0]);
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v4[1], testData.v4[1]);
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v4[2], testData.v4[2]);
-     VERIFY_ARE_EQUAL(pOutData->srvOut.v4[3], testData.v4[3]);
-   }
+   // verify expected values
+   VerifyRawBufferLdStTestResults<Ty>(test->Test, testData);
 }
 
+template <class Ty>
 void ExecutionTest::RunGraphicsRawBufferLdStTest(D3D_SHADER_MODEL shaderModel, RawBufferLdStType dataType,
-  const char *shaderOpName) {
-  WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+                                                 const char *shaderOpName, const RawBufferLdStTestData<Ty> &testData) {
+
+  WEX::TestExecution::SetVerifyOutput verifySettings(WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
+
+  CComPtr<ID3D12Device> pDevice;
+  CComPtr<IStream> pStream;
+  char *sTy, *additionalOptions;
+
+  if (!SetupRawBufferLdStTest(shaderModel, dataType, pDevice, pStream, sTy, additionalOptions)) {
+    return;
+  }
+
+  // format shader source
+  char rawBufferTestPixelShaderText[sizeof(RawBufferTestGraphicsPixelShaderTemplate) + sizeof(RawBufferTestShaderDeclarations) + sizeof(RawBufferTestShaderBody)];
+  VERIFY_IS_TRUE(sprintf_s(rawBufferTestPixelShaderText, sizeof(rawBufferTestPixelShaderText),
+                           RawBufferTestGraphicsPixelShaderTemplate, RawBufferTestShaderDeclarations, RawBufferTestShaderBody) != -1);
+
+  // format compiler args
+  char compilerOptions[256];
+  VERIFY_IS_TRUE(sprintf_s(compilerOptions, sizeof(compilerOptions), "-D COMPONENT_TYPE=%s -D COMPONENT_SIZE=%d %s", sTy, (int)sizeof(Ty), additionalOptions) != -1);
+
+  // run the shader
+  std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(pDevice, m_support, pStream, shaderOpName,
+    [&](LPCSTR Name, std::vector<BYTE> &Data, st::ShaderOp *pShaderOp) {
+    VERIFY_IS_TRUE(((0 == strncmp(Name, "SRVBuffer", 9)) || (0 == strncmp(Name, "UAVBuffer", 9))) &&
+      (Name[9] >= '0' && Name[9] <= '3'));
+    // pixel shader is at index 1, vertex shader at index 0
+    pShaderOp->Shaders.at(1).Arguments = compilerOptions;
+    pShaderOp->Shaders.at(1).Text = rawBufferTestPixelShaderText;
+
+    VERIFY_IS_TRUE(sizeof(RawBufferLdStTestData<Ty>) <= Data.size());
+    RawBufferLdStTestData<Ty> *pInData = (RawBufferLdStTestData<Ty>*)Data.data();
+    memcpy(pInData, &testData, sizeof(RawBufferLdStTestData<Ty>));
+  });
+
+  // verify expected values
+  VerifyRawBufferLdStTestResults<Ty>(test->Test, testData);
 }
 
 #ifndef _HLK_CONF