Explorar o código

Make shader model related code generated. (#2629)

* Make shader model related code generated.
Xiang Li %!s(int64=5) %!d(string=hai) anos
pai
achega
9c89a1c2c6

+ 3 - 0
include/dxc/DXIL/DxilConstants.h

@@ -27,7 +27,10 @@ import hctdb_instrhelp
 namespace DXIL {
   // DXIL version.
   const unsigned kDxilMajor = 1;
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_dxil_version_minor()</py>*/
+  // VALRULE-TEXT:BEGIN
   const unsigned kDxilMinor = 5;
+  // VALRULE-TEXT:END
 
   inline unsigned MakeDxilVersion(unsigned DxilMajor, unsigned DxilMinor) {
     return 0 | (DxilMajor << 8) | (DxilMinor);

+ 16 - 16
include/dxc/DXIL/DxilShaderModel.h

@@ -28,8 +28,11 @@ public:
   using Kind = DXIL::ShaderKind;
 
   // Major/Minor version of highest shader model
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_highest_shader_model()</py>*/
+  // VALRULE-TEXT:BEGIN
   static const unsigned kHighestMajor = 6;
   static const unsigned kHighestMinor = 5;
+  // VALRULE-TEXT:END
   static const unsigned kOfflineMinor = 0xF;
 
   bool IsPS() const     { return m_Kind == Kind::Pixel; }
@@ -56,25 +59,20 @@ public:
   }
   bool IsSM50Plus() const   { return IsSMAtLeast(5, 0); }
   bool IsSM51Plus() const   { return IsSMAtLeast(5, 1); }
-  bool IsSM60Plus() const   { return IsSMAtLeast(6, 0); }
-  bool IsSM61Plus() const   { return IsSMAtLeast(6, 1); }
-  bool IsSM62Plus() const   { return IsSMAtLeast(6, 2); }
-  bool IsSM63Plus() const   { return IsSMAtLeast(6, 3); }
-  bool IsSM64Plus() const   { return IsSMAtLeast(6, 4); }
-  bool IsSM65Plus() const   { return IsSMAtLeast(6, 5); }
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_is_shader_model_plus()</py>*/
+  // VALRULE-TEXT:BEGIN
+  bool IsSM60Plus() const { return IsSMAtLeast(6, 0); }
+  bool IsSM61Plus() const { return IsSMAtLeast(6, 1); }
+  bool IsSM62Plus() const { return IsSMAtLeast(6, 2); }
+  bool IsSM63Plus() const { return IsSMAtLeast(6, 3); }
+  bool IsSM64Plus() const { return IsSMAtLeast(6, 4); }
+  bool IsSM65Plus() const { return IsSMAtLeast(6, 5); }
+  // VALRULE-TEXT:END
   const char *GetName() const { return m_pszName; }
   const char *GetKindName() const;
-  unsigned GetNumTempRegs() const { return DXIL::kMaxTempRegCount; }
-  unsigned GetNumInputRegs() const { return m_NumInputRegs; }
-  unsigned GetNumOutputRegs() const { return m_NumOutputRegs; }
-  unsigned GetCBufferSize() const { return DXIL::kMaxCBufferSize; }
-  unsigned SupportsUAV() const { return m_bUAVs; }
-  unsigned SupportsTypedUAVs() const { return m_bTypedUavs; }
-  unsigned GetUAVRegLimit() const { return m_NumUAVRegs; }
+
   DXIL::PackingStrategy GetDefaultPackingStrategy() const { return DXIL::PackingStrategy::PrefixStable; }
 
-  static unsigned Count() { return kNumShaderModels - 1; }
-  static const ShaderModel *Get(unsigned Idx);
   static const ShaderModel *Get(Kind Kind, unsigned Major, unsigned Minor);
   static const ShaderModel *GetByName(const char *pszName);
   static const char *GetKindName(Kind kind);
@@ -97,8 +95,10 @@ private:
   ShaderModel(Kind Kind, unsigned Major, unsigned Minor, const char *pszName,
               unsigned m_NumInputRegs, unsigned m_NumOutputRegs,
               bool m_bUAVs, bool m_bTypedUavs, unsigned m_UAVRegsLim);
-
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_num_shader_models()</py>*/
+  // VALRULE-TEXT:BEGIN
   static const unsigned kNumShaderModels = 65;
+  // VALRULE-TEXT:END
   static const ShaderModel ms_ShaderModels[kNumShaderModels];
 
   static const ShaderModel *GetInvalid();

+ 4 - 1
include/dxc/Support/HLSLOptions.td

@@ -307,7 +307,10 @@ def Oconfig : CommaJoined<["-"], "Oconfig=">, Group<spirv_Group>, Flags<[CoreOpt
 // fxc-based flags that don't match those previously defined.
 
 def target_profile : JoinedOrSeparate<["-", "/"], "T">, Flags<[CoreOption]>, Group<hlslcomp_Group>, MetaVarName<"<profile>">,
-  HelpText<"Set target profile. \n\t<profile>: ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, \n\t\t vs_6_0, vs_6_1, vs_6_2, vs_6_3, vs_6_4, vs_6_5, \n\t\t cs_6_0, cs_6_1, cs_6_2, cs_6_3, cs_6_4, cs_6_5, \n\t\t gs_6_0, gs_6_1, gs_6_2, gs_6_3, gs_6_4, gs_6_5, \n\t\t ds_6_0, ds_6_1, ds_6_2, ds_6_3, ds_6_4, ds_6_5, \n\t\t hs_6_0, hs_6_1, hs_6_2, hs_6_3, hs_6_4, hs_6_5, \n\t\t lib_6_3, lib_6_4, lib_6_5, ms_6_5, as_6_5">;
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_target_profiles()</py>*/
+  // VALRULE-TEXT:BEGIN
+  HelpText<"Set target profile. \n\t<profile>: ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, \n\t\t vs_6_0, vs_6_1, vs_6_2, vs_6_3, vs_6_4, vs_6_5, \n\t\t gs_6_0, gs_6_1, gs_6_2, gs_6_3, gs_6_4, gs_6_5, \n\t\t hs_6_0, hs_6_1, hs_6_2, hs_6_3, hs_6_4, hs_6_5, \n\t\t ds_6_0, ds_6_1, ds_6_2, ds_6_3, ds_6_4, ds_6_5, \n\t\t cs_6_0, cs_6_1, cs_6_2, cs_6_3, cs_6_4, cs_6_5, \n\t\t lib_6_1, lib_6_2, lib_6_3, lib_6_4, lib_6_5, \n\t\t ms_6_5, \n\t\t as_6_5, \n\t\t ">;
+  // VALRULE-TEXT:END
 def entrypoint :  JoinedOrSeparate<["-", "/"], "E">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
   HelpText<"Entry point name">;
 // /I <include> - already defined above

+ 180 - 120
lib/DXIL/DxilShaderModel.cpp

@@ -12,6 +12,7 @@
 #include "dxc/DXIL/DxilShaderModel.h"
 #include "dxc/DXIL/DxilSemantic.h"
 #include "dxc/Support/Global.h"
+#include <unordered_map>
 
 
 namespace hlsl {
@@ -54,12 +55,15 @@ bool ShaderModel::IsValidForDxil() const {
   switch (m_Major) {
     case 6: {
       switch (m_Minor) {
+      /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_is_valid_for_dxil()</py>*/
+      // VALRULE-TEXT:BEGIN
       case 0:
       case 1:
       case 2:
       case 3:
       case 4:
       case 5:
+      // VALRULE-TEXT:END
         return true;
       case kOfflineMinor:
         return m_Kind == Kind::Library;
@@ -75,31 +79,82 @@ bool ShaderModel::IsValidForModule() const {
   return IsValid() && !IsRay();
 }
 
-const ShaderModel *ShaderModel::Get(unsigned Idx) {
-  DXASSERT_NOMSG(Idx < kNumShaderModels - 1);
-  if (Idx < kNumShaderModels - 1)
-    return &ms_ShaderModels[Idx];
-  else
-    return GetInvalid();
-}
-
 const ShaderModel *ShaderModel::Get(Kind Kind, unsigned Major, unsigned Minor) {
-  const ShaderModel *pSM = std::lower_bound(
-    &ms_ShaderModels[0], &ms_ShaderModels[kNumShaderModels - 1],
-    ShaderModel(Kind, Major, Minor, "",  0,  0, false,  false, 0),
-    [](const ShaderModel& a, const ShaderModel& b) -> bool {
-      if (a.m_Kind < b.m_Kind) return 1;
-      if (b.m_Kind < a.m_Kind) return 0;
-      if (a.m_Major < b.m_Major) return 1;
-      if (b.m_Major < a.m_Major) return 0;
-      if (a.m_Minor < b.m_Minor) return 1;
-      return 0;
-    });
-  if (pSM && pSM < ms_ShaderModels + kNumShaderModels &&
-      pSM->m_Kind == Kind && pSM->m_Major == Major && pSM->m_Minor == Minor)
-    return pSM;
-
-  return GetInvalid();
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_shader_model_get()</py>*/
+  // VALRULE-TEXT:BEGIN
+  const static std::unordered_map<unsigned, unsigned> hashToIdxMap = {
+  {1024,0}, //ps_4_0
+  {1025,1}, //ps_4_1
+  {1280,2}, //ps_5_0
+  {1281,3}, //ps_5_1
+  {1536,4}, //ps_6_0
+  {1537,5}, //ps_6_1
+  {1538,6}, //ps_6_2
+  {1539,7}, //ps_6_3
+  {1540,8}, //ps_6_4
+  {1541,9}, //ps_6_5
+  {66560,10}, //vs_4_0
+  {66561,11}, //vs_4_1
+  {66816,12}, //vs_5_0
+  {66817,13}, //vs_5_1
+  {67072,14}, //vs_6_0
+  {67073,15}, //vs_6_1
+  {67074,16}, //vs_6_2
+  {67075,17}, //vs_6_3
+  {67076,18}, //vs_6_4
+  {67077,19}, //vs_6_5
+  {132096,20}, //gs_4_0
+  {132097,21}, //gs_4_1
+  {132352,22}, //gs_5_0
+  {132353,23}, //gs_5_1
+  {132608,24}, //gs_6_0
+  {132609,25}, //gs_6_1
+  {132610,26}, //gs_6_2
+  {132611,27}, //gs_6_3
+  {132612,28}, //gs_6_4
+  {132613,29}, //gs_6_5
+  {197888,30}, //hs_5_0
+  {197889,31}, //hs_5_1
+  {198144,32}, //hs_6_0
+  {198145,33}, //hs_6_1
+  {198146,34}, //hs_6_2
+  {198147,35}, //hs_6_3
+  {198148,36}, //hs_6_4
+  {198149,37}, //hs_6_5
+  {263424,38}, //ds_5_0
+  {263425,39}, //ds_5_1
+  {263680,40}, //ds_6_0
+  {263681,41}, //ds_6_1
+  {263682,42}, //ds_6_2
+  {263683,43}, //ds_6_3
+  {263684,44}, //ds_6_4
+  {263685,45}, //ds_6_5
+  {328704,46}, //cs_4_0
+  {328705,47}, //cs_4_1
+  {328960,48}, //cs_5_0
+  {328961,49}, //cs_5_1
+  {329216,50}, //cs_6_0
+  {329217,51}, //cs_6_1
+  {329218,52}, //cs_6_2
+  {329219,53}, //cs_6_3
+  {329220,54}, //cs_6_4
+  {329221,55}, //cs_6_5
+  {394753,56}, //lib_6_1
+  {394754,57}, //lib_6_2
+  {394755,58}, //lib_6_3
+  {394756,59}, //lib_6_4
+  {394757,60}, //lib_6_5
+  // lib_6_x is for offline linking only, and relaxes restrictions
+  {394767,61},//lib_6_x
+  {853509,62}, //ms_6_5
+  {919045,63}, //as_6_5
+  };
+  unsigned hash = (unsigned)Kind << 16 | Major << 8 | Minor;
+  auto it = hashToIdxMap.find(hash);
+  if (it == hashToIdxMap.end())
+    return GetInvalid();
+  return &ms_ShaderModels[it->second];
+  // VALRULE-TEXT:END
 }
 
 const ShaderModel *ShaderModel::GetByName(const char *pszName) {
@@ -141,30 +196,33 @@ const ShaderModel *ShaderModel::GetByName(const char *pszName) {
   switch (pszName[Idx++]) {
     case '0': Minor = 0;  break;
     case '1': Minor = 1;  break;
-    case '2':
-      if (Major == 6) {
-        Minor = 2;
-        break;
-      }
-      else return GetInvalid();
-    case '3':
-      if (Major == 6) {
-        Minor = 3;
-        break;
-      }
-      else return GetInvalid();
-    case '4':
-      if (Major == 6) {
-        Minor = 4;
-        break;
-      }
-      else return GetInvalid();
-    case '5':
-      if (Major == 6) {
-        Minor = 5;
-        break;
-      }
-      else return GetInvalid();
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_shader_model_by_name()</py>*/
+  // VALRULE-TEXT:BEGIN
+  case '2':
+    if (Major == 6) {
+      Minor = 2;
+      break;
+    }
+  else return GetInvalid();
+  case '3':
+    if (Major == 6) {
+      Minor = 3;
+      break;
+    }
+  else return GetInvalid();
+  case '4':
+    if (Major == 6) {
+      Minor = 4;
+      break;
+    }
+  else return GetInvalid();
+  case '5':
+    if (Major == 6) {
+      Minor = 5;
+      break;
+    }
+  else return GetInvalid();
+  // VALRULE-TEXT:END
     case 'x':
       if (kind == Kind::Library && Major == 6) {
         Minor = kOfflineMinor;
@@ -183,6 +241,8 @@ void ShaderModel::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const
   DXASSERT(IsValidForDxil(), "invalid shader model");
   DxilMajor = 1;
   switch (m_Minor) {
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_dxil_version()</py>*/
+  // VALRULE-TEXT:BEGIN
   case 0:
     DxilMinor = 0;
     break;
@@ -199,9 +259,12 @@ void ShaderModel::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const
     DxilMinor = 4;
     break;
   case 5:
+    DxilMinor = 5;
+    break;
   case kOfflineMinor: // Always update this to highest dxil version
     DxilMinor = 5;
     break;
+  // VALRULE-TEXT:END
   default:
     DXASSERT(0, "IsValidForDxil() should have caught this.");
     break;
@@ -212,6 +275,8 @@ void ShaderModel::GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor)
   DXASSERT(IsValidForDxil(), "invalid shader model");
   ValMajor = 1;
   switch (m_Minor) {
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_min_validator_version()</py>*/
+  // VALRULE-TEXT:BEGIN
   case 0:
     ValMinor = 0;
     break;
@@ -230,6 +295,7 @@ void ShaderModel::GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor)
   case 5:
     ValMinor = 5;
     break;
+  // VALRULE-TEXT:END
   case kOfflineMinor:
     ValMajor = 0;
     ValMinor = 0;
@@ -265,82 +331,76 @@ typedef ShaderModel SM;
 typedef Semantic SE;
 const ShaderModel ShaderModel::ms_ShaderModels[kNumShaderModels] = {
   //                                  IR  OR   UAV?   TyUAV? UAV base
-  SM(Kind::Pixel,    4, 0, "ps_4_0",  32, 8,   false, false, 0),
-  SM(Kind::Pixel,    4, 1, "ps_4_1",  32, 8,   false, false, 0),
-  SM(Kind::Pixel,    5, 0, "ps_5_0",  32, 8,   true,  true,  64),
-  SM(Kind::Pixel,    5, 1, "ps_5_1",  32, 8,   true,  true,  UINT_MAX),
-  SM(Kind::Pixel,    6, 0, "ps_6_0",  32, 8,   true,  true,  UINT_MAX),
-  SM(Kind::Pixel,    6, 1, "ps_6_1",  32, 8,   true,  true,  UINT_MAX),
-  SM(Kind::Pixel,    6, 2, "ps_6_2",  32, 8,   true,  true,  UINT_MAX),
-  SM(Kind::Pixel,    6, 3, "ps_6_3",  32, 8,   true,  true,  UINT_MAX),
-  SM(Kind::Pixel,    6, 4, "ps_6_4",  32, 8,   true,  true,  UINT_MAX),
-  SM(Kind::Pixel,    6, 5, "ps_6_5",  32, 8,   true,  true,  UINT_MAX),
-
-  SM(Kind::Vertex,   4, 0, "vs_4_0",  16, 16,  false, false, 0),
-  SM(Kind::Vertex,   4, 1, "vs_4_1",  32, 32,  false, false, 0),
-  SM(Kind::Vertex,   5, 0, "vs_5_0",  32, 32,  true,  true,  64),
-  SM(Kind::Vertex,   5, 1, "vs_5_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Vertex,   6, 0, "vs_6_0",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Vertex,   6, 1, "vs_6_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Vertex,   6, 2, "vs_6_2",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Vertex,   6, 3, "vs_6_3",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Vertex,   6, 4, "vs_6_4",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Vertex,   6, 5, "vs_6_5",  32, 32,  true,  true,  UINT_MAX),
-
-  SM(Kind::Geometry, 4, 0, "gs_4_0",  16, 32,  false, false, 0),
-  SM(Kind::Geometry, 4, 1, "gs_4_1",  32, 32,  false, false, 0),
-  SM(Kind::Geometry, 5, 0, "gs_5_0",  32, 32,  true,  true,  64),
-  SM(Kind::Geometry, 5, 1, "gs_5_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Geometry, 6, 0, "gs_6_0",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Geometry, 6, 1, "gs_6_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Geometry, 6, 2, "gs_6_2",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Geometry, 6, 3, "gs_6_3",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Geometry, 6, 4, "gs_6_4",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Geometry, 6, 5, "gs_6_5",  32, 32,  true,  true,  UINT_MAX),
-
-  SM(Kind::Hull,     5, 0, "hs_5_0",  32, 32,  true,  true,  64),
-  SM(Kind::Hull,     5, 1, "hs_5_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Hull,     6, 0, "hs_6_0",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Hull,     6, 1, "hs_6_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Hull,     6, 2, "hs_6_2",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Hull,     6, 3, "hs_6_3",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Hull,     6, 4, "hs_6_4",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Hull,     6, 5, "hs_6_5",  32, 32,  true,  true,  UINT_MAX),
-
-  SM(Kind::Domain,   5, 0, "ds_5_0",  32, 32,  true,  true,  64),
-  SM(Kind::Domain,   5, 1, "ds_5_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Domain,   6, 0, "ds_6_0",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Domain,   6, 1, "ds_6_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Domain,   6, 2, "ds_6_2",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Domain,   6, 3, "ds_6_3",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Domain,   6, 4, "ds_6_4",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Domain,   6, 5, "ds_6_5",  32, 32,  true,  true,  UINT_MAX),
-
-  SM(Kind::Compute,  4, 0, "cs_4_0",  0,  0,   true,  false, 1),
-  SM(Kind::Compute,  4, 1, "cs_4_1",  0,  0,   true,  false, 1),
-  SM(Kind::Compute,  5, 0, "cs_5_0",  0,  0,   true,  true,  64),
-  SM(Kind::Compute,  5, 1, "cs_5_1",  0,  0,   true,  true,  UINT_MAX),
-  SM(Kind::Compute,  6, 0, "cs_6_0",  0,  0,   true,  true,  UINT_MAX),
-  SM(Kind::Compute,  6, 1, "cs_6_1",  0,  0,   true,  true,  UINT_MAX),
-  SM(Kind::Compute,  6, 2, "cs_6_2",  0,  0,   true,  true,  UINT_MAX),
-  SM(Kind::Compute,  6, 3, "cs_6_3",  0,  0,   true,  true,  UINT_MAX),
-  SM(Kind::Compute,  6, 4, "cs_6_4",  0,  0,   true,  true,  UINT_MAX),
-  SM(Kind::Compute,  6, 5, "cs_6_5",  0,  0,   true,  true,  UINT_MAX),
-
-  SM(Kind::Library,  6, 1, "lib_6_1",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Library,  6, 2, "lib_6_2",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Library,  6, 3, "lib_6_3",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Library,  6, 4, "lib_6_4",  32, 32,  true,  true,  UINT_MAX),
-  SM(Kind::Library,  6, 5, "lib_6_5",  32, 32,  true,  true,  UINT_MAX),
-
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_shader_models()</py>*/
+  // VALRULE-TEXT:BEGIN
+  SM(Kind::Pixel, 4, 0, "ps_4_0", 32, 8, false, false, 0),
+  SM(Kind::Pixel, 4, 1, "ps_4_1", 32, 8, false, false, 0),
+  SM(Kind::Pixel, 5, 0, "ps_5_0", 32, 8, true, true, 64),
+  SM(Kind::Pixel, 5, 1, "ps_5_1", 32, 8, true, true, 64),
+  SM(Kind::Pixel, 6, 0, "ps_6_0", 32, 8, true, true, UINT_MAX),
+  SM(Kind::Pixel, 6, 1, "ps_6_1", 32, 8, true, true, UINT_MAX),
+  SM(Kind::Pixel, 6, 2, "ps_6_2", 32, 8, true, true, UINT_MAX),
+  SM(Kind::Pixel, 6, 3, "ps_6_3", 32, 8, true, true, UINT_MAX),
+  SM(Kind::Pixel, 6, 4, "ps_6_4", 32, 8, true, true, UINT_MAX),
+  SM(Kind::Pixel, 6, 5, "ps_6_5", 32, 8, true, true, UINT_MAX),
+  SM(Kind::Vertex, 4, 0, "vs_4_0", 16, 16, false, false, 0),
+  SM(Kind::Vertex, 4, 1, "vs_4_1", 32, 32, false, false, 0),
+  SM(Kind::Vertex, 5, 0, "vs_5_0", 32, 32, true, true, 64),
+  SM(Kind::Vertex, 5, 1, "vs_5_1", 32, 32, true, true, 64),
+  SM(Kind::Vertex, 6, 0, "vs_6_0", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Vertex, 6, 1, "vs_6_1", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Vertex, 6, 2, "vs_6_2", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Vertex, 6, 3, "vs_6_3", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Vertex, 6, 4, "vs_6_4", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Vertex, 6, 5, "vs_6_5", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Geometry, 4, 0, "gs_4_0", 16, 32, false, false, 0),
+  SM(Kind::Geometry, 4, 1, "gs_4_1", 32, 32, false, false, 0),
+  SM(Kind::Geometry, 5, 0, "gs_5_0", 32, 32, true, true, 64),
+  SM(Kind::Geometry, 5, 1, "gs_5_1", 32, 32, true, true, 64),
+  SM(Kind::Geometry, 6, 0, "gs_6_0", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Geometry, 6, 1, "gs_6_1", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Geometry, 6, 2, "gs_6_2", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Geometry, 6, 3, "gs_6_3", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Geometry, 6, 4, "gs_6_4", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Geometry, 6, 5, "gs_6_5", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Hull, 5, 0, "hs_5_0", 32, 32, true, true, 64),
+  SM(Kind::Hull, 5, 1, "hs_5_1", 32, 32, true, true, 64),
+  SM(Kind::Hull, 6, 0, "hs_6_0", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Hull, 6, 1, "hs_6_1", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Hull, 6, 2, "hs_6_2", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Hull, 6, 3, "hs_6_3", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Hull, 6, 4, "hs_6_4", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Hull, 6, 5, "hs_6_5", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Domain, 5, 0, "ds_5_0", 32, 32, true, true, 64),
+  SM(Kind::Domain, 5, 1, "ds_5_1", 32, 32, true, true, 64),
+  SM(Kind::Domain, 6, 0, "ds_6_0", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Domain, 6, 1, "ds_6_1", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Domain, 6, 2, "ds_6_2", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Domain, 6, 3, "ds_6_3", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Domain, 6, 4, "ds_6_4", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Domain, 6, 5, "ds_6_5", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Compute, 4, 0, "cs_4_0", 0, 0, false, false, 0),
+  SM(Kind::Compute, 4, 1, "cs_4_1", 0, 0, false, false, 0),
+  SM(Kind::Compute, 5, 0, "cs_5_0", 0, 0, true, true, 64),
+  SM(Kind::Compute, 5, 1, "cs_5_1", 0, 0, true, true, 64),
+  SM(Kind::Compute, 6, 0, "cs_6_0", 0, 0, true, true, UINT_MAX),
+  SM(Kind::Compute, 6, 1, "cs_6_1", 0, 0, true, true, UINT_MAX),
+  SM(Kind::Compute, 6, 2, "cs_6_2", 0, 0, true, true, UINT_MAX),
+  SM(Kind::Compute, 6, 3, "cs_6_3", 0, 0, true, true, UINT_MAX),
+  SM(Kind::Compute, 6, 4, "cs_6_4", 0, 0, true, true, UINT_MAX),
+  SM(Kind::Compute, 6, 5, "cs_6_5", 0, 0, true, true, UINT_MAX),
+  SM(Kind::Library, 6, 1, "lib_6_1", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Library, 6, 2, "lib_6_2", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Library, 6, 3, "lib_6_3", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Library, 6, 4, "lib_6_4", 32, 32, true, true, UINT_MAX),
+  SM(Kind::Library, 6, 5, "lib_6_5", 32, 32, true, true, UINT_MAX),
   // lib_6_x is for offline linking only, and relaxes restrictions
   SM(Kind::Library,  6, kOfflineMinor, "lib_6_x",  32, 32,  true,  true,  UINT_MAX),
-  
-  SM(Kind::Mesh,     6, 5, "ms_6_5",    0,  0,  true,  true,  UINT_MAX),
-  SM(Kind::Amplification, 6, 5, "as_6_5", 0, 0, true,  true,  UINT_MAX),
-
+  SM(Kind::Mesh, 6, 5, "ms_6_5", 0, 0, true, true, UINT_MAX),
+  SM(Kind::Amplification, 6, 5, "as_6_5", 0, 0, true, true, UINT_MAX),
   // Values before Invalid must remain sorted by Kind, then Major, then Minor.
   SM(Kind::Invalid,  0, 0, "invalid", 0,  0,   false, false, 0),
+  // VALRULE-TEXT:END
 };
 
 } // namespace hlsl

+ 3 - 0
lib/HLSL/DxilValidation.cpp

@@ -5586,6 +5586,8 @@ static void ValidateUninitializedOutput(ValidationContext &ValCtx) {
 }
 
 void GetValidationVersion(_Out_ unsigned *pMajor, _Out_ unsigned *pMinor) {
+  /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_validation_version()</py>*/
+  // VALRULE-TEXT:BEGIN
   // 1.0 is the first validator.
   // 1.1 adds:
   // - ILDN container part support
@@ -5605,6 +5607,7 @@ void GetValidationVersion(_Out_ unsigned *pMajor, _Out_ unsigned *pMinor) {
   // - DXR 1.1 & RayQuery support
   *pMajor = 1;
   *pMinor = 5;
+  // VALRULE-TEXT:END
 }
 
 _Use_decl_annotations_ HRESULT

+ 255 - 0
utils/hct/hctdb_instrhelp.py

@@ -1086,6 +1086,258 @@ def get_interpretation_table():
     gen = db_sigpoint_gen(db)
     return run_with_stdout(lambda: gen.print_interpretation_table())
 
+highest_major = 6
+highest_minor = 5
+highest_shader_models = {4:1, 5:1, 6:highest_minor}
+
+def getShaderModels():
+    shader_models = []
+    for major, minor in highest_shader_models.items():
+        for i in range(0, minor+1):
+            shader_models.append(str(major) + "_" + str(i))
+
+    return shader_models;
+
+def get_highest_shader_model():
+    result = """static const unsigned kHighestMajor = %d;
+static const unsigned kHighestMinor = %d;"""%(highest_major, highest_minor)
+    return result
+
+def get_dxil_version_minor():
+    return "const unsigned kDxilMinor = %d;"%highest_minor
+
+def get_is_shader_model_plus():
+    result = ""
+
+    for i in range(0, highest_minor+1):
+        result += "bool IsSM%d%dPlus() const { return IsSMAtLeast(%d, %d); }\n"%(highest_major, i,highest_major, i)
+    return result
+
+profile_to_kind = {"ps":"Kind::Pixel", "vs":"Kind::Vertex", "gs":"Kind::Geometry", "hs":"5_0", "ds":"5_0", "cs":"4_0", "lib":"6_1", "ms":"6_5", "as":"6_5"}
+
+class shader_profile(object):
+    "The profile description for a DXIL instruction"
+    def __init__(self, kind, kind_name, enum_name, start_sm, input_size, output_size):
+        self.kind = kind                  # position in parameter list
+        self.kind_name = kind_name
+        self.enum_name = enum_name
+        self.start_sm = start_sm
+        self.input_size = input_size
+        self.output_size = output_size
+
+# kind is from DXIL::ShaderKind.
+shader_profiles = [ shader_profile(0, "ps", "Kind::Pixel", "4_0", 32, 8),
+             shader_profile(1, "vs", "Kind::Vertex", "4_0", 32, 32),
+             shader_profile(2, "gs", "Kind::Geometry", "4_0", 32, 32),
+             shader_profile(3, "hs", "Kind::Hull", "5_0", 32, 32),
+             shader_profile(4, "ds", "Kind::Domain", "5_0", 32, 32),
+             shader_profile(5, "cs", "Kind::Compute", "4_0", 0,0),
+             shader_profile(6, "lib", "Kind::Library", "6_1", 32,32),
+             shader_profile(13, "ms", "Kind::Mesh", "6_5", 0,0),
+             shader_profile(14, "as", "Kind::Amplification", "6_5", 0,0),
+             ]
+
+def getShaderProfiles():
+    # order match DXIL::ShaderKind.
+    profiles = {"ps":"4_0", "vs":"4_0", "gs":"4_0", "hs":"5_0", "ds":"5_0", "cs":"4_0", "lib":"6_1", "ms":"6_5", "as":"6_5"}
+    return profiles;
+
+def get_shader_models():
+    result = ""
+    for profile in shader_profiles:
+        min_sm = profile.start_sm
+        input_size = profile.input_size
+        output_size = profile.output_size
+        kind = profile.kind
+        kind_name = profile.kind_name
+        enum_name = profile.enum_name
+
+        for major, minor in highest_shader_models.items():
+
+            UAV_info = "true, true, UINT_MAX"
+            if major > 5:
+                pass
+            elif major == 4:
+                UAV_info = "false, false, 0"
+                if kind == "cs":
+                    UAV_info = "true, false, 1"
+
+            elif major == 5:
+                UAV_info = "true, true, 64"
+
+            for i in range(0, minor+1):
+                sm = "%d_%d"%(major, i)
+                if (min_sm > sm):
+                    continue
+
+                input_size = profile.input_size
+                output_size = profile.output_size
+
+                if major == 4:
+                    if i == 0:
+                        if kind_name == "gs":
+                            input_size = 16
+                        elif kind_name == "vs":
+                            input_size = 16
+                            output_size = 16
+
+                sm_name = "%s_%s"%(kind_name,sm)
+                result += "SM(%s, %d, %d, \"%s\", %d, %d, %s),\n" % (enum_name, major, i, sm_name, input_size, output_size, UAV_info)
+
+        if kind_name == "lib":
+            result += "// lib_6_x is for offline linking only, and relaxes restrictions\n"
+            result += "SM(Kind::Library,  6, kOfflineMinor, \"lib_6_x\",  32, 32,  true,  true,  UINT_MAX),\n"
+
+    result += "// Values before Invalid must remain sorted by Kind, then Major, then Minor.\n"
+    result += "SM(Kind::Invalid,  0, 0, \"invalid\", 0,  0,   false, false, 0),\n"
+    return result
+
+def get_num_shader_models():
+    count = 0
+    for profile in shader_profiles:
+        min_sm = profile.start_sm
+        input_size = profile.input_size
+        output_size = profile.output_size
+        kind = profile.kind
+        kind_name = profile.kind_name
+        enum_name = profile.enum_name
+
+        for major, minor in highest_shader_models.items():
+
+            for i in range(0, minor+1):
+                sm = "%d_%d"%(major, i)
+                if (min_sm > sm):
+                    continue
+                count += 1
+
+        if kind_name == "lib":
+            # for lib_6_x
+            count += 1
+    # for invalid shader_model.
+    count += 1
+    return "static const unsigned kNumShaderModels = %d;"%count
+
+def build_shader_model_hash_idx_map():
+    #must match get_shader_models.
+    result = "const static std::unordered_map<unsigned, unsigned> hashToIdxMap = {\n"
+    count = 0
+    for profile in shader_profiles:
+        min_sm = profile.start_sm
+        kind = profile.kind
+        kind_name = profile.kind_name
+
+        for major, minor in highest_shader_models.items():
+
+            for i in range(0, minor+1):
+                sm = "%d_%d"%(major, i)
+                if (min_sm > sm):
+                    continue
+                sm_name = "%s_%s"%(kind_name,sm)
+                hash_v = kind << 16 | major << 8 | i;
+                result += "{%d,%d}, //%s\n" % (hash_v, count, sm_name)
+                count += 1
+
+        if kind_name == "lib":
+            result += "// lib_6_x is for offline linking only, and relaxes restrictions\n"
+            major = 6
+            #static const unsigned kOfflineMinor = 0xF;
+            i = 15
+            hash_v = kind << 16 | major << 8 | i;
+            result += "{%d,%d},//%s\n" % (hash_v, count, "lib_6_x")
+            count += 1
+
+    result += "};\n"
+    return result
+
+def get_validation_version():
+    result = """// 1.0 is the first validator.
+// 1.1 adds:
+// - ILDN container part support
+// 1.2 adds:
+// - Metadata for floating point denorm mode
+// 1.3 adds:
+// - Library support
+// - Raytracing support
+// - i64/f64 overloads for rawBufferLoad/Store
+// 1.4 adds:
+// - packed u8x4/i8x4 dot with accumulate to i32
+// - half dot2 with accumulate to float
+// 1.5 adds:
+// - WaveMatch, WaveMultiPrefixOp, WaveMultiPrefixBitCount
+// - HASH container part support
+// - Mesh and Amplification shaders
+// - DXR 1.1 & RayQuery support
+*pMajor = 1;
+*pMinor = %d;
+""" % highest_minor
+    return result
+
+def get_target_profiles():
+    result = "HelpText<\"Set target profile. \\n"
+    result += "\\t<profile>: "
+
+    profiles = getShaderProfiles()
+    shader_models = getShaderModels()
+
+    base_sm = "%d_0"%highest_major
+    for profile, min_sm in profiles.items():
+        for shader_model in shader_models:
+            if (base_sm > shader_model):
+                continue
+            if (min_sm > shader_model):
+                continue
+            result += "%s_%s, "%(profile,shader_model)
+        result += "\\n\\t\\t "
+
+    result += "\">;"
+    return result
+
+def get_min_validator_version():
+    result = ""
+    for i in range(0, highest_minor+1):
+        result += "case %d:\n"%i
+        result += "  ValMinor = %d;\n"%i
+        result += "  break;\n"
+    return result
+
+def get_dxil_version():
+    result = ""
+    for i in range(0, highest_minor+1):
+        result += "case %d:\n"%i
+        result += "  DxilMinor = %d;\n"%i
+        result += "  break;\n"
+    result += "case kOfflineMinor: // Always update this to highest dxil version\n"
+    result += "  DxilMinor = %d;\n"%highest_minor
+    result += "  break;\n"
+    return result
+
+def get_shader_model_get():
+    # const static std::unordered_map<unsigned, unsigned> hashToIdxMap = {};
+    result = build_shader_model_hash_idx_map()
+    result += "unsigned hash = (unsigned)Kind << 16 | Major << 8 | Minor;\n"
+    result += "auto it = hashToIdxMap.find(hash);\n"
+    result += "if (it == hashToIdxMap.end())\n"
+    result += "  return GetInvalid();\n"
+    result += "return &ms_ShaderModels[it->second];"
+    return result
+
+def get_shader_model_by_name():
+    result = ""
+    for i in range(2, highest_minor+1):
+        result += "case '%d':\n"%i
+        result += "  if (Major == %d) {\n"%highest_major
+        result += "    Minor = %d;\n"%i
+        result += "    break;\n"
+        result += "  }\n"
+        result += "else return GetInvalid();\n"
+
+    return result
+
+def get_is_valid_for_dxil():
+    result = ""
+    for i in range(0, highest_minor+1):
+        result += "case %d:\n"%i
+    return result
 
 def RunCodeTagUpdate(file_path):
     import os
@@ -1155,8 +1407,11 @@ if __name__ == "__main__":
         files = [
             'docs/DXIL.rst',
             'lib/DXIL/DXILOperations.cpp',
+            'lib/DXIL/DXILShaderModel.cpp',
             'include/dxc/DXIL/DXILConstants.h',
+            'include/dxc/DXIL/DXILShaderModel.h',
             'include/dxc/HLSL/DxilValidation.h',
+            'include/dxc/Support/HLSLOptions.td',
             'include/dxc/DXIL/DxilInstructions.h',
             'lib/HLSL/DxcOptimizer.cpp',
             'lib/DxilPIXPasses/DxilPIXPasses.cpp',