Jelajahi Sumber

Move DxilRootSignature to its own directory. (#1609)

* Move DxilRootSignature to its own directory.
* Move DxilContainer into its own directory.
* Move DxilLoadMetadata into DxilUtil.
Xiang Li 6 tahun lalu
induk
melakukan
16a5f94ab2
77 mengubah file dengan 1401 tambahan dan 1088 penghapusan
  1. 32 0
      include/dxc/DXIL/DxilConstants.h
  2. 2 2
      include/dxc/DXIL/DxilMetadataHelper.h
  3. 3 4
      include/dxc/DXIL/DxilModule.h
  4. 5 0
      include/dxc/DXIL/DxilUtil.h
  5. 0 58
      include/dxc/DxilContainer/DxilContainer.h
  6. 55 0
      include/dxc/DxilContainer/DxilContainerAssembler.h
  7. 2 1
      include/dxc/DxilRootSignature/DxilRootSignature.h
  8. 0 2
      include/dxc/HLSL/DxilGenerationPass.h
  9. 3 4
      include/dxc/HLSL/HLModule.h
  10. 2 0
      lib/CMakeLists.txt
  11. 0 1
      lib/DXIL/CMakeLists.txt
  12. 11 11
      lib/DXIL/DxilMetadataHelper.cpp
  13. 14 13
      lib/DXIL/DxilModule.cpp
  14. 39 20
      lib/DXIL/DxilShaderFlags.cpp
  15. 14 10
      lib/DXIL/DxilSignatureElement.cpp
  16. 29 0
      lib/DXIL/DxilUtil.cpp
  17. 11 0
      lib/DxilContainer/CMakeLists.txt
  18. 1 1
      lib/DxilContainer/DxilContainer.cpp
  19. 23 4
      lib/DxilContainer/DxilContainerAssembler.cpp
  20. 16 0
      lib/DxilContainer/LLVMBuild.txt
  21. 14 0
      lib/DxilRootSignature/CMakeLists.txt
  22. 194 0
      lib/DxilRootSignature/DxilRootSignature.cpp
  23. 197 0
      lib/DxilRootSignature/DxilRootSignatureConvert.cpp
  24. 43 0
      lib/DxilRootSignature/DxilRootSignatureHelper.h
  25. 574 0
      lib/DxilRootSignature/DxilRootSignatureSerializer.cpp
  26. 7 857
      lib/DxilRootSignature/DxilRootSignatureValidator.cpp
  27. 16 0
      lib/DxilRootSignature/LLVMBuild.txt
  28. 0 2
      lib/HLSL/CMakeLists.txt
  29. 1 1
      lib/HLSL/DxcOptimizer.cpp
  30. 2 1
      lib/HLSL/DxilContainerReflection.cpp
  31. 1 1
      lib/HLSL/DxilGenerationPass.cpp
  32. 1 1
      lib/HLSL/DxilLinker.cpp
  33. 1 1
      lib/HLSL/DxilPatchShaderRecordBindings.cpp
  34. 0 29
      lib/HLSL/DxilPreparePasses.cpp
  35. 8 10
      lib/HLSL/DxilValidation.cpp
  36. 13 12
      lib/HLSL/HLModule.cpp
  37. 1 1
      lib/HLSL/WaveSensitivityAnalysis.cpp
  38. 3 1
      lib/LLVMBuild.txt
  39. 0 1
      lib/Transforms/IPO/PassManagerBuilder.cpp
  40. 16 4
      tools/clang/lib/CodeGen/CGHLSLMS.cpp
  41. 1 1
      tools/clang/lib/Frontend/FrontendActions.cpp
  42. 1 1
      tools/clang/lib/Parse/HLSLRootSignature.h
  43. 1 1
      tools/clang/tools/d3dcomp/d3dcomp.cpp
  44. 1 0
      tools/clang/tools/dxa/CMakeLists.txt
  45. 1 1
      tools/clang/tools/dxa/dxa.cpp
  46. 1 0
      tools/clang/tools/dxc/CMakeLists.txt
  47. 2 2
      tools/clang/tools/dxc/dxc.cpp
  48. 2 0
      tools/clang/tools/dxcompiler/CMakeLists.txt
  49. 1 1
      tools/clang/tools/dxcompiler/dxcassembler.cpp
  50. 1 1
      tools/clang/tools/dxcompiler/dxcdia.cpp
  51. 2 1
      tools/clang/tools/dxcompiler/dxcdisassembler.cpp
  52. 1 1
      tools/clang/tools/dxcompiler/dxcfilesystem.cpp
  53. 1 1
      tools/clang/tools/dxcompiler/dxclinker.cpp
  54. 2 2
      tools/clang/tools/dxcompiler/dxcompilerobj.cpp
  55. 1 1
      tools/clang/tools/dxcompiler/dxcontainerbuilder.cpp
  56. 1 1
      tools/clang/tools/dxcompiler/dxcutil.cpp
  57. 2 2
      tools/clang/tools/dxcompiler/dxcvalidator.cpp
  58. 1 1
      tools/clang/tools/dxl/dxl.cpp
  59. 1 1
      tools/clang/tools/dxlib-sample/lib_share_compile.cpp
  60. 1 1
      tools/clang/tools/dxopt/dxopt.cpp
  61. 2 0
      tools/clang/tools/dxrfallbackcompiler/CMakeLists.txt
  62. 1 1
      tools/clang/tools/dxrfallbackcompiler/dxcdxrfallbackcompiler.cpp
  63. 1 1
      tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp
  64. 2 2
      tools/clang/tools/dxrfallbackcompiler/dxcvalidator.cpp
  65. 2 0
      tools/clang/unittests/HLSL/CMakeLists.txt
  66. 1 1
      tools/clang/unittests/HLSL/CompilerTest.cpp
  67. 1 1
      tools/clang/unittests/HLSL/D3DReflectionDumper.cpp
  68. 1 1
      tools/clang/unittests/HLSL/D3DReflectionDumper.h
  69. 1 1
      tools/clang/unittests/HLSL/DxilContainerTest.cpp
  70. 1 1
      tools/clang/unittests/HLSL/DxilModuleTest.cpp
  71. 1 1
      tools/clang/unittests/HLSL/FileCheckerTest.cpp
  72. 1 1
      tools/clang/unittests/HLSL/FunctionTest.cpp
  73. 1 1
      tools/clang/unittests/HLSL/OptimizerTest.cpp
  74. 2 1
      tools/clang/unittests/HLSL/ValidationTest.cpp
  75. 1 0
      tools/clang/unittests/SPIRV/CMakeLists.txt
  76. 1 0
      tools/clang/unittests/dxc_batch/CMakeLists.txt
  77. 2 2
      tools/clang/unittests/dxc_batch/dxc_batch.cpp

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

@@ -1098,6 +1098,38 @@ namespace DXIL {
     TriangleBackFace = 0xFF,
   };
 
+  // Constant for Container.
+  const uint8_t DxilProgramSigMaskX = 1;
+  const uint8_t DxilProgramSigMaskY = 2;
+  const uint8_t DxilProgramSigMaskZ = 4;
+  const uint8_t DxilProgramSigMaskW = 8;
+
+  // DFCC_FeatureInfo is a uint64_t value with these flags.
+  const uint64_t ShaderFeatureInfo_Doubles = 0x0001;
+  const uint64_t
+      ShaderFeatureInfo_ComputeShadersPlusRawAndStructuredBuffersViaShader4X =
+          0x0002;
+  const uint64_t ShaderFeatureInfo_UAVsAtEveryStage = 0x0004;
+  const uint64_t ShaderFeatureInfo_64UAVs = 0x0008;
+  const uint64_t ShaderFeatureInfo_MinimumPrecision = 0x0010;
+  const uint64_t ShaderFeatureInfo_11_1_DoubleExtensions = 0x0020;
+  const uint64_t ShaderFeatureInfo_11_1_ShaderExtensions = 0x0040;
+  const uint64_t ShaderFeatureInfo_LEVEL9ComparisonFiltering = 0x0080;
+  const uint64_t ShaderFeatureInfo_TiledResources = 0x0100;
+  const uint64_t ShaderFeatureInfo_StencilRef = 0x0200;
+  const uint64_t ShaderFeatureInfo_InnerCoverage = 0x0400;
+  const uint64_t ShaderFeatureInfo_TypedUAVLoadAdditionalFormats = 0x0800;
+  const uint64_t ShaderFeatureInfo_ROVs = 0x1000;
+  const uint64_t
+      ShaderFeatureInfo_ViewportAndRTArrayIndexFromAnyShaderFeedingRasterizer =
+          0x2000;
+  const uint64_t ShaderFeatureInfo_WaveOps = 0x4000;
+  const uint64_t ShaderFeatureInfo_Int64Ops = 0x8000;
+  const uint64_t ShaderFeatureInfo_ViewID = 0x10000;
+  const uint64_t ShaderFeatureInfo_Barycentrics = 0x20000;
+  const uint64_t ShaderFeatureInfo_NativeLowPrecision = 0x40000;
+
+  const unsigned ShaderFeatureInfoCount = 19;
 
   extern const char* kLegacyLayoutString;
   extern const char* kNewLayoutString;

+ 2 - 2
include/dxc/DXIL/DxilMetadataHelper.h

@@ -295,11 +295,11 @@ public:
   void LoadDxilSignatures(const llvm::MDOperand &MDO,
                           DxilEntrySignature &EntrySig);
   llvm::MDTuple *EmitSignatureMetadata(const DxilSignature &Sig);
-  void EmitRootSignature(RootSignatureHandle &RootSig);
+  void EmitRootSignature(std::vector<uint8_t> &SerializedRootSignature);
   void LoadSignatureMetadata(const llvm::MDOperand &MDO, DxilSignature &Sig);
   llvm::MDTuple *EmitSignatureElement(const DxilSignatureElement &SE);
   void LoadSignatureElement(const llvm::MDOperand &MDO, DxilSignatureElement &SE);
-  void LoadRootSignature(RootSignatureHandle &RootSig);
+  void LoadRootSignature(std::vector<uint8_t> &SerializedRootSignature);
 
   // Resources.
   llvm::MDTuple *EmitDxilResourceTuple(llvm::MDTuple *pSRVs, llvm::MDTuple *pUAVs, 

+ 3 - 4
include/dxc/DXIL/DxilModule.h

@@ -40,7 +40,6 @@ namespace hlsl {
 
 class ShaderModel;
 class OP;
-class RootSignatureHandle;
 struct DxilFunctionProps;
 
 class DxilEntryProps;
@@ -120,7 +119,7 @@ public:
   const DxilSignature &GetOutputSignature() const;
   DxilSignature &GetPatchConstantSignature();
   const DxilSignature &GetPatchConstantSignature() const;
-  const RootSignatureHandle &GetRootSignature() const;
+  const std::vector<uint8_t> &GetSerializedRootSignature() const;
 
   bool HasDxilEntrySignature(const llvm::Function *F) const;
   DxilEntrySignature &GetDxilEntrySignature(const llvm::Function *F);
@@ -178,7 +177,7 @@ public:
 
   // Reset functions used to transfer ownership.
   void ResetEntrySignature(DxilEntrySignature *pValue);
-  void ResetRootSignature(RootSignatureHandle *pValue);
+  void ResetSerializedRootSignature(std::vector<uint8_t> &Value);
   void ResetTypeSystem(DxilTypeSystem *pValue);
   void ResetOP(hlsl::OP *hlslOP);
   void ResetEntryPropsMap(DxilEntryPropsMap &&PropMap);
@@ -271,7 +270,7 @@ public:
 
 private:
   // Signatures.
-  std::unique_ptr<RootSignatureHandle> m_RootSignature;
+  std::vector<uint8_t> m_SerializedRootSignature;
 
   // Shader resources.
   std::vector<std::unique_ptr<DxilResource> > m_SRVs;

+ 5 - 0
include/dxc/DXIL/DxilUtil.h

@@ -28,6 +28,11 @@ class Value;
 class Instruction;
 class BasicBlock;
 class raw_ostream;
+class ModulePass;
+class PassRegistry;
+
+ModulePass *createDxilLoadMetadataPass();
+void initializeDxilLoadMetadataPass(llvm::PassRegistry&);
 }
 
 namespace hlsl {

+ 0 - 58
include/dxc/DXIL/DxilContainer.h → include/dxc/DxilContainer/DxilContainer.h

@@ -16,7 +16,6 @@
 
 #include <stdint.h>
 #include <iterator>
-#include <functional>
 #include "dxc/DXIL/DxilConstants.h"
 #include "dxc/Support/WinAdapter.h"
 
@@ -88,29 +87,6 @@ enum DxilFourCC {
 
 #undef DXIL_FOURCC
 
-// DFCC_FeatureInfo is a uint64_t value with these flags.
-static const uint64_t ShaderFeatureInfo_Doubles = 0x0001;
-static const uint64_t ShaderFeatureInfo_ComputeShadersPlusRawAndStructuredBuffersViaShader4X = 0x0002;
-static const uint64_t ShaderFeatureInfo_UAVsAtEveryStage = 0x0004;
-static const uint64_t ShaderFeatureInfo_64UAVs = 0x0008;
-static const uint64_t ShaderFeatureInfo_MinimumPrecision = 0x0010;
-static const uint64_t ShaderFeatureInfo_11_1_DoubleExtensions = 0x0020;
-static const uint64_t ShaderFeatureInfo_11_1_ShaderExtensions = 0x0040;
-static const uint64_t ShaderFeatureInfo_LEVEL9ComparisonFiltering = 0x0080;
-static const uint64_t ShaderFeatureInfo_TiledResources = 0x0100;
-static const uint64_t ShaderFeatureInfo_StencilRef = 0x0200;
-static const uint64_t ShaderFeatureInfo_InnerCoverage = 0x0400;
-static const uint64_t ShaderFeatureInfo_TypedUAVLoadAdditionalFormats = 0x0800;
-static const uint64_t ShaderFeatureInfo_ROVs = 0x1000;
-static const uint64_t ShaderFeatureInfo_ViewportAndRTArrayIndexFromAnyShaderFeedingRasterizer = 0x2000;
-static const uint64_t ShaderFeatureInfo_WaveOps = 0x4000;
-static const uint64_t ShaderFeatureInfo_Int64Ops = 0x8000;
-static const uint64_t ShaderFeatureInfo_ViewID = 0x10000;
-static const uint64_t ShaderFeatureInfo_Barycentrics = 0x20000;
-static const uint64_t ShaderFeatureInfo_NativeLowPrecision = 0x40000;
-
-static const unsigned ShaderFeatureInfoCount = 19;
-
 struct DxilShaderFeatureInfo {
   uint64_t FeatureFlags;
 };
@@ -189,11 +165,6 @@ enum class DxilProgramSigCompType : uint32_t {
   Float64 = 9,
 };
 
-static const uint8_t DxilProgramSigMaskX = 1;
-static const uint8_t DxilProgramSigMaskY = 2;
-static const uint8_t DxilProgramSigMaskZ = 4;
-static const uint8_t DxilProgramSigMaskW = 8;
-
 struct DxilProgramSignatureElement {
   uint32_t Stream;                    // Stream index (parameters must appear in non-decreasing stream order)
   uint32_t SemanticName;              // Offset to LPCSTR from start of DxilProgramSignature.
@@ -418,28 +389,6 @@ inline bool GetDxilShaderDebugName(const DxilPartHeader *pDebugNamePart,
   return true;
 }
 
-class DxilPartWriter {
-public:
-  virtual ~DxilPartWriter() {}
-  virtual uint32_t size() const = 0;
-  virtual void write(AbstractMemoryStream *pStream) = 0;
-};
-
-DxilPartWriter *NewProgramSignatureWriter(const DxilModule &M, DXIL::SignatureKind Kind);
-DxilPartWriter *NewRootSignatureWriter(const RootSignatureHandle &S);
-DxilPartWriter *NewFeatureInfoWriter(const DxilModule &M);
-DxilPartWriter *NewPSVWriter(const DxilModule &M, uint32_t PSVVersion = 0);
-DxilPartWriter *NewRDATWriter(const DxilModule &M, uint32_t InfoVersion = 0);
-
-class DxilContainerWriter : public DxilPartWriter  {
-public:
-  typedef std::function<void(AbstractMemoryStream*)> WriteFn;
-  virtual ~DxilContainerWriter() {}
-  virtual void AddPart(uint32_t FourCC, uint32_t Size, WriteFn Write) = 0;
-};
-
-DxilContainerWriter *NewDxilContainerWriter();
-
 enum class SerializeDxilFlags : uint32_t {
   None = 0,                     // No flags defined.
   IncludeDebugInfoPart = 1,     // Include the debug info part in the container.
@@ -461,13 +410,6 @@ inline SerializeDxilFlags operator~(SerializeDxilFlags l) {
   return static_cast<SerializeDxilFlags>(~static_cast<uint32_t>(l));
 }
 
-void SerializeDxilContainerForModule(hlsl::DxilModule *pModule,
-                                     AbstractMemoryStream *pModuleBitcode,
-                                     AbstractMemoryStream *pStream,
-                                     SerializeDxilFlags Flags);
-void SerializeDxilContainerForRootSignature(hlsl::RootSignatureHandle *pRootSigHandle,
-                                     AbstractMemoryStream *pStream);
-
 void CreateDxcContainerReflection(IDxcContainerReflection **ppResult);
 
 // Converts uint32_t partKind to char array object.

+ 55 - 0
include/dxc/DxilContainer/DxilContainerAssembler.h

@@ -0,0 +1,55 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilContainerWriter.h                                                     //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Helper class to write dxil container.                                     //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include <functional>
+#include "dxc/DxilContainer/DxilContainer.h"
+
+namespace hlsl {
+
+class AbstractMemoryStream;
+class DxilModule;
+class RootSignatureHandle;
+namespace DXIL {
+enum class SignatureKind;
+}
+
+class DxilPartWriter {
+public:
+  virtual ~DxilPartWriter() {}
+  virtual uint32_t size() const = 0;
+  virtual void write(AbstractMemoryStream *pStream) = 0;
+};
+
+class DxilContainerWriter : public DxilPartWriter  {
+public:
+  typedef std::function<void(AbstractMemoryStream*)> WriteFn;
+  virtual ~DxilContainerWriter() {}
+  virtual void AddPart(uint32_t FourCC, uint32_t Size, WriteFn Write) = 0;
+};
+
+DxilPartWriter *NewProgramSignatureWriter(const DxilModule &M, DXIL::SignatureKind Kind);
+DxilPartWriter *NewRootSignatureWriter(const RootSignatureHandle &S);
+DxilPartWriter *NewFeatureInfoWriter(const DxilModule &M);
+DxilPartWriter *NewPSVWriter(const DxilModule &M, uint32_t PSVVersion = 0);
+DxilPartWriter *NewRDATWriter(const DxilModule &M, uint32_t InfoVersion = 0);
+
+DxilContainerWriter *NewDxilContainerWriter();
+
+void SerializeDxilContainerForModule(hlsl::DxilModule *pModule,
+                                     AbstractMemoryStream *pModuleBitcode,
+                                     AbstractMemoryStream *pStream,
+                                     SerializeDxilFlags Flags);
+void SerializeDxilContainerForRootSignature(hlsl::RootSignatureHandle *pRootSigHandle,
+                                     AbstractMemoryStream *pStream);
+
+} // namespace hlsl

+ 2 - 1
include/dxc/HLSL/DxilRootSignature.h → include/dxc/DxilRootSignature/DxilRootSignature.h

@@ -361,7 +361,8 @@ bool VerifyRootSignatureWithShaderPSV(_In_ const DxilVersionedRootSignatureDesc
 
 // standalone verification
 bool VerifyRootSignature(_In_ const DxilVersionedRootSignatureDesc *pDesc,
-                         _In_ llvm::raw_ostream &DiagStream);
+                         _In_ llvm::raw_ostream &DiagStream,
+                         _In_ bool bAllowReservedRegisterSpace);
 
 } // namespace hlsl
 

+ 0 - 2
include/dxc/HLSL/DxilGenerationPass.h

@@ -55,7 +55,6 @@ ModulePass *createDxilEmitMetadataPass();
 FunctionPass *createDxilExpandTrigIntrinsicsPass();
 ModulePass *createDxilConvergentMarkPass();
 ModulePass *createDxilConvergentClearPass();
-ModulePass *createDxilLoadMetadataPass();
 ModulePass *createDxilDeadFunctionEliminationPass();
 ModulePass *createHLDeadFunctionEliminationPass();
 ModulePass *createHLPreprocessPass();
@@ -84,7 +83,6 @@ void initializeHLEmitMetadataPass(llvm::PassRegistry&);
 void initializeDxilFinalizeModulePass(llvm::PassRegistry&);
 void initializeDxilEmitMetadataPass(llvm::PassRegistry&);
 void initializeDxilExpandTrigIntrinsicsPass(llvm::PassRegistry&);
-void initializeDxilLoadMetadataPass(llvm::PassRegistry&);
 void initializeDxilDeadFunctionEliminationPass(llvm::PassRegistry&);
 void initializeHLDeadFunctionEliminationPass(llvm::PassRegistry&);
 void initializeHLPreprocessPass(llvm::PassRegistry&);

+ 3 - 4
include/dxc/HLSL/HLModule.h

@@ -44,7 +44,6 @@ namespace hlsl {
 
 class ShaderModel;
 class OP;
-class RootSignatureHandle;
 
 struct HLOptions {
   HLOptions()
@@ -131,7 +130,8 @@ public:
   void AddGroupSharedVariable(llvm::GlobalVariable *GV);
 
   // Signatures.
-  RootSignatureHandle &GetRootSignature();
+  std::vector<uint8_t> &GetSerializedRootSignature();
+  void SetSerializedRootSignature(const uint8_t *pData, unsigned size);
 
   // DxilFunctionProps.
   bool HasDxilFunctionProps(llvm::Function *F);
@@ -224,7 +224,6 @@ public:
   // Release functions used to transfer ownership.
   DxilTypeSystem *ReleaseTypeSystem();
   OP *ReleaseOP();
-  RootSignatureHandle *ReleaseRootSignature();
   DxilFunctionPropsMap &&ReleaseFunctionPropsMap();
 
   llvm::DebugInfoFinder &GetOrCreateDebugInfoFinder();
@@ -245,7 +244,7 @@ public:
 
 private:
   // Signatures.
-  std::unique_ptr<RootSignatureHandle> m_RootSignature;
+  std::vector<uint8_t> m_SerializedRootSignature;
 
   // Shader resources.
   std::vector<std::unique_ptr<HLResource> > m_SRVs;

+ 2 - 0
lib/CMakeLists.txt

@@ -23,5 +23,7 @@ add_subdirectory(ProfileData)
 add_subdirectory(DxcSupport) # HLSL Change
 add_subdirectory(HLSL) # HLSL Change
 add_subdirectory(DXIL) # HLSL Change
+add_subdirectory(DxilContainer) # HLSL Change
 add_subdirectory(DxilPIXPasses) # HLSL Change
+add_subdirectory(DxilRootSignature) # HLSL Change
 add_subdirectory(DxrFallback) # HLSL Change

+ 0 - 1
lib/DXIL/CMakeLists.txt

@@ -3,7 +3,6 @@
 add_llvm_library(LLVMDXIL
   DxilCBuffer.cpp
   DxilCompType.cpp
-  DxilContainer.cpp
   DxilInterpolationMode.cpp
   DxilMetadataHelper.cpp
   DxilModule.cpp

+ 11 - 11
lib/DXIL/DxilMetadataHelper.cpp

@@ -16,8 +16,6 @@
 #include "dxc/DXIL/DxilSignatureElement.h"
 #include "dxc/DXIL/DxilSignature.h"
 #include "dxc/DXIL/DxilTypeSystem.h"
-#include "dxc/HLSL/DxilRootSignature.h"
-#include "dxc/HLSL/ComputeViewIdState.h"
 #include "dxc/DXIL/DxilFunctionProps.h"
 #include "dxc/DXIL/DxilShaderFlags.h"
 
@@ -294,15 +292,15 @@ MDTuple *DxilMDHelper::EmitDxilSignatures(const DxilEntrySignature &EntrySig) {
   return pSignatureTupleMD;
 }
 
-void DxilMDHelper::EmitRootSignature(RootSignatureHandle &RootSig) {
-  if (RootSig.IsEmpty()) {
+void DxilMDHelper::EmitRootSignature(
+    std::vector<uint8_t> &SerializedRootSignature) {
+  if (SerializedRootSignature.empty()) {
     return;
   }
 
-  RootSig.EnsureSerializedAvailable();
   Constant *V = llvm::ConstantDataArray::get(
-      m_Ctx, llvm::ArrayRef<uint8_t>(RootSig.GetSerializedBytes(),
-                                     RootSig.GetSerializedSize()));
+      m_Ctx, llvm::ArrayRef<uint8_t>(SerializedRootSignature.data(),
+                                     SerializedRootSignature.size()));
 
   NamedMDNode *pRootSignatureNamedMD = m_pModule->getNamedMetadata(kDxilRootSignatureMDName);
   IFTBOOL(pRootSignatureNamedMD == nullptr, DXC_E_INCORRECT_DXIL_METADATA);
@@ -353,7 +351,7 @@ void DxilMDHelper::LoadSignatureMetadata(const MDOperand &MDO, DxilSignature &Si
   }
 }
 
-void DxilMDHelper::LoadRootSignature(RootSignatureHandle &Sig) {
+void DxilMDHelper::LoadRootSignature(std::vector<uint8_t> &SerializedRootSignature) {
   NamedMDNode *pRootSignatureNamedMD = m_pModule->getNamedMetadata(kDxilRootSignatureMDName);
   if(!pRootSignatureNamedMD)
     return;
@@ -372,9 +370,11 @@ void DxilMDHelper::LoadRootSignature(RootSignatureHandle &Sig) {
   IFTBOOL(pData->getElementType() == Type::getInt8Ty(m_Ctx),
           DXC_E_INCORRECT_DXIL_METADATA);
 
-  Sig.Clear();
-  Sig.LoadSerialized((const uint8_t *)pData->getRawDataValues().begin(),
-                     pData->getRawDataValues().size());
+  SerializedRootSignature.clear();
+  unsigned size = pData->getRawDataValues().size();
+  SerializedRootSignature.resize(size);
+  memcpy(SerializedRootSignature.data(),
+         (const uint8_t *)pData->getRawDataValues().begin(), size);
 }
 
 static const MDTuple *CastToTupleOrNull(const MDOperand &MDO) {

+ 14 - 13
lib/DXIL/DxilModule.cpp

@@ -10,10 +10,9 @@
 #include "dxc/Support/Global.h"
 #include "dxc/DXIL/DxilOperations.h"
 #include "dxc/DXIL/DxilModule.h"
+#include "dxc/DXIL/DxilConstants.h"
 #include "dxc/DXIL/DxilShaderModel.h"
 #include "dxc/DXIL/DxilSignatureElement.h"
-#include "dxc/DXIL/DxilContainer.h"
-#include "dxc/HLSL/DxilRootSignature.h"
 #include "dxc/DXIL/DxilFunctionProps.h"
 #include "dxc/Support/WinAdapter.h"
 #include "dxc/DXIL/DxilEntryProps.h"
@@ -80,8 +79,7 @@ const char* kFP32DenormValueFtzString      = "ftz";
 //  DxilModule methods.
 //
 DxilModule::DxilModule(Module *pModule)
-: m_RootSignature(nullptr)
-, m_StreamPrimitiveTopology(DXIL::PrimitiveTopology::Undefined)
+: m_StreamPrimitiveTopology(DXIL::PrimitiveTopology::Undefined)
 , m_ActiveStreamMask(0)
 , m_Ctx(pModule->getContext())
 , m_pModule(pModule)
@@ -138,7 +136,7 @@ void DxilModule::SetShaderModel(const ShaderModel *pSM, bool bUseMinPrecision) {
     m_DxilEntryPropsMap[nullptr] =
       llvm::make_unique<DxilEntryProps>(props, m_bUseMinPrecision);
   }
-  m_RootSignature.reset(new RootSignatureHandle());
+  m_SerializedRootSignature.clear();
 }
 
 const ShaderModel *DxilModule::GetShaderModel() const {
@@ -177,7 +175,8 @@ bool DxilModule::GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor)
   if (!m_pSM)
     return false;
   m_pSM->GetMinValidatorVersion(ValMajor, ValMinor);
-  if (ValMajor == 1 && ValMinor == 0 && (m_ShaderFlags.GetFeatureInfo() & hlsl::ShaderFeatureInfo_ViewID))
+  if (ValMajor == 1 && ValMinor == 0 &&
+      (m_ShaderFlags.GetFeatureInfo() & hlsl::DXIL::ShaderFeatureInfo_ViewID))
     ValMinor = 1;
   return true;
 }
@@ -953,8 +952,8 @@ const DxilSignature &DxilModule::GetPatchConstantSignature() const {
   return m_DxilEntryPropsMap.begin()->second->sig.PatchConstantSignature;
 }
 
-const RootSignatureHandle &DxilModule::GetRootSignature() const {
-  return *m_RootSignature;
+const std::vector<uint8_t> &DxilModule::GetSerializedRootSignature() const {
+  return m_SerializedRootSignature;
 }
 
 // Entry props.
@@ -1046,8 +1045,10 @@ void DxilModule::UpdateValidatorVersionMetadata() {
   m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
 }
 
-void DxilModule::ResetRootSignature(RootSignatureHandle *pValue) {
-  m_RootSignature.reset(pValue);
+void DxilModule::ResetSerializedRootSignature(std::vector<uint8_t> &Value) {
+  m_SerializedRootSignature.clear();
+  m_SerializedRootSignature.reserve(Value.size());
+  m_SerializedRootSignature.assign(Value.begin(), Value.end());
 }
 
 DxilTypeSystem &DxilModule::GetTypeSystem() {
@@ -1217,8 +1218,8 @@ void DxilModule::EmitDxilMetadata() {
   }
   m_pMDHelper->EmitDxilEntryPoints(Entries);
 
-  if (!m_RootSignature->IsEmpty()) {
-    m_pMDHelper->EmitRootSignature(*m_RootSignature.get());
+  if (!m_SerializedRootSignature.empty()) {
+    m_pMDHelper->EmitRootSignature(m_SerializedRootSignature);
   }
 }
 
@@ -1318,7 +1319,7 @@ void DxilModule::LoadDxilMetadata() {
 
   m_pMDHelper->LoadDxilTypeSystem(*m_pTypeSystem.get());
 
-  m_pMDHelper->LoadRootSignature(*m_RootSignature.get());
+  m_pMDHelper->LoadRootSignature(m_SerializedRootSignature);
 
   m_pMDHelper->LoadDxilViewIdState(m_SerializedState);
 }

+ 39 - 20
lib/DXIL/DxilShaderFlags.cpp

@@ -7,7 +7,6 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/DXIL/DxilContainer.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DXIL/DxilShaderFlags.h"
 #include "dxc/DXIL/DxilOperations.h"
@@ -52,25 +51,45 @@ ShaderFlags::ShaderFlags():
 
 uint64_t ShaderFlags::GetFeatureInfo() const {
   uint64_t Flags = 0;
-  Flags |= m_bEnableDoublePrecision ? hlsl::ShaderFeatureInfo_Doubles : 0;
-  Flags |= m_bLowPrecisionPresent && !m_bUseNativeLowPrecision ? hlsl::ShaderFeatureInfo_MinimumPrecision: 0;
-  Flags |= m_bLowPrecisionPresent && m_bUseNativeLowPrecision ? hlsl::ShaderFeatureInfo_NativeLowPrecision : 0;
-  Flags |= m_bEnableDoubleExtensions ? hlsl::ShaderFeatureInfo_11_1_DoubleExtensions : 0;
-  Flags |= m_bWaveOps ? hlsl::ShaderFeatureInfo_WaveOps : 0;
-  Flags |= m_bInt64Ops ? hlsl::ShaderFeatureInfo_Int64Ops : 0;
-  Flags |= m_bROVS ? hlsl::ShaderFeatureInfo_ROVs : 0;
-  Flags |= m_bViewportAndRTArrayIndex ? hlsl::ShaderFeatureInfo_ViewportAndRTArrayIndexFromAnyShaderFeedingRasterizer : 0;
-  Flags |= m_bInnerCoverage ? hlsl::ShaderFeatureInfo_InnerCoverage : 0;
-  Flags |= m_bStencilRef ? hlsl::ShaderFeatureInfo_StencilRef : 0;
-  Flags |= m_bTiledResources ? hlsl::ShaderFeatureInfo_TiledResources : 0;
-  Flags |= m_bEnableMSAD ? hlsl::ShaderFeatureInfo_11_1_ShaderExtensions : 0;
-  Flags |= m_bCSRawAndStructuredViaShader4X ? hlsl::ShaderFeatureInfo_ComputeShadersPlusRawAndStructuredBuffersViaShader4X : 0;
-  Flags |= m_UAVsAtEveryStage ? hlsl::ShaderFeatureInfo_UAVsAtEveryStage : 0;
-  Flags |= m_b64UAVs ? hlsl::ShaderFeatureInfo_64UAVs : 0;
-  Flags |= m_bLevel9ComparisonFiltering ? hlsl::ShaderFeatureInfo_LEVEL9ComparisonFiltering : 0;
-  Flags |= m_bUAVLoadAdditionalFormats ? hlsl::ShaderFeatureInfo_TypedUAVLoadAdditionalFormats : 0;
-  Flags |= m_bViewID ? hlsl::ShaderFeatureInfo_ViewID : 0;
-  Flags |= m_bBarycentrics ? hlsl::ShaderFeatureInfo_Barycentrics : 0;
+  Flags |= m_bEnableDoublePrecision ? hlsl::DXIL::ShaderFeatureInfo_Doubles : 0;
+  Flags |= m_bLowPrecisionPresent && !m_bUseNativeLowPrecision
+               ? hlsl::DXIL::ShaderFeatureInfo_MinimumPrecision
+               : 0;
+  Flags |= m_bLowPrecisionPresent && m_bUseNativeLowPrecision
+               ? hlsl::DXIL::ShaderFeatureInfo_NativeLowPrecision
+               : 0;
+  Flags |= m_bEnableDoubleExtensions
+               ? hlsl::DXIL::ShaderFeatureInfo_11_1_DoubleExtensions
+               : 0;
+  Flags |= m_bWaveOps ? hlsl::DXIL::ShaderFeatureInfo_WaveOps : 0;
+  Flags |= m_bInt64Ops ? hlsl::DXIL::ShaderFeatureInfo_Int64Ops : 0;
+  Flags |= m_bROVS ? hlsl::DXIL::ShaderFeatureInfo_ROVs : 0;
+  Flags |=
+      m_bViewportAndRTArrayIndex
+          ? hlsl::DXIL::
+                ShaderFeatureInfo_ViewportAndRTArrayIndexFromAnyShaderFeedingRasterizer
+          : 0;
+  Flags |= m_bInnerCoverage ? hlsl::DXIL::ShaderFeatureInfo_InnerCoverage : 0;
+  Flags |= m_bStencilRef ? hlsl::DXIL::ShaderFeatureInfo_StencilRef : 0;
+  Flags |= m_bTiledResources ? hlsl::DXIL::ShaderFeatureInfo_TiledResources : 0;
+  Flags |=
+      m_bEnableMSAD ? hlsl::DXIL::ShaderFeatureInfo_11_1_ShaderExtensions : 0;
+  Flags |=
+      m_bCSRawAndStructuredViaShader4X
+          ? hlsl::DXIL::
+                ShaderFeatureInfo_ComputeShadersPlusRawAndStructuredBuffersViaShader4X
+          : 0;
+  Flags |=
+      m_UAVsAtEveryStage ? hlsl::DXIL::ShaderFeatureInfo_UAVsAtEveryStage : 0;
+  Flags |= m_b64UAVs ? hlsl::DXIL::ShaderFeatureInfo_64UAVs : 0;
+  Flags |= m_bLevel9ComparisonFiltering
+               ? hlsl::DXIL::ShaderFeatureInfo_LEVEL9ComparisonFiltering
+               : 0;
+  Flags |= m_bUAVLoadAdditionalFormats
+               ? hlsl::DXIL::ShaderFeatureInfo_TypedUAVLoadAdditionalFormats
+               : 0;
+  Flags |= m_bViewID ? hlsl::DXIL::ShaderFeatureInfo_ViewID : 0;
+  Flags |= m_bBarycentrics ? hlsl::DXIL::ShaderFeatureInfo_Barycentrics : 0;
 
   return Flags;
 }

+ 14 - 10
lib/DXIL/DxilSignatureElement.cpp

@@ -14,7 +14,6 @@
 #include "dxc/DXIL/DxilSemantic.h"
 #include "dxc/DXIL/DxilSigPoint.h"
 #include "dxc/DXIL/DxilShaderModel.h"
-#include "dxc/DXIL/DxilContainer.h"
 #include <memory>
 
 using std::string;
@@ -233,29 +232,34 @@ uint8_t DxilSignatureElement::GetColsAsMask() const {
   case 0: {
     switch (m_Cols) {
     case 1:
-      return DxilProgramSigMaskX;
+      return hlsl::DXIL::DxilProgramSigMaskX;
     case 2:
-      return DxilProgramSigMaskX | DxilProgramSigMaskY;
+      return hlsl::DXIL::DxilProgramSigMaskX | hlsl::DXIL::DxilProgramSigMaskY;
     case 3:
-      return DxilProgramSigMaskX | DxilProgramSigMaskY | DxilProgramSigMaskZ;
+      return hlsl::DXIL::DxilProgramSigMaskX | hlsl::DXIL::DxilProgramSigMaskY |
+             hlsl::DXIL::DxilProgramSigMaskZ;
     default:
-      return DxilProgramSigMaskX | DxilProgramSigMaskY | DxilProgramSigMaskZ | DxilProgramSigMaskW;
+      return hlsl::DXIL::DxilProgramSigMaskX | hlsl::DXIL::DxilProgramSigMaskY |
+             hlsl::DXIL::DxilProgramSigMaskZ | hlsl::DXIL::DxilProgramSigMaskW;
     }
   }
   case 1: {
     switch (m_Cols) {
     case 1:
-      return DxilProgramSigMaskY;
+      return hlsl::DXIL::DxilProgramSigMaskY;
     case 2:
-      return DxilProgramSigMaskY | DxilProgramSigMaskZ;
+      return hlsl::DXIL::DxilProgramSigMaskY | hlsl::DXIL::DxilProgramSigMaskZ;
     default:
-      return DxilProgramSigMaskY | DxilProgramSigMaskZ | DxilProgramSigMaskW;
+      return hlsl::DXIL::DxilProgramSigMaskY | hlsl::DXIL::DxilProgramSigMaskZ |
+             hlsl::DXIL::DxilProgramSigMaskW;
     }
   }
-  case 2: return DxilProgramSigMaskZ | ((m_Cols == 1) ? 0 : DxilProgramSigMaskW);
+  case 2:
+    return hlsl::DXIL::DxilProgramSigMaskZ |
+           ((m_Cols == 1) ? 0 : hlsl::DXIL::DxilProgramSigMaskW);
   case 3:
   default:
-    return DxilProgramSigMaskW;
+    return hlsl::DXIL::DxilProgramSigMaskW;
   }
 }
 

+ 29 - 0
lib/DXIL/DxilUtil.cpp

@@ -471,3 +471,32 @@ bool IsSplat(llvm::ConstantDataVector *cdv) {
 
 }
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace {
+class DxilLoadMetadata : public ModulePass {
+public:
+  static char ID; // Pass identification, replacement for typeid
+  explicit DxilLoadMetadata () : ModulePass(ID) {}
+
+  const char *getPassName() const override { return "HLSL load DxilModule from metadata"; }
+
+  bool runOnModule(Module &M) override {
+    if (!M.HasDxilModule()) {
+      (void)M.GetOrCreateDxilModule();
+      return true;
+    }
+
+    return false;
+  }
+};
+}
+
+char DxilLoadMetadata::ID = 0;
+
+ModulePass *llvm::createDxilLoadMetadataPass() {
+  return new DxilLoadMetadata();
+}
+
+INITIALIZE_PASS(DxilLoadMetadata, "hlsl-dxilload", "HLSL load DxilModule from metadata", false, false)

+ 11 - 0
lib/DxilContainer/CMakeLists.txt

@@ -0,0 +1,11 @@
+# Copyright (C) Microsoft Corporation. All rights reserved.
+# This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details.
+add_llvm_library(LLVMDxilContainer
+  DxilContainer.cpp
+  DxilContainerAssembler.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR
+)
+
+add_dependencies(LLVMDxilContainer intrinsics_gen)

+ 1 - 1
lib/DXIL/DxilContainer.cpp → lib/DxilContainer/DxilContainer.cpp

@@ -9,7 +9,7 @@
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include <algorithm>
 
 namespace hlsl {

+ 23 - 4
lib/HLSL/DxilContainerAssembler.cpp → lib/DxilContainer/DxilContainerAssembler.cpp

@@ -16,10 +16,11 @@
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/Support/MD5.h"
 #include "llvm/ADT/STLExtras.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DXIL/DxilShaderModel.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
+#include "dxc/DxilContainer/DxilContainerAssembler.h"
 #include "dxc/DXIL/DxilUtil.h"
 #include "dxc/DXIL/DxilFunctionProps.h"
 #include "dxc/DXIL/DxilOperations.h"
@@ -149,6 +150,7 @@ struct sort_sig {
   }
 };
 
+
 class DxilProgramSignatureWriter : public DxilPartWriter {
 private:
   const DxilSignature &m_signature;
@@ -1341,6 +1343,23 @@ static void WriteProgramPart(const ShaderModel *pModel,
   }
 }
 
+namespace {
+
+class RootSignatureWriter : public DxilPartWriter {
+private:
+  const std::vector<uint8_t> &m_Sig;
+
+public:
+  RootSignatureWriter(const std::vector<uint8_t> &S) : m_Sig(S) {}
+  uint32_t size() const { return m_Sig.size(); }
+  void write(AbstractMemoryStream *pStream) {
+    ULONG cbWritten;
+    IFT(pStream->Write(m_Sig.data(), size(), &cbWritten));
+  }
+};
+
+} // namespace
+
 void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
                                            AbstractMemoryStream *pModuleBitcode,
                                            AbstractMemoryStream *pFinalStream,
@@ -1419,9 +1438,9 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
         [&](AbstractMemoryStream *pStream) { pPSVWriter->write(pStream); });
   }
   // Write the root signature (RTS0) part.
-  DxilProgramRootSignatureWriter rootSigWriter(pModule->GetRootSignature());
+  RootSignatureWriter rootSigWriter(pModule->GetSerializedRootSignature());
   CComPtr<AbstractMemoryStream> pInputProgramStream = pModuleBitcode;
-  if (!pModule->GetRootSignature().IsEmpty()) {
+  if (!pModule->GetSerializedRootSignature().empty()) {
     writer.AddPart(
         DFCC_RootSignature, rootSigWriter.size(),
         [&](AbstractMemoryStream *pStream) { rootSigWriter.write(pStream); });

+ 16 - 0
lib/DxilContainer/LLVMBuild.txt

@@ -0,0 +1,16 @@
+; Copyright (C) Microsoft Corporation. All rights reserved.
+; This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details.
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = DxilContainer
+parent = Libraries
+required_libraries = BitReader Core DxcSupport IPA Support

+ 14 - 0
lib/DxilRootSignature/CMakeLists.txt

@@ -0,0 +1,14 @@
+# Copyright (C) Microsoft Corporation. All rights reserved.
+# This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details.
+add_llvm_library(LLVMDxilRootSignature
+  DxilRootSignature.cpp
+  DxilRootSignatureConvert.cpp
+  DxilRootSignatureSerializer.cpp
+  DxilRootSignatureValidator.cpp
+
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR
+)
+
+add_dependencies(LLVMDxilRootSignature intrinsics_gen)

+ 194 - 0
lib/DxilRootSignature/DxilRootSignature.cpp

@@ -0,0 +1,194 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilRootSignature.cpp                                                     //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Provides support for manipulating root signature structures.              //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "dxc/DXIL/DxilConstants.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
+#include "dxc/HLSL/DxilPipelineStateValidation.h"
+#include "dxc/Support/Global.h"
+#include "dxc/Support/WinIncludes.h"
+#include "dxc/Support/WinFunctions.h"
+#include "dxc/Support/FileIOHelper.h"
+#include "dxc/dxcapi.h"
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+
+#include <string>
+#include <algorithm>
+#include <utility>
+#include <vector>
+#include <set>
+
+#include "DxilRootSignatureHelper.h"
+
+using namespace llvm;
+using std::string;
+
+namespace hlsl {
+
+//////////////////////////////////////////////////////////////////////////////
+// Root signature handler.
+
+RootSignatureHandle::RootSignatureHandle(RootSignatureHandle&& other) {
+  m_pDesc = nullptr;
+  m_pSerialized = nullptr;
+  std::swap(m_pDesc, other.m_pDesc);
+  std::swap(m_pSerialized, other.m_pSerialized);
+}
+
+void RootSignatureHandle::Assign(const DxilVersionedRootSignatureDesc *pDesc,
+                                 IDxcBlob *pSerialized) {
+  Clear();
+  m_pDesc = pDesc;
+  m_pSerialized = pSerialized;
+  if (m_pSerialized)
+    m_pSerialized->AddRef();
+}
+
+void RootSignatureHandle::Clear() {
+  hlsl::DeleteRootSignature(m_pDesc);
+  m_pDesc = nullptr;
+  if (m_pSerialized != nullptr) {
+    m_pSerialized->Release();
+    m_pSerialized = nullptr;
+  }
+}
+
+const uint8_t *RootSignatureHandle::GetSerializedBytes() const {
+  DXASSERT_NOMSG(m_pSerialized != nullptr);
+  return (uint8_t *)m_pSerialized->GetBufferPointer();
+}
+
+unsigned RootSignatureHandle::GetSerializedSize() const {
+  DXASSERT_NOMSG(m_pSerialized != nullptr);
+  return m_pSerialized->GetBufferSize();
+}
+
+void RootSignatureHandle::EnsureSerializedAvailable() {
+  DXASSERT_NOMSG(!IsEmpty());
+  if (m_pSerialized == nullptr) {
+    CComPtr<IDxcBlob> pResult;
+    hlsl::SerializeRootSignature(m_pDesc, &pResult, nullptr, false);
+    IFTBOOL(pResult != nullptr, E_FAIL);
+    m_pSerialized = pResult.Detach();
+  }
+}
+
+void RootSignatureHandle::Deserialize() {
+  DXASSERT_NOMSG(m_pSerialized && !m_pDesc);
+  DeserializeRootSignature((uint8_t*)m_pSerialized->GetBufferPointer(), (uint32_t)m_pSerialized->GetBufferSize(), &m_pDesc);
+}
+
+void RootSignatureHandle::LoadSerialized(const uint8_t *pData,
+                                         unsigned length) {
+  DXASSERT_NOMSG(IsEmpty());
+  IDxcBlobEncoding *pCreated;
+  IFT(DxcCreateBlobWithEncodingOnHeapCopy(pData, length, CP_UTF8, &pCreated));
+  m_pSerialized = pCreated;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace root_sig_helper {
+// GetFlags/SetFlags overloads.
+DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor &) {
+  // Upconvert root parameter flags to be volatile.
+  return DxilRootDescriptorFlags::DataVolatile;
+}
+void SetFlags(DxilRootDescriptor &, DxilRootDescriptorFlags) {
+  // Drop the flags; none existed in rs_1_0.
+}
+DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor1 &D) {
+  return D.Flags;
+}
+void SetFlags(DxilRootDescriptor1 &D, DxilRootDescriptorFlags Flags) {
+  D.Flags = Flags;
+}
+void SetFlags(DxilContainerRootDescriptor1 &D, DxilRootDescriptorFlags Flags) {
+  D.Flags = (uint32_t)Flags;
+}
+DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange &D) {
+  // Upconvert range flags to be volatile.
+  DxilDescriptorRangeFlags Flags =
+      DxilDescriptorRangeFlags::DescriptorsVolatile;
+
+  // Sampler does not have data.
+  if (D.RangeType != DxilDescriptorRangeType::Sampler)
+    Flags = (DxilDescriptorRangeFlags)(
+        (unsigned)Flags | (unsigned)DxilDescriptorRangeFlags::DataVolatile);
+
+  return Flags;
+}
+void SetFlags(DxilDescriptorRange &, DxilDescriptorRangeFlags) {}
+DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange &D) {
+  // Upconvert range flags to be volatile.
+  DxilDescriptorRangeFlags Flags =
+      DxilDescriptorRangeFlags::DescriptorsVolatile;
+
+  // Sampler does not have data.
+  if (D.RangeType != (uint32_t)DxilDescriptorRangeType::Sampler)
+    Flags |= DxilDescriptorRangeFlags::DataVolatile;
+
+  return Flags;
+}
+void SetFlags(DxilContainerDescriptorRange &, DxilDescriptorRangeFlags) {}
+DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange1 &D) {
+  return D.Flags;
+}
+void SetFlags(DxilDescriptorRange1 &D, DxilDescriptorRangeFlags Flags) {
+  D.Flags = Flags;
+}
+DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange1 &D) {
+  return (DxilDescriptorRangeFlags)D.Flags;
+}
+void SetFlags(DxilContainerDescriptorRange1 &D,
+              DxilDescriptorRangeFlags Flags) {
+  D.Flags = (uint32_t)Flags;
+}
+
+} // namespace root_sig_helper
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+void DeleteRootSignatureTemplate(const T &RS) {
+  for (unsigned i = 0; i < RS.NumParameters; i++) {
+    const auto &P = RS.pParameters[i];
+    if (P.ParameterType == DxilRootParameterType::DescriptorTable) {
+      delete[] P.DescriptorTable.pDescriptorRanges;
+    }
+  }
+
+  delete[] RS.pParameters;
+  delete[] RS.pStaticSamplers;
+}
+
+void DeleteRootSignature(const DxilVersionedRootSignatureDesc * pRootSignature)
+{
+  if (pRootSignature == nullptr)
+    return;
+
+  switch (pRootSignature->Version)
+  {
+  case DxilRootSignatureVersion::Version_1_0:
+    DeleteRootSignatureTemplate<DxilRootSignatureDesc>(pRootSignature->Desc_1_0);
+    break;
+  case DxilRootSignatureVersion::Version_1_1:
+  default:
+    DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else version is incorrect");
+    DeleteRootSignatureTemplate<DxilRootSignatureDesc1>(pRootSignature->Desc_1_1);
+    break;
+  }
+
+  delete pRootSignature;
+}
+
+} // namespace hlsl

+ 197 - 0
lib/DxilRootSignature/DxilRootSignatureConvert.cpp

@@ -0,0 +1,197 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilRootSignatureConvert.cpp                                              //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Convert root signature structures.                                        //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "dxc/DXIL/DxilConstants.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
+#include "dxc/HLSL/DxilPipelineStateValidation.h"
+#include "dxc/Support/Global.h"
+#include "dxc/Support/WinIncludes.h"
+#include "dxc/Support/WinFunctions.h"
+#include "dxc/Support/FileIOHelper.h"
+#include "dxc/dxcapi.h"
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+
+#include <string>
+#include <algorithm>
+#include <utility>
+#include <vector>
+#include <set>
+
+#include "DxilRootSignatureHelper.h"
+
+using namespace llvm;
+using std::string;
+
+namespace hlsl {
+
+using namespace root_sig_helper;
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+template<typename IN_DXIL_ROOT_SIGNATURE_DESC,
+  typename OUT_DXIL_ROOT_SIGNATURE_DESC,
+  typename OUT_DXIL_ROOT_PARAMETER,
+  typename OUT_DXIL_ROOT_DESCRIPTOR,
+  typename OUT_DXIL_DESCRIPTOR_RANGE>
+void ConvertRootSignatureTemplate(const IN_DXIL_ROOT_SIGNATURE_DESC &DescIn,
+                                  DxilRootSignatureVersion DescVersionOut,
+                                  OUT_DXIL_ROOT_SIGNATURE_DESC &DescOut)
+{
+  const IN_DXIL_ROOT_SIGNATURE_DESC *pDescIn = &DescIn;
+  OUT_DXIL_ROOT_SIGNATURE_DESC *pDescOut = &DescOut;
+
+  // Root signature descriptor.
+  pDescOut->Flags = pDescIn->Flags;
+  pDescOut->NumParameters = 0;
+  pDescOut->NumStaticSamplers = 0;
+  // Intialize all pointers early so that clean up works properly.
+  pDescOut->pParameters = nullptr;
+  pDescOut->pStaticSamplers = nullptr;
+
+  // Root signature parameters.
+  if (pDescIn->NumParameters > 0) {
+    pDescOut->pParameters = new OUT_DXIL_ROOT_PARAMETER[pDescIn->NumParameters];
+    pDescOut->NumParameters = pDescIn->NumParameters;
+    memset((void *)pDescOut->pParameters, 0, pDescOut->NumParameters*sizeof(OUT_DXIL_ROOT_PARAMETER));
+  }
+
+  for (unsigned iRP = 0; iRP < pDescIn->NumParameters; iRP++) {
+    const auto &ParamIn = pDescIn->pParameters[iRP];
+    OUT_DXIL_ROOT_PARAMETER &ParamOut = (OUT_DXIL_ROOT_PARAMETER &)pDescOut->pParameters[iRP];
+
+    ParamOut.ParameterType = ParamIn.ParameterType;
+    ParamOut.ShaderVisibility = ParamIn.ShaderVisibility;
+
+    switch (ParamIn.ParameterType) {
+    case DxilRootParameterType::DescriptorTable: {
+      ParamOut.DescriptorTable.pDescriptorRanges = nullptr;
+      unsigned NumRanges = ParamIn.DescriptorTable.NumDescriptorRanges;
+      if (NumRanges > 0) {
+        ParamOut.DescriptorTable.pDescriptorRanges = new OUT_DXIL_DESCRIPTOR_RANGE[NumRanges];
+        ParamOut.DescriptorTable.NumDescriptorRanges = NumRanges;
+      }
+
+      for (unsigned i = 0; i < NumRanges; i++) {
+        const auto &RangeIn = ParamIn.DescriptorTable.pDescriptorRanges[i];
+        OUT_DXIL_DESCRIPTOR_RANGE &RangeOut = (OUT_DXIL_DESCRIPTOR_RANGE &)ParamOut.DescriptorTable.pDescriptorRanges[i];
+
+        RangeOut.RangeType = RangeIn.RangeType;
+        RangeOut.NumDescriptors = RangeIn.NumDescriptors;
+        RangeOut.BaseShaderRegister = RangeIn.BaseShaderRegister;
+        RangeOut.RegisterSpace = RangeIn.RegisterSpace;
+        RangeOut.OffsetInDescriptorsFromTableStart = RangeIn.OffsetInDescriptorsFromTableStart;
+        DxilDescriptorRangeFlags Flags = GetFlags(RangeIn);
+        SetFlags(RangeOut, Flags);
+      }
+      break;
+    }
+    case DxilRootParameterType::Constants32Bit: {
+      ParamOut.Constants.Num32BitValues = ParamIn.Constants.Num32BitValues;
+      ParamOut.Constants.ShaderRegister = ParamIn.Constants.ShaderRegister;
+      ParamOut.Constants.RegisterSpace = ParamIn.Constants.RegisterSpace;
+      break;
+    }
+    case DxilRootParameterType::CBV:
+    case DxilRootParameterType::SRV:
+    case DxilRootParameterType::UAV: {
+      ParamOut.Descriptor.ShaderRegister = ParamIn.Descriptor.ShaderRegister;
+      ParamOut.Descriptor.RegisterSpace = ParamIn.Descriptor.RegisterSpace;
+      DxilRootDescriptorFlags Flags = GetFlags(ParamIn.Descriptor);
+      SetFlags(ParamOut.Descriptor, Flags);
+      break;
+    }
+    default:
+      IFT(E_FAIL);
+    }
+  }
+
+  // Static samplers.
+  if (pDescIn->NumStaticSamplers > 0) {
+    pDescOut->pStaticSamplers = new DxilStaticSamplerDesc[pDescIn->NumStaticSamplers];
+    pDescOut->NumStaticSamplers = pDescIn->NumStaticSamplers;
+    memcpy((void*)pDescOut->pStaticSamplers, pDescIn->pStaticSamplers, pDescOut->NumStaticSamplers*sizeof(DxilStaticSamplerDesc));
+  }
+}
+
+void ConvertRootSignature(const DxilVersionedRootSignatureDesc * pRootSignatureIn,
+                          DxilRootSignatureVersion RootSignatureVersionOut,
+                          const DxilVersionedRootSignatureDesc ** ppRootSignatureOut) {
+  IFTBOOL(pRootSignatureIn != nullptr && ppRootSignatureOut != nullptr, E_INVALIDARG);
+  *ppRootSignatureOut = nullptr;
+
+  if (pRootSignatureIn->Version == RootSignatureVersionOut){
+    // No conversion. Return the original root signature pointer; no cloning.
+    *ppRootSignatureOut = pRootSignatureIn;
+    return;
+  }
+
+  DxilVersionedRootSignatureDesc *pRootSignatureOut = nullptr;
+
+  try {
+    pRootSignatureOut = new DxilVersionedRootSignatureDesc();
+    memset(pRootSignatureOut, 0, sizeof(*pRootSignatureOut));
+
+    // Convert root signature.
+    switch (RootSignatureVersionOut) {
+    case DxilRootSignatureVersion::Version_1_0:
+      switch (pRootSignatureIn->Version) {
+      case DxilRootSignatureVersion::Version_1_1:
+        pRootSignatureOut->Version = DxilRootSignatureVersion::Version_1_0;
+        ConvertRootSignatureTemplate<
+          DxilRootSignatureDesc1,
+          DxilRootSignatureDesc,
+          DxilRootParameter,
+          DxilRootDescriptor,
+          DxilDescriptorRange>(pRootSignatureIn->Desc_1_1,
+            DxilRootSignatureVersion::Version_1_0,
+            pRootSignatureOut->Desc_1_0);
+        break;
+      default:
+        IFT(E_INVALIDARG);
+      }
+      break;
+
+    case DxilRootSignatureVersion::Version_1_1:
+      switch (pRootSignatureIn->Version) {
+      case DxilRootSignatureVersion::Version_1_0:
+        pRootSignatureOut->Version = DxilRootSignatureVersion::Version_1_1;
+        ConvertRootSignatureTemplate<
+          DxilRootSignatureDesc,
+          DxilRootSignatureDesc1,
+          DxilRootParameter1,
+          DxilRootDescriptor1,
+          DxilDescriptorRange1>(pRootSignatureIn->Desc_1_0,
+            DxilRootSignatureVersion::Version_1_1,
+            pRootSignatureOut->Desc_1_1);
+        break;
+      default:
+        IFT(E_INVALIDARG);
+      }
+      break;
+
+    default:
+      IFT(E_INVALIDARG);
+      break;
+    }
+  }
+  catch (...) {
+    DeleteRootSignature(pRootSignatureOut);
+    throw;
+  }
+
+  *ppRootSignatureOut = pRootSignatureOut;
+}
+
+
+} // namespace hlsl

+ 43 - 0
lib/DxilRootSignature/DxilRootSignatureHelper.h

@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilRootSignature.cpp                                                     //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Provides support for manipulating root signature structures.              //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include "dxc/Support/Global.h"
+
+namespace hlsl {
+
+DEFINE_ENUM_FLAG_OPERATORS(DxilRootSignatureFlags)
+DEFINE_ENUM_FLAG_OPERATORS(DxilRootDescriptorFlags)
+DEFINE_ENUM_FLAG_OPERATORS(DxilDescriptorRangeType)
+DEFINE_ENUM_FLAG_OPERATORS(DxilDescriptorRangeFlags)
+
+// Execute (error) and throw.
+#define EAT(x) { (x); throw ::hlsl::Exception(E_FAIL); }
+
+namespace root_sig_helper {
+// GetFlags/SetFlags overloads.
+DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor &);
+void SetFlags(DxilRootDescriptor &, DxilRootDescriptorFlags);
+DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor1 &D);
+void SetFlags(DxilRootDescriptor1 &D, DxilRootDescriptorFlags Flags);
+void SetFlags(DxilContainerRootDescriptor1 &D, DxilRootDescriptorFlags Flags);
+DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange &D);
+void SetFlags(DxilDescriptorRange &, DxilDescriptorRangeFlags);
+DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange &D);
+void SetFlags(DxilContainerDescriptorRange &, DxilDescriptorRangeFlags);
+DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange1 &D);
+void SetFlags(DxilDescriptorRange1 &D, DxilDescriptorRangeFlags Flags);
+DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange1 &D);
+void SetFlags(DxilContainerDescriptorRange1 &D, DxilDescriptorRangeFlags Flags);
+}
+
+}

+ 574 - 0
lib/DxilRootSignature/DxilRootSignatureSerializer.cpp

@@ -0,0 +1,574 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// DxilRootSignatureSerializer.cpp                                           //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Serializer for root signature structures.                                 //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "dxc/DXIL/DxilConstants.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
+#include "dxc/HLSL/DxilPipelineStateValidation.h"
+#include "dxc/Support/Global.h"
+#include "dxc/Support/WinIncludes.h"
+#include "dxc/Support/WinFunctions.h"
+#include "dxc/Support/FileIOHelper.h"
+#include "dxc/dxcapi.h"
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+
+#include <string>
+#include <algorithm>
+#include <utility>
+#include <vector>
+#include <set>
+
+#include "DxilRootSignatureHelper.h"
+
+using namespace llvm;
+using std::string;
+
+namespace hlsl {
+
+using namespace root_sig_helper;
+
+//////////////////////////////////////////////////////////////////////////////
+// Simple serializer.
+
+class SimpleSerializer {
+  struct Segment {
+    void *pData;
+    unsigned cbSize;
+    bool bOwner;
+    unsigned Offset;
+    Segment *pNext;
+  };
+
+public:
+  SimpleSerializer();
+  ~SimpleSerializer();
+
+  HRESULT AddBlock(void *pData, unsigned cbSize, unsigned *pOffset);
+  HRESULT ReserveBlock(void **ppData, unsigned cbSize, unsigned *pOffset);
+
+  HRESULT Compact(_Out_writes_bytes_(cbSize) char *pData, unsigned cbSize);
+  unsigned GetSize();
+
+protected:
+  unsigned m_cbSegments;
+  Segment *m_pSegment;
+  Segment **m_ppSegment;
+};
+
+SimpleSerializer::SimpleSerializer() {
+  m_cbSegments = 0;
+  m_pSegment = nullptr;
+  m_ppSegment = &m_pSegment;
+}
+
+SimpleSerializer::~SimpleSerializer() {
+  while (m_pSegment) {
+    Segment *pSegment = m_pSegment;
+    m_pSegment = pSegment->pNext;
+
+    if (pSegment->bOwner) {
+      delete[] (char*)pSegment->pData;
+    }
+
+    delete pSegment;
+  }
+}
+
+HRESULT SimpleSerializer::AddBlock(void *pData, unsigned cbSize,
+                                   unsigned *pOffset) {
+  Segment *pSegment = nullptr;
+  IFRBOOL(!(cbSize != 0 && pData == nullptr), E_FAIL);
+
+  IFROOM(pSegment = new (std::nothrow) Segment);
+  pSegment->pData = pData;
+
+  m_cbSegments = (m_cbSegments + 3) & ~3;
+  pSegment->Offset = m_cbSegments;
+  pSegment->cbSize = cbSize;
+  pSegment->bOwner = false;
+  pSegment->pNext = nullptr;
+
+  m_cbSegments += pSegment->cbSize;
+  *m_ppSegment = pSegment;
+  m_ppSegment = &pSegment->pNext;
+
+  if (pOffset != nullptr) {
+    *pOffset = pSegment->Offset;
+  }
+
+  return S_OK;
+}
+
+HRESULT SimpleSerializer::ReserveBlock(void **ppData, unsigned cbSize,
+                                       unsigned *pOffset) {
+  HRESULT hr = S_OK;
+  Segment *pSegment = nullptr;
+  void *pClonedData = nullptr;
+
+  IFCOOM(pSegment = new (std::nothrow) Segment);
+  pSegment->pData = nullptr;
+
+  IFCOOM(pClonedData = new (std::nothrow) char[cbSize]);
+  pSegment->pData = pClonedData;
+
+  m_cbSegments = (m_cbSegments + 3) & ~3;
+  pSegment->Offset = m_cbSegments;
+  pSegment->cbSize = cbSize;
+  pSegment->bOwner = true;
+  pSegment->pNext = nullptr;
+
+  m_cbSegments += pSegment->cbSize;
+  *m_ppSegment = pSegment;
+  m_ppSegment = &pSegment->pNext;
+
+  *ppData = pClonedData;
+  if (pOffset) {
+    *pOffset = pSegment->Offset;
+  }
+
+Cleanup:
+  if (FAILED(hr)) {
+    delete[] (char*)pClonedData;
+    delete pSegment;
+  }
+  return hr;
+}
+
+HRESULT SimpleSerializer::Compact(_Out_writes_bytes_(cbSize) char *pData,
+                                  unsigned cbSize) {
+  unsigned cb = GetSize();
+  IFRBOOL(cb <= cbSize, E_FAIL);
+  DXASSERT_NOMSG(cb <= UINT32_MAX / 2);
+
+  char *p = (char *)pData;
+  cb = 0;
+
+  for (Segment *pSegment = m_pSegment; pSegment; pSegment = pSegment->pNext) {
+    unsigned cbAlign = ((cb + 3) & ~3) - cb;
+
+    _Analysis_assume_(p + cbAlign <= pData + cbSize);
+    memset(p, 0xab, cbAlign);
+
+    p += cbAlign;
+    cb += cbAlign;
+
+    _Analysis_assume_(p + pSegment->cbSize <= pData + cbSize);
+    memcpy(p, pSegment->pData, pSegment->cbSize);
+
+    p += pSegment->cbSize;
+    cb += pSegment->cbSize;
+  }
+
+  // Trailing zeros
+  _Analysis_assume_(p + cbSize - cb <= pData + cbSize);
+  memset(p, 0xab, cbSize - cb);
+
+  return S_OK;
+}
+
+unsigned SimpleSerializer::GetSize() {
+  // Round up to 4==sizeof(unsigned).
+  return ((m_cbSegments + 3) >> 2) * 4;
+}
+
+template<typename T_ROOT_SIGNATURE_DESC,
+  typename T_ROOT_PARAMETER,
+  typename T_ROOT_DESCRIPTOR_INTERNAL,
+  typename T_DESCRIPTOR_RANGE_INTERNAL>
+void SerializeRootSignatureTemplate(_In_ const T_ROOT_SIGNATURE_DESC* pRootSignature,
+                                    DxilRootSignatureVersion DescVersion,
+                                    _COM_Outptr_ IDxcBlob** ppBlob,
+                                    DiagnosticPrinter &DiagPrinter,
+                                    _In_ bool bAllowReservedRegisterSpace) {
+  DxilContainerRootSignatureDesc RS;
+  uint32_t Offset;
+  SimpleSerializer Serializer;
+  IFT(Serializer.AddBlock(&RS, sizeof(RS), &Offset));
+  IFTBOOL(Offset == 0, E_FAIL);
+
+  const T_ROOT_SIGNATURE_DESC *pRS = pRootSignature;
+  RS.Version = (uint32_t)DescVersion;
+  RS.Flags = (uint32_t)pRS->Flags;
+  RS.NumParameters = pRS->NumParameters;
+  RS.NumStaticSamplers = pRS->NumStaticSamplers;
+
+  DxilContainerRootParameter *pRP;
+  IFT(Serializer.ReserveBlock((void**)&pRP,
+    sizeof(DxilContainerRootParameter)*RS.NumParameters, &RS.RootParametersOffset));
+
+  for (uint32_t iRP = 0; iRP < RS.NumParameters; iRP++) {
+    const T_ROOT_PARAMETER *pInRP = &pRS->pParameters[iRP];
+    DxilContainerRootParameter *pOutRP = &pRP[iRP];
+    pOutRP->ParameterType = (uint32_t)pInRP->ParameterType;
+    pOutRP->ShaderVisibility = (uint32_t)pInRP->ShaderVisibility;
+    switch (pInRP->ParameterType) {
+    case DxilRootParameterType::DescriptorTable: {
+      DxilContainerRootDescriptorTable *p1;
+      IFT(Serializer.ReserveBlock((void**)&p1,
+                                  sizeof(DxilContainerRootDescriptorTable),
+                                  &pOutRP->PayloadOffset));
+      p1->NumDescriptorRanges = pInRP->DescriptorTable.NumDescriptorRanges;
+
+      T_DESCRIPTOR_RANGE_INTERNAL *p2;
+      IFT(Serializer.ReserveBlock((void**)&p2,
+                                  sizeof(T_DESCRIPTOR_RANGE_INTERNAL)*p1->NumDescriptorRanges,
+                                  &p1->DescriptorRangesOffset));
+
+      for (uint32_t i = 0; i < p1->NumDescriptorRanges; i++) {
+        p2[i].RangeType = (uint32_t)pInRP->DescriptorTable.pDescriptorRanges[i].RangeType;
+        p2[i].NumDescriptors = pInRP->DescriptorTable.pDescriptorRanges[i].NumDescriptors;
+        p2[i].BaseShaderRegister = pInRP->DescriptorTable.pDescriptorRanges[i].BaseShaderRegister;
+        p2[i].RegisterSpace = pInRP->DescriptorTable.pDescriptorRanges[i].RegisterSpace;
+        p2[i].OffsetInDescriptorsFromTableStart = pInRP->DescriptorTable.pDescriptorRanges[i].OffsetInDescriptorsFromTableStart;
+        DxilDescriptorRangeFlags Flags = GetFlags(pInRP->DescriptorTable.pDescriptorRanges[i]);
+        SetFlags(p2[i], Flags);
+      }
+      break;
+    }
+    case DxilRootParameterType::Constants32Bit: {
+      DxilRootConstants *p;
+      IFT(Serializer.ReserveBlock((void**)&p, sizeof(DxilRootConstants), &pOutRP->PayloadOffset));
+      p->Num32BitValues = pInRP->Constants.Num32BitValues;
+      p->ShaderRegister = pInRP->Constants.ShaderRegister;
+      p->RegisterSpace = pInRP->Constants.RegisterSpace;
+      break;
+    }
+    case DxilRootParameterType::CBV:
+    case DxilRootParameterType::SRV:
+    case DxilRootParameterType::UAV: {
+      T_ROOT_DESCRIPTOR_INTERNAL *p;
+      IFT(Serializer.ReserveBlock((void**)&p, sizeof(T_ROOT_DESCRIPTOR_INTERNAL), &pOutRP->PayloadOffset));
+      p->ShaderRegister = pInRP->Descriptor.ShaderRegister;
+      p->RegisterSpace = pInRP->Descriptor.RegisterSpace;
+      DxilRootDescriptorFlags Flags = GetFlags(pInRP->Descriptor);
+      SetFlags(*p, Flags);
+      break;
+    }
+    default:
+      EAT(DiagPrinter << "D3DSerializeRootSignature: unknown root parameter type ("
+                      << (uint32_t)pInRP->ParameterType << ")\n");
+    }
+  }
+
+  DxilStaticSamplerDesc *pSS;
+  unsigned StaticSamplerSize = sizeof(DxilStaticSamplerDesc)*RS.NumStaticSamplers;
+  IFT(Serializer.ReserveBlock((void**)&pSS, StaticSamplerSize, &RS.StaticSamplersOffset));
+  memcpy(pSS, pRS->pStaticSamplers, StaticSamplerSize);
+
+  // Create the result blob.
+  CDxcMallocHeapPtr<char> bytes(DxcGetThreadMallocNoRef());
+  CComPtr<IDxcBlob> pBlob;
+  unsigned cb = Serializer.GetSize();
+  DXASSERT_NOMSG((cb & 0x3) == 0);
+  IFTBOOL(bytes.Allocate(cb), E_OUTOFMEMORY);
+  IFT(Serializer.Compact(bytes.m_pData, cb));
+  IFT(DxcCreateBlobOnHeap(bytes.m_pData, cb, ppBlob));
+  bytes.Detach(); // Ownership transfered to ppBlob.
+}
+
+_Use_decl_annotations_
+void SerializeRootSignature(const DxilVersionedRootSignatureDesc *pRootSignature,
+                            IDxcBlob **ppBlob, IDxcBlobEncoding **ppErrorBlob,
+                            bool bAllowReservedRegisterSpace) {
+  DXASSERT_NOMSG(pRootSignature != nullptr);
+  DXASSERT_NOMSG(ppBlob != nullptr);
+  DXASSERT_NOMSG(ppErrorBlob != nullptr);
+
+  *ppBlob = nullptr;
+  *ppErrorBlob = nullptr;
+
+  // TODO: change SerializeRootSignature to take raw_ostream&
+  string DiagString;
+  raw_string_ostream DiagStream(DiagString);
+  DiagnosticPrinterRawOStream DiagPrinter(DiagStream);
+
+  // Verify root signature.
+  if (!VerifyRootSignature(pRootSignature, DiagStream,
+                           bAllowReservedRegisterSpace)) {
+    DiagStream.flush();
+    DxcCreateBlobWithEncodingOnHeapCopy(DiagString.c_str(), DiagString.size(), CP_UTF8, ppErrorBlob);
+    return;
+  }
+
+  try {
+    switch (pRootSignature->Version)
+    {
+    case DxilRootSignatureVersion::Version_1_0:
+      SerializeRootSignatureTemplate<
+        DxilRootSignatureDesc,
+        DxilRootParameter,
+        DxilRootDescriptor,
+        DxilContainerDescriptorRange>(&pRootSignature->Desc_1_0,
+          DxilRootSignatureVersion::Version_1_0,
+          ppBlob, DiagPrinter,
+          bAllowReservedRegisterSpace);
+      break;
+
+    case DxilRootSignatureVersion::Version_1_1:
+    default:
+      DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else VerifyRootSignature didn't validate");
+      SerializeRootSignatureTemplate<
+        DxilRootSignatureDesc1,
+        DxilRootParameter1,
+        DxilContainerRootDescriptor1,
+        DxilContainerDescriptorRange1>(&pRootSignature->Desc_1_1,
+          DxilRootSignatureVersion::Version_1_1,
+          ppBlob, DiagPrinter,
+          bAllowReservedRegisterSpace);
+      break;
+    }
+  } catch (...) {
+    DiagStream.flush();
+    DxcCreateBlobWithEncodingOnHeapCopy(DiagString.c_str(), DiagString.size(), CP_UTF8, ppErrorBlob);
+  }
+}
+
+//=============================================================================
+//
+// CVersionedRootSignatureDeserializer.
+//
+//=============================================================================
+class CVersionedRootSignatureDeserializer {
+protected:
+  const DxilVersionedRootSignatureDesc *m_pRootSignature;
+  const DxilVersionedRootSignatureDesc *m_pRootSignature10;
+  const DxilVersionedRootSignatureDesc *m_pRootSignature11;
+
+public:
+  CVersionedRootSignatureDeserializer();
+  ~CVersionedRootSignatureDeserializer();
+
+  void Initialize(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
+                  _In_ uint32_t SrcDataSizeInBytes);
+
+  const DxilVersionedRootSignatureDesc *GetRootSignatureDescAtVersion(DxilRootSignatureVersion convertToVersion);
+
+  const DxilVersionedRootSignatureDesc *GetUnconvertedRootSignatureDesc();
+};
+
+CVersionedRootSignatureDeserializer::CVersionedRootSignatureDeserializer()
+  : m_pRootSignature(nullptr)
+  , m_pRootSignature10(nullptr)
+  , m_pRootSignature11(nullptr) {
+}
+
+CVersionedRootSignatureDeserializer::~CVersionedRootSignatureDeserializer() {
+  DeleteRootSignature(m_pRootSignature10);
+  DeleteRootSignature(m_pRootSignature11);
+}
+
+void CVersionedRootSignatureDeserializer::Initialize(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
+                                                     _In_ uint32_t SrcDataSizeInBytes) {
+  const DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
+  DeserializeRootSignature(pSrcData, SrcDataSizeInBytes, &pRootSignature);
+
+  switch (pRootSignature->Version) {
+  case DxilRootSignatureVersion::Version_1_0:
+    m_pRootSignature10 = pRootSignature;
+    break;
+
+  case DxilRootSignatureVersion::Version_1_1:
+    m_pRootSignature11 = pRootSignature;
+    break;
+
+  default:
+    DeleteRootSignature(pRootSignature);
+    return;
+  }
+
+  m_pRootSignature = pRootSignature;
+}
+
+const DxilVersionedRootSignatureDesc *
+CVersionedRootSignatureDeserializer::GetUnconvertedRootSignatureDesc() {
+  return m_pRootSignature;
+}
+
+const DxilVersionedRootSignatureDesc *
+CVersionedRootSignatureDeserializer::GetRootSignatureDescAtVersion(DxilRootSignatureVersion ConvertToVersion) {
+  switch (ConvertToVersion) {
+  case DxilRootSignatureVersion::Version_1_0:
+    if (m_pRootSignature10 == nullptr) {
+      ConvertRootSignature(m_pRootSignature,
+                           ConvertToVersion,
+                           (const DxilVersionedRootSignatureDesc **)&m_pRootSignature10);
+    }
+    return m_pRootSignature10;
+
+  case DxilRootSignatureVersion::Version_1_1:
+    if (m_pRootSignature11 == nullptr) {
+      ConvertRootSignature(m_pRootSignature,
+                           ConvertToVersion,
+                           (const DxilVersionedRootSignatureDesc **)&m_pRootSignature11);
+    }
+    return m_pRootSignature11;
+
+  default:
+    IFTBOOL(false, E_FAIL);
+  }
+
+  return nullptr;
+}
+
+template<typename T_ROOT_SIGNATURE_DESC,
+         typename T_ROOT_PARAMETER,
+         typename T_ROOT_DESCRIPTOR,
+         typename T_ROOT_DESCRIPTOR_INTERNAL,
+         typename T_DESCRIPTOR_RANGE,
+         typename T_DESCRIPTOR_RANGE_INTERNAL>
+void DeserializeRootSignatureTemplate(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
+                                      _In_ uint32_t SrcDataSizeInBytes,
+                                      DxilRootSignatureVersion DescVersion,
+                                      T_ROOT_SIGNATURE_DESC &RootSignatureDesc) {
+  // Note that in case of failure, outside code must deallocate memory.
+  T_ROOT_SIGNATURE_DESC *pRootSignature = &RootSignatureDesc;
+  const char *pData = (const char *)pSrcData;
+  const char *pMaxPtr = pData + SrcDataSizeInBytes;
+  UNREFERENCED_PARAMETER(DescVersion);
+  DXASSERT_NOMSG(((const uint32_t*)pData)[0] == (uint32_t)DescVersion);
+
+  // Root signature.
+  IFTBOOL(pData + sizeof(DxilContainerRootSignatureDesc) <= pMaxPtr, E_FAIL);
+  const DxilContainerRootSignatureDesc *pRS = (const DxilContainerRootSignatureDesc *)pData;
+  pRootSignature->Flags = (DxilRootSignatureFlags)pRS->Flags;
+  pRootSignature->NumParameters = pRS->NumParameters;
+  pRootSignature->NumStaticSamplers = pRS->NumStaticSamplers;
+  // Intialize all pointers early so that clean up works properly.
+  pRootSignature->pParameters = nullptr;
+  pRootSignature->pStaticSamplers = nullptr;
+
+  size_t s = sizeof(DxilContainerRootParameter)*pRS->NumParameters;
+  const DxilContainerRootParameter *pInRTS = (const DxilContainerRootParameter *)(pData + pRS->RootParametersOffset);
+  IFTBOOL(((const char*)pInRTS) + s <= pMaxPtr, E_FAIL);
+  if (pRootSignature->NumParameters) {
+    pRootSignature->pParameters = new T_ROOT_PARAMETER[pRootSignature->NumParameters];
+  }
+  memset((void *)pRootSignature->pParameters, 0, s);
+
+  for(unsigned iRP = 0; iRP < pRootSignature->NumParameters; iRP++) {
+    DxilRootParameterType ParameterType = (DxilRootParameterType)pInRTS[iRP].ParameterType;
+    T_ROOT_PARAMETER *pOutRTS = (T_ROOT_PARAMETER *)&pRootSignature->pParameters[iRP];
+    pOutRTS->ParameterType = ParameterType;
+    pOutRTS->ShaderVisibility = (DxilShaderVisibility)pInRTS[iRP].ShaderVisibility;
+    switch(ParameterType) {
+    case DxilRootParameterType::DescriptorTable: {
+      const DxilContainerRootDescriptorTable *p1 = (const DxilContainerRootDescriptorTable*)(pData + pInRTS[iRP].PayloadOffset);
+      IFTBOOL((const char*)p1 + sizeof(DxilContainerRootDescriptorTable) <= pMaxPtr, E_FAIL);
+      pOutRTS->DescriptorTable.NumDescriptorRanges = p1->NumDescriptorRanges;
+      pOutRTS->DescriptorTable.pDescriptorRanges = nullptr;
+      const T_DESCRIPTOR_RANGE_INTERNAL *p2 = (const T_DESCRIPTOR_RANGE_INTERNAL*)(pData + p1->DescriptorRangesOffset);
+      IFTBOOL((const char*)p2 + sizeof(T_DESCRIPTOR_RANGE_INTERNAL) <= pMaxPtr, E_FAIL);
+      if (p1->NumDescriptorRanges) {
+        pOutRTS->DescriptorTable.pDescriptorRanges = new T_DESCRIPTOR_RANGE[p1->NumDescriptorRanges];
+      }
+      for (unsigned i = 0; i < p1->NumDescriptorRanges; i++) {
+        T_DESCRIPTOR_RANGE *p3 = (T_DESCRIPTOR_RANGE *)&pOutRTS->DescriptorTable.pDescriptorRanges[i];
+        p3->RangeType                         = (DxilDescriptorRangeType)p2[i].RangeType;
+        p3->NumDescriptors                    = p2[i].NumDescriptors;
+        p3->BaseShaderRegister                = p2[i].BaseShaderRegister;
+        p3->RegisterSpace                     = p2[i].RegisterSpace;
+        p3->OffsetInDescriptorsFromTableStart = p2[i].OffsetInDescriptorsFromTableStart;
+        DxilDescriptorRangeFlags Flags = GetFlags(p2[i]);
+        SetFlags(*p3, Flags);
+      }
+      break;
+    }
+    case DxilRootParameterType::Constants32Bit: {
+      const DxilRootConstants *p = (const DxilRootConstants*)(pData + pInRTS[iRP].PayloadOffset);
+      IFTBOOL((const char*)p + sizeof(DxilRootConstants) <= pMaxPtr, E_FAIL);
+      pOutRTS->Constants.Num32BitValues = p->Num32BitValues;
+      pOutRTS->Constants.ShaderRegister = p->ShaderRegister;
+      pOutRTS->Constants.RegisterSpace  = p->RegisterSpace;
+      break;
+    }
+    case DxilRootParameterType::CBV:
+    case DxilRootParameterType::SRV:
+    case DxilRootParameterType::UAV: {
+      const T_ROOT_DESCRIPTOR *p = (const T_ROOT_DESCRIPTOR *)(pData + pInRTS[iRP].PayloadOffset);
+      IFTBOOL((const char*)p + sizeof(T_ROOT_DESCRIPTOR) <= pMaxPtr, E_FAIL);
+      pOutRTS->Descriptor.ShaderRegister = p->ShaderRegister;
+      pOutRTS->Descriptor.RegisterSpace  = p->RegisterSpace;
+      DxilRootDescriptorFlags Flags = GetFlags(*p);
+      SetFlags(pOutRTS->Descriptor, Flags);
+      break;
+    }
+    default:
+      IFT(E_FAIL);
+    }
+  }
+
+  s = sizeof(DxilStaticSamplerDesc)*pRS->NumStaticSamplers;
+  const DxilStaticSamplerDesc *pInSS = (const DxilStaticSamplerDesc *)(pData + pRS->StaticSamplersOffset);
+  IFTBOOL(((const char*)pInSS) + s <= pMaxPtr, E_FAIL);
+  if (pRootSignature->NumStaticSamplers) {
+    pRootSignature->pStaticSamplers = new DxilStaticSamplerDesc[pRootSignature->NumStaticSamplers];
+  }
+  memcpy((void*)pRootSignature->pStaticSamplers, pInSS, s);
+}
+
+_Use_decl_annotations_
+void DeserializeRootSignature(const void *pSrcData,
+                              uint32_t SrcDataSizeInBytes,
+                              const DxilVersionedRootSignatureDesc **ppRootSignature) {
+  DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
+  IFTBOOL(pSrcData != nullptr && SrcDataSizeInBytes != 0 && ppRootSignature != nullptr, E_INVALIDARG);
+  IFTBOOL(*ppRootSignature == nullptr, E_INVALIDARG);
+  const char *pData = (const char *)pSrcData;
+  IFTBOOL(pData + sizeof(uint32_t) < pData + SrcDataSizeInBytes, E_FAIL);
+
+  DxilRootSignatureVersion Version = (const DxilRootSignatureVersion)((const uint32_t*)pData)[0];
+
+  pRootSignature = new DxilVersionedRootSignatureDesc();
+
+  try {
+    switch (Version) {
+    case DxilRootSignatureVersion::Version_1_0:
+      pRootSignature->Version = DxilRootSignatureVersion::Version_1_0;
+      DeserializeRootSignatureTemplate<
+         DxilRootSignatureDesc,
+         DxilRootParameter,
+         DxilRootDescriptor,
+         DxilRootDescriptor,
+         DxilDescriptorRange,
+         DxilContainerDescriptorRange>(pSrcData,
+                                       SrcDataSizeInBytes,
+                                       DxilRootSignatureVersion::Version_1_0,
+                                       pRootSignature->Desc_1_0);
+      break;
+
+    case DxilRootSignatureVersion::Version_1_1:
+      pRootSignature->Version = DxilRootSignatureVersion::Version_1_1;
+      DeserializeRootSignatureTemplate<
+         DxilRootSignatureDesc1,
+         DxilRootParameter1,
+         DxilRootDescriptor1,
+         DxilContainerRootDescriptor1,
+         DxilDescriptorRange1,
+         DxilContainerDescriptorRange1>(pSrcData,
+                                        SrcDataSizeInBytes,
+                                        DxilRootSignatureVersion::Version_1_1,
+                                        pRootSignature->Desc_1_1);
+      break;
+
+    default:
+      IFT(E_FAIL);
+      break;
+    }
+  } catch(...) {
+    DeleteRootSignature(pRootSignature);
+    throw;
+  }
+
+  *ppRootSignature = pRootSignature;
+}
+
+} // namespace hlsl

+ 7 - 857
lib/HLSL/DxilRootSignature.cpp → lib/DxilRootSignature/DxilRootSignatureValidator.cpp

@@ -10,7 +10,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "dxc/DXIL/DxilConstants.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include "dxc/HLSL/DxilPipelineStateValidation.h"
 #include "dxc/Support/Global.h"
 #include "dxc/Support/WinIncludes.h"
@@ -27,223 +27,14 @@
 #include <vector>
 #include <set>
 
+#include "DxilRootSignatureHelper.h"
+
 using namespace llvm;
 using std::string;
 
 namespace hlsl {
 
-DEFINE_ENUM_FLAG_OPERATORS(DxilRootSignatureFlags)
-DEFINE_ENUM_FLAG_OPERATORS(DxilRootDescriptorFlags)
-DEFINE_ENUM_FLAG_OPERATORS(DxilDescriptorRangeType)
-DEFINE_ENUM_FLAG_OPERATORS(DxilDescriptorRangeFlags)
-
-// Execute (error) and throw.
-#define EAT(x) { (x); throw ::hlsl::Exception(E_FAIL); }
-
-//////////////////////////////////////////////////////////////////////////////
-// Root signature handler.
-
-RootSignatureHandle::RootSignatureHandle(RootSignatureHandle&& other) {
-  m_pDesc = nullptr;
-  m_pSerialized = nullptr;
-  std::swap(m_pDesc, other.m_pDesc);
-  std::swap(m_pSerialized, other.m_pSerialized);
-}
-
-void RootSignatureHandle::Assign(const DxilVersionedRootSignatureDesc *pDesc,
-                                 IDxcBlob *pSerialized) {
-  Clear();
-  m_pDesc = pDesc;
-  m_pSerialized = pSerialized;
-  if (m_pSerialized)
-    m_pSerialized->AddRef();
-}
-
-void RootSignatureHandle::Clear() {
-  hlsl::DeleteRootSignature(m_pDesc);
-  m_pDesc = nullptr;
-  if (m_pSerialized != nullptr) {
-    m_pSerialized->Release();
-    m_pSerialized = nullptr;
-  }
-}
-
-const uint8_t *RootSignatureHandle::GetSerializedBytes() const {
-  DXASSERT_NOMSG(m_pSerialized != nullptr);
-  return (uint8_t *)m_pSerialized->GetBufferPointer();
-}
-
-unsigned RootSignatureHandle::GetSerializedSize() const {
-  DXASSERT_NOMSG(m_pSerialized != nullptr);
-  return m_pSerialized->GetBufferSize();
-}
-
-void RootSignatureHandle::EnsureSerializedAvailable() {
-  DXASSERT_NOMSG(!IsEmpty());
-  if (m_pSerialized == nullptr) {
-    CComPtr<IDxcBlob> pResult;
-    hlsl::SerializeRootSignature(m_pDesc, &pResult, nullptr, false);
-    IFTBOOL(pResult != nullptr, E_FAIL);
-    m_pSerialized = pResult.Detach();
-  }
-}
-
-void RootSignatureHandle::Deserialize() {
-  DXASSERT_NOMSG(m_pSerialized && !m_pDesc);
-  DeserializeRootSignature((uint8_t*)m_pSerialized->GetBufferPointer(), (uint32_t)m_pSerialized->GetBufferSize(), &m_pDesc);
-}
-
-void RootSignatureHandle::LoadSerialized(const uint8_t *pData,
-                                         unsigned length) {
-  DXASSERT_NOMSG(IsEmpty());
-  IDxcBlobEncoding *pCreated;
-  IFT(DxcCreateBlobWithEncodingOnHeapCopy(pData, length, CP_UTF8, &pCreated));
-  m_pSerialized = pCreated;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Simple serializer.
-
-class SimpleSerializer {
-  struct Segment {
-    void *pData;
-    unsigned cbSize;
-    bool bOwner;
-    unsigned Offset;
-    Segment *pNext;
-  };
-
-public:
-  SimpleSerializer();
-  ~SimpleSerializer();
-
-  HRESULT AddBlock(void *pData, unsigned cbSize, unsigned *pOffset);
-  HRESULT ReserveBlock(void **ppData, unsigned cbSize, unsigned *pOffset);
-
-  HRESULT Compact(_Out_writes_bytes_(cbSize) char *pData, unsigned cbSize);
-  unsigned GetSize();
-
-protected:
-  unsigned m_cbSegments;
-  Segment *m_pSegment;
-  Segment **m_ppSegment;
-};
-
-SimpleSerializer::SimpleSerializer() {
-  m_cbSegments = 0;
-  m_pSegment = nullptr;
-  m_ppSegment = &m_pSegment;
-}
-
-SimpleSerializer::~SimpleSerializer() {
-  while (m_pSegment) {
-    Segment *pSegment = m_pSegment;
-    m_pSegment = pSegment->pNext;
-
-    if (pSegment->bOwner) {
-      delete[] (char*)pSegment->pData;
-    }
-
-    delete pSegment;
-  }
-}
-
-HRESULT SimpleSerializer::AddBlock(void *pData, unsigned cbSize,
-                                   unsigned *pOffset) {
-  Segment *pSegment = nullptr;
-  IFRBOOL(!(cbSize != 0 && pData == nullptr), E_FAIL);
-
-  IFROOM(pSegment = new (std::nothrow) Segment);
-  pSegment->pData = pData;
-
-  m_cbSegments = (m_cbSegments + 3) & ~3;
-  pSegment->Offset = m_cbSegments;
-  pSegment->cbSize = cbSize;
-  pSegment->bOwner = false;
-  pSegment->pNext = nullptr;
-
-  m_cbSegments += pSegment->cbSize;
-  *m_ppSegment = pSegment;
-  m_ppSegment = &pSegment->pNext;
-
-  if (pOffset != nullptr) {
-    *pOffset = pSegment->Offset;
-  }
-
-  return S_OK;
-}
-
-HRESULT SimpleSerializer::ReserveBlock(void **ppData, unsigned cbSize,
-                                       unsigned *pOffset) {
-  HRESULT hr = S_OK;
-  Segment *pSegment = nullptr;
-  void *pClonedData = nullptr;
-
-  IFCOOM(pSegment = new (std::nothrow) Segment);
-  pSegment->pData = nullptr;
-
-  IFCOOM(pClonedData = new (std::nothrow) char[cbSize]);
-  pSegment->pData = pClonedData;
-
-  m_cbSegments = (m_cbSegments + 3) & ~3;
-  pSegment->Offset = m_cbSegments;
-  pSegment->cbSize = cbSize;
-  pSegment->bOwner = true;
-  pSegment->pNext = nullptr;
-
-  m_cbSegments += pSegment->cbSize;
-  *m_ppSegment = pSegment;
-  m_ppSegment = &pSegment->pNext;
-
-  *ppData = pClonedData;
-  if (pOffset) {
-    *pOffset = pSegment->Offset;
-  }
-
-Cleanup:
-  if (FAILED(hr)) {
-    delete[] (char*)pClonedData;
-    delete pSegment;
-  }
-  return hr;
-}
-
-HRESULT SimpleSerializer::Compact(_Out_writes_bytes_(cbSize) char *pData,
-                                  unsigned cbSize) {
-  unsigned cb = GetSize();
-  IFRBOOL(cb <= cbSize, E_FAIL);
-  DXASSERT_NOMSG(cb <= UINT32_MAX / 2);
-
-  char *p = (char *)pData;
-  cb = 0;
-
-  for (Segment *pSegment = m_pSegment; pSegment; pSegment = pSegment->pNext) {
-    unsigned cbAlign = ((cb + 3) & ~3) - cb;
-
-    _Analysis_assume_(p + cbAlign <= pData + cbSize);
-    memset(p, 0xab, cbAlign);
-
-    p += cbAlign;
-    cb += cbAlign;
-
-    _Analysis_assume_(p + pSegment->cbSize <= pData + cbSize);
-    memcpy(p, pSegment->pData, pSegment->cbSize);
-
-    p += pSegment->cbSize;
-    cb += pSegment->cbSize;
-  }
-
-  // Trailing zeros
-  _Analysis_assume_(p + cbSize - cb <= pData + cbSize);
-  memset(p, 0xab, cbSize - cb);
-
-  return S_OK;
-}
-
-unsigned SimpleSerializer::GetSize() {
-  // Round up to 4==sizeof(unsigned).
-  return ((m_cbSegments + 3) >> 2) * 4;
-}
+using namespace root_sig_helper;
 
 //////////////////////////////////////////////////////////////////////////////
 // Interval helper.
@@ -1007,649 +798,6 @@ void StaticSamplerVerifier::Verify(const DxilStaticSamplerDesc* pDesc,
   }
 }
 
-//////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-void DeleteRootSignatureTemplate(const T &RS) {
-  for (unsigned i = 0; i < RS.NumParameters; i++) {
-    const auto &P = RS.pParameters[i];
-    if (P.ParameterType == DxilRootParameterType::DescriptorTable) {
-      delete[] P.DescriptorTable.pDescriptorRanges;
-    }
-  }
-
-  delete[] RS.pParameters;
-  delete[] RS.pStaticSamplers;
-}
-
-void DeleteRootSignature(const DxilVersionedRootSignatureDesc * pRootSignature)
-{
-  if (pRootSignature == nullptr)
-    return;
-
-  switch (pRootSignature->Version)
-  {
-  case DxilRootSignatureVersion::Version_1_0:
-    DeleteRootSignatureTemplate<DxilRootSignatureDesc>(pRootSignature->Desc_1_0);
-    break;
-  case DxilRootSignatureVersion::Version_1_1:
-  default:
-    DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else version is incorrect");
-    DeleteRootSignatureTemplate<DxilRootSignatureDesc1>(pRootSignature->Desc_1_1);
-    break;
-  }
-
-  delete pRootSignature;
-}
-
-// GetFlags/SetFlags overloads.
-static DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor &)
-{
-  // Upconvert root parameter flags to be volatile.
-  return DxilRootDescriptorFlags::DataVolatile;
-}
-static void SetFlags(DxilRootDescriptor &, DxilRootDescriptorFlags)
-{
-  // Drop the flags; none existed in rs_1_0.
-}
-static DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor1 &D)
-{
-  return D.Flags;
-}
-static void SetFlags(DxilRootDescriptor1 &D, DxilRootDescriptorFlags Flags)
-{
-  D.Flags = Flags;
-}
-static void SetFlags(DxilContainerRootDescriptor1 &D, DxilRootDescriptorFlags Flags)
-{
-  D.Flags = (uint32_t)Flags;
-}
-static DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange &D)
-{
-  // Upconvert range flags to be volatile.
-  DxilDescriptorRangeFlags Flags = DxilDescriptorRangeFlags::DescriptorsVolatile;
-
-  // Sampler does not have data.
-  if (D.RangeType != DxilDescriptorRangeType::Sampler)
-    Flags = (DxilDescriptorRangeFlags)((unsigned)Flags | (unsigned)DxilDescriptorRangeFlags::DataVolatile);
-
-  return Flags;
-}
-static void SetFlags(DxilDescriptorRange &, DxilDescriptorRangeFlags)
-{
-}
-static DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange &D)
-{
-  // Upconvert range flags to be volatile.
-  DxilDescriptorRangeFlags Flags = DxilDescriptorRangeFlags::DescriptorsVolatile;
-
-  // Sampler does not have data.
-  if (D.RangeType != (uint32_t)DxilDescriptorRangeType::Sampler)
-    Flags |= DxilDescriptorRangeFlags::DataVolatile;
-
-  return Flags;
-}
-static void SetFlags(DxilContainerDescriptorRange &, DxilDescriptorRangeFlags)
-{
-}
-static DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange1 &D)
-{
-  return D.Flags;
-}
-static void SetFlags(DxilDescriptorRange1 &D, DxilDescriptorRangeFlags Flags)
-{
-  D.Flags = Flags;
-}
-static DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange1 &D)
-{
-  return (DxilDescriptorRangeFlags)D.Flags;
-}
-static void SetFlags(DxilContainerDescriptorRange1 &D, DxilDescriptorRangeFlags Flags)
-{
-  D.Flags = (uint32_t)Flags;
-}
-
-template<typename IN_DXIL_ROOT_SIGNATURE_DESC,
-  typename OUT_DXIL_ROOT_SIGNATURE_DESC,
-  typename OUT_DXIL_ROOT_PARAMETER,
-  typename OUT_DXIL_ROOT_DESCRIPTOR,
-  typename OUT_DXIL_DESCRIPTOR_RANGE>
-void ConvertRootSignatureTemplate(const IN_DXIL_ROOT_SIGNATURE_DESC &DescIn,
-                                  DxilRootSignatureVersion DescVersionOut,
-                                  OUT_DXIL_ROOT_SIGNATURE_DESC &DescOut)
-{
-  const IN_DXIL_ROOT_SIGNATURE_DESC *pDescIn = &DescIn;
-  OUT_DXIL_ROOT_SIGNATURE_DESC *pDescOut = &DescOut;
-
-  // Root signature descriptor.
-  pDescOut->Flags = pDescIn->Flags;
-  pDescOut->NumParameters = 0;
-  pDescOut->NumStaticSamplers = 0;
-  // Intialize all pointers early so that clean up works properly.
-  pDescOut->pParameters = nullptr;
-  pDescOut->pStaticSamplers = nullptr;
-
-  // Root signature parameters.
-  if (pDescIn->NumParameters > 0) {
-    pDescOut->pParameters = new OUT_DXIL_ROOT_PARAMETER[pDescIn->NumParameters];
-    pDescOut->NumParameters = pDescIn->NumParameters;
-    memset((void *)pDescOut->pParameters, 0, pDescOut->NumParameters*sizeof(OUT_DXIL_ROOT_PARAMETER));
-  }
-
-  for (unsigned iRP = 0; iRP < pDescIn->NumParameters; iRP++) {
-    const auto &ParamIn = pDescIn->pParameters[iRP];
-    OUT_DXIL_ROOT_PARAMETER &ParamOut = (OUT_DXIL_ROOT_PARAMETER &)pDescOut->pParameters[iRP];
-
-    ParamOut.ParameterType = ParamIn.ParameterType;
-    ParamOut.ShaderVisibility = ParamIn.ShaderVisibility;
-
-    switch (ParamIn.ParameterType) {
-    case DxilRootParameterType::DescriptorTable: {
-      ParamOut.DescriptorTable.pDescriptorRanges = nullptr;
-      unsigned NumRanges = ParamIn.DescriptorTable.NumDescriptorRanges;
-      if (NumRanges > 0) {
-        ParamOut.DescriptorTable.pDescriptorRanges = new OUT_DXIL_DESCRIPTOR_RANGE[NumRanges];
-        ParamOut.DescriptorTable.NumDescriptorRanges = NumRanges;
-      }
-
-      for (unsigned i = 0; i < NumRanges; i++) {
-        const auto &RangeIn = ParamIn.DescriptorTable.pDescriptorRanges[i];
-        OUT_DXIL_DESCRIPTOR_RANGE &RangeOut = (OUT_DXIL_DESCRIPTOR_RANGE &)ParamOut.DescriptorTable.pDescriptorRanges[i];
-
-        RangeOut.RangeType = RangeIn.RangeType;
-        RangeOut.NumDescriptors = RangeIn.NumDescriptors;
-        RangeOut.BaseShaderRegister = RangeIn.BaseShaderRegister;
-        RangeOut.RegisterSpace = RangeIn.RegisterSpace;
-        RangeOut.OffsetInDescriptorsFromTableStart = RangeIn.OffsetInDescriptorsFromTableStart;
-        DxilDescriptorRangeFlags Flags = GetFlags(RangeIn);
-        SetFlags(RangeOut, Flags);
-      }
-      break;
-    }
-    case DxilRootParameterType::Constants32Bit: {
-      ParamOut.Constants.Num32BitValues = ParamIn.Constants.Num32BitValues;
-      ParamOut.Constants.ShaderRegister = ParamIn.Constants.ShaderRegister;
-      ParamOut.Constants.RegisterSpace = ParamIn.Constants.RegisterSpace;
-      break;
-    }
-    case DxilRootParameterType::CBV:
-    case DxilRootParameterType::SRV:
-    case DxilRootParameterType::UAV: {
-      ParamOut.Descriptor.ShaderRegister = ParamIn.Descriptor.ShaderRegister;
-      ParamOut.Descriptor.RegisterSpace = ParamIn.Descriptor.RegisterSpace;
-      DxilRootDescriptorFlags Flags = GetFlags(ParamIn.Descriptor);
-      SetFlags(ParamOut.Descriptor, Flags);
-      break;
-    }
-    default:
-      IFT(E_FAIL);
-    }
-  }
-
-  // Static samplers.
-  if (pDescIn->NumStaticSamplers > 0) {
-    pDescOut->pStaticSamplers = new DxilStaticSamplerDesc[pDescIn->NumStaticSamplers];
-    pDescOut->NumStaticSamplers = pDescIn->NumStaticSamplers;
-    memcpy((void*)pDescOut->pStaticSamplers, pDescIn->pStaticSamplers, pDescOut->NumStaticSamplers*sizeof(DxilStaticSamplerDesc));
-  }
-}
-
-void ConvertRootSignature(const DxilVersionedRootSignatureDesc * pRootSignatureIn,
-                          DxilRootSignatureVersion RootSignatureVersionOut,
-                          const DxilVersionedRootSignatureDesc ** ppRootSignatureOut) {
-  IFTBOOL(pRootSignatureIn != nullptr && ppRootSignatureOut != nullptr, E_INVALIDARG);
-  *ppRootSignatureOut = nullptr;
-
-  if (pRootSignatureIn->Version == RootSignatureVersionOut){
-    // No conversion. Return the original root signature pointer; no cloning.
-    *ppRootSignatureOut = pRootSignatureIn;
-    return;
-  }
-
-  DxilVersionedRootSignatureDesc *pRootSignatureOut = nullptr;
-
-  try {
-    pRootSignatureOut = new DxilVersionedRootSignatureDesc();
-    memset(pRootSignatureOut, 0, sizeof(*pRootSignatureOut));
-
-    // Convert root signature.
-    switch (RootSignatureVersionOut) {
-    case DxilRootSignatureVersion::Version_1_0:
-      switch (pRootSignatureIn->Version) {
-      case DxilRootSignatureVersion::Version_1_1:
-        pRootSignatureOut->Version = DxilRootSignatureVersion::Version_1_0;
-        ConvertRootSignatureTemplate<
-          DxilRootSignatureDesc1,
-          DxilRootSignatureDesc,
-          DxilRootParameter,
-          DxilRootDescriptor,
-          DxilDescriptorRange>(pRootSignatureIn->Desc_1_1,
-            DxilRootSignatureVersion::Version_1_0,
-            pRootSignatureOut->Desc_1_0);
-        break;
-      default:
-        IFT(E_INVALIDARG);
-      }
-      break;
-
-    case DxilRootSignatureVersion::Version_1_1:
-      switch (pRootSignatureIn->Version) {
-      case DxilRootSignatureVersion::Version_1_0:
-        pRootSignatureOut->Version = DxilRootSignatureVersion::Version_1_1;
-        ConvertRootSignatureTemplate<
-          DxilRootSignatureDesc,
-          DxilRootSignatureDesc1,
-          DxilRootParameter1,
-          DxilRootDescriptor1,
-          DxilDescriptorRange1>(pRootSignatureIn->Desc_1_0,
-            DxilRootSignatureVersion::Version_1_1,
-            pRootSignatureOut->Desc_1_1);
-        break;
-      default:
-        IFT(E_INVALIDARG);
-      }
-      break;
-
-    default:
-      IFT(E_INVALIDARG);
-      break;
-    }
-  }
-  catch (...) {
-    DeleteRootSignature(pRootSignatureOut);
-    throw;
-  }
-
-  *ppRootSignatureOut = pRootSignatureOut;
-}
-
-template<typename T_ROOT_SIGNATURE_DESC,
-  typename T_ROOT_PARAMETER,
-  typename T_ROOT_DESCRIPTOR_INTERNAL,
-  typename T_DESCRIPTOR_RANGE_INTERNAL>
-void SerializeRootSignatureTemplate(_In_ const T_ROOT_SIGNATURE_DESC* pRootSignature,
-                                    DxilRootSignatureVersion DescVersion,
-                                    _COM_Outptr_ IDxcBlob** ppBlob,
-                                    DiagnosticPrinter &DiagPrinter,
-                                    _In_ bool bAllowReservedRegisterSpace) {
-  DxilContainerRootSignatureDesc RS;
-  uint32_t Offset;
-  SimpleSerializer Serializer;
-  IFT(Serializer.AddBlock(&RS, sizeof(RS), &Offset));
-  IFTBOOL(Offset == 0, E_FAIL);
-
-  const T_ROOT_SIGNATURE_DESC *pRS = pRootSignature;
-  RS.Version = (uint32_t)DescVersion;
-  RS.Flags = (uint32_t)pRS->Flags;
-  RS.NumParameters = pRS->NumParameters;
-  RS.NumStaticSamplers = pRS->NumStaticSamplers;
-
-  DxilContainerRootParameter *pRP;
-  IFT(Serializer.ReserveBlock((void**)&pRP,
-    sizeof(DxilContainerRootParameter)*RS.NumParameters, &RS.RootParametersOffset));
-
-  for (uint32_t iRP = 0; iRP < RS.NumParameters; iRP++) {
-    const T_ROOT_PARAMETER *pInRP = &pRS->pParameters[iRP];
-    DxilContainerRootParameter *pOutRP = &pRP[iRP];
-    pOutRP->ParameterType = (uint32_t)pInRP->ParameterType;
-    pOutRP->ShaderVisibility = (uint32_t)pInRP->ShaderVisibility;
-    switch (pInRP->ParameterType) {
-    case DxilRootParameterType::DescriptorTable: {
-      DxilContainerRootDescriptorTable *p1;
-      IFT(Serializer.ReserveBlock((void**)&p1,
-                                  sizeof(DxilContainerRootDescriptorTable),
-                                  &pOutRP->PayloadOffset));
-      p1->NumDescriptorRanges = pInRP->DescriptorTable.NumDescriptorRanges;
-
-      T_DESCRIPTOR_RANGE_INTERNAL *p2;
-      IFT(Serializer.ReserveBlock((void**)&p2,
-                                  sizeof(T_DESCRIPTOR_RANGE_INTERNAL)*p1->NumDescriptorRanges,
-                                  &p1->DescriptorRangesOffset));
-
-      for (uint32_t i = 0; i < p1->NumDescriptorRanges; i++) {
-        p2[i].RangeType = (uint32_t)pInRP->DescriptorTable.pDescriptorRanges[i].RangeType;
-        p2[i].NumDescriptors = pInRP->DescriptorTable.pDescriptorRanges[i].NumDescriptors;
-        p2[i].BaseShaderRegister = pInRP->DescriptorTable.pDescriptorRanges[i].BaseShaderRegister;
-        p2[i].RegisterSpace = pInRP->DescriptorTable.pDescriptorRanges[i].RegisterSpace;
-        p2[i].OffsetInDescriptorsFromTableStart = pInRP->DescriptorTable.pDescriptorRanges[i].OffsetInDescriptorsFromTableStart;
-        DxilDescriptorRangeFlags Flags = GetFlags(pInRP->DescriptorTable.pDescriptorRanges[i]);
-        SetFlags(p2[i], Flags);
-      }
-      break;
-    }
-    case DxilRootParameterType::Constants32Bit: {
-      DxilRootConstants *p;
-      IFT(Serializer.ReserveBlock((void**)&p, sizeof(DxilRootConstants), &pOutRP->PayloadOffset));
-      p->Num32BitValues = pInRP->Constants.Num32BitValues;
-      p->ShaderRegister = pInRP->Constants.ShaderRegister;
-      p->RegisterSpace = pInRP->Constants.RegisterSpace;
-      break;
-    }
-    case DxilRootParameterType::CBV:
-    case DxilRootParameterType::SRV:
-    case DxilRootParameterType::UAV: {
-      T_ROOT_DESCRIPTOR_INTERNAL *p;
-      IFT(Serializer.ReserveBlock((void**)&p, sizeof(T_ROOT_DESCRIPTOR_INTERNAL), &pOutRP->PayloadOffset));
-      p->ShaderRegister = pInRP->Descriptor.ShaderRegister;
-      p->RegisterSpace = pInRP->Descriptor.RegisterSpace;
-      DxilRootDescriptorFlags Flags = GetFlags(pInRP->Descriptor);
-      SetFlags(*p, Flags);
-      break;
-    }
-    default:
-      EAT(DiagPrinter << "D3DSerializeRootSignature: unknown root parameter type ("
-                      << (uint32_t)pInRP->ParameterType << ")\n");
-    }
-  }
-
-  DxilStaticSamplerDesc *pSS;
-  unsigned StaticSamplerSize = sizeof(DxilStaticSamplerDesc)*RS.NumStaticSamplers;
-  IFT(Serializer.ReserveBlock((void**)&pSS, StaticSamplerSize, &RS.StaticSamplersOffset));
-  memcpy(pSS, pRS->pStaticSamplers, StaticSamplerSize);
-
-  // Create the result blob.
-  CDxcMallocHeapPtr<char> bytes(DxcGetThreadMallocNoRef());
-  CComPtr<IDxcBlob> pBlob;
-  unsigned cb = Serializer.GetSize();
-  DXASSERT_NOMSG((cb & 0x3) == 0);
-  IFTBOOL(bytes.Allocate(cb), E_OUTOFMEMORY);
-  IFT(Serializer.Compact(bytes.m_pData, cb));
-  IFT(DxcCreateBlobOnHeap(bytes.m_pData, cb, ppBlob));
-  bytes.Detach(); // Ownership transfered to ppBlob.
-}
-
-_Use_decl_annotations_
-void SerializeRootSignature(const DxilVersionedRootSignatureDesc *pRootSignature,
-                            IDxcBlob **ppBlob, IDxcBlobEncoding **ppErrorBlob,
-                            bool bAllowReservedRegisterSpace) {
-  DXASSERT_NOMSG(pRootSignature != nullptr);
-  DXASSERT_NOMSG(ppBlob != nullptr);
-  DXASSERT_NOMSG(ppErrorBlob != nullptr);
-
-  *ppBlob = nullptr;
-  *ppErrorBlob = nullptr;
-
-  RootSignatureVerifier RSV;
-  // TODO: change SerializeRootSignature to take raw_ostream&
-  string DiagString;
-  raw_string_ostream DiagStream(DiagString);
-  DiagnosticPrinterRawOStream DiagPrinter(DiagStream);
-
-  // Verify root signature.
-  RSV.AllowReservedRegisterSpace(bAllowReservedRegisterSpace);
-  try {
-    RSV.VerifyRootSignature(pRootSignature, DiagPrinter);
-    switch (pRootSignature->Version)
-    {
-    case DxilRootSignatureVersion::Version_1_0:
-      SerializeRootSignatureTemplate<
-        DxilRootSignatureDesc,
-        DxilRootParameter,
-        DxilRootDescriptor,
-        DxilContainerDescriptorRange>(&pRootSignature->Desc_1_0,
-          DxilRootSignatureVersion::Version_1_0,
-          ppBlob, DiagPrinter,
-          bAllowReservedRegisterSpace);
-      break;
-
-    case DxilRootSignatureVersion::Version_1_1:
-    default:
-      DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else VerifyRootSignature didn't validate");
-      SerializeRootSignatureTemplate<
-        DxilRootSignatureDesc1,
-        DxilRootParameter1,
-        DxilContainerRootDescriptor1,
-        DxilContainerDescriptorRange1>(&pRootSignature->Desc_1_1,
-          DxilRootSignatureVersion::Version_1_1,
-          ppBlob, DiagPrinter,
-          bAllowReservedRegisterSpace);
-      break;
-    }
-  } catch (...) {
-    DiagStream.flush();
-    DxcCreateBlobWithEncodingOnHeapCopy(DiagString.c_str(), DiagString.size(), CP_UTF8, ppErrorBlob);
-  }
-}
-
-//=============================================================================
-//
-// CVersionedRootSignatureDeserializer.
-//
-//=============================================================================
-class CVersionedRootSignatureDeserializer {
-protected:
-  const DxilVersionedRootSignatureDesc *m_pRootSignature;
-  const DxilVersionedRootSignatureDesc *m_pRootSignature10;
-  const DxilVersionedRootSignatureDesc *m_pRootSignature11;
-
-public:
-  CVersionedRootSignatureDeserializer();
-  ~CVersionedRootSignatureDeserializer();
-
-  void Initialize(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
-                  _In_ uint32_t SrcDataSizeInBytes);
-
-  const DxilVersionedRootSignatureDesc *GetRootSignatureDescAtVersion(DxilRootSignatureVersion convertToVersion);
-
-  const DxilVersionedRootSignatureDesc *GetUnconvertedRootSignatureDesc();
-};
-
-CVersionedRootSignatureDeserializer::CVersionedRootSignatureDeserializer()
-  : m_pRootSignature(nullptr)
-  , m_pRootSignature10(nullptr)
-  , m_pRootSignature11(nullptr) {
-}
-
-CVersionedRootSignatureDeserializer::~CVersionedRootSignatureDeserializer() {
-  DeleteRootSignature(m_pRootSignature10);
-  DeleteRootSignature(m_pRootSignature11);
-}
-
-void CVersionedRootSignatureDeserializer::Initialize(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
-                                                     _In_ uint32_t SrcDataSizeInBytes) {
-  const DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
-  DeserializeRootSignature(pSrcData, SrcDataSizeInBytes, &pRootSignature);
-
-  switch (pRootSignature->Version) {
-  case DxilRootSignatureVersion::Version_1_0:
-    m_pRootSignature10 = pRootSignature;
-    break;
-
-  case DxilRootSignatureVersion::Version_1_1:
-    m_pRootSignature11 = pRootSignature;
-    break;
-
-  default:
-    DeleteRootSignature(pRootSignature);
-    return;
-  }
-
-  m_pRootSignature = pRootSignature;
-}
-
-const DxilVersionedRootSignatureDesc *
-CVersionedRootSignatureDeserializer::GetUnconvertedRootSignatureDesc() {
-  return m_pRootSignature;
-}
-
-const DxilVersionedRootSignatureDesc *
-CVersionedRootSignatureDeserializer::GetRootSignatureDescAtVersion(DxilRootSignatureVersion ConvertToVersion) {
-  switch (ConvertToVersion) {
-  case DxilRootSignatureVersion::Version_1_0:
-    if (m_pRootSignature10 == nullptr) {
-      ConvertRootSignature(m_pRootSignature,
-                           ConvertToVersion,
-                           (const DxilVersionedRootSignatureDesc **)&m_pRootSignature10);
-    }
-    return m_pRootSignature10;
-
-  case DxilRootSignatureVersion::Version_1_1:
-    if (m_pRootSignature11 == nullptr) {
-      ConvertRootSignature(m_pRootSignature,
-                           ConvertToVersion,
-                           (const DxilVersionedRootSignatureDesc **)&m_pRootSignature11);
-    }
-    return m_pRootSignature11;
-
-  default:
-    IFTBOOL(false, E_FAIL);
-  }
-
-  return nullptr;
-}
-
-template<typename T_ROOT_SIGNATURE_DESC,
-         typename T_ROOT_PARAMETER,
-         typename T_ROOT_DESCRIPTOR,
-         typename T_ROOT_DESCRIPTOR_INTERNAL,
-         typename T_DESCRIPTOR_RANGE,
-         typename T_DESCRIPTOR_RANGE_INTERNAL>
-void DeserializeRootSignatureTemplate(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
-                                      _In_ uint32_t SrcDataSizeInBytes,
-                                      DxilRootSignatureVersion DescVersion,
-                                      T_ROOT_SIGNATURE_DESC &RootSignatureDesc) {
-  // Note that in case of failure, outside code must deallocate memory.
-  T_ROOT_SIGNATURE_DESC *pRootSignature = &RootSignatureDesc;
-  const char *pData = (const char *)pSrcData;
-  const char *pMaxPtr = pData + SrcDataSizeInBytes;
-  UNREFERENCED_PARAMETER(DescVersion);
-  DXASSERT_NOMSG(((const uint32_t*)pData)[0] == (uint32_t)DescVersion);
-
-  // Root signature.
-  IFTBOOL(pData + sizeof(DxilContainerRootSignatureDesc) <= pMaxPtr, E_FAIL);
-  const DxilContainerRootSignatureDesc *pRS = (const DxilContainerRootSignatureDesc *)pData;
-  pRootSignature->Flags = (DxilRootSignatureFlags)pRS->Flags;
-  pRootSignature->NumParameters = pRS->NumParameters;
-  pRootSignature->NumStaticSamplers = pRS->NumStaticSamplers;
-  // Intialize all pointers early so that clean up works properly.
-  pRootSignature->pParameters = nullptr;
-  pRootSignature->pStaticSamplers = nullptr;
-
-  size_t s = sizeof(DxilContainerRootParameter)*pRS->NumParameters;
-  const DxilContainerRootParameter *pInRTS = (const DxilContainerRootParameter *)(pData + pRS->RootParametersOffset);
-  IFTBOOL(((const char*)pInRTS) + s <= pMaxPtr, E_FAIL);
-  if (pRootSignature->NumParameters) {
-    pRootSignature->pParameters = new T_ROOT_PARAMETER[pRootSignature->NumParameters];
-  }
-  memset((void *)pRootSignature->pParameters, 0, s);
-
-  for(unsigned iRP = 0; iRP < pRootSignature->NumParameters; iRP++) {
-    DxilRootParameterType ParameterType = (DxilRootParameterType)pInRTS[iRP].ParameterType;
-    T_ROOT_PARAMETER *pOutRTS = (T_ROOT_PARAMETER *)&pRootSignature->pParameters[iRP];
-    pOutRTS->ParameterType = ParameterType;
-    pOutRTS->ShaderVisibility = (DxilShaderVisibility)pInRTS[iRP].ShaderVisibility;
-    switch(ParameterType) {
-    case DxilRootParameterType::DescriptorTable: {
-      const DxilContainerRootDescriptorTable *p1 = (const DxilContainerRootDescriptorTable*)(pData + pInRTS[iRP].PayloadOffset);
-      IFTBOOL((const char*)p1 + sizeof(DxilContainerRootDescriptorTable) <= pMaxPtr, E_FAIL);
-      pOutRTS->DescriptorTable.NumDescriptorRanges = p1->NumDescriptorRanges;
-      pOutRTS->DescriptorTable.pDescriptorRanges = nullptr;
-      const T_DESCRIPTOR_RANGE_INTERNAL *p2 = (const T_DESCRIPTOR_RANGE_INTERNAL*)(pData + p1->DescriptorRangesOffset);
-      IFTBOOL((const char*)p2 + sizeof(T_DESCRIPTOR_RANGE_INTERNAL) <= pMaxPtr, E_FAIL);
-      if (p1->NumDescriptorRanges) {
-        pOutRTS->DescriptorTable.pDescriptorRanges = new T_DESCRIPTOR_RANGE[p1->NumDescriptorRanges];
-      }
-      for (unsigned i = 0; i < p1->NumDescriptorRanges; i++) {
-        T_DESCRIPTOR_RANGE *p3 = (T_DESCRIPTOR_RANGE *)&pOutRTS->DescriptorTable.pDescriptorRanges[i];
-        p3->RangeType                         = (DxilDescriptorRangeType)p2[i].RangeType;
-        p3->NumDescriptors                    = p2[i].NumDescriptors;
-        p3->BaseShaderRegister                = p2[i].BaseShaderRegister;
-        p3->RegisterSpace                     = p2[i].RegisterSpace;
-        p3->OffsetInDescriptorsFromTableStart = p2[i].OffsetInDescriptorsFromTableStart;
-        DxilDescriptorRangeFlags Flags = GetFlags(p2[i]);
-        SetFlags(*p3, Flags);
-      }
-      break;
-    }
-    case DxilRootParameterType::Constants32Bit: {
-      const DxilRootConstants *p = (const DxilRootConstants*)(pData + pInRTS[iRP].PayloadOffset);
-      IFTBOOL((const char*)p + sizeof(DxilRootConstants) <= pMaxPtr, E_FAIL);
-      pOutRTS->Constants.Num32BitValues = p->Num32BitValues;
-      pOutRTS->Constants.ShaderRegister = p->ShaderRegister;
-      pOutRTS->Constants.RegisterSpace  = p->RegisterSpace;
-      break;
-    }
-    case DxilRootParameterType::CBV:
-    case DxilRootParameterType::SRV:
-    case DxilRootParameterType::UAV: {
-      const T_ROOT_DESCRIPTOR *p = (const T_ROOT_DESCRIPTOR *)(pData + pInRTS[iRP].PayloadOffset);
-      IFTBOOL((const char*)p + sizeof(T_ROOT_DESCRIPTOR) <= pMaxPtr, E_FAIL);
-      pOutRTS->Descriptor.ShaderRegister = p->ShaderRegister;
-      pOutRTS->Descriptor.RegisterSpace  = p->RegisterSpace;
-      DxilRootDescriptorFlags Flags = GetFlags(*p);
-      SetFlags(pOutRTS->Descriptor, Flags);
-      break;
-    }
-    default:
-      IFT(E_FAIL);
-    }
-  }
-
-  s = sizeof(DxilStaticSamplerDesc)*pRS->NumStaticSamplers;
-  const DxilStaticSamplerDesc *pInSS = (const DxilStaticSamplerDesc *)(pData + pRS->StaticSamplersOffset);
-  IFTBOOL(((const char*)pInSS) + s <= pMaxPtr, E_FAIL);
-  if (pRootSignature->NumStaticSamplers) {
-    pRootSignature->pStaticSamplers = new DxilStaticSamplerDesc[pRootSignature->NumStaticSamplers];
-  }
-  memcpy((void*)pRootSignature->pStaticSamplers, pInSS, s);
-}
-
-_Use_decl_annotations_
-void DeserializeRootSignature(const void *pSrcData,
-                              uint32_t SrcDataSizeInBytes,
-                              const DxilVersionedRootSignatureDesc **ppRootSignature) {
-  DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
-  IFTBOOL(pSrcData != nullptr && SrcDataSizeInBytes != 0 && ppRootSignature != nullptr, E_INVALIDARG);
-  IFTBOOL(*ppRootSignature == nullptr, E_INVALIDARG);
-  const char *pData = (const char *)pSrcData;
-  IFTBOOL(pData + sizeof(uint32_t) < pData + SrcDataSizeInBytes, E_FAIL);
-
-  DxilRootSignatureVersion Version = (const DxilRootSignatureVersion)((const uint32_t*)pData)[0];
-
-  pRootSignature = new DxilVersionedRootSignatureDesc();
-
-  try {
-    switch (Version) {
-    case DxilRootSignatureVersion::Version_1_0:
-      pRootSignature->Version = DxilRootSignatureVersion::Version_1_0;
-      DeserializeRootSignatureTemplate<
-         DxilRootSignatureDesc,
-         DxilRootParameter,
-         DxilRootDescriptor,
-         DxilRootDescriptor,
-         DxilDescriptorRange,
-         DxilContainerDescriptorRange>(pSrcData,
-                                       SrcDataSizeInBytes,
-                                       DxilRootSignatureVersion::Version_1_0,
-                                       pRootSignature->Desc_1_0);
-      break;
-
-    case DxilRootSignatureVersion::Version_1_1:
-      pRootSignature->Version = DxilRootSignatureVersion::Version_1_1;
-      DeserializeRootSignatureTemplate<
-         DxilRootSignatureDesc1,
-         DxilRootParameter1,
-         DxilRootDescriptor1,
-         DxilContainerRootDescriptor1,
-         DxilDescriptorRange1,
-         DxilContainerDescriptorRange1>(pSrcData,
-                                        SrcDataSizeInBytes,
-                                        DxilRootSignatureVersion::Version_1_1,
-                                        pRootSignature->Desc_1_1);
-      break;
-
-    default:
-      IFT(E_FAIL);
-      break;
-    }
-  } catch(...) {
-    DeleteRootSignature(pRootSignature);
-    throw;
-  }
-
-  *ppRootSignature = pRootSignature;
-}
-
 static DxilShaderVisibility GetVisibilityType(DXIL::ShaderKind ShaderKind) {
   switch(ShaderKind) {
   case DXIL::ShaderKind::Pixel:       return DxilShaderVisibility::Pixel;
@@ -1680,9 +828,11 @@ bool VerifyRootSignatureWithShaderPSV(const DxilVersionedRootSignatureDesc *pDes
 }
 
 bool VerifyRootSignature(_In_ const DxilVersionedRootSignatureDesc *pDesc,
-                         _In_ llvm::raw_ostream &DiagStream) {
+                         _In_ llvm::raw_ostream &DiagStream,
+                         _In_ bool bAllowReservedRegisterSpace) {
   try {
     RootSignatureVerifier RSV;
+    RSV.AllowReservedRegisterSpace(bAllowReservedRegisterSpace);
     DiagnosticPrinterRawOStream DiagPrinter(DiagStream);
     RSV.VerifyRootSignature(pDesc, DiagPrinter);
   } catch (...) {

+ 16 - 0
lib/DxilRootSignature/LLVMBuild.txt

@@ -0,0 +1,16 @@
+; Copyright (C) Microsoft Corporation. All rights reserved.
+; This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details.
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = DxilRootSignature
+parent = Libraries
+required_libraries = BitReader Core DxcSupport IPA Support

+ 0 - 2
lib/HLSL/CMakeLists.txt

@@ -5,7 +5,6 @@ add_llvm_library(LLVMHLSL
   ComputeViewIdStateBuilder.cpp
   ControlDependence.cpp
   DxilCondenseResources.cpp
-  DxilContainerAssembler.cpp
   DxilContainerReflection.cpp
   DxilConvergent.cpp
   DxilEliminateOutputDynamicIndexing.cpp
@@ -17,7 +16,6 @@ add_llvm_library(LLVMHLSL
   DxilPackSignatureElement.cpp
   DxilPatchShaderRecordBindings.cpp
   DxilPreserveAllOutputs.cpp
-  DxilRootSignature.cpp
   DxilSignatureValidation.cpp
   DxilTargetLowering.cpp
   DxilTargetTransformInfo.cpp

+ 1 - 1
lib/HLSL/DxcOptimizer.cpp

@@ -13,7 +13,7 @@
 #include "dxc/Support/Global.h"
 #include "dxc/Support/Unicode.h"
 #include "dxc/Support/microcom.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/HLSL/ReducibilityAnalysis.h"

+ 2 - 1
lib/HLSL/DxilContainerReflection.cpp

@@ -12,7 +12,7 @@
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/InstIterator.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DXIL/DxilShaderModel.h"
 #include "dxc/DXIL/DxilOperations.h"
@@ -47,6 +47,7 @@ const GUID IID_ID3D11ShaderReflection_47 = {
 
 using namespace llvm;
 using namespace hlsl;
+using namespace hlsl::DXIL;
 
 class DxilContainerReflection : public IDxcContainerReflection {
 private:

+ 1 - 1
lib/HLSL/DxilGenerationPass.cpp

@@ -184,7 +184,7 @@ void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, bool HasDebugInfo) {
   }
 
   // Signatures.
-  M.ResetRootSignature(H.ReleaseRootSignature());
+  M.ResetSerializedRootSignature(H.GetSerializedRootSignature());
 
   // Shader properties.
   //bool m_bDisableOptimizations;

+ 1 - 1
lib/HLSL/DxilLinker.cpp

@@ -31,7 +31,7 @@
 #include <memory>
 #include <vector>
 
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/DebugInfo.h"

+ 1 - 1
lib/HLSL/DxilPatchShaderRecordBindings.cpp

@@ -24,7 +24,7 @@
 #include "dxc/DXIL/DxilConstants.h"
 #include "dxc/DXIL/DxilInstructions.h"
 #include "dxc/HLSL/DxilSpanAllocator.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include "dxc/DXIL/DxilUtil.h"
 #include "llvm/Transforms/Utils/Cloning.h"
 

+ 0 - 29
lib/HLSL/DxilPreparePasses.cpp

@@ -109,35 +109,6 @@ bool SimplifyInst::runOnFunction(Function &F) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-namespace {
-class DxilLoadMetadata : public ModulePass {
-public:
-  static char ID; // Pass identification, replacement for typeid
-  explicit DxilLoadMetadata () : ModulePass(ID) {}
-
-  const char *getPassName() const override { return "HLSL load DxilModule from metadata"; }
-
-  bool runOnModule(Module &M) override {
-    if (!M.HasDxilModule()) {
-      (void)M.GetOrCreateDxilModule();
-      return true;
-    }
-
-    return false;
-  }
-};
-}
-
-char DxilLoadMetadata::ID = 0;
-
-ModulePass *llvm::createDxilLoadMetadataPass() {
-  return new DxilLoadMetadata();
-}
-
-INITIALIZE_PASS(DxilLoadMetadata, "hlsl-dxilload", "HLSL load DxilModule from metadata", false, false)
-
-///////////////////////////////////////////////////////////////////////////////
-
 namespace {
 class DxilDeadFunctionElimination : public ModulePass {
 public:

+ 8 - 10
lib/HLSL/DxilValidation.cpp

@@ -10,11 +10,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "dxc/HLSL/DxilValidation.h"
+#include "dxc/DxilContainer/DxilContainerAssembler.h"
 #include "dxc/HLSL/DxilGenerationPass.h"
 #include "dxc/DXIL/DxilOperations.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DXIL/DxilShaderModel.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DXIL/DxilFunctionProps.h"
 #include "dxc/Support/Global.h"
 #include "dxc/DXIL/DxilUtil.h"
@@ -46,7 +47,7 @@
 #include "dxc/HLSL/DxilSpanAllocator.h"
 #include "dxc/HLSL/DxilSignatureAllocator.h"
 #include "dxc/HLSL/DxilPackSignatureElement.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include <algorithm>
 #include <deque>
 
@@ -5489,22 +5490,19 @@ HRESULT ValidateDxilBitcode(
     return hr;
 
   DxilModule &dxilModule = pModule->GetDxilModule();
-  if (!dxilModule.GetRootSignature().IsEmpty()) {
+  auto &SerializedRootSig = dxilModule.GetSerializedRootSignature();
+  if (!SerializedRootSig.empty()) {
     unique_ptr<DxilPartWriter> pWriter(NewPSVWriter(dxilModule, 0));
     DXASSERT_NOMSG(pWriter->size());
     CComPtr<AbstractMemoryStream> pOutputStream;
     IFT(CreateMemoryStream(DxcGetThreadMallocNoRef(), &pOutputStream));
     pOutputStream->Reserve(pWriter->size());
     pWriter->write(pOutputStream);
-    const DxilVersionedRootSignatureDesc* pDesc = dxilModule.GetRootSignature().GetDesc();
-    RootSignatureHandle RS;
     try {
+      const DxilVersionedRootSignatureDesc* pDesc = nullptr;
+      DeserializeRootSignature(SerializedRootSig.data(), SerializedRootSig.size(), &pDesc);
       if (!pDesc) {
-        RS.Assign(nullptr, dxilModule.GetRootSignature().GetSerialized());
-        RS.Deserialize();
-        pDesc = RS.GetDesc();
-        if (!pDesc)
-          return DXC_E_INCORRECT_ROOT_SIGNATURE;
+        return DXC_E_INCORRECT_ROOT_SIGNATURE;
       }
       IFTBOOL(VerifyRootSignatureWithShaderPSV(pDesc,
                                                dxilModule.GetShaderModel()->GetKind(),

+ 13 - 12
lib/HLSL/HLModule.cpp

@@ -14,7 +14,6 @@
 #include "dxc/DXIL/DxilCBuffer.h"
 #include "dxc/HLSL/HLModule.h"
 #include "dxc/DXIL/DxilTypeSystem.h"
-#include "dxc/HLSL/DxilRootSignature.h"
 #include "dxc/Support/WinAdapter.h"
 
 #include "llvm/ADT/STLExtras.h"
@@ -84,7 +83,7 @@ void HLModule::SetShaderModel(const ShaderModel *pSM) {
   m_pSM = pSM;
   m_pSM->GetDxilVersion(m_DxilMajor, m_DxilMinor);
   m_pMDHelper->SetShaderModel(m_pSM);
-  m_RootSignature = llvm::make_unique<RootSignatureHandle>();
+  m_SerializedRootSignature.clear();
 }
 
 const ShaderModel *HLModule::GetShaderModel() const {
@@ -297,8 +296,14 @@ void HLModule::AddGroupSharedVariable(GlobalVariable *GV) {
   m_TGSMVariables.emplace_back(GV);
 }
 
-RootSignatureHandle &HLModule::GetRootSignature() {
-  return *m_RootSignature;
+std::vector<uint8_t> &HLModule::GetSerializedRootSignature() {
+  return m_SerializedRootSignature;
+}
+
+void HLModule::SetSerializedRootSignature(const uint8_t *pData, unsigned size) {
+  m_SerializedRootSignature.clear();
+  m_SerializedRootSignature.resize(size);
+  memcpy(m_SerializedRootSignature.data(), pData, size);
 }
 
 DxilTypeSystem &HLModule::GetTypeSystem() {
@@ -313,10 +318,6 @@ hlsl::OP *HLModule::ReleaseOP() {
   return m_pOP.release();
 }
 
-RootSignatureHandle *HLModule::ReleaseRootSignature() {
-  return m_RootSignature.release();
-}
-
 DxilFunctionPropsMap &&HLModule::ReleaseFunctionPropsMap() {
   return std::move(m_DxilFunctionPropsMap);
 }
@@ -475,8 +476,8 @@ void HLModule::EmitHLMetadata() {
     resTyAnnotations->addOperand(EmitResTyAnnotations());
   }
 
-  if (!m_RootSignature->IsEmpty()) {
-    m_pMDHelper->EmitRootSignature(*m_RootSignature.get());
+  if (!m_SerializedRootSignature.empty()) {
+    m_pMDHelper->EmitRootSignature(m_SerializedRootSignature);
   }
 }
 
@@ -484,7 +485,7 @@ void HLModule::LoadHLMetadata() {
   m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor);
   m_pMDHelper->LoadValidatorVersion(m_ValMajor, m_ValMinor);
   m_pMDHelper->LoadDxilShaderModel(m_pSM);
-  m_RootSignature = llvm::make_unique<RootSignatureHandle>();
+  m_SerializedRootSignature.clear();
 
   const llvm::NamedMDNode *pEntries = m_pMDHelper->GetDxilEntryPoints();
 
@@ -531,7 +532,7 @@ void HLModule::LoadHLMetadata() {
       LoadResTyAnnotations(MDResTyAnnotations->getOperand(0));
   }
 
-  m_pMDHelper->LoadRootSignature(*m_RootSignature.get());
+  m_pMDHelper->LoadRootSignature(m_SerializedRootSignature);
 }
 
 void HLModule::ClearHLMetadata(llvm::Module &M) {

+ 1 - 1
lib/HLSL/WaveSensitivityAnalysis.cpp

@@ -15,7 +15,7 @@
 #include "dxc/DXIL/DxilOperations.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DXIL/DxilShaderModel.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/Global.h"
 #include "dxc/HLSL/HLOperations.h"
 #include "dxc/HLSL/HLModule.h"

+ 3 - 1
lib/LLVMBuild.txt

@@ -40,9 +40,11 @@ subdirectories =
  Transforms
  HLSL
  DXIL
+ DxilContainer
  DxrFallback
+ DxilRootSignature
 
-; HLSL Change: remove LibDriver, LineEditor, add HLSL, add DxrtFallback, add DXIL, add DxilPIXPasses
+; HLSL Change: remove LibDriver, LineEditor, add HLSL, DxrtFallback, DXIL, DxilContainer, DxilPIXPasses, DxilRootSignature
 
 [component_0]
 type = Group

+ 0 - 1
lib/Transforms/IPO/PassManagerBuilder.cpp

@@ -268,7 +268,6 @@ static void addHLSLPasses(bool HLSLHighLevel, unsigned OptLevel, hlsl::HLSLExten
   MPM.add(createFailUndefResourcePass());
 
   MPM.add(createDxilGenerationPass(NoOpt, ExtHelper));
-  MPM.add(createDxilLoadMetadataPass()); // Ensure DxilModule is loaded for optimizations.
 
   // Propagate precise attribute.
   MPM.add(createDxilPrecisePropagatePass());

+ 16 - 4
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -39,7 +39,7 @@
 #include <unordered_set>
 #include <set>
 
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include "dxc/DXIL/DxilCBuffer.h"
 #include "clang/Parse/ParseHLSL.h"      // root sig would be in Parser if part of lang
 #include "dxc/Support/WinIncludes.h"    // stream support
@@ -4825,9 +4825,16 @@ void CGMSHLSLRuntime::FinishCodeGen() {
       HLSLExtensionsCodegenHelper::CustomRootSignature customRootSig;
       Status status = CGM.getCodeGenOpts().HLSLExtensionsCodegen->GetCustomRootSignature(&customRootSig);
       if (status == Status::FOUND) {
+         RootSignatureHandle RootSigHandle;
           CompileRootSignature(customRootSig.RootSignature, Diags,
                                SourceLocation::getFromRawEncoding(customRootSig.EncodedSourceLocation),
-                               rootSigVer, &m_pHLModule->GetRootSignature());
+                               rootSigVer, &RootSigHandle);
+          if (!RootSigHandle.IsEmpty()) {
+            RootSigHandle.EnsureSerializedAvailable();
+            m_pHLModule->SetSerializedRootSignature(
+                RootSigHandle.GetSerializedBytes(),
+                RootSigHandle.GetSerializedSize());
+          }
       }
     }
   }
@@ -6777,8 +6784,13 @@ void CGMSHLSLRuntime::EmitHLSLRootSignature(CodeGenFunction &CGF,
   StringRef StrRef = RSA->getSignatureName();
   DiagnosticsEngine &Diags = CGF.getContext().getDiagnostics();
   SourceLocation SLoc = RSA->getLocation();
-
-  clang::CompileRootSignature(StrRef, Diags, SLoc, rootSigVer, &m_pHLModule->GetRootSignature());
+  RootSignatureHandle RootSigHandle;
+  clang::CompileRootSignature(StrRef, Diags, SLoc, rootSigVer, &RootSigHandle);
+  if (!RootSigHandle.IsEmpty()) {
+    RootSigHandle.EnsureSerializedAvailable();
+    m_pHLModule->SetSerializedRootSignature(RootSigHandle.GetSerializedBytes(),
+                                            RootSigHandle.GetSerializedSize());
+  }
 }
 
 void CGMSHLSLRuntime::EmitHLSLOutParamConversionInit(

+ 1 - 1
tools/clang/lib/Frontend/FrontendActions.cpp

@@ -29,7 +29,7 @@
 #include <memory>
 #include <system_error>
 // HLSL Change Begin.
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include "clang/Parse/ParseHLSL.h"
 // HLSL Change End.
 using namespace clang;

+ 1 - 1
tools/clang/lib/Parse/HLSLRootSignature.h

@@ -11,7 +11,7 @@
 #pragma once
 
 #include "dxc/DXIL/DXIL.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 
 namespace llvm {
 class raw_ostream;

+ 1 - 1
tools/clang/tools/d3dcomp/d3dcomp.cpp

@@ -11,7 +11,7 @@
 
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/Support/Global.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/dxcapi.h"
 
 #include <d3dcompiler.h>

+ 1 - 0
tools/clang/tools/dxa/CMakeLists.txt

@@ -9,6 +9,7 @@ endif (WIN32)
 set( LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
   DXIL
+  DxilContainer
   HLSL
   dxcsupport
   Option     # option library

+ 1 - 1
tools/clang/tools/dxa/dxa.cpp

@@ -16,7 +16,7 @@
 #include "dxc/dxcapi.h"
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/HLSLOptions.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 
 #include "llvm/Support/CommandLine.h"
 #include <dia2.h>

+ 1 - 0
tools/clang/tools/dxc/CMakeLists.txt

@@ -10,6 +10,7 @@ set( LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
   dxcsupport
   DXIL
+  DxilContainer
   HLSL
   Option     # option library
   Support    # just for assert and raw streams

+ 2 - 2
tools/clang/tools/dxc/dxc.cpp

@@ -49,9 +49,9 @@
 #include "dxc/dxctools.h"
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/HLSLOptions.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DXIL/DxilShaderModel.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/microcom.h"
 #include "llvm/Option/OptTable.h"

+ 2 - 0
tools/clang/tools/dxcompiler/CMakeLists.txt

@@ -18,7 +18,9 @@ set(LLVM_LINK_COMPONENTS
 #  debuginfopdb # no support for PDB files
   dxcsupport
   dxil
+  dxilcontainer
   dxilpixpasses # for DxcOptimizerPass
+  dxilrootsignature
   hlsl
   instcombine
   ipa

+ 1 - 1
tools/clang/tools/dxcompiler/dxcassembler.cpp

@@ -13,7 +13,7 @@
 #include "dxc/Support/Global.h"
 #include "dxc/Support/Unicode.h"
 #include "dxc/Support/microcom.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/Support/dxcapi.impl.h"

+ 1 - 1
tools/clang/tools/dxcompiler/dxcdia.cpp

@@ -21,7 +21,7 @@
 #include "llvm/IR/Instructions.h"
 
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DXIL/DxilShaderModel.h"
 #include "dxc/DXIL/DxilMetadataHelper.h"
 #include "dxc/DXIL/DxilModule.h"

+ 2 - 1
tools/clang/tools/dxcompiler/dxcdisassembler.cpp

@@ -27,12 +27,13 @@
 #include "llvm/Support/Format.h"
 #include "dxc/HLSL/DxilPipelineStateValidation.h"
 #include "dxc/HLSL/ComputeViewIdState.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DXIL/DxilUtil.h"
 #include "dxcutil.h"
 
 using namespace llvm;
 using namespace hlsl;
+using namespace hlsl::DXIL;
 
 namespace {
 // Disassemble helper functions.

+ 1 - 1
tools/clang/tools/dxcompiler/dxcfilesystem.cpp

@@ -10,7 +10,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/Global.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/dxcapi.h"

+ 1 - 1
tools/clang/tools/dxcompiler/dxclinker.cpp

@@ -10,7 +10,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/ErrorCodes.h"
 #include "dxc/Support/Global.h"
 #include "dxc/Support/FileIOHelper.h"

+ 2 - 2
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -26,11 +26,11 @@
 #include "llvm/IR/LLVMContext.h"
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/HLSL/HLSLExtensionsCodegenHelper.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include "dxcutil.h"
 #include "dxc/Support/dxcfilesystem.h"
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainerAssembler.h"
 #include "dxc/dxcapi.internal.h"
 
 #include "dxc/Support/dxcapi.use.h"

+ 1 - 1
tools/clang/tools/dxcompiler/dxcontainerbuilder.cpp

@@ -11,7 +11,7 @@
 
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/dxcapi.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/Global.h"
 #include "dxc/Support/ErrorCodes.h"
 #include "dxc/Support/FileIOHelper.h"

+ 1 - 1
tools/clang/tools/dxcompiler/dxcutil.cpp

@@ -10,7 +10,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainerAssembler.h"
 #include "dxc/Support/Global.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/dxcapi.h"

+ 2 - 2
tools/clang/tools/dxcompiler/dxcvalidator.cpp

@@ -14,7 +14,7 @@
 #include "llvm/IR/DiagnosticPrinter.h"
 
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/HLSL/DxilValidation.h"
 
 #include "dxc/Support/Global.h"
@@ -23,7 +23,7 @@
 #include "dxc/Support/microcom.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/dxcapi.impl.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 
 #ifdef _WIN32
 #include "dxcetw.h"

+ 1 - 1
tools/clang/tools/dxl/dxl.cpp

@@ -16,7 +16,7 @@
 #include "dxc/dxcapi.h"
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/HLSLOptions.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support//MSFileSystem.h"

+ 1 - 1
tools/clang/tools/dxlib-sample/lib_share_compile.cpp

@@ -10,7 +10,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DXIL/DxilShaderModel.h"
 #include "dxc/Support/Global.h"
 #include "dxc/dxcapi.h"

+ 1 - 1
tools/clang/tools/dxopt/dxopt.cpp

@@ -20,7 +20,7 @@
 #include "dxc/dxctools.h"
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/HLSLOptions.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/microcom.h"
 #include <comdef.h>

+ 2 - 0
tools/clang/tools/dxrfallbackcompiler/CMakeLists.txt

@@ -16,6 +16,8 @@ set(LLVM_LINK_COMPONENTS
   dxcsupport
   dxrfallback
   dxil
+  dxilcontainer
+  dxilrootsignature
   hlsl
   instcombine
   ipa

+ 1 - 1
tools/clang/tools/dxrfallbackcompiler/dxcdxrfallbackcompiler.cpp

@@ -15,7 +15,7 @@
 #include "dxc/Support/microcom.h"
 #include "dxc/dxcdxrfallbackcompiler.h"
 #include "dxc/DxrFallback/DxrFallbackCompiler.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/HLSL/DxilLinker.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "dxc/DXIL/DxilUtil.h"

+ 1 - 1
tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp

@@ -12,7 +12,7 @@
 #pragma once
 
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainerAssembler.h"
 #include "dxc/Support/Global.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/dxcapi.h"

+ 2 - 2
tools/clang/tools/dxrfallbackcompiler/dxcvalidator.cpp

@@ -14,7 +14,7 @@
 #include "llvm/IR/DiagnosticPrinter.h"
 
 #include "dxc/Support/WinIncludes.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/HLSL/DxilValidation.h"
 
 #include "dxc/Support/Global.h"
@@ -23,7 +23,7 @@
 #include "dxc/Support/microcom.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/dxcapi.impl.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include "dxcetw.h"
 
 using namespace llvm;

+ 2 - 0
tools/clang/unittests/HLSL/CMakeLists.txt

@@ -12,6 +12,8 @@ set( LLVM_LINK_COMPONENTS
   mssupport
   dxcsupport
   dxil
+  dxilcontainer
+  dxilrootsignature
   hlsl
   option
   bitreader

+ 1 - 1
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -20,7 +20,7 @@
 #include <cassert>
 #include <sstream>
 #include <algorithm>
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/dxcapi.h"
 #ifdef _WIN32

+ 1 - 1
tools/clang/unittests/HLSL/D3DReflectionDumper.cpp

@@ -11,7 +11,7 @@
 
 #include "dxc/Support/Global.h"
 #include "D3DReflectionDumper.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include <sstream>
 
 // Copied from llvm/ADT/StringExtras.h

+ 1 - 1
tools/clang/unittests/HLSL/D3DReflectionDumper.h

@@ -19,7 +19,7 @@
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/dxcapi.h"
 #include <d3d12shader.h>
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 
 LPCSTR ToString(D3D_CBUFFER_TYPE CBType);
 LPCSTR ToString(D3D_SHADER_INPUT_TYPE Type);

+ 1 - 1
tools/clang/unittests/HLSL/DxilContainerTest.cpp

@@ -42,7 +42,7 @@
 #include "dxc/Support/Global.h"
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/HLSLOptions.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/HLSL/DxilRuntimeReflection.h"
 #include "dxc/DXIL/DxilShaderFlags.h"
 #include "dxc/DXIL/DxilUtil.h"

+ 1 - 1
tools/clang/unittests/HLSL/DxilModuleTest.cpp

@@ -16,7 +16,7 @@
 #include "dxc/HlslIntrinsicOp.h"
 #include "dxc/DXIL/DxilOperations.h"
 #include "dxc/DXIL/DxilInstructions.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DXIL/DxilModule.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/MSFileSystem.h"

+ 1 - 1
tools/clang/unittests/HLSL/FileCheckerTest.cpp

@@ -33,7 +33,7 @@
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/HLSLOptions.h"
 #include "dxc/Support/Unicode.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "D3DReflectionDumper.h"
 
 #include "d3d12shader.h"

+ 1 - 1
tools/clang/unittests/HLSL/FunctionTest.cpp

@@ -20,7 +20,7 @@
 #include "HlslTestUtils.h"
 #include "DxcTestUtils.h"
 #include "dxc/Support/Global.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 
 #ifdef _WIN32
 class FunctionTest {

+ 1 - 1
tools/clang/unittests/HLSL/OptimizerTest.cpp

@@ -20,7 +20,7 @@
 #include <cassert>
 #include <sstream>
 #include <algorithm>
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/dxcapi.h"
 

+ 2 - 1
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -16,7 +16,8 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "dxc/DXIL/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainer.h"
+#include "dxc/DxilContainer/DxilContainerAssembler.h"
 
 #ifdef _WIN32
 #include <atlbase.h>

+ 1 - 0
tools/clang/unittests/SPIRV/CMakeLists.txt

@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS
   Support
   dxcsupport
   dxil
+  dxilrootsignature
   hlsl
   )
 

+ 1 - 0
tools/clang/unittests/dxc_batch/CMakeLists.txt

@@ -8,6 +8,7 @@ set( LLVM_LINK_COMPONENTS
   ipa
   dxcsupport
   DXIL
+  DxilContainer
   HLSL
   Option     # option library
   Support    # just for assert and raw streams

+ 2 - 2
tools/clang/unittests/dxc_batch/dxc_batch.cpp

@@ -18,8 +18,8 @@
 #include <string>
 #include <vector>
 
-#include "dxc/DXIL/DxilContainer.h"
-#include "dxc/HLSL/DxilRootSignature.h"
+#include "dxc/DxilContainer/DxilContainer.h"
+#include "dxc/DxilRootSignature/DxilRootSignature.h"
 #include "dxc/DXIL/DxilShaderModel.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/HLSLOptions.h"