瀏覽代碼

Dxil versioned OpCode/Class counts, and other dxil versioning fixes (#263)

Tex Riddell 8 年之前
父節點
當前提交
c0d3163ee3

+ 5 - 1
include/dxc/HLSL/DxilConstants.h

@@ -27,7 +27,7 @@ import hctdb_instrhelp
 namespace DXIL {
   // DXIL version.
   const unsigned kDxilMajor = 1;
-  const unsigned kDxilMinor = 0;
+  const unsigned kDxilMinor = 1;
 
   inline unsigned MakeDxilVersion(unsigned DxilMajor, unsigned DxilMinor) {
     return 0 | (DxilMajor << 8) | (DxilMinor);
@@ -453,6 +453,8 @@ namespace DXIL {
     WaveReadLaneAt = 117, // returns the value from the specified lane
     WaveReadLaneFirst = 118, // returns the value from the first lane
   
+    NumOpCodes_Dxil_1_0 = 137,
+  
     NumOpCodes = 143 // exclusive last value of enumeration
   };
   // OPCODE-ENUM:END
@@ -612,6 +614,8 @@ namespace DXIL {
     WaveReadLaneAt,
     WaveReadLaneFirst,
   
+    NumOpClasses_Dxil_1_0 = 93,
+  
     NumOpClasses = 99 // exclusive last value of enumeration
   };
   // OPCODECLASS-ENUM:END

+ 6 - 4
include/dxc/HLSL/DxilContainer.h

@@ -316,9 +316,10 @@ inline bool IsValidDxilBitcodeHeader(const DxilBitcodeHeader *pHeader,
 }
 
 inline void InitBitcodeHeader(DxilBitcodeHeader &header,
+  uint32_t dxilVersion,
   uint32_t bitcodeSize) {
   header.DxilMagic = DxilMagicValue;
-  header.DxilVersion = DXIL::GetCurrentDxilVersion();
+  header.DxilVersion = dxilVersion;
   header.BitcodeOffset = sizeof(DxilBitcodeHeader);
   header.BitcodeSize = bitcodeSize;
 }
@@ -340,13 +341,14 @@ inline bool IsValidDxilProgramHeader(const DxilProgramHeader *pHeader,
       length - offsetof(DxilProgramHeader, BitcodeHeader));
 }
 
-inline void InitProgramHeader(DxilProgramHeader &header, uint32_t version,
+inline void InitProgramHeader(DxilProgramHeader &header, uint32_t shaderVersion,
+                              uint32_t dxilVersion,
                               uint32_t bitcodeSize) {
-  header.ProgramVersion = version;
+  header.ProgramVersion = shaderVersion;
   header.SizeInUint32 =
     sizeof(DxilProgramHeader) / sizeof(uint32_t) +
     bitcodeSize / sizeof(uint32_t) + ((bitcodeSize % 4) ? 1 : 0);
-  InitBitcodeHeader(header.BitcodeHeader, bitcodeSize);
+  InitBitcodeHeader(header.BitcodeHeader, dxilVersion, bitcodeSize);
 }
 
 inline const char *GetDxilBitcodeData(const DxilProgramHeader *pHeader) {

+ 1 - 0
include/dxc/HLSL/DxilShaderModel.h

@@ -38,6 +38,7 @@ public:
   bool IsDS() const     { return m_Kind == Kind::Domain; }
   bool IsCS() const     { return m_Kind == Kind::Compute; }
   bool IsValid() const;
+  bool IsValidForDxil() const;
 
   Kind GetKind() const      { return m_Kind; }
   unsigned GetMajor() const { return m_Major; }

+ 5 - 2
lib/HLSL/DxilContainerAssembler.cpp

@@ -588,9 +588,12 @@ static void WriteProgramPart(const ShaderModel *pModel,
                              AbstractMemoryStream *pStream) {
   DXASSERT(pModel != nullptr, "else generation should have failed");
   DxilProgramHeader programHeader;
-  uint32_t ver =
+  uint32_t shaderVersion =
       EncodeVersion(pModel->GetKind(), pModel->GetMajor(), pModel->GetMinor());
-  InitProgramHeader(programHeader, ver, pModuleBitcode->GetPtrSize());
+  unsigned dxilMajor, dxilMinor;
+  pModel->GetDxilVersion(dxilMajor, dxilMinor);
+  uint32_t dxilVersion = DXIL::MakeDxilVersion(dxilMajor, dxilMinor);
+  InitProgramHeader(programHeader, shaderVersion, dxilVersion, pModuleBitcode->GetPtrSize());
 
   uint32_t programInUInt32, programPaddingBytes;
   GetPaddedProgramPartSize(pModuleBitcode, programInUInt32,

+ 1 - 1
lib/HLSL/DxilMetadataHelper.cpp

@@ -135,7 +135,7 @@ void DxilMDHelper::LoadDxilShaderModel(const ShaderModel *&pSM) {
   string ShaderModelName = pShaderTypeMD->getString();
   ShaderModelName += "_" + std::to_string(Major) + "_" + std::to_string(Minor);
   pSM = ShaderModel::GetByName(ShaderModelName.c_str());
-  if (!pSM->IsValid()) {
+  if (!pSM->IsValidForDxil()) {
     char ErrorMsgTxt[40];
     StringCchPrintfA(ErrorMsgTxt, _countof(ErrorMsgTxt),
                      "Unknown shader model '%s'", ShaderModelName.c_str());

+ 2 - 1
lib/HLSL/DxilModule.cpp

@@ -128,7 +128,9 @@ OP *DxilModule::GetOP() const { return m_pOP.get(); }
 
 void DxilModule::SetShaderModel(const ShaderModel *pSM) {
   DXASSERT(m_pSM == nullptr || (pSM != nullptr && *m_pSM == *pSM), "shader model must not change for the module");
+  DXASSERT(pSM != nullptr && pSM->IsValidForDxil(), "shader model must be valid");
   m_pSM = pSM;
+  m_pSM->GetDxilVersion(m_DxilMajor, m_DxilMinor);
   m_pMDHelper->SetShaderModel(m_pSM);
   DXIL::ShaderKind shaderKind = pSM->GetKind();
   m_InputSignature.reset(new DxilSignature(shaderKind, DXIL::SignatureKind::Input));
@@ -932,7 +934,6 @@ vector<GlobalVariable* > &DxilModule::GetLLVMUsed() {
 
 // DXIL metadata serialization/deserialization.
 void DxilModule::EmitDxilMetadata() {
-  m_pSM->GetDxilVersion(m_DxilMajor, m_DxilMinor);
   m_pMDHelper->EmitDxilVersion(m_DxilMajor, m_DxilMinor);
   m_pMDHelper->EmitDxilShaderModel(m_pSM);
 

+ 18 - 2
lib/HLSL/DxilShaderModel.cpp

@@ -44,6 +44,22 @@ bool ShaderModel::IsValid() const {
   return m_Kind != Kind::Invalid;
 }
 
+bool ShaderModel::IsValidForDxil() const {
+  if (!IsValid())
+    return false;
+  switch (m_Major) {
+    case 6: {
+      switch (m_Minor) {
+      case 0:
+      case 1:
+        return true;
+      }
+    }
+    break;
+  }
+  return false;
+}
+
 const ShaderModel *ShaderModel::Get(unsigned Idx) {
   DXASSERT_NOMSG(Idx < kNumShaderModels - 1);
   if (Idx < kNumShaderModels - 1)
@@ -102,7 +118,7 @@ const ShaderModel *ShaderModel::GetByName(const char *pszName) {
 }
 
 void ShaderModel::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const {
-  DXASSERT(m_Major == 6, "invalid major");
+  DXASSERT(IsValidForDxil(), "invalid shader model");
   DxilMajor = 1;
   switch (m_Minor) {
   case 0:
@@ -112,7 +128,7 @@ void ShaderModel::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const
     DxilMinor = 1;
     break;
   default:
-    DXASSERT(0, "invalid minor");
+    DXASSERT(0, "IsValidForDxil() should have caught this.");
     break;
   }
 }

+ 1 - 2
lib/HLSL/DxilValidation.cpp

@@ -2789,8 +2789,7 @@ static void ValidateMetadata(ValidationContext &ValCtx) {
   }
 
   const hlsl::ShaderModel *SM = ValCtx.DxilMod.GetShaderModel();
-  if (!SM->IsValid() || SM->GetMajor() != 6 || 
-    (SM->GetMinor() != 0 && SM->GetMinor() != 1)) {
+  if (!SM->IsValidForDxil()) {
     ValCtx.EmitFormatError(ValidationRule::SmName,
                            {ValCtx.DxilMod.GetShaderModel()->GetName()});
   }

+ 1 - 0
lib/HLSL/HLModule.cpp

@@ -82,6 +82,7 @@ OP *HLModule::GetOP() const { return m_pOP.get(); }
 
 void HLModule::SetShaderModel(const ShaderModel *pSM) {
   DXASSERT(m_pSM == nullptr, "shader model must not change for the module");
+  DXASSERT(pSM != nullptr && pSM->IsValidForDxil(), "shader model must be valid");
   m_pSM = pSM;
   m_pSM->GetDxilVersion(m_DxilMajor, m_DxilMinor);
   m_pMDHelper->SetShaderModel(m_pSM);

+ 14 - 0
utils/hct/hctdb.py

@@ -135,6 +135,7 @@ class db_dxil(object):
         self.passes = []        # inventory of available passes (db_dxil_pass)
         self.name_idx = {}      # DXIL instructions by name
         self.enum_idx = {}      # enumerations by name
+        self.dxil_version_info = {}
 
         self.populate_llvm_instructions()
         self.call_instr = self.get_instr_by_llvm_name("CallInst")
@@ -206,6 +207,11 @@ class db_dxil(object):
                 assert val + 1 == i_val, "values in predicate are not sequential and dense, %d follows %d for %s" % (i_val, val, name_proj(i))
             val = i_val
 
+    def set_op_count_for_version(self, major, minor, op_count):
+        info = self.dxil_version_info.setdefault((major, minor), dict())
+        info['NumOpCodes'] = op_count
+        info['NumOpClasses'] = len(set([op.dxil_class for op in self.instr]))
+
     def populate_categories_and_models(self):
         "Populate the category and shader_stages member of instructions."
         for i in "TempRegLoad,TempRegStore,MinPrecXRegLoad,MinPrecXRegStore,LoadInput,StoreOutput".split(","):
@@ -1043,6 +1049,10 @@ class db_dxil(object):
             db_dxil_param(0, "i32", "", "operation result"),
             db_dxil_param(2, "i1", "value", "input value")])
         next_op_idx += 1
+
+        # End of DXIL 1.0 opcodes.
+        self.set_op_count_for_version(1, 0, next_op_idx)
+
         self.add_dxil_op("Barycentrics", next_op_idx, "Barycentrics", "return weights at a current location.", "f", "rn", [
             db_dxil_param(0, "f", "", "result"),
             db_dxil_param(2, "i8", "VertexID", "Vertex Index")])
@@ -1074,6 +1084,10 @@ class db_dxil(object):
             db_dxil_param(0, "i32", "", "result")])
         next_op_idx += 1
 
+        # End of DXIL 1.1 opcodes.
+        # Uncomment this when 1.1 is final.
+        #self.set_op_count_for_version(1, 1, next_op_idx)
+
         assert next_op_idx == 143, "next operation index is %d rather than 143 and thus opcodes are broken" % next_op_idx
 
         # Set interesting properties.

+ 9 - 1
utils/hct/hctdb_instrhelp.py

@@ -301,8 +301,16 @@ class db_enumhelp_gen:
                 line_format += " // {doc}"
             print(line_format.format(name=v.name, value=v.value, doc=v.doc))
         if e.name in self.lastEnumNames:
+            lastName = self.lastEnumNames[e.name]
+            versioned = ["%s_Dxil_%d_%d = %d," % (lastName, major, minor, info[lastName])
+                         for (major, minor), info in sorted(self.db.dxil_version_info.items())
+                         if lastName in info]
+            if versioned:
+                print("")
+                for val in versioned:
+                    print("  " + val)
             print("")
-            print("  " + self.lastEnumNames[e.name] + " = " + str(len(sorted_values)) + " // exclusive last value of enumeration")
+            print("  " + lastName + " = " + str(len(sorted_values)) + " // exclusive last value of enumeration")
         print("};")
 
     def print_content(self):