Browse Source

Add ml intrinsics tests (#1872)

Add ML intrinsics tests (WIP)
Patrice Vignola 6 years ago
parent
commit
cff1af74ca

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

@@ -360,6 +360,45 @@
     </Shader>
     </Shader>
   </ShaderOp>
   </ShaderOp>
 
 
+  <ShaderOp Name="Dot2AddOp" CS="CS" DispatchX="8" DispatchY="8">
+    <RootSignature>RootFlags(0), UAV(u0)</RootSignature>
+    <Resource Name="SDot2AddOp" Dimension="BUFFER" Width="1024" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <RootValues>
+      <RootValue Index="0" ResName="SDot2AddOp" />
+    </RootValues>
+    <Shader Name="CS" Target="cs_6_4">
+      <![CDATA[
+      void main(uint GI : SV_GroupIndex) {};
+      ]]>
+    </Shader>
+  </ShaderOp>
+
+  <ShaderOp Name="Dot4AddI8PackedOp" CS="CS" DispatchX="8" DispatchY="8">
+    <RootSignature>RootFlags(0), UAV(u0)</RootSignature>
+    <Resource Name="SDot4AddI8PackedOp" Dimension="BUFFER" Width="1024" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <RootValues>
+      <RootValue Index="0" ResName="SDot4AddI8PackedOp" />
+    </RootValues>
+    <Shader Name="CS" Target="cs_6_4">
+      <![CDATA[
+      void main(uint GI : SV_GroupIndex) {};
+      ]]>
+    </Shader>
+  </ShaderOp>
+
+  <ShaderOp Name="Dot4AddU8PackedOp" CS="CS" DispatchX="8" DispatchY="8">
+    <RootSignature>RootFlags(0), UAV(u0)</RootSignature>
+    <Resource Name="SDot4AddU8PackedOp" Dimension="BUFFER" Width="1024" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
+    <RootValues>
+      <RootValue Index="0" ResName="SDot4AddU8PackedOp" />
+    </RootValues>
+    <Shader Name="CS" Target="cs_6_4">
+      <![CDATA[
+      void main(uint GI : SV_GroupIndex) {};
+      ]]>
+    </Shader>
+  </ShaderOp>
+
   <ShaderOp Name="Msad4" CS="CS" DispatchX="8" DispatchY="8">
   <ShaderOp Name="Msad4" CS="CS" DispatchX="8" DispatchY="8">
     <RootSignature>RootFlags(0), UAV(u0)</RootSignature>
     <RootSignature>RootFlags(0), UAV(u0)</RootSignature>
     <Resource Name="SMsad4" Dimension="BUFFER" Width="1024" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />
     <Resource Name="SMsad4" Dimension="BUFFER" Width="1024" Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" TransitionTo="UNORDERED_ACCESS" Init="ByName" ReadBack="true" />

+ 351 - 22
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -452,6 +452,7 @@ public:
     D3D_SHADER_MODEL_6_1 = 0x61,
     D3D_SHADER_MODEL_6_1 = 0x61,
     D3D_SHADER_MODEL_6_2 = 0x62,
     D3D_SHADER_MODEL_6_2 = 0x62,
     D3D_SHADER_MODEL_6_3 = 0x63,
     D3D_SHADER_MODEL_6_3 = 0x63,
+    D3D_SHADER_MODEL_6_4 = 0x64,
 } D3D_SHADER_MODEL;
 } D3D_SHADER_MODEL;
 
 
 #if WDK_NTDDI_VERSION == NTDDI_WIN10_RS2
 #if WDK_NTDDI_VERSION == NTDDI_WIN10_RS2
@@ -507,6 +508,11 @@ public:
 
 
   void RunBasicShaderModelTest(D3D_SHADER_MODEL shaderModel);
   void RunBasicShaderModelTest(D3D_SHADER_MODEL shaderModel);
 
 
+  void RunDotOp();
+  void RunDot2AddOp();
+  void RunDot4AddI8PackedOp();
+  void RunDot4AddU8PackedOp();
+
   enum class RawBufferLdStType {
   enum class RawBufferLdStType {
      I32,
      I32,
      Float,
      Float,
@@ -599,12 +605,16 @@ public:
   }
   }
 
 
   bool CreateDevice(_COM_Outptr_ ID3D12Device **ppDevice,
   bool CreateDevice(_COM_Outptr_ ID3D12Device **ppDevice,
-                    D3D_SHADER_MODEL testModel = D3D_SHADER_MODEL_6_0) {
+                    D3D_SHADER_MODEL testModel = D3D_SHADER_MODEL_6_0, bool skipUnsupported = true) {
     if (testModel > HIGHEST_SHADER_MODEL) {
     if (testModel > HIGHEST_SHADER_MODEL) {
       UINT minor = (UINT)testModel & 0x0f;
       UINT minor = (UINT)testModel & 0x0f;
       LogCommentFmt(L"Installed SDK does not support "
       LogCommentFmt(L"Installed SDK does not support "
           L"shader model 6.%1u", minor);
           L"shader model 6.%1u", minor);
-      WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+
+      if (skipUnsupported) {
+        WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+      }
+
       return false;
       return false;
     }
     }
     const D3D_FEATURE_LEVEL FeatureLevelRequired = D3D_FEATURE_LEVEL_11_0;
     const D3D_FEATURE_LEVEL FeatureLevelRequired = D3D_FEATURE_LEVEL_11_0;
@@ -621,7 +631,11 @@ public:
                                            IID_PPV_ARGS(&pDevice));
                                            IID_PPV_ARGS(&pDevice));
       if (FAILED(createHR)) {
       if (FAILED(createHR)) {
         LogCommentFmt(L"The available version of WARP does not support d3d12.");
         LogCommentFmt(L"The available version of WARP does not support d3d12.");
-        WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+
+        if (skipUnsupported) {
+          WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+        }
+
         return false;
         return false;
       }
       }
     } else {
     } else {
@@ -663,7 +677,11 @@ public:
         UINT minor = (UINT)testModel & 0x0f;
         UINT minor = (UINT)testModel & 0x0f;
         LogCommentFmt(L"The selected device does not support "
         LogCommentFmt(L"The selected device does not support "
                       L"shader model 6.%1u", minor);
                       L"shader model 6.%1u", minor);
-        WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+
+        if (skipUnsupported) {
+          WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+        }
+
         return false;
         return false;
       }
       }
     }
     }
@@ -2726,6 +2744,44 @@ struct SDotOp {
     float o_dot4;
     float o_dot4;
 };
 };
 
 
+struct Half2
+{
+    uint16_t x;
+    uint16_t y;
+
+    Half2() = default;
+
+    Half2(const Half2&) = default;
+    Half2& operator=(const Half2&) = default;
+
+    Half2(Half2&&) = default;
+    Half2& operator=(Half2&&) = default;
+
+    constexpr Half2(uint16_t _x, uint16_t _y) : x(_x), y(_y) {}
+    explicit Half2(_In_reads_(2) const uint16_t *pArray) : x(pArray[0]), y(pArray[1]) {}
+};
+
+struct SDot2AddOp {
+    Half2 input1;
+    Half2 input2;
+    float acc;
+    float result;
+};
+
+struct SDot4AddI8PackedOp {
+    uint32_t input1;
+    uint32_t input2;
+    int32_t acc;
+    int32_t result;
+};
+
+struct SDot4AddU8PackedOp {
+    uint32_t input1;
+    uint32_t input2;
+    uint32_t acc;
+    uint32_t result;
+};
+
 struct SMsad4 {
 struct SMsad4 {
     unsigned int ref;
     unsigned int ref;
     XMUINT2 src;
     XMUINT2 src;
@@ -3094,15 +3150,45 @@ static TableParameter TertiaryUint16OpParameters[] = {
 };
 };
 
 
 static TableParameter DotOpParameters[] = {
 static TableParameter DotOpParameters[] = {
-    { L"ShaderOp.Target", TableParameter::STRING, true },
-    { L"ShaderOp.Text", TableParameter::STRING, true },
-    { L"Validation.Input1", TableParameter::STRING_TABLE, true },
-    { L"Validation.Input2", TableParameter::STRING_TABLE, true },
-    { L"Validation.Expected1", TableParameter::STRING_TABLE, true },
-    { L"Validation.Expected2", TableParameter::STRING_TABLE, true },
-    { L"Validation.Expected3", TableParameter::STRING_TABLE, true },
-    { L"Validation.Type", TableParameter::STRING, true },
-    { L"Validation.Tolerance", TableParameter::DOUBLE, true },
+    { L"Dot.ShaderOp.Target", TableParameter::STRING, true },
+    { L"Dot.ShaderOp.Text", TableParameter::STRING, true },
+    { L"Dot.Validation.Input1", TableParameter::STRING_TABLE, true },
+    { L"Dot.Validation.Input2", TableParameter::STRING_TABLE, true },
+    { L"Dot.Validation.Expected1", TableParameter::STRING_TABLE, true },
+    { L"Dot.Validation.Expected2", TableParameter::STRING_TABLE, true },
+    { L"Dot.Validation.Expected3", TableParameter::STRING_TABLE, true },
+    { L"Dot.Validation.Type", TableParameter::STRING, true },
+    { L"Dot.Validation.Tolerance", TableParameter::DOUBLE, true },
+};
+
+static TableParameter Dot2AddOpParameters[] = {
+    { L"Dot2Add.ShaderOp.Target", TableParameter::STRING, true },
+    { L"Dot2Add.ShaderOp.Text", TableParameter::STRING, true },
+    { L"Dot2Add.ShaderOp.Arguments", TableParameter::STRING, true },
+    { L"Dot2Add.Validation.Input1", TableParameter::STRING_TABLE, true },
+    { L"Dot2Add.Validation.Input2", TableParameter::STRING_TABLE, true },
+    { L"Dot2Add.Validation.Input3", TableParameter::FLOAT_TABLE, true },
+    { L"Dot2Add.Validation.Expected1", TableParameter::FLOAT_TABLE, true },
+    { L"Dot2Add.Validation.Type", TableParameter::STRING, true },
+    { L"Dot2Add.Validation.Tolerance", TableParameter::DOUBLE, true },
+};
+
+static TableParameter Dot4AddI8PackedOpParameters[] = {
+    { L"Dot4AddI8Packed.ShaderOp.Target", TableParameter::STRING, true },
+    { L"Dot4AddI8Packed.ShaderOp.Text", TableParameter::STRING, true },
+    { L"Dot4AddI8Packed.Validation.Input1", TableParameter::UINT32_TABLE, true },
+    { L"Dot4AddI8Packed.Validation.Input2", TableParameter::UINT32_TABLE, true },
+    { L"Dot4AddI8Packed.Validation.Input3", TableParameter::INT32_TABLE, true },
+    { L"Dot4AddI8Packed.Validation.Expected1", TableParameter::INT32_TABLE, true },
+};
+
+static TableParameter Dot4AddU8PackedOpParameters[] = {
+    { L"Dot4AddU8Packed.ShaderOp.Target", TableParameter::STRING, true },
+    { L"Dot4AddU8Packed.ShaderOp.Text", TableParameter::STRING, true },
+    { L"Dot4AddU8Packed.Validation.Input1", TableParameter::UINT32_TABLE, true },
+    { L"Dot4AddU8Packed.Validation.Input2", TableParameter::UINT32_TABLE, true },
+    { L"Dot4AddU8Packed.Validation.Input3", TableParameter::UINT32_TABLE, true },
+    { L"Dot4AddU8Packed.Validation.Expected1", TableParameter::UINT32_TABLE, true },
 };
 };
 
 
 static TableParameter Msad4OpParameters[] = {
 static TableParameter Msad4OpParameters[] = {
@@ -3292,6 +3378,23 @@ static HRESULT ParseDataToVectorFloat(PCWSTR str, float *ptr, size_t count) {
     return S_OK;
     return S_OK;
 }
 }
 
 
+static HRESULT ParseDataToVectorHalf(PCWSTR str, uint16_t *ptr, size_t count) {
+    std::wstring wstr(str);
+    size_t curPosition = 0;
+    // parse a string of dot product separated by commas
+    for (size_t i = 0; i < count; ++i) {
+        size_t nextPosition = wstr.find(L",", curPosition);
+        float floatValue;
+        if (FAILED(ParseDataToFloat(
+            wstr.substr(curPosition, nextPosition - curPosition).data(), floatValue))) {
+            return E_FAIL;
+        }
+        *(ptr + i) = ConvertFloat32ToFloat16(floatValue);
+        curPosition = nextPosition + 1;
+    }
+    return S_OK;
+}
+
 static HRESULT ParseDataToVectorUint(PCWSTR str, unsigned int *ptr, size_t count) {
 static HRESULT ParseDataToVectorUint(PCWSTR str, unsigned int *ptr, size_t count) {
     std::wstring wstr(str);
     std::wstring wstr(str);
     size_t curPosition = 0;
     size_t curPosition = 0;
@@ -3546,6 +3649,10 @@ static void VerifyOutputWithExpectedValueInt(int output, int ref, int tolerance)
     VERIFY_IS_TRUE(output - ref <= tolerance && ref - output <= tolerance);
     VERIFY_IS_TRUE(output - ref <= tolerance && ref - output <= tolerance);
 }
 }
 
 
+static void VerifyOutputWithExpectedValueUInt(uint32_t output, uint32_t ref, uint32_t tolerance) {
+    VERIFY_IS_TRUE(output - ref <= tolerance && ref - output <= tolerance);
+}
+
 static void VerifyOutputWithExpectedValueFloat(
 static void VerifyOutputWithExpectedValueFloat(
     float output, float ref, LPCWSTR type, double tolerance,
     float output, float ref, LPCWSTR type, double tolerance,
     hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
     hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
@@ -4928,7 +5035,18 @@ TEST_F(ExecutionTest, TertiaryUint16OpTest) {
   }
   }
 }
 }
 
 
+// TODO: Split into 4 different tests after 19H1 when we're allowed to add new tests
 TEST_F(ExecutionTest, DotTest) {
 TEST_F(ExecutionTest, DotTest) {
+    RunDotOp();
+    RunDot2AddOp();
+    RunDot4AddI8PackedOp();
+    RunDot4AddU8PackedOp();
+}
+
+// Helper for the Dot operator, which is part of DotTest
+void ExecutionTest::RunDotOp() {
+    WEX::Logging::Log::Comment(L"\nRunning Dot Op tests:\n");
+
     WEX::TestExecution::SetVerifyOutput verifySettings(
     WEX::TestExecution::SetVerifyOutput verifySettings(
         WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
         WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
     CComPtr<IStream> pStream;
     CComPtr<IStream> pStream;
@@ -4942,22 +5060,22 @@ TEST_F(ExecutionTest, DotTest) {
     int tableSize = sizeof(DotOpParameters) / sizeof(TableParameter);
     int tableSize = sizeof(DotOpParameters) / sizeof(TableParameter);
     TableParameterHandler handler(DotOpParameters, tableSize);
     TableParameterHandler handler(DotOpParameters, tableSize);
 
 
-    CW2A Target(handler.GetTableParamByName(L"ShaderOp.Target")->m_str);
-    CW2A Text(handler.GetTableParamByName(L"ShaderOp.Text")->m_str);
+    CW2A Target(handler.GetTableParamByName(L"Dot.ShaderOp.Target")->m_str);
+    CW2A Text(handler.GetTableParamByName(L"Dot.ShaderOp.Text")->m_str);
 
 
     std::vector<WEX::Common::String> *Validation_Input1 =
     std::vector<WEX::Common::String> *Validation_Input1 =
-        &handler.GetTableParamByName(L"Validation.Input1")->m_StringTable;
+        &handler.GetTableParamByName(L"Dot.Validation.Input1")->m_StringTable;
     std::vector<WEX::Common::String> *Validation_Input2 =
     std::vector<WEX::Common::String> *Validation_Input2 =
-        &handler.GetTableParamByName(L"Validation.Input2")->m_StringTable;
+        &handler.GetTableParamByName(L"Dot.Validation.Input2")->m_StringTable;
     std::vector<WEX::Common::String> *Validation_dot2 =
     std::vector<WEX::Common::String> *Validation_dot2 =
-        &handler.GetTableParamByName(L"Validation.Expected1")->m_StringTable;
+        &handler.GetTableParamByName(L"Dot.Validation.Expected1")->m_StringTable;
     std::vector<WEX::Common::String> *Validation_dot3 =
     std::vector<WEX::Common::String> *Validation_dot3 =
-        &handler.GetTableParamByName(L"Validation.Expected2")->m_StringTable;
+        &handler.GetTableParamByName(L"Dot.Validation.Expected2")->m_StringTable;
     std::vector<WEX::Common::String> *Validation_dot4 =
     std::vector<WEX::Common::String> *Validation_dot4 =
-        &handler.GetTableParamByName(L"Validation.Expected3")->m_StringTable;
+        &handler.GetTableParamByName(L"Dot.Validation.Expected3")->m_StringTable;
 
 
-    PCWSTR Validation_type = handler.GetTableParamByName(L"Validation.Type")->m_str;
-    double tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
+    PCWSTR Validation_type = handler.GetTableParamByName(L"Dot.Validation.Type")->m_str;
+    double tolerance = handler.GetTableParamByName(L"Dot.Validation.Tolerance")->m_double;
     size_t count = Validation_Input1->size();
     size_t count = Validation_Input1->size();
 
 
     std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
     std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
@@ -5011,6 +5129,217 @@ TEST_F(ExecutionTest, DotTest) {
     }
     }
 }
 }
 
 
+// Helper for the Dot2Add operator, which is part of DotTest
+void ExecutionTest::RunDot2AddOp() {
+    WEX::Logging::Log::Comment(L"\nRunning Dot2Add Op tests:\n");
+
+    WEX::TestExecution::SetVerifyOutput verifySettings(
+        WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
+    CComPtr<IStream> pStream;
+    ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
+
+    CComPtr<ID3D12Device> pDevice;
+    if (!CreateDevice(&pDevice, D3D_SHADER_MODEL::D3D_SHADER_MODEL_6_4, false)) {
+        return;
+    }
+
+    if (!DoesDeviceSupportNative16bitOps(pDevice)) {
+        WEX::Logging::Log::Comment(L"Device does not support native 16-bit operations.");
+        // Don't skip this test for now, otherwise the entire DotTest would be skipped
+        // TODO: Skip the test once the Dot tests have been split in 4 different tests
+        return;
+    }
+
+    int tableSize = sizeof(Dot2AddOpParameters) / sizeof(TableParameter);
+    TableParameterHandler handler(Dot2AddOpParameters, tableSize);
+
+    CW2A Target(handler.GetTableParamByName(L"Dot2Add.ShaderOp.Target")->m_str);
+    CW2A Text(handler.GetTableParamByName(L"Dot2Add.ShaderOp.Text")->m_str);
+    CW2A Arguments(handler.GetTableParamByName(L"Dot2Add.ShaderOp.Arguments")->m_str);
+
+    std::vector<WEX::Common::String> *validation_input1 =
+        &handler.GetTableParamByName(L"Dot2Add.Validation.Input1")->m_StringTable;
+    std::vector<WEX::Common::String> *validation_input2 =
+        &handler.GetTableParamByName(L"Dot2Add.Validation.Input2")->m_StringTable;
+    std::vector<float> *validation_acc = &handler.GetTableParamByName(L"Dot2Add.Validation.Input3")->m_floatTable;
+    std::vector<float> *validation_result = &handler.GetTableParamByName(L"Dot2Add.Validation.Expected1")->m_floatTable;
+
+    PCWSTR Validation_type = handler.GetTableParamByName(L"Dot2Add.Validation.Type")->m_str;
+    double tolerance = handler.GetTableParamByName(L"Dot2Add.Validation.Tolerance")->m_double;
+    size_t count = validation_input1->size();
+
+    std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
+        pDevice, m_support, pStream, "Dot2AddOp",
+        // this callback is called when the test
+        // is creating the resource to run the test
+        [&](LPCSTR Name, std::vector<BYTE> &Data, st::ShaderOp *pShaderOp) {
+        VERIFY_IS_TRUE(0 == _stricmp(Name, "SDot2AddOp"));
+        size_t size = sizeof(SDot2AddOp) * count;
+        Data.resize(size);
+        SDot2AddOp *pPrimitives = (SDot2AddOp*)Data.data();
+        for (size_t i = 0; i < count; ++i) {
+            SDot2AddOp *p = &pPrimitives[i];
+            Half2 val1,val2;
+            VERIFY_SUCCEEDED(ParseDataToVectorHalf((*validation_input1)[i],
+                                                    (uint16_t *)&val1, 2));
+            VERIFY_SUCCEEDED(ParseDataToVectorHalf((*validation_input2)[i],
+                                                    (uint16_t *)&val2, 2));
+            p->input1 = val1;
+            p->input2 = val2;
+            p->acc = (*validation_acc)[i];
+        }
+        // use shader from data table
+        pShaderOp->Shaders.at(0).Target = Target.m_psz;
+        pShaderOp->Shaders.at(0).Text = Text.m_psz;
+        pShaderOp->Shaders.at(0).Arguments = Arguments.m_psz;
+    });
+
+    MappedData data;
+    test->Test->GetReadBackData("SDot2AddOp", &data);
+
+    SDot2AddOp *pPrimitives = (SDot2AddOp*)data.data();
+    WEX::TestExecution::DisableVerifyExceptions dve;
+    for (size_t i = 0; i < count; ++i) {
+        SDot2AddOp *p = &pPrimitives[i];
+        float expectedResult = (*validation_result)[i];
+        float input1x = ConvertFloat16ToFloat32(p->input1.x);
+        float input1y = ConvertFloat16ToFloat32(p->input1.y);
+        float input2x = ConvertFloat16ToFloat32(p->input2.x);
+        float input2y = ConvertFloat16ToFloat32(p->input2.y);
+        LogCommentFmt(
+            L"element #%u, input1 = (%f, %f), input2 = (%f, %f), acc = %f\n"
+            L"result = %f, result_expected = %f",
+            i, input1x, input1y, input2x, input2y, p->acc, p->result, expectedResult);
+        VerifyOutputWithExpectedValueFloat(p->result, expectedResult, Validation_type, tolerance);
+    }
+}
+
+// Helper for the Dot4AddI8Packed operator, which is part of DotTest
+void ExecutionTest::RunDot4AddI8PackedOp() {
+    WEX::Logging::Log::Comment(L"\nRunning Dot4AddI8Packed Op tests:\n");
+
+    WEX::TestExecution::SetVerifyOutput verifySettings(
+        WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
+    CComPtr<IStream> pStream;
+    ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
+
+    CComPtr<ID3D12Device> pDevice;
+    if (!CreateDevice(&pDevice, D3D_SHADER_MODEL::D3D_SHADER_MODEL_6_4, false)) {
+        return;
+    }
+
+    int tableSize = sizeof(Dot4AddI8PackedOpParameters) / sizeof(TableParameter);
+    TableParameterHandler handler(Dot4AddI8PackedOpParameters, tableSize);
+
+    CW2A Target(handler.GetTableParamByName(L"Dot4AddI8Packed.ShaderOp.Target")->m_str);
+    CW2A Text(handler.GetTableParamByName(L"Dot4AddI8Packed.ShaderOp.Text")->m_str);
+
+    std::vector<uint32_t> *validation_input1 = &handler.GetTableParamByName(L"Dot4AddI8Packed.Validation.Input1")->m_uint32Table;
+    std::vector<uint32_t> *validation_input2 = &handler.GetTableParamByName(L"Dot4AddI8Packed.Validation.Input2")->m_uint32Table;
+    std::vector<int32_t> *validation_acc = &handler.GetTableParamByName(L"Dot4AddI8Packed.Validation.Input3")->m_int32Table;
+    std::vector<int32_t> *validation_result = &handler.GetTableParamByName(L"Dot4AddI8Packed.Validation.Expected1")->m_int32Table;
+
+    size_t count = validation_input1->size();
+
+    std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
+        pDevice, m_support, pStream, "Dot4AddI8PackedOp",
+        // this callback is called when the test
+        // is creating the resource to run the test
+        [&](LPCSTR Name, std::vector<BYTE> &Data, st::ShaderOp *pShaderOp) {
+        VERIFY_IS_TRUE(0 == _stricmp(Name, "SDot4AddI8PackedOp"));
+        size_t size = sizeof(SDot4AddI8PackedOp) * count;
+        Data.resize(size);
+        SDot4AddI8PackedOp *pPrimitives = (SDot4AddI8PackedOp*)Data.data();
+        for (size_t i = 0; i < count; ++i) {
+            SDot4AddI8PackedOp *p = &pPrimitives[i];
+            p->input1 = (*validation_input1)[i];
+            p->input2 = (*validation_input2)[i];
+            p->acc = (*validation_acc)[i];
+        }
+        // use shader from data table
+        pShaderOp->Shaders.at(0).Target = Target.m_psz;
+        pShaderOp->Shaders.at(0).Text = Text.m_psz;
+    });
+
+    MappedData data;
+    test->Test->GetReadBackData("SDot4AddI8PackedOp", &data);
+
+    SDot4AddI8PackedOp *pPrimitives = (SDot4AddI8PackedOp*)data.data();
+    WEX::TestExecution::DisableVerifyExceptions dve;
+    for (size_t i = 0; i < count; ++i) {
+        SDot4AddI8PackedOp *p = &pPrimitives[i];
+        int32_t expectedResult = (*validation_result)[i];
+        LogCommentFmt(
+            L"element #%u, input1 = %u, input2 = %u, acc = %d \n"
+            L"result = %d, result_expected = %d",
+            i, p->input1, p->input2, p->acc, p->result, expectedResult);
+        VerifyOutputWithExpectedValueInt(p->result, expectedResult, 0);
+    }
+}
+
+// Helper for the Dot4AddU8Packed operator, which is part of DotTest
+void ExecutionTest::RunDot4AddU8PackedOp() {
+    WEX::Logging::Log::Comment(L"\nRunning Dot4AddU8Packed Op tests\n");
+
+    WEX::TestExecution::SetVerifyOutput verifySettings(
+        WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
+    CComPtr<IStream> pStream;
+    ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
+
+    CComPtr<ID3D12Device> pDevice;
+    if (!CreateDevice(&pDevice, D3D_SHADER_MODEL::D3D_SHADER_MODEL_6_4, false)) {
+        return;
+    }
+
+    int tableSize = sizeof(Dot4AddU8PackedOpParameters) / sizeof(TableParameter);
+    TableParameterHandler handler(Dot4AddU8PackedOpParameters, tableSize);
+
+    CW2A Target(handler.GetTableParamByName(L"Dot4AddU8Packed.ShaderOp.Target")->m_str);
+    CW2A Text(handler.GetTableParamByName(L"Dot4AddU8Packed.ShaderOp.Text")->m_str);
+
+    std::vector<uint32_t> *validation_input1 = &handler.GetTableParamByName(L"Dot4AddU8Packed.Validation.Input1")->m_uint32Table;
+    std::vector<uint32_t> *validation_input2 = &handler.GetTableParamByName(L"Dot4AddU8Packed.Validation.Input2")->m_uint32Table;
+    std::vector<uint32_t> *validation_acc = &handler.GetTableParamByName(L"Dot4AddU8Packed.Validation.Input3")->m_uint32Table;
+    std::vector<uint32_t> *validation_result = &handler.GetTableParamByName(L"Dot4AddU8Packed.Validation.Expected1")->m_uint32Table;
+
+    size_t count = validation_input1->size();
+
+    std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
+        pDevice, m_support, pStream, "Dot4AddU8PackedOp",
+        // this callback is called when the test
+        // is creating the resource to run the test
+        [&](LPCSTR Name, std::vector<BYTE> &Data, st::ShaderOp *pShaderOp) {
+        VERIFY_IS_TRUE(0 == _stricmp(Name, "SDot4AddU8PackedOp"));
+        size_t size = sizeof(SDot4AddU8PackedOp) * count;
+        Data.resize(size);
+        SDot4AddU8PackedOp *pPrimitives = (SDot4AddU8PackedOp*)Data.data();
+        for (size_t i = 0; i < count; ++i) {
+            SDot4AddU8PackedOp *p = &pPrimitives[i];
+            p->input1 = (*validation_input1)[i];
+            p->input2 = (*validation_input2)[i];
+            p->acc = (*validation_acc)[i];
+        }
+        // use shader from data table
+        pShaderOp->Shaders.at(0).Target = Target.m_psz;
+        pShaderOp->Shaders.at(0).Text = Text.m_psz;
+    });
+
+    MappedData data;
+    test->Test->GetReadBackData("SDot4AddU8PackedOp", &data);
+
+    SDot4AddU8PackedOp *pPrimitives = (SDot4AddU8PackedOp*)data.data();
+    WEX::TestExecution::DisableVerifyExceptions dve;
+    for (size_t i = 0; i < count; ++i) {
+        SDot4AddU8PackedOp *p = &pPrimitives[i];
+        uint32_t expectedResult = (*validation_result)[i];
+        LogCommentFmt(
+            L"element #%u, input1 = %u, input2 = %u, acc = %u \n"
+            L"result = %u, result_expected = %u, ",
+            i, p->input1, p->input2, p->acc, p->result, expectedResult);
+        VerifyOutputWithExpectedValueUInt(p->result, expectedResult, 0);
+    }
+}
+
 TEST_F(ExecutionTest, Msad4Test) {
 TEST_F(ExecutionTest, Msad4Test) {
     WEX::TestExecution::SetVerifyOutput verifySettings(
     WEX::TestExecution::SetVerifyOutput verifySettings(
         WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
         WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);

+ 252 - 19
tools/clang/unittests/HLSL/ShaderOpArithTable.xml

@@ -4704,23 +4704,53 @@
             <Parameter Name="ShaderOp.Arguments">-enable-16bit-types</Parameter>
             <Parameter Name="ShaderOp.Arguments">-enable-16bit-types</Parameter>
         </Row>
         </Row>
     </Table>
     </Table>
+    <!-- TODO: Split into 4 separate tables after 19H1 -->
     <Table Id="DotOpTable">
     <Table Id="DotOpTable">
         <ParameterTypes>
         <ParameterTypes>
-            <ParameterType Name="ShaderOp.Target">String</ParameterType>
-            <ParameterType Name="ShaderOp.Arguments">String</ParameterType>
-            <ParameterType Name="ShaderOp.Text">String</ParameterType>
-            <ParameterType Name="Validation.Type">String</ParameterType>
-            <ParameterType Name="Validation.Tolerance">double</ParameterType>
-            <ParameterType Array="true" Name="Validation.Input1">String</ParameterType>
-            <ParameterType Array="true" Name="Validation.Input2">String</ParameterType>
-            <ParameterType Array="true" Name="Validation.Expected1">String</ParameterType>
-            <ParameterType Array="true" Name="Validation.Expected2">String</ParameterType>
-            <ParameterType Array="true" Name="Validation.Expected3">String</ParameterType>
+            <!-- DotAdd Parameters -->
+            <ParameterType Name="Dot.ShaderOp.Target">String</ParameterType>
+            <ParameterType Name="Dot.ShaderOp.Arguments">String</ParameterType>
+            <ParameterType Name="Dot.ShaderOp.Text">String</ParameterType>
+            <ParameterType Name="Dot.Validation.Type">String</ParameterType>
+            <ParameterType Name="Dot.Validation.Tolerance">double</ParameterType>
+            <ParameterType Array="true" Name="Dot.Validation.Input1">String</ParameterType>
+            <ParameterType Array="true" Name="Dot.Validation.Input2">String</ParameterType>
+            <ParameterType Array="true" Name="Dot.Validation.Expected1">String</ParameterType>
+            <ParameterType Array="true" Name="Dot.Validation.Expected2">String</ParameterType>
+            <ParameterType Array="true" Name="Dot.Validation.Expected3">String</ParameterType>
+
+            <!-- Dot2Add Parameters -->
+            <ParameterType Name="Dot2Add.ShaderOp.Target">String</ParameterType>
+            <ParameterType Name="Dot2Add.ShaderOp.Arguments">String</ParameterType>
+            <ParameterType Name="Dot2Add.ShaderOp.Text">String</ParameterType>
+            <ParameterType Name="Dot2Add.Validation.Type">String</ParameterType>
+            <ParameterType Name="Dot2Add.Validation.Tolerance">double</ParameterType>
+            <ParameterType Array="true" Name="Dot2Add.Validation.Input1">String</ParameterType>
+            <ParameterType Array="true" Name="Dot2Add.Validation.Input2">String</ParameterType>
+            <ParameterType Array="true" Name="Dot2Add.Validation.Input3">String</ParameterType>
+            <ParameterType Array="true" Name="Dot2Add.Validation.Expected1">String</ParameterType>
+
+            <!-- Dot4AddI8Packed Parameters -->
+            <ParameterType Name="Dot4AddI8Packed.ShaderOp.Target">String</ParameterType>
+            <ParameterType Name="Dot4AddI8Packed.ShaderOp.Text">String</ParameterType>
+            <ParameterType Array="true" Name="Dot4AddI8Packed.Validation.Input1">String</ParameterType>
+            <ParameterType Array="true" Name="Dot4AddI8Packed.Validation.Input2">String</ParameterType>
+            <ParameterType Array="true" Name="Dot4AddI8Packed.Validation.Input3">String</ParameterType>
+            <ParameterType Array="true" Name="Dot4AddI8Packed.Validation.Expected1">String</ParameterType>
+
+            <!-- Dot4AddU8Packed Parameters -->
+            <ParameterType Name="Dot4AddU8Packed.ShaderOp.Target">String</ParameterType>
+            <ParameterType Name="Dot4AddU8Packed.ShaderOp.Text">String</ParameterType>
+            <ParameterType Array="true" Name="Dot4AddU8Packed.Validation.Input1">String</ParameterType>
+            <ParameterType Array="true" Name="Dot4AddU8Packed.Validation.Input2">String</ParameterType>
+            <ParameterType Array="true" Name="Dot4AddU8Packed.Validation.Input3">String</ParameterType>
+            <ParameterType Array="true" Name="Dot4AddU8Packed.Validation.Expected1">String</ParameterType>
         </ParameterTypes>
         </ParameterTypes>
         <Row Name="Dot">
         <Row Name="Dot">
-            <Parameter Name="Validation.Type">epsilon</Parameter>
-            <Parameter Name="Validation.Tolerance">0.008</Parameter>
-            <Parameter Name="ShaderOp.Text"> struct SDotOp {
+            <!-- Dot Parameters -->
+            <Parameter Name="Dot.Validation.Type">epsilon</Parameter>
+            <Parameter Name="Dot.Validation.Tolerance">0.008</Parameter>
+            <Parameter Name="Dot.ShaderOp.Text"> struct SDotOp {
                    float4 input1;
                    float4 input1;
                    float4 input2;
                    float4 input2;
                    float o_dot2;
                    float o_dot2;
@@ -4736,8 +4766,8 @@
                     l.o_dot4 = dot(l.input1.xyzw, l.input2.xyzw);
                     l.o_dot4 = dot(l.input1.xyzw, l.input2.xyzw);
                     g_buf[GI] = l;
                     g_buf[GI] = l;
                 };</Parameter>
                 };</Parameter>
-            <Parameter Name="ShaderOp.Target">cs_6_0</Parameter>
-            <Parameter Name="Validation.Input1">
+            <Parameter Name="Dot.ShaderOp.Target">cs_6_0</Parameter>
+            <Parameter Name="Dot.Validation.Input1">
                 <Value>NaN,NaN,NaN,NaN</Value>
                 <Value>NaN,NaN,NaN,NaN</Value>
                 <Value>-Inf,-Inf,-Inf,-Inf</Value>
                 <Value>-Inf,-Inf,-Inf,-Inf</Value>
                 <Value>-denorm,-denorm,-denorm,-denorm</Value>
                 <Value>-denorm,-denorm,-denorm,-denorm</Value>
@@ -4749,7 +4779,7 @@
                 <Value>-10,0,0,10</Value>
                 <Value>-10,0,0,10</Value>
                 <Value>Inf,Inf,Inf,-Inf</Value>
                 <Value>Inf,Inf,Inf,-Inf</Value>
             </Parameter>
             </Parameter>
-            <Parameter Name="Validation.Input2">
+            <Parameter Name="Dot.Validation.Input2">
                 <Value>NaN,NaN,NaN,NaN</Value>
                 <Value>NaN,NaN,NaN,NaN</Value>
                 <Value>-Inf,-Inf,-Inf,-Inf</Value>
                 <Value>-Inf,-Inf,-Inf,-Inf</Value>
                 <Value>-denorm,-denorm,-denorm,-denorm</Value>
                 <Value>-denorm,-denorm,-denorm,-denorm</Value>
@@ -4761,7 +4791,7 @@
                 <Value>10,0,0,10</Value>
                 <Value>10,0,0,10</Value>
                 <Value>Inf,Inf,Inf,Inf</Value>
                 <Value>Inf,Inf,Inf,Inf</Value>
             </Parameter>
             </Parameter>
-            <Parameter Name="Validation.Expected1">
+            <Parameter Name="Dot.Validation.Expected1">
                 <Value>nan</Value>
                 <Value>nan</Value>
                 <Value>inf</Value>
                 <Value>inf</Value>
                 <Value>0</Value>
                 <Value>0</Value>
@@ -4773,7 +4803,7 @@
                 <Value>-100</Value>
                 <Value>-100</Value>
                 <Value>inf</Value>
                 <Value>inf</Value>
             </Parameter>
             </Parameter>
-            <Parameter Name="Validation.Expected2">
+            <Parameter Name="Dot.Validation.Expected2">
                 <Value>nan</Value>
                 <Value>nan</Value>
                 <Value>inf</Value>
                 <Value>inf</Value>
                 <Value>0</Value>
                 <Value>0</Value>
@@ -4785,7 +4815,7 @@
                 <Value>-100</Value>
                 <Value>-100</Value>
                 <Value>inf</Value>
                 <Value>inf</Value>
             </Parameter>
             </Parameter>
-            <Parameter Name="Validation.Expected3">
+            <Parameter Name="Dot.Validation.Expected3">
                 <Value>nan</Value>
                 <Value>nan</Value>
                 <Value>inf</Value>
                 <Value>inf</Value>
                 <Value>0</Value>
                 <Value>0</Value>
@@ -4797,6 +4827,209 @@
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>nan</Value>
                 <Value>nan</Value>
             </Parameter>
             </Parameter>
+
+            <!-- Dot2Add Parameters -->
+            <Parameter Name="Dot2Add.Validation.Type">epsilon</Parameter>
+            <Parameter Name="Dot2Add.Validation.Tolerance">0.008</Parameter>
+            <Parameter Name="Dot2Add.ShaderOp.Text"> struct SDot2AddOp {
+                   half2 input1;
+                   half2 input2;
+                   float acc;
+                   float result;
+                };
+                RWStructuredBuffer&lt;SDot2AddOp&gt; g_buf : register(u0);
+                [numthreads(8,8,1)]
+                void main(uint GI : SV_GroupIndex) {
+                    SDot2AddOp l = g_buf[GI];
+                    l.result = dot2add(l.input1, l.input2, l.acc);
+                    g_buf[GI] = l;
+                };</Parameter>
+            <Parameter Name="Dot2Add.ShaderOp.Target">cs_6_4</Parameter>
+            <Parameter Name="Dot2Add.Validation.Input1">
+                <Value>1,2</Value>
+                <Value>1,-2</Value>
+                <Value>1,2</Value>
+                <Value>-1,2</Value>
+                <Value>1,2</Value>
+                <Value>-1,2</Value>
+                <Value>1,2</Value>
+                <Value>-1,-2</Value>
+                <Value>65504,1</Value>
+                <Value>-65504,1</Value>
+                <Value>1,65504</Value>
+                <Value>1,-65504</Value>
+                <Value>65504,65504</Value>
+                <Value>inf,inf</Value>
+                <Value>denorm,denorm</Value>
+                <Value>-denorm,-denorm</Value>
+                <Value>nan,nan</Value>
+            </Parameter>
+            <Parameter Name="Dot2Add.Validation.Input2">
+                <Value>3,4</Value>
+                <Value>-3,4</Value>
+                <Value>3,4</Value>
+                <Value>3,-4</Value>
+                <Value>3,4</Value>
+                <Value>-3,4</Value>
+                <Value>3,4</Value>
+                <Value>-3,-4</Value>
+                <Value>1,65504</Value>
+                <Value>1,-65504</Value>
+                <Value>65504,1</Value>
+                <Value>-65504,1</Value>
+                <Value>65504,65504</Value>
+                <Value>inf,inf</Value>
+                <Value>denorm,denorm</Value>
+                <Value>-denorm,-denorm</Value>
+                <Value>nan,nan</Value>
+            </Parameter>
+            <Parameter Name="Dot2Add.Validation.Input3">
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>10</Value>
+                <Value>10</Value>
+                <Value>-5</Value>
+                <Value>-5</Value>
+                <Value>-30</Value>
+                <Value>-30</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>10000000</Value>
+                <Value>-10000000</Value>
+                <Value>0</Value>
+                <Value>inf</Value>
+                <Value>denorm</Value>
+                <Value>-denorm</Value>
+                <Value>nan</Value>
+            </Parameter>
+            <Parameter Name="Dot2Add.Validation.Expected1">
+                <Value>11</Value>
+                <Value>-11</Value>
+                <Value>21</Value>
+                <Value>-1</Value>
+                <Value>6</Value>
+                <Value>6</Value>
+                <Value>-19</Value>
+                <Value>-19</Value>
+                <Value>131008</Value>
+                <Value>-131008</Value>
+                <Value>10131008</Value>
+                <Value>-10131008</Value>
+                <Value>inf</Value>
+                <Value>inf</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>nan</Value>
+            </Parameter>
+            <Parameter Name="Dot2Add.ShaderOp.Arguments">-enable-16bit-types</Parameter>
+
+            <!-- Dot4AddI8Packed Parameters -->
+            <Parameter Name="Dot4AddI8Packed.ShaderOp.Text"> struct SDot4AddI8PackedOp {
+                   dword input1;
+                   dword input2;
+                   int acc;
+                   int result;
+                };
+                RWStructuredBuffer&lt;SDot4AddI8PackedOp&gt; g_buf : register(u0);
+                [numthreads(8,8,1)]
+                void main(uint GI : SV_GroupIndex) {
+                    SDot4AddI8PackedOp l = g_buf[GI];
+                    l.result = dot4add_i8packed(l.input1, l.input2, l.acc);
+                    g_buf[GI] = l;
+                };</Parameter>
+            <Parameter Name="Dot4AddI8Packed.ShaderOp.Target">cs_6_4</Parameter>
+            <Parameter Name="Dot4AddI8Packed.Validation.Input1">
+                <Value>0x00000102</Value>
+                <Value>0x00000102</Value>
+                <Value>0x00000102</Value>
+                <Value>0x00000102</Value>
+                <Value>0XFFFFFFFF</Value>
+                <Value>0x80808080</Value>
+                <Value>0x80808080</Value>
+                <Value>0x807F807F</Value>
+                <Value>0x7F7F7F7F</Value>
+                <Value>0x80808080</Value>
+            </Parameter>
+            <Parameter Name="Dot4AddI8Packed.Validation.Input2">
+                <Value>0x00000304</Value>
+                <Value>0x00000304</Value>
+                <Value>0x00000304</Value>
+                <Value>0x00000304</Value>
+                <Value>0xFFFFFFFF</Value>
+                <Value>0x01010101</Value>
+                <Value>0x7F7F7F7F</Value>
+                <Value>0x807F807F</Value>
+                <Value>0x7F7F7F7F</Value>
+                <Value>0x80808080</Value>
+            </Parameter>
+            <Parameter Name="Dot4AddI8Packed.Validation.Input3">
+                <Value>0</Value>
+                <Value>10</Value>
+                <Value>-5</Value>
+                <Value>-30</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+            </Parameter>
+            <Parameter Name="Dot4AddI8Packed.Validation.Expected1">
+                <Value>11</Value>
+                <Value>21</Value>
+                <Value>6</Value>
+                <Value>-19</Value>
+                <Value>4</Value>
+                <Value>-512</Value>
+                <Value>-65024</Value>
+                <Value>65026</Value>
+                <Value>64516</Value>
+                <Value>65536</Value>
+            </Parameter>
+
+            <!-- Dot4AddI8Packed Parameters -->
+            <Parameter Name="Dot4AddU8Packed.ShaderOp.Text"> struct SDot4AddU8PackedOp {
+                   dword input1;
+                   dword input2;
+                   dword acc;
+                   dword result;
+                };
+                RWStructuredBuffer&lt;SDot4AddU8PackedOp&gt; g_buf : register(u0);
+                [numthreads(8,8,1)]
+                void main(uint GI : SV_GroupIndex) {
+                    SDot4AddU8PackedOp l = g_buf[GI];
+                    l.result = dot4add_u8packed(l.input1, l.input2, l.acc);
+                    g_buf[GI] = l;
+                };</Parameter>
+            <Parameter Name="Dot4AddU8Packed.ShaderOp.Target">cs_6_4</Parameter>
+            <Parameter Name="Dot4AddU8Packed.Validation.Input1">
+                <Value>0x00000102</Value>
+                <Value>0x00000102</Value>
+                <Value>0x01234567</Value>
+                <Value>0xFFFFFFFF</Value>
+                <Value>0xFFFFFFFF</Value>
+            </Parameter>
+            <Parameter Name="Dot4AddU8Packed.Validation.Input2">
+                <Value>0x00000304</Value>
+                <Value>0x00000304</Value>
+                <Value>0x23456789</Value>
+                <Value>0xFFFFFFFF</Value>
+                <Value>0xFFFFFFFF</Value>
+            </Parameter>
+            <Parameter Name="Dot4AddU8Packed.Validation.Input3">
+                <Value>0</Value>
+                <Value>10</Value>
+                <Value>10000</Value>
+                <Value>0</Value>
+                <Value>3000000000</Value>
+            </Parameter>
+            <Parameter Name="Dot4AddU8Packed.Validation.Expected1">
+                <Value>11</Value>
+                <Value>21</Value>
+                <Value>33668</Value>
+                <Value>260100</Value>
+                <Value>3000260100</Value>
+            </Parameter>
         </Row>
         </Row>
     </Table>
     </Table>
     <Table Id="Msad4Table">
     <Table Id="Msad4Table">