浏览代码

Fix denorm tests and sm support (#1059)

- Fixing device support for > SM 6.0
- updating dxexp
- Also fixing the following tests:
ExecutionTest::DenormBinaryFloatOpTest#FDivDenormFTZ
ExecutionTest::DenormBinaryFloatOpTest#FAddDenormAny
ExecutionTest::DenormBinaryFloatOpTest#FMulDenormAny
ExecutionTest::DenormBinaryFloatOpTest#FDivDenormAny
ExecutionTest::DenormBinaryFloatOpTest#FMulDenormFTZ
ExecutionTest::DenormBinaryFloatOpTest#FAddDenormFTZ
ExecutionTest::DenormBinaryFloatOpTest#FSubDenormFTZ
ExecutionTest::DenormBinaryFloatOpTest#FSubDenormAny
ExecutionTest::DenormTertiaryFloatOpTest#FMadDenormAny
ExecutionTest::DenormTertiaryFloatOpTest#FMadDenormFTZ
Young Kim 7 年之前
父节点
当前提交
134127fde6

+ 102 - 24
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -71,6 +71,7 @@ static const GUID D3D12ExperimentalShaderModelsID = { /* 76f5573e-f13a-40f5-b297
 using namespace DirectX;
 using namespace DirectX;
 using namespace hlsl_test;
 using namespace hlsl_test;
 
 
+
 template <typename TSequence, typename T>
 template <typename TSequence, typename T>
 static bool contains(TSequence s, const T &val) {
 static bool contains(TSequence s, const T &val) {
   return std::cend(s) != std::find(std::cbegin(s), std::cend(s), val);
   return std::cend(s) != std::find(std::cbegin(s), std::cend(s), val);
@@ -360,7 +361,15 @@ public:
     D3D_SHADER_MODEL_6_2 = 0x62
     D3D_SHADER_MODEL_6_2 = 0x62
   } D3D_SHADER_MODEL;
   } D3D_SHADER_MODEL;
 
 
- dxc::DxcDllSupport m_support;
+#if WDK_NTDDI_VERSION == NTDDI_WIN10_RS2
+  static const D3D_SHADER_MODEL HIGHEST_SHADER_MODEL = D3D_SHADER_MODEL_6_0;
+#elif WDK_NTDDI_VERSION == NTDDI_WIN10_RS3
+  static const D3D_SHADER_MODEL HIGHEST_SHADER_MODEL = D3D_SHADER_MODEL_6_1;
+#else
+  static const D3D_SHADER_MODEL HIGHEST_SHADER_MODEL = D3D_SHADER_MODEL_6_2;
+#endif
+
+  dxc::DxcDllSupport m_support;
   VersionSupportInfo m_ver;
   VersionSupportInfo m_ver;
   bool m_ExperimentalModeEnabled = false;
   bool m_ExperimentalModeEnabled = false;
 
 
@@ -433,6 +442,12 @@ 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) {
+    if (testModel > HIGHEST_SHADER_MODEL) {
+      UINT minor = testModel & 0x0f;
+      LogCommentFmt(L"Installed SDK does not support "
+          L"shader model 6.%1u", minor);
+      return false;
+    }
     const D3D_FEATURE_LEVEL FeatureLevelRequired = D3D_FEATURE_LEVEL_11_0;
     const D3D_FEATURE_LEVEL FeatureLevelRequired = D3D_FEATURE_LEVEL_11_0;
     CComPtr<IDXGIFactory4> factory;
     CComPtr<IDXGIFactory4> factory;
     CComPtr<ID3D12Device> pDevice;
     CComPtr<ID3D12Device> pDevice;
@@ -477,10 +492,10 @@ public:
       } D3D12_FEATURE_DATA_SHADER_MODEL;
       } D3D12_FEATURE_DATA_SHADER_MODEL;
       const UINT D3D12_FEATURE_SHADER_MODEL = 7;
       const UINT D3D12_FEATURE_SHADER_MODEL = 7;
       D3D12_FEATURE_DATA_SHADER_MODEL SMData;
       D3D12_FEATURE_DATA_SHADER_MODEL SMData;
-      SMData.HighestShaderModel = D3D_SHADER_MODEL_6_0;
+      SMData.HighestShaderModel = HIGHEST_SHADER_MODEL;
       VERIFY_SUCCEEDED(pDevice->CheckFeatureSupport(
       VERIFY_SUCCEEDED(pDevice->CheckFeatureSupport(
         (D3D12_FEATURE)D3D12_FEATURE_SHADER_MODEL, &SMData, sizeof(SMData)));
         (D3D12_FEATURE)D3D12_FEATURE_SHADER_MODEL, &SMData, sizeof(SMData)));
-      if (SMData.HighestShaderModel != testModel) {
+      if (SMData.HighestShaderModel < testModel) {
         UINT minor = testModel & 0x0f;
         UINT minor = 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);
@@ -2834,6 +2849,7 @@ static TableParameter DenormTertiaryFPOpParameters[] = {
     { L"Validation.Input2", TableParameter::STRING_TABLE, true },
     { L"Validation.Input2", TableParameter::STRING_TABLE, true },
     { L"Validation.Input3", TableParameter::STRING_TABLE, true },
     { L"Validation.Input3", TableParameter::STRING_TABLE, true },
     { L"Validation.Expected1", TableParameter::STRING_TABLE, true },
     { L"Validation.Expected1", TableParameter::STRING_TABLE, true },
+    { L"Validation.Expected2", TableParameter::STRING_TABLE, false },
     { L"Validation.Type", TableParameter::STRING, true },
     { L"Validation.Type", TableParameter::STRING, true },
     { L"Validation.Tolerance", TableParameter::DOUBLE, true },
     { L"Validation.Tolerance", TableParameter::DOUBLE, true },
 };
 };
@@ -3206,6 +3222,21 @@ static void VerifyOutputWithExpectedValueFloat(
   }
   }
 }
 }
 
 
+static bool CompareOutputWithExpectedValueFloat(
+    float output, float ref, LPCWSTR type, double tolerance,
+    hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
+  if (_wcsicmp(type, L"Relative") == 0) {
+    return CompareFloatRelativeEpsilon(output, ref, (int)tolerance, mode);
+  } else if (_wcsicmp(type, L"Epsilon") == 0) {
+    return CompareFloatEpsilon(output, ref, (float)tolerance, mode);
+  } else if (_wcsicmp(type, L"ULP") == 0) {
+    return CompareFloatULP(output, ref, (int)tolerance, mode);
+  } else {
+    LogErrorFmt(L"Failed to read comparison type %S", type);
+    return false;
+  }
+}
+
 static void VerifyOutputWithExpectedValueHalf(
 static void VerifyOutputWithExpectedValueHalf(
   uint16_t output, uint16_t ref, LPCWSTR type, double tolerance) {
   uint16_t output, uint16_t ref, LPCWSTR type, double tolerance) {
   if (_wcsicmp(type, L"Relative") == 0) {
   if (_wcsicmp(type, L"Relative") == 0) {
@@ -4747,6 +4778,9 @@ TEST_F(ExecutionTest, DenormBinaryFloatOpTest) {
 
 
   std::vector<WEX::Common::String> *Validation_Expected1 =
   std::vector<WEX::Common::String> *Validation_Expected1 =
     &(handler.GetTableParamByName(L"Validation.Expected1")->m_StringTable);
     &(handler.GetTableParamByName(L"Validation.Expected1")->m_StringTable);
+  // two expected outputs for any mode
+  std::vector<WEX::Common::String> *Validation_Expected2 =
+    &(handler.GetTableParamByName(L"Validation.Expected2")->m_StringTable);
 
 
   LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
   LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
   double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
   double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
@@ -4760,7 +4794,10 @@ TEST_F(ExecutionTest, DenormBinaryFloatOpTest) {
   else if (strcmp(Arguments.m_psz, "-denorm ftz") == 0) {
   else if (strcmp(Arguments.m_psz, "-denorm ftz") == 0) {
     mode = Float32DenormMode::FTZ;
     mode = Float32DenormMode::FTZ;
   }
   }
-
+  if (mode == Float32DenormMode::Any) {
+    DXASSERT(Validation_Expected2->size() == Validation_Expected1->size(),
+             "must have same number of expected values");
+  }
   std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
   std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
     pDevice, m_support, pStream, "BinaryFPOp",
     pDevice, m_support, pStream, "BinaryFPOp",
     // this callbacked is called when the test
     // this callbacked is called when the test
@@ -4793,17 +4830,34 @@ TEST_F(ExecutionTest, DenormBinaryFloatOpTest) {
   SBinaryFPOp *pPrimitives = (SBinaryFPOp *)data.data();
   SBinaryFPOp *pPrimitives = (SBinaryFPOp *)data.data();
   WEX::TestExecution::DisableVerifyExceptions dve;
   WEX::TestExecution::DisableVerifyExceptions dve;
 
 
-
   for (unsigned i = 0; i < count; ++i) {
   for (unsigned i = 0; i < count; ++i) {
     SBinaryFPOp *p = &pPrimitives[i];
     SBinaryFPOp *p = &pPrimitives[i];
-    LPCWSTR str1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
-    float val1;
-    VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
-    LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, output1 = "
-      L"%6.8f, expected1 = %6.8f",
-      i, p->input1, p->input2, p->output1, val1);
-    VerifyOutputWithExpectedValueFloat(p->output1, val1, Validation_Type,
-      Validation_Tolerance, mode);
+    if (mode == Float32DenormMode::Any) {
+       LPCWSTR str1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
+       LPCWSTR str2 = (*Validation_Expected2)[i % Validation_Expected2->size()];
+       float val1;
+       float val2;
+       VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
+       VERIFY_SUCCEEDED(ParseDataToFloat(str2, val2));
+       LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, output = "
+         L"%6.8f, expected = %6.8f(%x) or %6.8f(%x)",
+         i, p->input1, p->input2, p->output1, val1, *(int *)&val1, val2, *(int *)&val2);
+       VERIFY_IS_TRUE(
+           CompareOutputWithExpectedValueFloat(
+               p->output1, val1, Validation_Type, Validation_Tolerance, mode) ||
+           CompareOutputWithExpectedValueFloat(
+               p->output1, val2, Validation_Type, Validation_Tolerance, mode));
+    }
+    else {
+       LPCWSTR str1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
+       float val1;
+       VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
+       LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, output = "
+         L"%6.8f, expected = %6.8f(%a)",
+         i, p->input1, p->input2, p->output1, val1, *(int *)&val1);
+       VerifyOutputWithExpectedValueFloat(p->output1, val1, Validation_Type,
+          Validation_Tolerance, mode);
+    }
   }
   }
 }
 }
 
 
@@ -4833,9 +4887,12 @@ TEST_F(ExecutionTest, DenormTertiaryFloatOpTest) {
   std::vector<WEX::Common::String> *Validation_Input3 =
   std::vector<WEX::Common::String> *Validation_Input3 =
     &(handler.GetTableParamByName(L"Validation.Input3")->m_StringTable);
     &(handler.GetTableParamByName(L"Validation.Input3")->m_StringTable);
 
 
-  std::vector<WEX::Common::String> *Validation_Expected =
+  std::vector<WEX::Common::String> *Validation_Expected1 =
     &(handler.GetTableParamByName(L"Validation.Expected1")->m_StringTable);
     &(handler.GetTableParamByName(L"Validation.Expected1")->m_StringTable);
-
+  
+  // two expected outputs for any mode
+  std::vector<WEX::Common::String> *Validation_Expected2 =
+    &(handler.GetTableParamByName(L"Validation.Expected2")->m_StringTable);
   LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
   LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
   double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
   double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
   size_t count = Validation_Input1->size();
   size_t count = Validation_Input1->size();
@@ -4848,7 +4905,10 @@ TEST_F(ExecutionTest, DenormTertiaryFloatOpTest) {
   else if (strcmp(Arguments.m_psz, "-denorm ftz") == 0) {
   else if (strcmp(Arguments.m_psz, "-denorm ftz") == 0) {
     mode = Float32DenormMode::FTZ;
     mode = Float32DenormMode::FTZ;
   }
   }
-
+  if (mode == Float32DenormMode::Any) {
+    DXASSERT(Validation_Expected2->size() == Validation_Expected1->size(),
+      "must have same number of expected values");
+  }
   std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
   std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
     pDevice, m_support, pStream, "TertiaryFPOp",
     pDevice, m_support, pStream, "TertiaryFPOp",
     // this callbacked is called when the test
     // this callbacked is called when the test
@@ -4886,14 +4946,32 @@ TEST_F(ExecutionTest, DenormTertiaryFloatOpTest) {
 
 
   for (unsigned i = 0; i < count; ++i) {
   for (unsigned i = 0; i < count; ++i) {
     STertiaryFPOp *p = &pPrimitives[i];
     STertiaryFPOp *p = &pPrimitives[i];
-    LPCWSTR str = (*Validation_Expected)[i % Validation_Expected->size()];
-    float val;
-    VERIFY_SUCCEEDED(ParseDataToFloat(str, val));
-    LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, input3 = %6.8f, output1 = "
-      L"%6.8f, expected = %6.8f",
-      i, p->input1, p->input2, p->input3, p->output, val);
-    VerifyOutputWithExpectedValueFloat(p->output, val, Validation_Type,
-      Validation_Tolerance);
+    if (mode == Float32DenormMode::Any) {
+        LPCWSTR str1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
+        LPCWSTR str2 = (*Validation_Expected2)[i % Validation_Expected2->size()];
+        float val1;
+        float val2;
+        VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
+        VERIFY_SUCCEEDED(ParseDataToFloat(str2, val2));
+        LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, input3 = %6.8f, output = "
+            L"%6.8f, expected = %6.8f(%x) or %6.8f(%x)",
+            i, p->input1, p->input2, p->input3, p->output, val1, *(int *)&val1, val2, *(int *)&val2);
+        VERIFY_IS_TRUE(
+            CompareOutputWithExpectedValueFloat(
+                p->output, val1, Validation_Type, Validation_Tolerance, mode) ||
+            CompareOutputWithExpectedValueFloat(
+                p->output, val2, Validation_Type, Validation_Tolerance, mode));
+    }
+    else {
+        LPCWSTR str1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
+        float val1;
+        VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
+        LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, input3 = %6.8f, output = "
+            L"%6.8f, expected = %6.8f(%a)",
+            i, p->input1, p->input2, p->input3, p->output, val1, *(int *)&val1);
+        VerifyOutputWithExpectedValueFloat(p->output, val1, Validation_Type,
+            Validation_Tolerance, mode);
+    }
   }
   }
 }
 }
 
 

+ 41 - 9
tools/clang/unittests/HLSL/ShaderOpArithTable.xml

@@ -5777,6 +5777,7 @@
             <ParameterType Array="true" Name="Validation.Input1">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Input1">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Input2">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Input2">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Expected1">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Expected1">String</ParameterType>
+            <ParameterType Array="true" Name="Validation.Expected2">String</ParameterType>
         </ParameterTypes>
         </ParameterTypes>
         <Row Name="FDivDenormFTZ">
         <Row Name="FDivDenormFTZ">
             <Parameter Name="Validation.Type">ulp</Parameter>
             <Parameter Name="Validation.Type">ulp</Parameter>
@@ -5809,7 +5810,7 @@
             </Parameter>
             </Parameter>
             <Parameter Name="Validation.Expected1">
             <Parameter Name="Validation.Expected1">
                 <Value>0</Value>
                 <Value>0</Value>
-                <Value>1</Value>
+                <Value>NaN</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
             </Parameter>
             </Parameter>
@@ -5846,10 +5847,16 @@
             </Parameter>
             </Parameter>
             <Parameter Name="Validation.Expected1">
             <Parameter Name="Validation.Expected1">
                 <Value>0x00FC0000</Value>
                 <Value>0x00FC0000</Value>
-                <Value>0</Value>
+                <Value>0x00400000</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0x00700000</Value>
                 <Value>0x00700000</Value>
             </Parameter>
             </Parameter>
+            <Parameter Name="Validation.Expected2">
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+            </Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
         </Row>
         </Row>
         <Row Name="FMulDenormAny">
         <Row Name="FMulDenormAny">
@@ -5890,6 +5897,13 @@
                 <Value>0x01960000</Value>
                 <Value>0x01960000</Value>
                 <Value>0x32400000</Value>
                 <Value>0x32400000</Value>
             </Parameter>
             </Parameter>
+            <Parameter Name="Validation.Expected2">
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+            </Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
         </Row>
         </Row>
         <Row Name="FDivDenormAny">
         <Row Name="FDivDenormAny">
@@ -5927,6 +5941,12 @@
                 <Value>0x00404040</Value>
                 <Value>0x00404040</Value>
                 <Value>0x00400000</Value>
                 <Value>0x00400000</Value>
             </Parameter>
             </Parameter>
+            <Parameter Name="Validation.Expected2">
+                <Value>0</Value>
+                <Value>NaN</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+            </Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
         </Row>
         </Row>
         <Row Name="FMulDenormFTZ">
         <Row Name="FMulDenormFTZ">
@@ -5964,8 +5984,8 @@
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
-                <Value>0x01960000</Value>
-                <Value>0x32400000</Value>
+                <Value>0</Value>
+                <Value>0</Value>
             </Parameter>
             </Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm ftz</Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm ftz</Parameter>
         </Row>
         </Row>
@@ -5999,7 +6019,7 @@
                 <Value>0x800E0000</Value>
                 <Value>0x800E0000</Value>
             </Parameter>
             </Parameter>
             <Parameter Name="Validation.Expected1">
             <Parameter Name="Validation.Expected1">
-                <Value>0x00FC0000</Value>
+                <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
@@ -6074,7 +6094,7 @@
             </Parameter>
             </Parameter>
             <Parameter Name="Validation.Expected1">
             <Parameter Name="Validation.Expected1">
                 <Value>0x0</Value>
                 <Value>0x0</Value>
-                <Value>0x00FE0000</Value>
+                <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0</Value>
             </Parameter>
             </Parameter>
@@ -6152,6 +6172,12 @@
                 <Value>0x007F0000</Value>
                 <Value>0x007F0000</Value>
                 <Value>0x007A0000</Value>
                 <Value>0x007A0000</Value>
             </Parameter>
             </Parameter>
+            <Parameter Name="Validation.Expected2">
+                <Value>0x0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+                <Value>0</Value>
+            </Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
         </Row>
         </Row>
         <Row Name="FAddDenormPreserve">
         <Row Name="FAddDenormPreserve">
@@ -6185,7 +6211,7 @@
             </Parameter>
             </Parameter>
             <Parameter Name="Validation.Expected1">
             <Parameter Name="Validation.Expected1">
                 <Value>0x00FC0000</Value>
                 <Value>0x00FC0000</Value>
-                <Value>0</Value>
+                <Value>0x00400000</Value>
                 <Value>0</Value>
                 <Value>0</Value>
                 <Value>0x00700000</Value>
                 <Value>0x00700000</Value>
             </Parameter>
             </Parameter>
@@ -6243,6 +6269,7 @@
             <ParameterType Array="true" Name="Validation.Input2">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Input2">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Input3">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Input3">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Expected1">String</ParameterType>
             <ParameterType Array="true" Name="Validation.Expected1">String</ParameterType>
+            <ParameterType Array="true" Name="Validation.Expected2">String</ParameterType>
         </ParameterTypes>
         </ParameterTypes>
         <Row Name="FMadDenormPreserve">
         <Row Name="FMadDenormPreserve">
             <Parameter Name="Validation.Type">ulp</Parameter>
             <Parameter Name="Validation.Type">ulp</Parameter>
@@ -6320,6 +6347,11 @@
                 <Value>0x80700000</Value>
                 <Value>0x80700000</Value>
                 <Value>0x01380000</Value>
                 <Value>0x01380000</Value>
             </Parameter>
             </Parameter>
+            <Parameter Name="Validation.Expected2">
+                <Value>0</Value>
+                <Value>0x00800000</Value>
+                <Value>0x00800000</Value>
+            </Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm any</Parameter>
         </Row>
         </Row>
         <Row Name="FMadDenormFTZ">
         <Row Name="FMadDenormFTZ">
@@ -6356,8 +6388,8 @@
             </Parameter>
             </Parameter>
             <Parameter Name="Validation.Expected1">
             <Parameter Name="Validation.Expected1">
                 <Value>0</Value>
                 <Value>0</Value>
-                <Value>0</Value>
-                <Value>0x01380000</Value>
+                <Value>0x00800000</Value>
+                <Value>0x00800000</Value>
             </Parameter>
             </Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm ftz</Parameter>
             <Parameter Name="ShaderOp.Arguments">-denorm ftz</Parameter>
         </Row>
         </Row>

+ 30 - 2
tools/dxexp/dxexp.cpp

@@ -78,6 +78,24 @@ typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS3
 } 	D3D12_FEATURE_DATA_D3D12_OPTIONS3;
 } 	D3D12_FEATURE_DATA_D3D12_OPTIONS3;
 #endif
 #endif
 
 
+#if WDK_NTDDI_VERSION <= NTDDI_WIN10_RS3
+#define D3D_SHADER_MODEL_6_2 ((D3D_SHADER_MODEL)0x62)
+#define D3D12_FEATURE_D3D12_OPTIONS4 ((D3D12_FEATURE)23)
+typedef enum D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER
+{
+    D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0,
+    D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_1,
+} D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS4
+{
+    _Out_ BOOL ReservedBufferPlacementSupported;
+    _Out_ D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER SharedResourceCompatibilityTier;
+    _Out_ BOOL Native16BitShaderOpsSupported;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS4;
+
+#endif
+
 static char *BoolToStrJson(bool value) {
 static char *BoolToStrJson(bool value) {
   return value ? "true" : "false";
   return value ? "true" : "false";
 }
 }
@@ -97,6 +115,7 @@ static char *ShaderModelToStr(D3D_SHADER_MODEL SM) {
   case D3D_SHADER_MODEL_5_1: return "5.1";
   case D3D_SHADER_MODEL_5_1: return "5.1";
   case D3D_SHADER_MODEL_6_0: return "6.0";
   case D3D_SHADER_MODEL_6_0: return "6.0";
   case D3D_SHADER_MODEL_6_1: return "6.1";
   case D3D_SHADER_MODEL_6_1: return "6.1";
+  case D3D_SHADER_MODEL_6_2: return "6.2";
   default: return "ERROR";
   default: return "ERROR";
   }
   }
 }
 }
@@ -129,8 +148,10 @@ static HRESULT PrintAdapters() {
       DXGI_ADAPTER_DESC1 AdapterDesc;
       DXGI_ADAPTER_DESC1 AdapterDesc;
       D3D12_FEATURE_DATA_D3D12_OPTIONS1 DeviceOptions;
       D3D12_FEATURE_DATA_D3D12_OPTIONS1 DeviceOptions;
       D3D12_FEATURE_DATA_D3D12_OPTIONS3 DeviceOptions3;
       D3D12_FEATURE_DATA_D3D12_OPTIONS3 DeviceOptions3;
+      D3D12_FEATURE_DATA_D3D12_OPTIONS4 DeviceOptions4;
       memset(&DeviceOptions, 0, sizeof(DeviceOptions));
       memset(&DeviceOptions, 0, sizeof(DeviceOptions));
       memset(&DeviceOptions3, 0, sizeof(DeviceOptions3));
       memset(&DeviceOptions3, 0, sizeof(DeviceOptions3));
+      memset(&DeviceOptions4, 0, sizeof(DeviceOptions4));
       D3D12_FEATURE_DATA_SHADER_MODEL DeviceSM;
       D3D12_FEATURE_DATA_SHADER_MODEL DeviceSM;
       AtlCheck(pAdapter->GetDesc1(&AdapterDesc));
       AtlCheck(pAdapter->GetDesc1(&AdapterDesc));
       AtlCheck(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&pDevice)));
       AtlCheck(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&pDevice)));
@@ -141,10 +162,15 @@ static HRESULT PrintAdapters() {
       // for highest shader model.
       // for highest shader model.
       if (SUCCEEDED(pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &DeviceOptions3, sizeof(DeviceOptions3))))
       if (SUCCEEDED(pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &DeviceOptions3, sizeof(DeviceOptions3))))
         DeviceSM.HighestShaderModel = D3D_SHADER_MODEL_6_1;
         DeviceSM.HighestShaderModel = D3D_SHADER_MODEL_6_1;
+      // CheckFeatureSupport with D3D12_FEATURE_D3D12_OPTIONS3 will fail on Fall Creators Update,
+      // but succeed on newer versions of Windows.  Use this to control the initial value
+      // for highest shader model.
+      if (SUCCEEDED(pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &DeviceOptions4, sizeof(DeviceOptions4))))
+        DeviceSM.HighestShaderModel = D3D_SHADER_MODEL_6_2;
       AtlCheck(pDevice->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &DeviceSM, sizeof(DeviceSM)));
       AtlCheck(pDevice->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &DeviceSM, sizeof(DeviceSM)));
       const char *Format = IsOutputJson ?
       const char *Format = IsOutputJson ?
         "%c { \"name\": \"%S\", \"sm\": \"%s\", \"wave\": %s, \"i64\": %s, \"bary\": %s, \"view-inst\": \"%s\" }\n" :
         "%c { \"name\": \"%S\", \"sm\": \"%s\", \"wave\": %s, \"i64\": %s, \"bary\": %s, \"view-inst\": \"%s\" }\n" :
-        "%c %S - Highest SM [%s] Wave [%s] I64 [%s] Barycentrics [%s] View Instancing [%s]\n";
+        "%c %S - Highest SM [%s] Wave [%s] I64 [%s] Barycentrics [%s] View Instancing [%s] 16bit Support [%s]\n";
       printf(Format,
       printf(Format,
              comma,
              comma,
              AdapterDesc.Description,
              AdapterDesc.Description,
@@ -152,7 +178,9 @@ static HRESULT PrintAdapters() {
              BoolToStr(DeviceOptions.WaveOps),
              BoolToStr(DeviceOptions.WaveOps),
              BoolToStr(DeviceOptions.Int64ShaderOps),
              BoolToStr(DeviceOptions.Int64ShaderOps),
              BoolToStr(DeviceOptions3.BarycentricsSupported),
              BoolToStr(DeviceOptions3.BarycentricsSupported),
-             ViewInstancingTierToStr(DeviceOptions3.ViewInstancingTier));
+             ViewInstancingTierToStr(DeviceOptions3.ViewInstancingTier),
+             BoolToStr(DeviceOptions4.Native16BitShaderOpsSupported)
+            );
       AdapterIndex++;
       AdapterIndex++;
       comma = IsOutputJson ? ',' : ' ';
       comma = IsOutputJson ? ',' : ' ';
     }
     }

+ 9 - 9
utils/hct/hctdb_test.py

@@ -110,7 +110,7 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole
                   output_lists_preserve, shader_target, shader_text, shader_arguments="-denorm preserve")
                   output_lists_preserve, shader_target, shader_text, shader_arguments="-denorm preserve")
     # we can expect the same output for "any" and "preserve" mode. We should make sure that for validation zero are accepted outputs for denormal outputs.
     # we can expect the same output for "any" and "preserve" mode. We should make sure that for validation zero are accepted outputs for denormal outputs.
     add_test_case(test_name + "Any", inst_names, validation_type, validation_tolerance, input_lists,
     add_test_case(test_name + "Any", inst_names, validation_type, validation_tolerance, input_lists,
-                  output_lists_preserve, shader_target, shader_text, shader_arguments="-denorm any")
+                  output_lists_preserve + output_lists_ftz, shader_target, shader_text, shader_arguments="-denorm any")
 
 
 
 
 g_shader_texts = {
 g_shader_texts = {
@@ -793,22 +793,22 @@ def add_test_cases():
     # Denorm Binary Float
     # Denorm Binary Float
     add_test_case_denorm('FAddDenorm', ['FAdd'], 'ulp', 1,
     add_test_case_denorm('FAddDenorm', ['FAdd'], 'ulp', 1,
     [['0x007E0000', '0x00200000', '0x007E0000', '0x007E0000'],['0x007E0000','0x00200000', '0x807E0000', '0x800E0000']],
     [['0x007E0000', '0x00200000', '0x007E0000', '0x007E0000'],['0x007E0000','0x00200000', '0x807E0000', '0x800E0000']],
-    [['0x00FC0000','0', '0', '0']],
-    [['0x00FC0000','0', '0', '0x00700000']],
+    [['0','0', '0', '0']],
+    [['0x00FC0000','0x00400000', '0', '0x00700000']],
     'cs_6_2', get_shader_text("binary float", "+"))
     'cs_6_2', get_shader_text("binary float", "+"))
     add_test_case_denorm('FSubDenorm', ['FSub'], 'ulp', 1,
     add_test_case_denorm('FSubDenorm', ['FSub'], 'ulp', 1,
     [['0x007E0000', '0x007F0000', '0x00FF0000', '0x007A0000'],['0x007E0000', '0x807F0000', '0x00800000', '0']],
     [['0x007E0000', '0x007F0000', '0x00FF0000', '0x007A0000'],['0x007E0000', '0x807F0000', '0x00800000', '0']],
-    [['0x0', '0x00FE0000', '0', '0']],
+    [['0x0', '0', '0', '0']],
     [['0x0', '0x00FE0000', '0x007F0000', '0x007A0000']],
     [['0x0', '0x00FE0000', '0x007F0000', '0x007A0000']],
     'cs_6_2', get_shader_text("binary float", "-"))
     'cs_6_2', get_shader_text("binary float", "-"))
     add_test_case_denorm('FDivDenorm', ['FDiv'], 'ulp', 1,
     add_test_case_denorm('FDivDenorm', ['FDiv'], 'ulp', 1,
     [['0x007F0000', '0x007F0000', '0x40000000', '0x00800000'],['1', '0x007F0000', '0x7F7F0000', '0x40000000']],
     [['0x007F0000', '0x007F0000', '0x40000000', '0x00800000'],['1', '0x007F0000', '0x7F7F0000', '0x40000000']],
-    [['0', '1', '0', '0']],
+    [['0', 'NaN', '0', '0']],
     [['0x007F0000', '1', '0x00404040', '0x00400000']],
     [['0x007F0000', '1', '0x00404040', '0x00400000']],
     'cs_6_2', get_shader_text("binary float", "/"))
     'cs_6_2', get_shader_text("binary float", "/"))
     add_test_case_denorm('FMulDenorm', ['FMul'], 'ulp', 1,
     add_test_case_denorm('FMulDenorm', ['FMul'], 'ulp', 1,
     [['0x00000300', '0x007F0000', '0x007F0000', '0x001E0000', '0x00000300'],['128', '1', '0x007F0000', '20', '0x78000000']],
     [['0x00000300', '0x007F0000', '0x007F0000', '0x001E0000', '0x00000300'],['128', '1', '0x007F0000', '20', '0x78000000']],
-    [['0', '0', '0', '0x01960000', '0x32400000']],
+    [['0', '0', '0', '0', '0']],
     [['0x00018000','0x007F0000', '0', '0x01960000', '0x32400000']],
     [['0x00018000','0x007F0000', '0', '0x01960000', '0x32400000']],
     'cs_6_2', get_shader_text("binary float", "*"))
     'cs_6_2', get_shader_text("binary float", "*"))
     # Tertiary Float
     # Tertiary Float
@@ -840,7 +840,7 @@ def add_test_cases():
     [['0x80780000', '0x80780000', '0x00780000'],
     [['0x80780000', '0x80780000', '0x00780000'],
      ['1', '2', '2'],
      ['1', '2', '2'],
      ['0x80780000', '0x00800000', '0x00800000']],
      ['0x80780000', '0x00800000', '0x00800000']],
-    [['0', '0', '0x01380000']],
+    [['0', '0x00800000', '0x00800000']],
      [['0x80780000', '0x80700000', '0x01380000']],
      [['0x80780000', '0x80700000', '0x01380000']],
                   'cs_6_2', get_shader_text("tertiary float", "mad"))
                   'cs_6_2', get_shader_text("tertiary float", "mad"))
 
 
@@ -1528,12 +1528,12 @@ def generate_table_for_taef():
             ET.SubElement(
             ET.SubElement(
                 root, "Table", attrib={
                 root, "Table", attrib={
                     "Id": "DenormBinaryFloatOpTable"
                     "Id": "DenormBinaryFloatOpTable"
-                }), 2, 1)
+                }), 2, 2) # 2 sets of expected values for any mode
         generate_parameter_types(
         generate_parameter_types(
             ET.SubElement(
             ET.SubElement(
                 root, "Table", attrib={
                 root, "Table", attrib={
                     "Id": "DenormTertiaryFloatOpTable"
                     "Id": "DenormTertiaryFloatOpTable"
-                }), 3, 1)
+                }), 3, 2)
 
 
         for case in g_test_cases.values():
         for case in g_test_cases.values():
             cur_inst = case.insts[0]
             cur_inst = case.insts[0]