Browse Source

Reflection Fixes: SB layout in lib, 16 and 64 bit types, tbuffer, more (#2916)

Tex Riddell 5 years ago
parent
commit
86073a3b0b
26 changed files with 1478 additions and 170 deletions
  1. 66 4
      include/dxc/Test/D3DReflectionDumper.h
  2. 99 11
      lib/HLSL/DxilCondenseResources.cpp
  3. 161 42
      lib/HLSL/DxilContainerReflection.cpp
  4. 55 9
      tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp
  5. 1 1
      tools/clang/test/HLSLFileCheck/d3dreflect/anon_struct.hlsl
  6. 193 0
      tools/clang/test/HLSLFileCheck/d3dreflect/cb_1x1array.hlsl
  7. 1 1
      tools/clang/test/HLSLFileCheck/d3dreflect/cb_array.hlsl
  8. 1 1
      tools/clang/test/HLSLFileCheck/d3dreflect/cb_sizes.hlsl
  9. 3 3
      tools/clang/test/HLSLFileCheck/d3dreflect/cbuf-usage-lib.hlsl
  10. 6 6
      tools/clang/test/HLSLFileCheck/d3dreflect/cbuf-usage-phi.hlsl
  11. 1 1
      tools/clang/test/HLSLFileCheck/d3dreflect/cbuffer_default_val.hlsl
  12. 2 2
      tools/clang/test/HLSLFileCheck/d3dreflect/empty_struct2.hlsl
  13. 4 4
      tools/clang/test/HLSLFileCheck/d3dreflect/lib_cb_matrix_array.hlsl
  14. 1 1
      tools/clang/test/HLSLFileCheck/d3dreflect/lib_exports1.hlsl
  15. 2 2
      tools/clang/test/HLSLFileCheck/d3dreflect/lib_exports2.hlsl
  16. 2 2
      tools/clang/test/HLSLFileCheck/d3dreflect/lib_exports4.hlsl
  17. 2 2
      tools/clang/test/HLSLFileCheck/d3dreflect/lib_exports_nocollision.hlsl
  18. 206 16
      tools/clang/test/HLSLFileCheck/d3dreflect/lib_global.hlsl
  19. 8 8
      tools/clang/test/HLSLFileCheck/d3dreflect/reflect-lib-1.hlsl
  20. 15 15
      tools/clang/test/HLSLFileCheck/d3dreflect/structured_buffer_layout.hlsl
  21. 288 0
      tools/clang/test/HLSLFileCheck/d3dreflect/tbuffer-16bit.hlsl
  22. 236 0
      tools/clang/test/HLSLFileCheck/d3dreflect/tbuffer.hlsl
  23. 18 18
      tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferMinPrec.hlsl
  24. 45 17
      tools/clang/unittests/HLSL/DxilContainerTest.cpp
  25. 61 4
      tools/clang/unittests/HLSLTestLib/D3DReflectionDumper.cpp
  26. 1 0
      tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp

+ 66 - 4
include/dxc/Test/D3DReflectionDumper.h

@@ -21,6 +21,8 @@
 #include <d3d12shader.h>
 #include <d3d12shader.h>
 #include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DxilContainer/DxilContainer.h"
 
 
+namespace refl_dump {
+
 LPCSTR ToString(D3D_CBUFFER_TYPE CBType);
 LPCSTR ToString(D3D_CBUFFER_TYPE CBType);
 LPCSTR ToString(D3D_SHADER_INPUT_TYPE Type);
 LPCSTR ToString(D3D_SHADER_INPUT_TYPE Type);
 LPCSTR ToString(D3D_RESOURCE_RETURN_TYPE ReturnType);
 LPCSTR ToString(D3D_RESOURCE_RETURN_TYPE ReturnType);
@@ -32,6 +34,55 @@ LPCSTR ToString(D3D_TESSELLATOR_PARTITIONING HSPartitioning);
 LPCSTR ToString(D3D_TESSELLATOR_DOMAIN TessellatorDomain);
 LPCSTR ToString(D3D_TESSELLATOR_DOMAIN TessellatorDomain);
 LPCSTR ToString(D3D_SHADER_VARIABLE_CLASS Class);
 LPCSTR ToString(D3D_SHADER_VARIABLE_CLASS Class);
 LPCSTR ToString(D3D_SHADER_VARIABLE_TYPE Type);
 LPCSTR ToString(D3D_SHADER_VARIABLE_TYPE Type);
+LPCSTR ToString(D3D_SHADER_VARIABLE_FLAGS Flag);
+LPCSTR ToString(D3D_SHADER_INPUT_FLAGS Flag);
+LPCSTR ToString(D3D_SHADER_CBUFFER_FLAGS Flag);
+LPCSTR ToString(D3D_PARAMETER_FLAGS Flag);
+
+template<typename _T>
+struct EnumValue {
+public:
+  EnumValue(const _T &e) : eValue(e) {}
+  _T eValue;
+};
+
+template<typename _T, typename _StoreT = uint32_t>
+struct FlagsValue {
+public:
+  FlagsValue(const _StoreT &f) : Flags(f) {}
+  _StoreT Flags;
+};
+
+template<typename _T>
+std::ostream& operator<<(std::ostream& out, const EnumValue<_T> &obj) {
+  if (LPCSTR szValue = ToString(obj.eValue))
+    return out << szValue;
+  else
+    return out << "<unknown: " << std::hex << std::showbase << (UINT)obj.eValue << ">";
+}
+
+template<typename _T, typename _StoreT>
+std::ostream& operator<<(std::ostream& out, const FlagsValue<_T, _StoreT> &obj) {
+  _StoreT Flags = obj.Flags;
+  if (!Flags) {
+    LPCSTR szValue = ToString((_T)0);
+    if (szValue)
+      return out << "0 (" << szValue << ")";
+    else
+      return out << "0";
+  }
+  uint32_t flag = 0;
+  out << "(";
+  while (Flags) {
+    if (flag)
+      out << " | ";
+    flag = (Flags & ~(Flags - 1));
+    Flags ^= flag;
+    out << EnumValue<_T>((_T)flag);
+  }
+  out << ")";
+  return out;
+}
 
 
 class DumperBase {
 class DumperBase {
 private:
 private:
@@ -70,13 +121,22 @@ public:
       << std::resetiosflags(std::ios_base::basefield | std::ios_base::showbase);
       << std::resetiosflags(std::ios_base::basefield | std::ios_base::showbase);
   }
   }
 
 
-  template<typename _T>
-  void DumpEnum(const char *Name, _T eValue) {
+  template <typename _T>
+  std::ostream &WriteEnumValue(_T eValue) {
     LPCSTR szValue = ToString(eValue);
     LPCSTR szValue = ToString(eValue);
     if (szValue)
     if (szValue)
-      WriteLn(Name, ": ", szValue);
+      return Write(szValue);
     else
     else
-      WriteLn(Name, ": <unknown: ", std::hex, std::showbase, (UINT)eValue, ">");
+      return Write("<unknown: ", std::hex, std::showbase, (UINT)eValue, ">");
+  }
+
+  template<typename _T>
+  void DumpEnum(const char *Name, _T eValue) {
+    WriteLn(Name, ": ", EnumValue<_T>(eValue));
+  }
+  template<typename _T, typename _StoreT = uint32_t>
+  void DumpFlags(const char *Name, _StoreT Flags) {
+    WriteLn(Name, ": ", FlagsValue<_T, _StoreT>(Flags));
   }
   }
 
 
   template<typename... Args>
   template<typename... Args>
@@ -117,3 +177,5 @@ public:
   void Dump(ID3D12LibraryReflection *pLibraryReflection);
   void Dump(ID3D12LibraryReflection *pLibraryReflection);
 
 
 };
 };
+
+} // namespace refl_dump

+ 99 - 11
lib/HLSL/DxilCondenseResources.cpp

@@ -1819,7 +1819,7 @@ void UpdateStructTypeForLegacyLayoutOnDM(DxilModule &DM) {
   }
   }
 
 
   for (auto &SRV : DM.GetSRVs()) {
   for (auto &SRV : DM.GetSRVs()) {
-    if (SRV->GetKind() == DxilResourceBase::Kind::StructuredBuffer)
+    if (SRV->IsStructuredBuffer() || SRV->IsTBuffer())
       UpdateStructTypeForLegacyLayout(*SRV.get(), TypeSys, M);
       UpdateStructTypeForLegacyLayout(*SRV.get(), TypeSys, M);
   }
   }
 }
 }
@@ -2098,6 +2098,10 @@ void PatchTBufferLoad(CallInst *handle, DxilModule &DM) {
     if (opcode == DXIL::OpCode::CBufferLoadLegacy) {
     if (opcode == DXIL::OpCode::CBufferLoadLegacy) {
       DxilInst_CBufferLoadLegacy cbLoad(I);
       DxilInst_CBufferLoadLegacy cbLoad(I);
 
 
+      StructType *cbRetTy = cast<StructType>(I->getType());
+      // elements will be 4, or 8 for native 16-bit types, which require special handling.
+      bool cbRet8Elt = cbRetTy->getNumElements() > 4;
+
       // Replace with appropriate buffer load instruction
       // Replace with appropriate buffer load instruction
       IRBuilder<> Builder(I);
       IRBuilder<> Builder(I);
       opcode = OP::OpCode::BufferLoad;
       opcode = OP::OpCode::BufferLoad;
@@ -2140,8 +2144,29 @@ void PatchTBufferLoad(CallInst *handle, DxilModule &DM) {
               result = EEBuilder.CreateOr(high, low);
               result = EEBuilder.CreateOr(high, low);
             }
             }
           } else {
           } else {
-            result = EEBuilder.CreateExtractValue(load, idx);
-            result = EEBuilder.CreateBitCast(result, EltTy);
+            if (cbRet8Elt) {
+              DXASSERT_NOMSG(cbRetTy->getNumElements() == 8);
+              DXASSERT_NOMSG(EltTy->getScalarSizeInBits() == 16);
+              // Translate extract from 16bit x 8 to extract and translate from i32 by 4
+              result = EEBuilder.CreateExtractValue(load, idx >> 1);
+              if (idx & 1)
+                result = EEBuilder.CreateLShr(result, 16);
+              result = EEBuilder.CreateTrunc(result, Type::getInt16Ty(Ctx));
+              if (EltTy->isHalfTy())
+                result = EEBuilder.CreateBitCast(result, EltTy);
+            } else {
+              result = EEBuilder.CreateExtractValue(load, idx);
+              if (Ty->getScalarSizeInBits() > EltTy->getScalarSizeInBits()) {
+                if (EltTy->isIntegerTy()) {
+                  result = EEBuilder.CreateTrunc(result, EltTy);
+                } else {
+                  result = EEBuilder.CreateBitCast(result, Type::getFloatTy(Ctx));
+                  result = EEBuilder.CreateFPTrunc(result, EltTy);
+                }
+              } else {
+                result = EEBuilder.CreateBitCast(result, EltTy);
+              }
+            }
           }
           }
         } else {
         } else {
           result = EEBuilder.CreateExtractValue(load, idx);
           result = EEBuilder.CreateExtractValue(load, idx);
@@ -2258,7 +2283,36 @@ static void MarkCBUse(unsigned offset, FieldAnnotationByOffsetMap &fieldMap) {
     it->second->SetCBVarUsed(true);
     it->second->SetCBVarUsed(true);
 }
 }
 
 
-static unsigned GetOffsetForCBExtractValue(ExtractValueInst *EV, bool bMinPrecision) {
+// Detect patterns of lshr v,16 or trunc to 16-bits and return low and high
+// word usage.
+static const unsigned kLowWordUsed = 1;
+static const unsigned kHighWordUsed = 2;
+static const unsigned kLowHighWordMask = kLowWordUsed | kHighWordUsed;
+static unsigned DetectLowAndHighWordUsage(ExtractValueInst *EV) {
+  unsigned result = 0;
+  if (EV->getType()->getScalarSizeInBits() == 32) {
+    for (auto U : EV->users()) {
+      Instruction *I = cast<Instruction>(U);
+      if (I->getOpcode() == LLVMLShr) {
+        ConstantInt *CShift = dyn_cast<ConstantInt>(I->getOperand(1));
+        if (CShift && CShift->getLimitedValue() == 16)
+          result |= kHighWordUsed;
+      } else if (I->getOpcode() == LLVMTrunc &&
+               I->getType()->getPrimitiveSizeInBits() == 16) {
+        result |= kLowWordUsed;
+      } else {
+        // Assume whole dword is used, return 0
+        return 0;
+      }
+      if ((result & kLowHighWordMask) == kLowHighWordMask)
+        break;
+    }
+  }
+  return result;
+}
+
+static unsigned GetOffsetForCBExtractValue(ExtractValueInst *EV, bool bMinPrecision,
+                                           unsigned &lowHighWordUsage) {
   DXASSERT(EV->getNumIndices() == 1, "otherwise, unexpected indices/type for extractvalue");
   DXASSERT(EV->getNumIndices() == 1, "otherwise, unexpected indices/type for extractvalue");
   unsigned typeSize = 4;
   unsigned typeSize = 4;
   unsigned bits = EV->getType()->getScalarSizeInBits();
   unsigned bits = EV->getType()->getScalarSizeInBits();
@@ -2266,9 +2320,24 @@ static unsigned GetOffsetForCBExtractValue(ExtractValueInst *EV, bool bMinPrecis
     typeSize = 8;
     typeSize = 8;
   else if (bits == 16 && !bMinPrecision)
   else if (bits == 16 && !bMinPrecision)
     typeSize = 2;
     typeSize = 2;
+  lowHighWordUsage = DetectLowAndHighWordUsage(EV);
   return (EV->getIndices().front() * typeSize);
   return (EV->getIndices().front() * typeSize);
 }
 }
 
 
+// Marks up to two CB uses for the case where only 16-bit type(s)
+// are being used from lower or upper word of a tbuffer load,
+// which is always 4 x 32 instead of 8 x 16, like cbuffer.
+static void MarkCBUsesForExtractElement(
+    unsigned offset, FieldAnnotationByOffsetMap &fieldMap,
+    ExtractValueInst *EV, bool bMinPrecision) {
+  unsigned lowHighWordUsage = 0;
+  unsigned evOffset = GetOffsetForCBExtractValue(EV, bMinPrecision, lowHighWordUsage);
+  if (!lowHighWordUsage || 0 != (lowHighWordUsage & kLowWordUsed))
+    MarkCBUse(offset + evOffset, fieldMap);
+  if (lowHighWordUsage & kHighWordUsed)
+    MarkCBUse(offset + evOffset + 2, fieldMap);
+}
+
 static void CollectInPhiChain(PHINode *cbUser, unsigned offset,
 static void CollectInPhiChain(PHINode *cbUser, unsigned offset,
                               std::unordered_set<Value *> &userSet,
                               std::unordered_set<Value *> &userSet,
                               FieldAnnotationByOffsetMap &fieldMap,
                               FieldAnnotationByOffsetMap &fieldMap,
@@ -2279,7 +2348,7 @@ static void CollectInPhiChain(PHINode *cbUser, unsigned offset,
   userSet.insert(cbUser);
   userSet.insert(cbUser);
   for (User *cbU : cbUser->users()) {
   for (User *cbU : cbUser->users()) {
     if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(cbU)) {
     if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(cbU)) {
-      MarkCBUse(offset + GetOffsetForCBExtractValue(EV, bMinPrecision), fieldMap);
+      MarkCBUsesForExtractElement(offset, fieldMap, EV, bMinPrecision);
     } else {
     } else {
       PHINode *phi = cast<PHINode>(cbU);
       PHINode *phi = cast<PHINode>(cbU);
       CollectInPhiChain(phi, offset, userSet, fieldMap, bMinPrecision);
       CollectInPhiChain(phi, offset, userSet, fieldMap, bMinPrecision);
@@ -2305,14 +2374,15 @@ static void CollectCBufferMemberUsage(Value *V,
         } else if (op == DXIL::OpCode::AnnotateHandle) {
         } else if (op == DXIL::OpCode::AnnotateHandle) {
           CollectCBufferMemberUsage(U, legacyFieldMap, newFieldMap, hlslOP,
           CollectCBufferMemberUsage(U, legacyFieldMap, newFieldMap, hlslOP,
                                     bMinPrecision, visited);
                                     bMinPrecision, visited);
-        } else if (op == DXIL::OpCode::CBufferLoadLegacy) {
-          DxilInst_CBufferLoadLegacy cbload(CI);
-          Value *resIndex = cbload.get_regIndex();
-          unsigned offset = GetCBOffset(resIndex, visited);
-          offset <<= 4; // translate 16-byte vector index to byte offset
+        } else if (op == DXIL::OpCode::CBufferLoadLegacy ||
+                   op == DXIL::OpCode::BufferLoad) {
+          Value *resIndex = (op == DXIL::OpCode::CBufferLoadLegacy) ?
+            DxilInst_CBufferLoadLegacy(CI).get_regIndex() :
+            DxilInst_BufferLoad(CI).get_index();
+          unsigned offset = GetCBOffset(resIndex, visited) << 4;
           for (User *cbU : U->users()) {
           for (User *cbU : U->users()) {
             if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(cbU)) {
             if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(cbU)) {
-              MarkCBUse(offset + GetOffsetForCBExtractValue(EV, bMinPrecision), legacyFieldMap);
+              MarkCBUsesForExtractElement(offset, legacyFieldMap, EV, bMinPrecision);
             } else {
             } else {
               PHINode *phi = cast<PHINode>(cbU);
               PHINode *phi = cast<PHINode>(cbU);
               std::unordered_set<Value *> userSet;
               std::unordered_set<Value *> userSet;
@@ -2336,11 +2406,29 @@ void DxilLowerCreateHandleForLib::UpdateCBufferUsage() {
   const DataLayout &DL = m_DM->GetModule()->getDataLayout();
   const DataLayout &DL = m_DM->GetModule()->getDataLayout();
   const auto &CBuffers = m_DM->GetCBuffers();
   const auto &CBuffers = m_DM->GetCBuffers();
   OffsetForValueMap visited;
   OffsetForValueMap visited;
+
+  SmallVector<GlobalVariable*, 4> CBufferVars;
+
+  // Collect cbuffers
   for (auto it = CBuffers.begin(); it != CBuffers.end(); it++) {
   for (auto it = CBuffers.begin(); it != CBuffers.end(); it++) {
     DxilCBuffer *CB = it->get();
     DxilCBuffer *CB = it->get();
     GlobalVariable *GV = dyn_cast<GlobalVariable>(CB->GetGlobalSymbol());
     GlobalVariable *GV = dyn_cast<GlobalVariable>(CB->GetGlobalSymbol());
     if (GV == nullptr)
     if (GV == nullptr)
       continue;
       continue;
+    CBufferVars.push_back(GV);
+  }
+
+  // Collect tbuffers
+  for (auto &it : m_DM->GetSRVs()) {
+    if (it->GetKind() != DXIL::ResourceKind::TBuffer)
+      continue;
+    GlobalVariable *GV = dyn_cast<GlobalVariable>(it->GetGlobalSymbol());
+    if (GV == nullptr)
+      continue;
+    CBufferVars.push_back(GV);
+  }
+
+  for (auto GV : CBufferVars) {
     Type *ElemTy = GV->getType()->getPointerElementType();
     Type *ElemTy = GV->getType()->getPointerElementType();
     ElemTy = dxilutil::StripArrayTypes(ElemTy, nullptr);
     ElemTy = dxilutil::StripArrayTypes(ElemTy, nullptr);
     StructType *ST = cast<StructType>(ElemTy);
     StructType *ST = cast<StructType>(ElemTy);

+ 161 - 42
lib/HLSL/DxilContainerReflection.cpp

@@ -41,6 +41,9 @@
 
 
 #include "dxc/DxilContainer/DxilRuntimeReflection.h"
 #include "dxc/DxilContainer/DxilRuntimeReflection.h"
 
 
+// Remove this workaround once newer version of d3dcommon.h can be compiled against
+#define ADD_16_64_BIT_TYPES
+
 const GUID IID_ID3D11ShaderReflection_43 = {
 const GUID IID_ID3D11ShaderReflection_43 = {
     0x0a233719,
     0x0a233719,
     0x3960,
     0x3960,
@@ -83,6 +86,14 @@ class CShaderReflectionType;
 
 
 enum class PublicAPI { D3D12 = 0, D3D11_47 = 1, D3D11_43 = 2 };
 enum class PublicAPI { D3D12 = 0, D3D11_47 = 1, D3D11_43 = 2 };
 
 
+#ifdef ADD_16_64_BIT_TYPES
+#define D3D_SVT_INT16   ((D3D_SHADER_VARIABLE_TYPE)58)
+#define D3D_SVT_UINT16  ((D3D_SHADER_VARIABLE_TYPE)59)
+#define D3D_SVT_FLOAT16 ((D3D_SHADER_VARIABLE_TYPE)60)
+#define D3D_SVT_INT64   ((D3D_SHADER_VARIABLE_TYPE)61)
+#define D3D_SVT_UINT64  ((D3D_SHADER_VARIABLE_TYPE)62)
+#endif // ADD_16_64_BIT_TYPES
+
 class DxilModuleReflection {
 class DxilModuleReflection {
 public:
 public:
   hlsl::RDAT::DxilRuntimeData m_RDAT;
   hlsl::RDAT::DxilRuntimeData m_RDAT;
@@ -93,6 +104,12 @@ public:
   std::vector<std::unique_ptr<CShaderReflectionConstantBuffer>>    m_CBs;
   std::vector<std::unique_ptr<CShaderReflectionConstantBuffer>>    m_CBs;
   std::vector<D3D12_SHADER_INPUT_BIND_DESC>       m_Resources;
   std::vector<D3D12_SHADER_INPUT_BIND_DESC>       m_Resources;
   std::vector<std::unique_ptr<CShaderReflectionType>> m_Types;
   std::vector<std::unique_ptr<CShaderReflectionType>> m_Types;
+  std::map<std::string, UINT> m_CBsByName;
+  // Due to the possibility of overlapping names between CB and other resources,
+  // m_StructuredBufferCBsByName is the index into m_CBs corresponding to
+  // StructuredBuffer resources, separately from CB resources.
+  std::map<std::string, UINT> m_StructuredBufferCBsByName;
+
   void CreateReflectionObjects();
   void CreateReflectionObjects();
   void CreateReflectionObjectForResource(DxilResourceBase *R);
   void CreateReflectionObjectForResource(DxilResourceBase *R);
 
 
@@ -492,6 +509,10 @@ public:
   void InitializeStructuredBuffer(DxilModule &M,
   void InitializeStructuredBuffer(DxilModule &M,
                                   DxilResource &R,
                                   DxilResource &R,
                                   std::vector<std::unique_ptr<CShaderReflectionType>>& allTypes);
                                   std::vector<std::unique_ptr<CShaderReflectionType>>& allTypes);
+  void InitializeTBuffer(DxilModule &M,
+                         DxilResource &R,
+                         std::vector<std::unique_ptr<CShaderReflectionType>>& allTypes,
+                         bool bUsageInMetadata);
   LPCSTR GetName() { return m_Desc.Name; }
   LPCSTR GetName() { return m_Desc.Name; }
 
 
   // ID3D12ShaderReflectionConstantBuffer
   // ID3D12ShaderReflectionConstantBuffer
@@ -855,15 +876,24 @@ HRESULT CShaderReflectionType::Initialize(
     //
     //
     // We might have an array of matrices, though, so we only exit if
     // We might have an array of matrices, though, so we only exit if
     // the field annotation says we have a matrix, and we've bottomed
     // the field annotation says we have a matrix, and we've bottomed
-    // out and the element type isn't itself an array.
+    // out at one array level, since matrix will be in the format:
+    // [rows x <cols x float>]
     //
     //
-    // For libraries however, we may have unlowered matrix types, so
-    // we have to check for HLMatrixType so we don't skip counting the
-    // inner-most matrix array size.
+    // This is in storage orientation, so rows/cols are swapped
+    // when the matrix is column_major.
+    //
+    // However, when the matrix has a row size of 1 in storage orientation,
+    // this array dimension appears to be missing.
+    // To properly count the array dimensions for this case,
+    // we must not break out of the loop one array early when rows == 1.
     if(typeAnnotation.HasMatrixAnnotation() && !elementType->isArrayTy() &&
     if(typeAnnotation.HasMatrixAnnotation() && !elementType->isArrayTy() &&
-       !HLMatrixType::isa(elementType))
-    {
-      break;
+        !HLMatrixType::isa(elementType)){
+      const DxilMatrixAnnotation &mat = typeAnnotation.GetMatrixAnnotation();
+      unsigned rows = mat.Orientation == MatrixOrientation::RowMajor ?
+        mat.Rows : mat.Cols;
+      // when rows == 1, in storage orientation, the row array is missing.
+      if (rows > 1)
+        break;
     }
     }
 
 
     // Non-array types should have `Elements` be zero, so as soon as we
     // Non-array types should have `Elements` be zero, so as soon as we
@@ -897,40 +927,42 @@ HRESULT CShaderReflectionType::Initialize(
     break;
     break;
 
 
   case hlsl::DXIL::ComponentType::I16:
   case hlsl::DXIL::ComponentType::I16:
-    componentType = D3D_SVT_MIN16INT;
     if (bMinPrec) {
     if (bMinPrec) {
+      componentType = D3D_SVT_MIN16INT;
       m_Name = "min16int";
       m_Name = "min16int";
     } else {
     } else {
+      componentType = D3D_SVT_INT16;
       m_Name = "int16_t";
       m_Name = "int16_t";
       cbCompSize = 2;
       cbCompSize = 2;
     }
     }
     break;
     break;
 
 
   case hlsl::DXIL::ComponentType::U16:
   case hlsl::DXIL::ComponentType::U16:
-    componentType = D3D_SVT_MIN16UINT;
     if (bMinPrec) {
     if (bMinPrec) {
+      componentType = D3D_SVT_MIN16UINT;
       m_Name = "min16uint";
       m_Name = "min16uint";
     } else {
     } else {
+      componentType = D3D_SVT_UINT16;
       m_Name = "uint16_t";
       m_Name = "uint16_t";
       cbCompSize = 2;
       cbCompSize = 2;
     }
     }
     break;
     break;
 
 
   case hlsl::DXIL::ComponentType::I64:
   case hlsl::DXIL::ComponentType::I64:
+    componentType = D3D_SVT_INT64;
+    m_Name = "int64_t";
     cbCompSize = 8;
     cbCompSize = 8;
-#ifdef DBG
-    OutputDebugStringA("DxilContainerReflection.cpp: warning: component of type 'I64' being reflected as if 'I32'\n");
-#endif
+    break;
   case hlsl::DXIL::ComponentType::I32:
   case hlsl::DXIL::ComponentType::I32:
     componentType = D3D_SVT_INT;
     componentType = D3D_SVT_INT;
     m_Name = "int";
     m_Name = "int";
     break;
     break;
 
 
   case hlsl::DXIL::ComponentType::U64:
   case hlsl::DXIL::ComponentType::U64:
+    componentType = D3D_SVT_UINT64;
+    m_Name = "uint64_t";
     cbCompSize = 8;
     cbCompSize = 8;
-#ifdef DBG
-    OutputDebugStringA("DxilContainerReflection.cpp: warning: component of type 'U64' being reflected as if 'U32'\n");
-#endif
+    break;
   case hlsl::DXIL::ComponentType::U32:
   case hlsl::DXIL::ComponentType::U32:
     componentType = D3D_SVT_UINT;
     componentType = D3D_SVT_UINT;
     m_Name = "uint";
     m_Name = "uint";
@@ -939,10 +971,11 @@ HRESULT CShaderReflectionType::Initialize(
   case hlsl::DXIL::ComponentType::F16:
   case hlsl::DXIL::ComponentType::F16:
   case hlsl::DXIL::ComponentType::SNormF16:
   case hlsl::DXIL::ComponentType::SNormF16:
   case hlsl::DXIL::ComponentType::UNormF16:
   case hlsl::DXIL::ComponentType::UNormF16:
-    componentType = D3D_SVT_MIN16FLOAT;
     if (bMinPrec) {
     if (bMinPrec) {
+      componentType = D3D_SVT_MIN16FLOAT;
       m_Name = "min16float";
       m_Name = "min16float";
     } else {
     } else {
+      componentType = D3D_SVT_FLOAT16;
       m_Name = "float16_t";
       m_Name = "float16_t";
       cbCompSize = 2;
       cbCompSize = 2;
     }
     }
@@ -1233,32 +1266,32 @@ void CShaderReflectionConstantBuffer::Initialize(
   }
   }
 }
 }
 
 
-static unsigned CalcTypeSize(Type *Ty) {
+
+static unsigned CalcTypeSize(Type *Ty, unsigned &alignment) {
   // Assume aligned values.
   // Assume aligned values.
-  if (Ty->isIntegerTy() || Ty->isFloatTy()) {
-    return Ty->getPrimitiveSizeInBits() / 8;
-  }
-  else if (Ty->isArrayTy()) {
+  if (Ty->isArrayTy()) {
     ArrayType *AT = dyn_cast<ArrayType>(Ty);
     ArrayType *AT = dyn_cast<ArrayType>(Ty);
-    return AT->getNumElements() * CalcTypeSize(AT->getArrayElementType());
+    return AT->getNumElements() * CalcTypeSize(AT->getArrayElementType(), alignment);
   }
   }
   else if (Ty->isStructTy()) {
   else if (Ty->isStructTy()) {
     StructType *ST = dyn_cast<StructType>(Ty);
     StructType *ST = dyn_cast<StructType>(Ty);
     unsigned i = 0, c = ST->getStructNumElements();
     unsigned i = 0, c = ST->getStructNumElements();
     unsigned result = 0;
     unsigned result = 0;
     for (; i < c; ++i) {
     for (; i < c; ++i) {
-      result += CalcTypeSize(ST->getStructElementType(i));
-      // TODO: align!
+      unsigned memberalign = 0;
+      result += CalcTypeSize(ST->getStructElementType(i), memberalign);
+      alignment = std::max(alignment, memberalign);
+      result = (unsigned)RoundUpToAlignment(result, memberalign);
     }
     }
+    result = (unsigned)RoundUpToAlignment(result, alignment);
     return result;
     return result;
   }
   }
   else if (Ty->isVectorTy()) {
   else if (Ty->isVectorTy()) {
     VectorType *VT = dyn_cast<VectorType>(Ty);
     VectorType *VT = dyn_cast<VectorType>(Ty);
-    return VT->getVectorNumElements() * CalcTypeSize(VT->getVectorElementType());
+    return VT->getVectorNumElements() * CalcTypeSize(VT->getVectorElementType(), alignment);
   }
   }
   else {
   else {
-    DXASSERT_NOMSG(false);
-    return 0;
+    return alignment = Ty->getPrimitiveSizeInBits() / 8;
   }
   }
 }
 }
 
 
@@ -1268,7 +1301,11 @@ static unsigned CalcResTypeSize(DxilModule &M, DxilResource &R) {
   if (R.IsStructuredBuffer()) {
   if (R.IsStructuredBuffer()) {
     Ty = dxilutil::StripArrayTypes(Ty);
     Ty = dxilutil::StripArrayTypes(Ty);
   }
   }
-  return CalcTypeSize(Ty);
+  return M.GetModule()->getDataLayout().getTypeAllocSize(Ty);
+
+  // Don't think we need this one if we can just use the data layout:
+  //unsigned alignment = 0;
+  //return CalcTypeSize(Ty, alignment);
 }
 }
 
 
 void CShaderReflectionConstantBuffer::InitializeStructuredBuffer(
 void CShaderReflectionConstantBuffer::InitializeStructuredBuffer(
@@ -1331,6 +1368,60 @@ void CShaderReflectionConstantBuffer::InitializeStructuredBuffer(
   m_Desc.Size = VarDesc.Size;
   m_Desc.Size = VarDesc.Size;
 }
 }
 
 
+void CShaderReflectionConstantBuffer::InitializeTBuffer(
+    DxilModule &M,
+    DxilResource &R,
+    std::vector<std::unique_ptr<CShaderReflectionType>>& allTypes,
+    bool bUsageInMetadata) {
+  ZeroMemory(&m_Desc, sizeof(m_Desc));
+  m_ReflectionName = R.GetGlobalName();
+  m_Desc.Type = D3D11_CT_TBUFFER;
+  m_Desc.uFlags = 0;
+
+  Type *Ty = R.GetGlobalSymbol()->getType()->getPointerElementType();
+
+  DxilTypeSystem &typeSys = M.GetTypeSystem();
+  StructType *ST = cast<StructType>(Ty);
+  DxilStructAnnotation *annotation =
+    typeSys.GetStructAnnotation(cast<StructType>(ST));
+  // Dxil from dxbc doesn't have annotation.
+  if (!annotation)
+    return;
+
+  m_Desc.Name = m_ReflectionName.c_str();
+  m_Desc.Variables = ST->getNumContainedTypes();
+
+  // If only one member, it's used if it's here.
+  bool bAllUsed = ST->getNumContainedTypes() < 2;
+  bAllUsed |= !bUsageInMetadata;  // Will update in SetCBufferUsage.
+
+  for (unsigned i = 0; i < ST->getNumContainedTypes(); ++i) {
+    DxilFieldAnnotation &fieldAnnotation = annotation->GetFieldAnnotation(i);
+
+    D3D12_SHADER_VARIABLE_DESC VarDesc;
+    ZeroMemory(&VarDesc, sizeof(VarDesc));
+    VarDesc.uFlags = (bAllUsed || fieldAnnotation.IsCBVarUsed()) ? D3D_SVF_USED : 0;
+    CShaderReflectionVariable Var;
+    //Create reflection type.
+    CShaderReflectionType *pVarType = new CShaderReflectionType();
+    allTypes.push_back(std::unique_ptr<CShaderReflectionType>(pVarType));
+    pVarType->Initialize(M, ST->getContainedType(i), fieldAnnotation, fieldAnnotation.GetCBufferOffset(), allTypes, true);
+
+    BYTE *pDefaultValue = nullptr;
+
+    VarDesc.Name = fieldAnnotation.GetFieldName().c_str();
+    VarDesc.StartOffset = fieldAnnotation.GetCBufferOffset();
+    VarDesc.Size = pVarType->GetCBufferSize();
+    VarDesc.StartTexture = UINT_MAX;
+    VarDesc.StartSampler = UINT_MAX;
+    Var.Initialize(this, &VarDesc, pVarType, pDefaultValue);
+    m_Variables.push_back(Var);
+
+    m_Desc.Size = std::max(m_Desc.Size, VarDesc.StartOffset + VarDesc.Size);
+  }
+  m_Desc.Size = (m_Desc.Size + 0x0f) & ~(0x0f); // Round up to 16 bytes for reflection.
+}
+
 HRESULT CShaderReflectionConstantBuffer::GetDesc(D3D12_SHADER_BUFFER_DESC *pDesc) {
 HRESULT CShaderReflectionConstantBuffer::GetDesc(D3D12_SHADER_BUFFER_DESC *pDesc) {
   if (!pDesc)
   if (!pDesc)
     return E_POINTER;
     return E_POINTER;
@@ -1392,6 +1483,7 @@ static D3D_SHADER_INPUT_TYPE ResourceToShaderInputType(DxilResourceBase *RB) {
     return D3D_SIT_UAV_RWSTRUCTURED;
     return D3D_SIT_UAV_RWSTRUCTURED;
   }
   }
   case DxilResource::Kind::TBuffer:
   case DxilResource::Kind::TBuffer:
+    return D3D_SIT_TBUFFER;
   case DxilResource::Kind::TypedBuffer:
   case DxilResource::Kind::TypedBuffer:
   case DxilResource::Kind::Texture1D:
   case DxilResource::Kind::Texture1D:
   case DxilResource::Kind::Texture1DArray:
   case DxilResource::Kind::Texture1DArray:
@@ -1415,7 +1507,7 @@ static D3D_SHADER_INPUT_TYPE ResourceToShaderInputType(DxilResourceBase *RB) {
 
 
 static D3D_RESOURCE_RETURN_TYPE ResourceToReturnType(DxilResourceBase *RB) {
 static D3D_RESOURCE_RETURN_TYPE ResourceToReturnType(DxilResourceBase *RB) {
   DxilResource *R = DxilResourceFromBase(RB);
   DxilResource *R = DxilResourceFromBase(RB);
-  if (R != nullptr) {
+  if (R != nullptr && !R->IsTBuffer()) {
     CompType CT = R->GetCompType();
     CompType CT = R->GetCompType();
     if (CT.GetKind() == CompType::Kind::F64) return D3D_RETURN_TYPE_DOUBLE;
     if (CT.GetKind() == CompType::Kind::F64) return D3D_RETURN_TYPE_DOUBLE;
     if (CT.IsUNorm()) return D3D_RETURN_TYPE_UNORM;
     if (CT.IsUNorm()) return D3D_RETURN_TYPE_UNORM;
@@ -1437,8 +1529,9 @@ static D3D_SRV_DIMENSION ResourceToDimension(DxilResourceBase *RB) {
   switch (RB->GetKind()) {
   switch (RB->GetKind()) {
   case DxilResource::Kind::StructuredBuffer:
   case DxilResource::Kind::StructuredBuffer:
   case DxilResource::Kind::TypedBuffer:
   case DxilResource::Kind::TypedBuffer:
-  case DxilResource::Kind::TBuffer:
     return D3D_SRV_DIMENSION_BUFFER;
     return D3D_SRV_DIMENSION_BUFFER;
+  case DxilResource::Kind::TBuffer:
+    return D3D_SRV_DIMENSION_UNKNOWN; // Fxc returns this
   case DxilResource::Kind::Texture1D:
   case DxilResource::Kind::Texture1D:
     return D3D_SRV_DIMENSION_TEXTURE1D;
     return D3D_SRV_DIMENSION_TEXTURE1D;
   case DxilResource::Kind::Texture1DArray:
   case DxilResource::Kind::Texture1DArray:
@@ -1467,6 +1560,8 @@ static D3D_SRV_DIMENSION ResourceToDimension(DxilResourceBase *RB) {
 }
 }
 
 
 static UINT ResourceToFlags(DxilResourceBase *RB) {
 static UINT ResourceToFlags(DxilResourceBase *RB) {
+  if (RB->GetClass() == DXIL::ResourceClass::CBuffer)
+    return D3D_SIF_USERPACKED;
   UINT result = 0;
   UINT result = 0;
   DxilResource *R = DxilResourceFromBase(RB);
   DxilResource *R = DxilResourceFromBase(RB);
   if (R != nullptr &&
   if (R != nullptr &&
@@ -1486,9 +1581,9 @@ static UINT ResourceToFlags(DxilResourceBase *RB) {
         break;
         break;
       }
       }
     }
     }
-  }
-  // D3D_SIF_USERPACKED
-  if (RB->GetClass() == DXIL::ResourceClass::Sampler) {
+  } else  if (R && R->IsTBuffer()) {
+    return D3D_SIF_USERPACKED;
+  } else  if (RB->GetClass() == DXIL::ResourceClass::Sampler) {
     DxilSampler *S = static_cast<DxilSampler *>(RB);
     DxilSampler *S = static_cast<DxilSampler *>(RB);
     if (S->GetSamplerKind() == DXIL::SamplerKind::Comparison)
     if (S->GetSamplerKind() == DXIL::SamplerKind::Comparison)
       result |= D3D_SIF_COMPARISON_SAMPLER;
       result |= D3D_SIF_COMPARISON_SAMPLER;
@@ -1520,8 +1615,7 @@ void DxilModuleReflection::CreateReflectionObjectForResource(DxilResourceBase *R
     if (inputBind.NumSamples == 0) {
     if (inputBind.NumSamples == 0) {
       if (R->IsStructuredBuffer()) {
       if (R->IsStructuredBuffer()) {
         inputBind.NumSamples = CalcResTypeSize(*m_pDxilModule, *R);
         inputBind.NumSamples = CalcResTypeSize(*m_pDxilModule, *R);
-      }
-      else if (!R->IsRawBuffer()) {
+      } else if (!R->IsRawBuffer() && !R->IsTBuffer()) {
         inputBind.NumSamples = 0xFFFFFFFF;
         inputBind.NumSamples = 0xFFFFFFFF;
       }
       }
     }
     }
@@ -1711,6 +1805,7 @@ void DxilModuleReflection::CreateReflectionObjects() {
   for (auto && cb : m_pDxilModule->GetCBuffers()) {
   for (auto && cb : m_pDxilModule->GetCBuffers()) {
     std::unique_ptr<CShaderReflectionConstantBuffer> rcb(new CShaderReflectionConstantBuffer());
     std::unique_ptr<CShaderReflectionConstantBuffer> rcb(new CShaderReflectionConstantBuffer());
     rcb->Initialize(*m_pDxilModule, *(cb.get()), m_Types, m_bUsageInMetadata);
     rcb->Initialize(*m_pDxilModule, *(cb.get()), m_Types, m_bUsageInMetadata);
+    m_CBsByName[rcb->GetName()] = (UINT)m_CBs.size();
     m_CBs.emplace_back(std::move(rcb));
     m_CBs.emplace_back(std::move(rcb));
   }
   }
 
 
@@ -1721,14 +1816,22 @@ void DxilModuleReflection::CreateReflectionObjects() {
     }
     }
     std::unique_ptr<CShaderReflectionConstantBuffer> rcb(new CShaderReflectionConstantBuffer());
     std::unique_ptr<CShaderReflectionConstantBuffer> rcb(new CShaderReflectionConstantBuffer());
     rcb->InitializeStructuredBuffer(*m_pDxilModule, *(uav.get()), m_Types);
     rcb->InitializeStructuredBuffer(*m_pDxilModule, *(uav.get()), m_Types);
+    m_StructuredBufferCBsByName[rcb->GetName()] = (UINT)m_CBs.size();
     m_CBs.emplace_back(std::move(rcb));
     m_CBs.emplace_back(std::move(rcb));
   }
   }
   for (auto && srv : m_pDxilModule->GetSRVs()) {
   for (auto && srv : m_pDxilModule->GetSRVs()) {
-    if (srv->GetKind() != DxilResource::Kind::StructuredBuffer) {
+    if (srv->GetKind() != DxilResource::Kind::StructuredBuffer &&
+        srv->GetKind() != DxilResource::Kind::TBuffer) {
       continue;
       continue;
     }
     }
     std::unique_ptr<CShaderReflectionConstantBuffer> rcb(new CShaderReflectionConstantBuffer());
     std::unique_ptr<CShaderReflectionConstantBuffer> rcb(new CShaderReflectionConstantBuffer());
-    rcb->InitializeStructuredBuffer(*m_pDxilModule, *(srv.get()), m_Types);
+    if (srv->GetKind() == DxilResource::Kind::TBuffer) {
+      rcb->InitializeTBuffer(*m_pDxilModule, *(srv.get()), m_Types, m_bUsageInMetadata);
+      m_CBsByName[rcb->GetName()] = (UINT)m_CBs.size();
+    } else {
+      rcb->InitializeStructuredBuffer(*m_pDxilModule, *(srv.get()), m_Types);
+      m_StructuredBufferCBsByName[rcb->GetName()] = (UINT)m_CBs.size();
+    }
     m_CBs.emplace_back(std::move(rcb));
     m_CBs.emplace_back(std::move(rcb));
   }
   }
 
 
@@ -2156,11 +2259,13 @@ ID3D12ShaderReflectionConstantBuffer* DxilModuleReflection::_GetConstantBufferBy
   if (!Name) {
   if (!Name) {
     return &g_InvalidSRConstantBuffer;
     return &g_InvalidSRConstantBuffer;
   }
   }
-  for (UINT index = 0; index < m_CBs.size(); ++index) {
-    if (0 == strcmp(m_CBs[index]->GetName(), Name)) {
-      return m_CBs[index].get();
-    }
-  }
+
+  auto it = m_CBsByName.find(Name);
+  if (it == m_CBsByName.end())
+    it = m_StructuredBufferCBsByName.find(Name);
+  if (it != m_StructuredBufferCBsByName.end())
+    return m_CBs[it->second].get();
+
   return &g_InvalidSRConstantBuffer;
   return &g_InvalidSRConstantBuffer;
 }
 }
 
 
@@ -2499,9 +2604,23 @@ void DxilLibraryReflection::AddResourceDependencies() {
         break;
         break;
       case DXIL::ResourceClass::SRV:
       case DXIL::ResourceClass::SRV:
         func->AddResourceReference(SRVsStart + id);
         func->AddResourceReference(SRVsStart + id);
+        if (DXIL::IsStructuredBuffer(RR.GetResourceKind())) {
+          auto it = m_StructuredBufferCBsByName.find(RR.GetName());
+          if (it != m_StructuredBufferCBsByName.end())
+            func->AddCBReference(it->second);
+        } else if (RR.GetResourceKind() == DXIL::ResourceKind::TBuffer) {
+          auto it = m_CBsByName.find(RR.GetName());
+          if (it != m_CBsByName.end())
+            func->AddCBReference(it->second);
+        }
         break;
         break;
       case DXIL::ResourceClass::UAV:
       case DXIL::ResourceClass::UAV:
         func->AddResourceReference(UAVsStart + id);
         func->AddResourceReference(UAVsStart + id);
+        if (DXIL::IsStructuredBuffer(RR.GetResourceKind())) {
+          auto it = m_StructuredBufferCBsByName.find(RR.GetName());
+          if (it != m_StructuredBufferCBsByName.end())
+            func->AddCBReference(it->second);
+        }
         break;
         break;
       default:
       default:
         DXASSERT(false, "Unrecognized ResourceClass in RDAT");
         DXASSERT(false, "Unrecognized ResourceClass in RDAT");

+ 55 - 9
tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp

@@ -1597,19 +1597,62 @@ unsigned RoundToAlign(unsigned num, unsigned mod) {
   return num;
   return num;
 }
 }
 
 
+// Retrieve the last scalar or vector element type.
+// This has to be recursive for the nasty empty struct case.
+// returns true if found, false if we must backtrack.
+bool RetrieveLastElementType(Type *Ty, Type *&EltTy) {
+  if (Ty->isStructTy()) {
+    if (Ty->getStructNumElements() == 0)
+      return false;
+    for (unsigned i = Ty->getStructNumElements(); i > 0; --i) {
+      if (RetrieveLastElementType(Ty->getStructElementType(i - 1), EltTy))
+        return true;
+    }
+  } else if (Ty->isArrayTy()) {
+    if (RetrieveLastElementType(Ty->getArrayElementType(), EltTy))
+      return true;
+  } else if ((Ty->isVectorTy() || Ty->isSingleValueType())) {
+    EltTy = Ty->getScalarType();
+    return true;
+  }
+  return false;
+}
+
 // Here the size is CB size.
 // Here the size is CB size.
 // Offset still needs to be aligned based on type since this
 // Offset still needs to be aligned based on type since this
 // is the legacy cbuffer global path.
 // is the legacy cbuffer global path.
 unsigned AlignCBufferOffset(unsigned offset, unsigned size, llvm::Type *Ty,
 unsigned AlignCBufferOffset(unsigned offset, unsigned size, llvm::Type *Ty,
-                            bool bRowMajor) {
+                            bool bRowMajor,
+                            bool bMinPrecMode, bool &bCurRowIsMinPrec) {
   DXASSERT(!(offset & 1), "otherwise we have an invalid offset.");
   DXASSERT(!(offset & 1), "otherwise we have an invalid offset.");
   bool bNeedNewRow = Ty->isArrayTy();
   bool bNeedNewRow = Ty->isArrayTy();
-  if (!bNeedNewRow && Ty->isStructTy()) {
-    if (HLMatrixType mat = HLMatrixType::dyn_cast(Ty)) {
-      bNeedNewRow |= !bRowMajor && mat.getNumColumns() > 1;
-      bNeedNewRow |= bRowMajor && mat.getNumRows() > 1;
+  // In min-precision mode, a new row is needed when
+  // going into or out of min-precision component type.
+  if (!bNeedNewRow) {
+    bool bMinPrec = false;
+    if (Ty->isStructTy()) {
+      if (HLMatrixType mat = HLMatrixType::dyn_cast(Ty)) {
+        bNeedNewRow |= !bRowMajor && mat.getNumColumns() > 1;
+        bNeedNewRow |= bRowMajor && mat.getNumRows() > 1;
+        bMinPrec = bMinPrecMode && mat.getElementType(false)->getScalarSizeInBits() < 32;
+      } else {
+        bNeedNewRow = true;
+        if (bMinPrecMode) {
+          // Need to get min-prec of last element of structure,
+          // in case we pack something else into the end.
+          Type *EltTy = nullptr;
+          if (RetrieveLastElementType(Ty, EltTy))
+            bCurRowIsMinPrec = EltTy->getScalarSizeInBits() < 32;
+        }
+      }
     } else {
     } else {
-      bNeedNewRow = true;
+      DXASSERT_NOMSG(Ty->isVectorTy() || Ty->isSingleValueType());
+      // vector or scalar
+      bMinPrec = bMinPrecMode && Ty->getScalarSizeInBits() < 32;
+    }
+    if (bMinPrecMode) {
+      bNeedNewRow |= bCurRowIsMinPrec != bMinPrec;
+      bCurRowIsMinPrec = bMinPrec;
     }
     }
   }
   }
   unsigned scalarSizeInBytes = Ty->getScalarSizeInBits() / 8;
   unsigned scalarSizeInBytes = Ty->getScalarSizeInBits() / 8;
@@ -1621,7 +1664,8 @@ unsigned AlignCBufferOffset(unsigned offset, unsigned size, llvm::Type *Ty,
 unsigned
 unsigned
 AllocateDxilConstantBuffer(HLCBuffer &CB,
 AllocateDxilConstantBuffer(HLCBuffer &CB,
                            std::unordered_map<Constant *, DxilFieldAnnotation>
                            std::unordered_map<Constant *, DxilFieldAnnotation>
-                               &constVarAnnotationMap) {
+                               &constVarAnnotationMap,
+                           bool bMinPrecMode) {
   unsigned offset = 0;
   unsigned offset = 0;
 
 
   // Scan user allocated constants first.
   // Scan user allocated constants first.
@@ -1636,6 +1680,7 @@ AllocateDxilConstantBuffer(HLCBuffer &CB,
   }
   }
 
 
   // Alloc after user allocated constants.
   // Alloc after user allocated constants.
+  bool bCurRowIsMinPrec = false;
   for (const std::unique_ptr<DxilResourceBase> &C : CB.GetConstants()) {
   for (const std::unique_ptr<DxilResourceBase> &C : CB.GetConstants()) {
     if (C->GetLowerBound() != UINT_MAX)
     if (C->GetLowerBound() != UINT_MAX)
       continue;
       continue;
@@ -1648,7 +1693,7 @@ AllocateDxilConstantBuffer(HLCBuffer &CB,
                                MatrixOrientation::RowMajor
                                MatrixOrientation::RowMajor
                          : false;
                          : false;
     // Align offset.
     // Align offset.
-    offset = AlignCBufferOffset(offset, size, Ty, bRowMajor);
+    offset = AlignCBufferOffset(offset, size, Ty, bRowMajor, bMinPrecMode, bCurRowIsMinPrec);
     if (C->GetLowerBound() == UINT_MAX) {
     if (C->GetLowerBound() == UINT_MAX) {
       C->SetLowerBound(offset);
       C->SetLowerBound(offset);
     }
     }
@@ -1663,7 +1708,8 @@ void AllocateDxilConstantBuffers(
                        &constVarAnnotationMap) {
                        &constVarAnnotationMap) {
   for (unsigned i = 0; i < HLM.GetCBuffers().size(); i++) {
   for (unsigned i = 0; i < HLM.GetCBuffers().size(); i++) {
     HLCBuffer &CB = *static_cast<HLCBuffer *>(&(HLM.GetCBuffer(i)));
     HLCBuffer &CB = *static_cast<HLCBuffer *>(&(HLM.GetCBuffer(i)));
-    unsigned size = AllocateDxilConstantBuffer(CB, constVarAnnotationMap);
+    unsigned size = AllocateDxilConstantBuffer(CB, constVarAnnotationMap,
+      HLM.GetHLOptions().bUseMinPrecision);
     CB.SetSize(size);
     CB.SetSize(size);
   }
   }
 }
 }

+ 1 - 1
tools/clang/test/HLSLFileCheck/d3dreflect/anon_struct.hlsl

@@ -25,7 +25,7 @@ float main(int N : A, int C : B) : SV_TARGET {
 // CHECK:         ID3D12ShaderReflectionVariable:
 // CHECK:         ID3D12ShaderReflectionVariable:
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: CB
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: CB
 // CHECK:             Size: 4
 // CHECK:             Size: 4
-// CHECK:             uFlags: 0x2
+// CHECK:             uFlags: (D3D_SVF_USED)
 // CHECK:           ID3D12ShaderReflectionType:
 // CHECK:           ID3D12ShaderReflectionType:
 // CHECK:             D3D12_SHADER_TYPE_DESC: Name: anon
 // CHECK:             D3D12_SHADER_TYPE_DESC: Name: anon
 // CHECK:               Class: D3D_SVC_STRUCT
 // CHECK:               Class: D3D_SVC_STRUCT

+ 193 - 0
tools/clang/test/HLSLFileCheck/d3dreflect/cb_1x1array.hlsl

@@ -0,0 +1,193 @@
+// RUN: %dxc -E main -T vs_6_0 -Vd -validator-version 0.0 %s | %D3DReflect %s | FileCheck %s
+
+float1x1 i1x1_arr0_1[1];
+float1x1 i1x1_arr0[3];
+float3x1 i3x1_arr0[4];
+float1x3 i1x3_arr0[5];
+row_major float3x1 rm_i3x1_arr0[6];
+row_major float1x3 rm_i1x3_arr0[7];
+
+cbuffer CB1 {
+  float1x1 i1x1_arr1[8];
+}
+
+struct CBStruct {
+  float1x1 i1x1_arr2[9];
+};
+
+ConstantBuffer<CBStruct> CB2;
+
+float main() : OUT {
+  return i1x1_arr0[0]
+    + i1x1_arr1[1]
+    + CB2.i1x1_arr2[2];
+}
+
+#if 0
+
+// CHECK:     Constant Buffers:
+// CHECK-NEXT:     ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: $Globals
+// CHECK-NEXT:         Type: D3D_CT_CBUFFER
+// CHECK-NEXT:         Size: 768
+// CHECK-NEXT:         uFlags: 0
+// CHECK-NEXT:         Num Variables: 6
+// CHECK-NEXT:       {
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i1x1_arr0_1
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 0
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float1x1
+// CHECK-NEXT:               Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 1
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: $Globals
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i1x1_arr0
+// CHECK-NEXT:             Size: 36
+// CHECK-NEXT:             StartOffset: 16
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float1x1
+// CHECK-NEXT:               Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 3
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: $Globals
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i3x1_arr0
+// CHECK-NEXT:             Size: 60
+// CHECK-NEXT:             StartOffset: 64
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float3x1
+// CHECK-NEXT:               Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 4
+// CHECK-NEXT:               Rows: 3
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: $Globals
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i1x3_arr0
+// CHECK-NEXT:             Size: 228
+// CHECK-NEXT:             StartOffset: 128
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float1x3
+// CHECK-NEXT:               Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 5
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 3
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: $Globals
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: rm_i3x1_arr0
+// CHECK-NEXT:             Size: 276
+// CHECK-NEXT:             StartOffset: 368
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float3x1
+// CHECK-NEXT:               Class: D3D_SVC_MATRIX_ROWS
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 6
+// CHECK-NEXT:               Rows: 3
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: $Globals
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: rm_i1x3_arr0
+// CHECK-NEXT:             Size: 108
+// CHECK-NEXT:             StartOffset: 656
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float1x3
+// CHECK-NEXT:               Class: D3D_SVC_MATRIX_ROWS
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 7
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 3
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: $Globals
+// CHECK-NEXT:       }
+// CHECK-NEXT:     ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: CB1
+// CHECK-NEXT:         Type: D3D_CT_CBUFFER
+// CHECK-NEXT:         Size: 128
+// CHECK-NEXT:         uFlags: 0
+// CHECK-NEXT:         Num Variables: 1
+// CHECK-NEXT:       {
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i1x1_arr1
+// CHECK-NEXT:             Size: 116
+// CHECK-NEXT:             StartOffset: 0
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float1x1
+// CHECK-NEXT:               Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 8
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: CB1
+// CHECK-NEXT:       }
+// CHECK-NEXT:     ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: CB2
+// CHECK-NEXT:         Type: D3D_CT_CBUFFER
+// CHECK-NEXT:         Size: 144
+// CHECK-NEXT:         uFlags: 0
+// CHECK-NEXT:         Num Variables: 1
+// CHECK-NEXT:       {
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: CB2
+// CHECK-NEXT:             Size: 132
+// CHECK-NEXT:             StartOffset: 0
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: CBStruct
+// CHECK-NEXT:               Class: D3D_SVC_STRUCT
+// CHECK-NEXT:               Type: D3D_SVT_VOID
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 9
+// CHECK-NEXT:               Members: 1
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:             {
+// CHECK-NEXT:               ID3D12ShaderReflectionType:
+// CHECK-NEXT:                 D3D12_SHADER_TYPE_DESC: Name: float1x1
+// CHECK-NEXT:                   Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                   Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                   Elements: 9
+// CHECK-NEXT:                   Rows: 1
+// CHECK-NEXT:                   Columns: 1
+// CHECK-NEXT:                   Members: 0
+// CHECK-NEXT:                   Offset: 0
+// CHECK-NEXT:             }
+// CHECK-NEXT:           CBuffer: CB2
+// CHECK-NEXT:       }
+
+#endif

+ 1 - 1
tools/clang/test/HLSLFileCheck/d3dreflect/cb_array.hlsl

@@ -23,7 +23,7 @@ float main(int i : A) : SV_TARGET
 // CHECK:         ID3D12ShaderReflectionVariable:
 // CHECK:         ID3D12ShaderReflectionVariable:
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: A
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: A
 // CHECK:             Size: 84
 // CHECK:             Size: 84
-// CHECK:             uFlags: 0x2
+// CHECK:             uFlags: (D3D_SVF_USED)
 // CHECK:           ID3D12ShaderReflectionType:
 // CHECK:           ID3D12ShaderReflectionType:
 // CHECK:             D3D12_SHADER_TYPE_DESC: Name: float
 // CHECK:             D3D12_SHADER_TYPE_DESC: Name: float
 // CHECK:               Class: D3D_SVC_SCALAR
 // CHECK:               Class: D3D_SVC_SCALAR

+ 1 - 1
tools/clang/test/HLSLFileCheck/d3dreflect/cb_sizes.hlsl

@@ -22,7 +22,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: B
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: B
 // CHECK-NEXT:            Size: 16
 // CHECK-NEXT:            Size: 16
 // CHECK-NEXT:            StartOffset: 16
 // CHECK-NEXT:            StartOffset: 16
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 
 
 // CHECK:        ID3D12ShaderReflectionVariable:
 // CHECK:        ID3D12ShaderReflectionVariable:
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: D
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: D

+ 3 - 3
tools/clang/test/HLSLFileCheck/d3dreflect/cbuf-usage-lib.hlsl

@@ -7,7 +7,7 @@
 // CHECK: D3D12_SHADER_BUFFER_DESC: Name: CBuf1
 // CHECK: D3D12_SHADER_BUFFER_DESC: Name: CBuf1
 // CHECK: Num Variables: 1
 // CHECK: Num Variables: 1
 // CHECK: D3D12_SHADER_VARIABLE_DESC: Name: CBuf1
 // CHECK: D3D12_SHADER_VARIABLE_DESC: Name: CBuf1
-// CHECK: uFlags: 0x2
+// CHECK: uFlags: (D3D_SVF_USED)
 // CHECK: CBuffer: CBuf1
 // CHECK: CBuffer: CBuf1
 
 
 // CHECK: D3D12_SHADER_BUFFER_DESC: Name: CBuf0
 // CHECK: D3D12_SHADER_BUFFER_DESC: Name: CBuf0
@@ -15,13 +15,13 @@
 // CHECK: D3D12_SHADER_VARIABLE_DESC: Name: i1
 // CHECK: D3D12_SHADER_VARIABLE_DESC: Name: i1
 // CHECK: uFlags: 0
 // CHECK: uFlags: 0
 // CHECK: D3D12_SHADER_VARIABLE_DESC: Name: f1
 // CHECK: D3D12_SHADER_VARIABLE_DESC: Name: f1
-// CHECK: uFlags: 0x2
+// CHECK: uFlags: (D3D_SVF_USED)
 // CHECK: CBuffer: CBuf0
 // CHECK: CBuffer: CBuf0
 
 
 // CHECK: D3D12_SHADER_BUFFER_DESC: Name: CBuf2
 // CHECK: D3D12_SHADER_BUFFER_DESC: Name: CBuf2
 // CHECK: Num Variables: 1
 // CHECK: Num Variables: 1
 // CHECK: D3D12_SHADER_VARIABLE_DESC: Name: CBuf2
 // CHECK: D3D12_SHADER_VARIABLE_DESC: Name: CBuf2
-// CHECK: uFlags: 0x2
+// CHECK: uFlags: (D3D_SVF_USED)
 // CHECK: CBuffer: CBuf2
 // CHECK: CBuffer: CBuf2
 
 
 cbuffer CBuf0 {
 cbuffer CBuf0 {

+ 6 - 6
tools/clang/test/HLSLFileCheck/d3dreflect/cbuf-usage-phi.hlsl

@@ -41,26 +41,26 @@ float4 main() : SV_Target {
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: UnusedGlobal
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: UnusedGlobal
 // CHECK:             uFlags: 0{{$}}
 // CHECK:             uFlags: 0{{$}}
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: LookupTable
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: LookupTable
-// CHECK:             uFlags: 0x2
+// CHECK:             uFlags: (D3D_SVF_USED)
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: TestBool
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: TestBool
-// CHECK:             uFlags: 0x2
+// CHECK:             uFlags: (D3D_SVF_USED)
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: TestBool2
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: TestBool2
-// CHECK:             uFlags: 0x2
+// CHECK:             uFlags: (D3D_SVF_USED)
 // CHECK:       }
 // CHECK:       }
 // CHECK:     ID3D12ShaderReflectionConstantBuffer:
 // CHECK:     ID3D12ShaderReflectionConstantBuffer:
 // CHECK:       D3D12_SHADER_BUFFER_DESC: Name: CB
 // CHECK:       D3D12_SHADER_BUFFER_DESC: Name: CB
 // CHECK:       {
 // CHECK:       {
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: TestInt
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: TestInt
-// CHECK:             uFlags: 0x2
+// CHECK:             uFlags: (D3D_SVF_USED)
 // CHECK:       }
 // CHECK:       }
 // CHECK:   Bound Resources:
 // CHECK:   Bound Resources:
 // CHECK:     D3D12_SHADER_BUFFER_DESC: Name: $Globals
 // CHECK:     D3D12_SHADER_BUFFER_DESC: Name: $Globals
 // CHECK:       BindCount: 1
 // CHECK:       BindCount: 1
 // CHECK:       BindPoint: 0
 // CHECK:       BindPoint: 0
 // CHECK:       Space: 0
 // CHECK:       Space: 0
-// CHECK:       uFlags: 0{{$}}
+// CHECK:       uFlags: (D3D_SIF_USERPACKED)
 // CHECK:     D3D12_SHADER_BUFFER_DESC: Name: CB
 // CHECK:     D3D12_SHADER_BUFFER_DESC: Name: CB
 // CHECK:       BindCount: 1
 // CHECK:       BindCount: 1
 // CHECK:       BindPoint: 1
 // CHECK:       BindPoint: 1
 // CHECK:       Space: 0
 // CHECK:       Space: 0
-// CHECK:       uFlags: 0{{$}}
+// CHECK:       uFlags: (D3D_SIF_USERPACKED)

+ 1 - 1
tools/clang/test/HLSLFileCheck/d3dreflect/cbuffer_default_val.hlsl

@@ -24,7 +24,7 @@ float main() : SV_TARGET
 // CHECK:         ID3D12ShaderReflectionVariable:
 // CHECK:         ID3D12ShaderReflectionVariable:
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: t
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: t
 // CHECK:             Size: 4
 // CHECK:             Size: 4
-// CHECK:             uFlags: 0x2
+// CHECK:             uFlags: (D3D_SVF_USED)
 // CHECK:             DefaultValue: <nullptr>
 // CHECK:             DefaultValue: <nullptr>
 // CHECK:           ID3D12ShaderReflectionType:
 // CHECK:           ID3D12ShaderReflectionType:
 // CHECK:             D3D12_SHADER_TYPE_DESC: Name: float
 // CHECK:             D3D12_SHADER_TYPE_DESC: Name: float

+ 2 - 2
tools/clang/test/HLSLFileCheck/d3dreflect/empty_struct2.hlsl

@@ -50,7 +50,7 @@ float4 main(float4 pos : POSITION) : SV_POSITION { return foo + bar; }
 // CHECK:         ID3D12ShaderReflectionVariable:
 // CHECK:         ID3D12ShaderReflectionVariable:
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: foo
 // CHECK:           D3D12_SHADER_VARIABLE_DESC: Name: foo
 // CHECK:             Size: 16
 // CHECK:             Size: 16
-// CHECK:             uFlags: 0x2
+// CHECK:             uFlags: (D3D_SVF_USED)
 // CHECK:           ID3D12ShaderReflectionType:
 // CHECK:           ID3D12ShaderReflectionType:
 // CHECK:             D3D12_SHADER_TYPE_DESC: Name: float4
 // CHECK:             D3D12_SHADER_TYPE_DESC: Name: float4
 // CHECK:               Class: D3D_SVC_VECTOR
 // CHECK:               Class: D3D_SVC_VECTOR
@@ -86,7 +86,7 @@ float4 main(float4 pos : POSITION) : SV_POSITION { return foo + bar; }
 // CHECK:          D3D12_SHADER_VARIABLE_DESC: Name: bar
 // CHECK:          D3D12_SHADER_VARIABLE_DESC: Name: bar
 // CHECK:            Size: 16
 // CHECK:            Size: 16
 // CHECK:            StartOffset: 0
 // CHECK:            StartOffset: 0
-// CHECK:            uFlags: 0x2
+// CHECK:            uFlags: (D3D_SVF_USED)
 // CHECK:            DefaultValue: <nullptr>
 // CHECK:            DefaultValue: <nullptr>
 // CHECK:          ID3D12ShaderReflectionType:
 // CHECK:          ID3D12ShaderReflectionType:
 // CHECK:            D3D12_SHADER_TYPE_DESC: Name: float4
 // CHECK:            D3D12_SHADER_TYPE_DESC: Name: float4

+ 4 - 4
tools/clang/test/HLSLFileCheck/d3dreflect/lib_cb_matrix_array.hlsl

@@ -42,7 +42,7 @@ void RayGenShader()
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: Color
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: Color
 // CHECK-NEXT:               Size: 16
 // CHECK-NEXT:               Size: 16
 // CHECK-NEXT:               StartOffset: 0
 // CHECK-NEXT:               StartOffset: 0
-// CHECK-NEXT:               uFlags: 0x2
+// CHECK-NEXT:               uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float4
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float4
@@ -58,7 +58,7 @@ void RayGenShader()
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: VectorArray
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: VectorArray
 // CHECK-NEXT:               Size: 48
 // CHECK-NEXT:               Size: 48
 // CHECK-NEXT:               StartOffset: 16
 // CHECK-NEXT:               StartOffset: 16
-// CHECK-NEXT:               uFlags: 0x2
+// CHECK-NEXT:               uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float4
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float4
@@ -74,7 +74,7 @@ void RayGenShader()
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: FloatArray
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: FloatArray
 // CHECK-NEXT:               Size: 244
 // CHECK-NEXT:               Size: 244
 // CHECK-NEXT:               StartOffset: 64
 // CHECK-NEXT:               StartOffset: 64
-// CHECK-NEXT:               uFlags: 0x2
+// CHECK-NEXT:               uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float
@@ -90,7 +90,7 @@ void RayGenShader()
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: MatrixArray
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: MatrixArray
 // CHECK-NEXT:               Size: 128
 // CHECK-NEXT:               Size: 128
 // CHECK-NEXT:               StartOffset: 320
 // CHECK-NEXT:               StartOffset: 320
-// CHECK-NEXT:               uFlags: 0x2
+// CHECK-NEXT:               uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float4x4
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float4x4

+ 1 - 1
tools/clang/test/HLSLFileCheck/d3dreflect/lib_exports1.hlsl

@@ -65,7 +65,7 @@ float4 PSMain(int idx : INDEX) : SV_Target {
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         NumSamples (or stride): 4294967295
 // CHECK:         NumSamples (or stride): 4294967295
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:     D3D12_FUNCTION_DESC: Name: PS_RENAMED
 // CHECK:     D3D12_FUNCTION_DESC: Name: PS_RENAMED
 // CHECK:       Shader Version: Pixel 6.3
 // CHECK:       Shader Version: Pixel 6.3

+ 2 - 2
tools/clang/test/HLSLFileCheck/d3dreflect/lib_exports2.hlsl

@@ -74,7 +74,7 @@ void RayGen() {
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         NumSamples (or stride): 4294967295
 // CHECK:         NumSamples (or stride): 4294967295
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:     D3D12_FUNCTION_DESC: Name: VSMain
 // CHECK:     D3D12_FUNCTION_DESC: Name: VSMain
 // CHECK:       Shader Version: Vertex 6.3
 // CHECK:       Shader Version: Vertex 6.3
@@ -89,4 +89,4 @@ void RayGen() {
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         NumSamples (or stride): 4294967295
 // CHECK:         NumSamples (or stride): 4294967295
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)

+ 2 - 2
tools/clang/test/HLSLFileCheck/d3dreflect/lib_exports4.hlsl

@@ -35,7 +35,7 @@ float4 PSMain(int idx : INDEX) : SV_Target {
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         NumSamples (or stride): 4294967295
 // CHECK:         NumSamples (or stride): 4294967295
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:     D3D12_FUNCTION_DESC: Name: \01?VSMain@@YA?AV?$vector@M$03@@H@Z
 // CHECK:     D3D12_FUNCTION_DESC: Name: \01?VSMain@@YA?AV?$vector@M$03@@H@Z
 // CHECK:       Shader Version: Library 6.3
 // CHECK:       Shader Version: Library 6.3
@@ -75,7 +75,7 @@ float4 PSMain(int idx : INDEX) : SV_Target {
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         NumSamples (or stride): 4294967295
 // CHECK:         NumSamples (or stride): 4294967295
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:     D3D12_FUNCTION_DESC: Name: VSMain
 // CHECK:     D3D12_FUNCTION_DESC: Name: VSMain
 // CHECK:       Shader Version: Pixel 6.3
 // CHECK:       Shader Version: Pixel 6.3

+ 2 - 2
tools/clang/test/HLSLFileCheck/d3dreflect/lib_exports_nocollision.hlsl

@@ -49,7 +49,7 @@ void RayGen() {
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         NumSamples (or stride): 4294967295
 // CHECK:         NumSamples (or stride): 4294967295
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:     D3D12_FUNCTION_DESC: Name: \01?Foo@@YAXXZ
 // CHECK:     D3D12_FUNCTION_DESC: Name: \01?Foo@@YAXXZ
 // CHECK:       Shader Version: RayGeneration 6.3
 // CHECK:       Shader Version: RayGeneration 6.3
@@ -94,4 +94,4 @@ void RayGen() {
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK:         NumSamples (or stride): 4294967295
 // CHECK:         NumSamples (or stride): 4294967295
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)

+ 206 - 16
tools/clang/test/HLSLFileCheck/d3dreflect/lib_global.hlsl

@@ -8,16 +8,14 @@
 #if 0
 #if 0
 // CHECK: ID3D12LibraryReflection:
 // CHECK: ID3D12LibraryReflection:
 // CHECK-NEXT:   D3D12_LIBRARY_DESC:
 // CHECK-NEXT:   D3D12_LIBRARY_DESC:
-// CHECK-NEXT:     Creator: <nullptr>
-// CHECK-NEXT:     Flags: 0
+// CHECK:     Flags: 0
 // CHECK-NEXT:     FunctionCount: 2
 // CHECK-NEXT:     FunctionCount: 2
 // CHECK-NEXT:   ID3D12FunctionReflection:
 // CHECK-NEXT:   ID3D12FunctionReflection:
 // CHECK-NEXT:     D3D12_FUNCTION_DESC: Name: _GLOBAL__sub_I_lib_global.hlsl
 // CHECK-NEXT:     D3D12_FUNCTION_DESC: Name: _GLOBAL__sub_I_lib_global.hlsl
 // CHECK-NEXT:       Shader Version: Library 6.3
 // CHECK-NEXT:       Shader Version: Library 6.3
-// CHECK-NEXT:       Creator: <nullptr>
-// CHECK-NEXT:       Flags: 0
-// CHECK-NEXT:       ConstantBuffers: 1
-// CHECK-NEXT:       BoundResources: 1
+// CHECK:       Flags: 0
+// CHECK-NEXT:       ConstantBuffers: 2
+// CHECK-NEXT:       BoundResources: 2
 // CHECK-NEXT:       FunctionParameterCount: 0
 // CHECK-NEXT:       FunctionParameterCount: 0
 // CHECK-NEXT:       HasReturn: FALSE
 // CHECK-NEXT:       HasReturn: FALSE
 // CHECK-NEXT:     Constant Buffers:
 // CHECK-NEXT:     Constant Buffers:
@@ -37,7 +35,7 @@
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float16_t
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float16_t
 // CHECK-NEXT:                 Class: D3D_SVC_SCALAR
 // CHECK-NEXT:                 Class: D3D_SVC_SCALAR
-// CHECK-NEXT:                 Type: D3D_SVT_MIN16FLOAT
+// CHECK-NEXT:                 Type: D3D_SVT_FLOAT16
 // CHECK-NEXT:                 Elements: 0
 // CHECK-NEXT:                 Elements: 0
 // CHECK-NEXT:                 Rows: 1
 // CHECK-NEXT:                 Rows: 1
 // CHECK-NEXT:                 Columns: 1
 // CHECK-NEXT:                 Columns: 1
@@ -48,12 +46,12 @@
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: f
 // CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: f
 // CHECK-NEXT:               Size: 2
 // CHECK-NEXT:               Size: 2
 // CHECK-NEXT:               StartOffset: 2
 // CHECK-NEXT:               StartOffset: 2
-// CHECK-NEXT:               uFlags: 0x2
+// CHECK-NEXT:               uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:               DefaultValue: <nullptr>
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:             ID3D12ShaderReflectionType:
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float16_t
 // CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float16_t
 // CHECK-NEXT:                 Class: D3D_SVC_SCALAR
 // CHECK-NEXT:                 Class: D3D_SVC_SCALAR
-// CHECK-NEXT:                 Type: D3D_SVT_MIN16FLOAT
+// CHECK-NEXT:                 Type: D3D_SVT_FLOAT16
 // CHECK-NEXT:                 Elements: 0
 // CHECK-NEXT:                 Elements: 0
 // CHECK-NEXT:                 Rows: 1
 // CHECK-NEXT:                 Rows: 1
 // CHECK-NEXT:                 Columns: 1
 // CHECK-NEXT:                 Columns: 1
@@ -61,6 +59,86 @@
 // CHECK-NEXT:                 Offset: 0
 // CHECK-NEXT:                 Offset: 0
 // CHECK-NEXT:             CBuffer: X
 // CHECK-NEXT:             CBuffer: X
 // CHECK-NEXT:         }
 // CHECK-NEXT:         }
+// CHECK-NEXT:       ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:         D3D12_SHADER_BUFFER_DESC: Name: X
+// CHECK-NEXT:           Type: D3D_CT_RESOURCE_BIND_INFO
+// CHECK-NEXT:           Size: 56
+// CHECK-NEXT:           uFlags: 0
+// CHECK-NEXT:           Num Variables: 1
+// CHECK-NEXT:         {
+// CHECK-NEXT:           ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: $Element
+// CHECK-NEXT:               Size: 56
+// CHECK-NEXT:               StartOffset: 0
+// CHECK-NEXT:               uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:               DefaultValue: <nullptr>
+// CHECK-NEXT:             ID3D12ShaderReflectionType:
+// CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: SBStruct
+// CHECK-NEXT:                 Class: D3D_SVC_STRUCT
+// CHECK-NEXT:                 Type: D3D_SVT_VOID
+// CHECK-NEXT:                 Elements: 0
+// CHECK-NEXT:                 Rows: 1
+// CHECK-NEXT:                 Columns: 9
+// CHECK-NEXT:                 Members: 6
+// CHECK-NEXT:                 Offset: 0
+// CHECK-NEXT:               {
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: uint64_t
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_UINT64
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 0
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: int64_t
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_INT64
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 8
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: float4
+// CHECK-NEXT:                     Class: D3D_SVC_VECTOR
+// CHECK-NEXT:                     Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 4
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 16
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: int16_t
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_INT16
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 32
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: double
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_DOUBLE
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 40
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: uint16_t
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_UINT16
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 48
+// CHECK-NEXT:               }
+// CHECK-NEXT:             CBuffer: X
+// CHECK-NEXT:         }
 // CHECK-NEXT:     Bound Resources:
 // CHECK-NEXT:     Bound Resources:
 // CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: X
 // CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: X
 // CHECK-NEXT:         Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:         Type: D3D_SIT_CBUFFER
@@ -71,16 +149,106 @@
 // CHECK-NEXT:         ReturnType: <unknown: 0>
 // CHECK-NEXT:         ReturnType: <unknown: 0>
 // CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:         NumSamples (or stride): 0
 // CHECK-NEXT:         NumSamples (or stride): 0
+// CHECK-NEXT:         uFlags: (D3D_SIF_USERPACKED)
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: X
+// CHECK-NEXT:         Type: D3D_SIT_STRUCTURED
+// CHECK-NEXT:         uID: 1
+// CHECK-NEXT:         BindCount: 1
+// CHECK-NEXT:         BindPoint: 4294967295
+// CHECK-NEXT:         Space: 4294967295
+// CHECK-NEXT:         ReturnType: D3D_RETURN_TYPE_MIXED
+// CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_BUFFER
+// CHECK-NEXT:         NumSamples (or stride): 56
 // CHECK-NEXT:         uFlags: 0
 // CHECK-NEXT:         uFlags: 0
 // CHECK-NEXT:   ID3D12FunctionReflection:
 // CHECK-NEXT:   ID3D12FunctionReflection:
 // CHECK-NEXT:     D3D12_FUNCTION_DESC: Name: test
 // CHECK-NEXT:     D3D12_FUNCTION_DESC: Name: test
 // CHECK-NEXT:       Shader Version: Pixel 6.3
 // CHECK-NEXT:       Shader Version: Pixel 6.3
-// CHECK-NEXT:       Creator: <nullptr>
-// CHECK-NEXT:       Flags: 0
-// CHECK-NEXT:       ConstantBuffers: 0
-// CHECK-NEXT:       BoundResources: 2
+// CHECK:       Flags: 0
+// CHECK-NEXT:       ConstantBuffers: 1
+// CHECK-NEXT:       BoundResources: 3
 // CHECK-NEXT:       FunctionParameterCount: 0
 // CHECK-NEXT:       FunctionParameterCount: 0
 // CHECK-NEXT:       HasReturn: FALSE
 // CHECK-NEXT:       HasReturn: FALSE
+// CHECK-NEXT:     Constant Buffers:
+// CHECK-NEXT:       ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:         D3D12_SHADER_BUFFER_DESC: Name: X
+// CHECK-NEXT:           Type: D3D_CT_RESOURCE_BIND_INFO
+// CHECK-NEXT:           Size: 56
+// CHECK-NEXT:           uFlags: 0
+// CHECK-NEXT:           Num Variables: 1
+// CHECK-NEXT:         {
+// CHECK-NEXT:           ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: $Element
+// CHECK-NEXT:               Size: 56
+// CHECK-NEXT:               StartOffset: 0
+// CHECK-NEXT:               uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:               DefaultValue: <nullptr>
+// CHECK-NEXT:             ID3D12ShaderReflectionType:
+// CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: SBStruct
+// CHECK-NEXT:                 Class: D3D_SVC_STRUCT
+// CHECK-NEXT:                 Type: D3D_SVT_VOID
+// CHECK-NEXT:                 Elements: 0
+// CHECK-NEXT:                 Rows: 1
+// CHECK-NEXT:                 Columns: 9
+// CHECK-NEXT:                 Members: 6
+// CHECK-NEXT:                 Offset: 0
+// CHECK-NEXT:               {
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: uint64_t
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_UINT64
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 0
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: int64_t
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_INT64
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 8
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: float4
+// CHECK-NEXT:                     Class: D3D_SVC_VECTOR
+// CHECK-NEXT:                     Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 4
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 16
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: int16_t
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_INT16
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 32
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: double
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_DOUBLE
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 40
+// CHECK-NEXT:                 ID3D12ShaderReflectionType:
+// CHECK-NEXT:                   D3D12_SHADER_TYPE_DESC: Name: uint16_t
+// CHECK-NEXT:                     Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                     Type: D3D_SVT_UINT16
+// CHECK-NEXT:                     Elements: 0
+// CHECK-NEXT:                     Rows: 1
+// CHECK-NEXT:                     Columns: 1
+// CHECK-NEXT:                     Members: 0
+// CHECK-NEXT:                     Offset: 48
+// CHECK-NEXT:               }
+// CHECK-NEXT:             CBuffer: X
+// CHECK-NEXT:         }
 // CHECK-NEXT:     Bound Resources:
 // CHECK-NEXT:     Bound Resources:
 // CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: g_samLinear
 // CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: g_samLinear
 // CHECK-NEXT:         Type: D3D_SIT_SAMPLER
 // CHECK-NEXT:         Type: D3D_SIT_SAMPLER
@@ -101,23 +269,45 @@
 // CHECK-NEXT:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK-NEXT:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
 // CHECK-NEXT:         NumSamples (or stride): 4294967295
 // CHECK-NEXT:         NumSamples (or stride): 4294967295
-// CHECK-NEXT:         uFlags: 0xc
+// CHECK-NEXT:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: X
+// CHECK-NEXT:         Type: D3D_SIT_STRUCTURED
+// CHECK-NEXT:         uID: 1
+// CHECK-NEXT:         BindCount: 1
+// CHECK-NEXT:         BindPoint: 4294967295
+// CHECK-NEXT:         Space: 4294967295
+// CHECK-NEXT:         ReturnType: D3D_RETURN_TYPE_MIXED
+// CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_BUFFER
+// CHECK-NEXT:         NumSamples (or stride): 56
+// CHECK-NEXT:         uFlags: 0
 #endif
 #endif
 
 
 Texture2D    g_txDiffuse;
 Texture2D    g_txDiffuse;
 SamplerState    g_samLinear;
 SamplerState    g_samLinear;
 
 
+struct SBStruct {
+  uint64_t u64;
+  int64_t i64;
+  float4 f4;
+  int16_t i16;
+  double d;     // Here to test alignment
+  uint16_t u16;
+};
+
+// Note legal name collision with cbuffer X
+StructuredBuffer<SBStruct> X;
+
 cbuffer X {
 cbuffer X {
   half e, f;
   half e, f;
 }
 }
 
 
-static float g[2] = { 1, f };
+static float g[2] = { 1, f + X[0].f4.z };
 
 
 [shader("pixel")]
 [shader("pixel")]
 float4 test(float2 c : C) : SV_TARGET
 float4 test(float2 c : C) : SV_TARGET
 {
 {
   float4 x = g_txDiffuse.Sample( g_samLinear, c );
   float4 x = g_txDiffuse.Sample( g_samLinear, c );
-  return x + g[1];
+  return x + g[1] + X[0].f4;
 }
 }
 
 
 void update() {
 void update() {

+ 8 - 8
tools/clang/test/HLSLFileCheck/d3dreflect/reflect-lib-1.hlsl

@@ -32,7 +32,7 @@ float4 function2(float4 x : POSITION) : SV_Position { return x + cbval1 + cbval3
 // CHECK:           ID3D12ShaderReflectionVariable:
 // CHECK:           ID3D12ShaderReflectionVariable:
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval2
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval2
 // CHECK:               Size: 16
 // CHECK:               Size: 16
-// CHECK:               uFlags: 0x2
+// CHECK:               uFlags: (D3D_SVF_USED)
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: int4
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: int4
 // CHECK:                 Class: D3D_SVC_VECTOR
 // CHECK:                 Class: D3D_SVC_VECTOR
@@ -44,7 +44,7 @@ float4 function2(float4 x : POSITION) : SV_Position { return x + cbval1 + cbval3
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval3
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval3
 // CHECK:               Size: 16
 // CHECK:               Size: 16
 // CHECK:               StartOffset: 16
 // CHECK:               StartOffset: 16
-// CHECK:               uFlags: 0x2
+// CHECK:               uFlags: (D3D_SVF_USED)
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: int4
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: int4
 // CHECK:                 Class: D3D_SVC_VECTOR
 // CHECK:                 Class: D3D_SVC_VECTOR
@@ -66,7 +66,7 @@ float4 function2(float4 x : POSITION) : SV_Position { return x + cbval1 + cbval3
 // CHECK:         BindPoint: 5
 // CHECK:         BindPoint: 5
 // CHECK:         ReturnType: D3D_RETURN_TYPE_SINT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_SINT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE1D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE1D
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:   ID3D12FunctionReflection:
 // CHECK:     D3D12_FUNCTION_DESC: Name: \01?function1@@YAMM$min12i@@Z
 // CHECK:     D3D12_FUNCTION_DESC: Name: \01?function1@@YAMM$min12i@@Z
 // CHECK:       Shader Version: Library 6.3
 // CHECK:       Shader Version: Library 6.3
@@ -82,7 +82,7 @@ float4 function2(float4 x : POSITION) : SV_Position { return x + cbval1 + cbval3
 // CHECK:           ID3D12ShaderReflectionVariable:
 // CHECK:           ID3D12ShaderReflectionVariable:
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval1
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval1
 // CHECK:               Size: 4
 // CHECK:               Size: 4
-// CHECK:               uFlags: 0x2
+// CHECK:               uFlags: (D3D_SVF_USED)
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: float
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: float
 // CHECK:                 Class: D3D_SVC_SCALAR
 // CHECK:                 Class: D3D_SVC_SCALAR
@@ -107,7 +107,7 @@ float4 function2(float4 x : POSITION) : SV_Position { return x + cbval1 + cbval3
 // CHECK:         BindPoint: 0
 // CHECK:         BindPoint: 0
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         ReturnType: D3D_RETURN_TYPE_FLOAT
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE1D
 // CHECK:         Dimension: D3D_SRV_DIMENSION_TEXTURE1D
-// CHECK:         uFlags: 0xc
+// CHECK:         uFlags: (D3D_SIF_TEXTURE_COMPONENT_0 | D3D_SIF_TEXTURE_COMPONENT_1)
 // CHECK:       D3D12_SHADER_BUFFER_DESC: Name: b_buf
 // CHECK:       D3D12_SHADER_BUFFER_DESC: Name: b_buf
 // CHECK:         Type: D3D_SIT_UAV_RWBYTEADDRESS
 // CHECK:         Type: D3D_SIT_UAV_RWBYTEADDRESS
 // CHECK:         uID: 1
 // CHECK:         uID: 1
@@ -128,7 +128,7 @@ float4 function2(float4 x : POSITION) : SV_Position { return x + cbval1 + cbval3
 // CHECK:           ID3D12ShaderReflectionVariable:
 // CHECK:           ID3D12ShaderReflectionVariable:
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval1
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval1
 // CHECK:               Size: 4
 // CHECK:               Size: 4
-// CHECK:               uFlags: 0x2
+// CHECK:               uFlags: (D3D_SVF_USED)
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: float
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: float
 // CHECK:                 Class: D3D_SVC_SCALAR
 // CHECK:                 Class: D3D_SVC_SCALAR
@@ -146,7 +146,7 @@ float4 function2(float4 x : POSITION) : SV_Position { return x + cbval1 + cbval3
 // CHECK:           ID3D12ShaderReflectionVariable:
 // CHECK:           ID3D12ShaderReflectionVariable:
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval2
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval2
 // CHECK:               Size: 16
 // CHECK:               Size: 16
-// CHECK:               uFlags: 0x2
+// CHECK:               uFlags: (D3D_SVF_USED)
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: int4
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: int4
 // CHECK:                 Class: D3D_SVC_VECTOR
 // CHECK:                 Class: D3D_SVC_VECTOR
@@ -158,7 +158,7 @@ float4 function2(float4 x : POSITION) : SV_Position { return x + cbval1 + cbval3
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval3
 // CHECK:             D3D12_SHADER_VARIABLE_DESC: Name: cbval3
 // CHECK:               Size: 16
 // CHECK:               Size: 16
 // CHECK:               StartOffset: 16
 // CHECK:               StartOffset: 16
-// CHECK:               uFlags: 0x2
+// CHECK:               uFlags: (D3D_SVF_USED)
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:             ID3D12ShaderReflectionType:
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: int4
 // CHECK:               D3D12_SHADER_TYPE_DESC: Name: int4
 // CHECK:                 Class: D3D_SVC_VECTOR
 // CHECK:                 Class: D3D_SVC_VECTOR

+ 15 - 15
tools/clang/test/HLSLFileCheck/d3dreflect/structured_buffer_layout.hlsl

@@ -16,7 +16,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: CB
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: CB
 // CHECK-NEXT:            Size: 116
 // CHECK-NEXT:            Size: 116
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            StartOffset: 0
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
@@ -244,7 +244,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: s2
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: s2
 // CHECK-NEXT:            Size: 4
 // CHECK-NEXT:            Size: 4
 // CHECK-NEXT:            StartOffset: 128
 // CHECK-NEXT:            StartOffset: 128
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S2
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S2
@@ -271,7 +271,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: s3
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: s3
 // CHECK-NEXT:            Size: 4
 // CHECK-NEXT:            Size: 4
 // CHECK-NEXT:            StartOffset: 144
 // CHECK-NEXT:            StartOffset: 144
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S2
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S2
@@ -370,7 +370,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: ConstantBufferArray
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: ConstantBufferArray
 // CHECK-NEXT:            Size: 244
 // CHECK-NEXT:            Size: 244
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            StartOffset: 0
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: SA
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: SA
@@ -499,7 +499,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: ConstantBufferA1
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: ConstantBufferA1
 // CHECK-NEXT:            Size: 116
 // CHECK-NEXT:            Size: 116
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            StartOffset: 0
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
@@ -617,7 +617,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: ConstantBufferUnbounded
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: ConstantBufferUnbounded
 // CHECK-NEXT:            Size: 116
 // CHECK-NEXT:            Size: 116
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            StartOffset: 0
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
@@ -735,7 +735,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: $Element
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: $Element
 // CHECK-NEXT:            Size: 64
 // CHECK-NEXT:            Size: 64
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            StartOffset: 0
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
@@ -853,7 +853,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: $Element
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: $Element
 // CHECK-NEXT:            Size: 128
 // CHECK-NEXT:            Size: 128
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            StartOffset: 0
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: SA
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: SA
@@ -982,7 +982,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: $Element
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: $Element
 // CHECK-NEXT:            Size: 64
 // CHECK-NEXT:            Size: 64
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            StartOffset: 0
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
@@ -1100,7 +1100,7 @@
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: $Element
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: $Element
 // CHECK-NEXT:            Size: 64
 // CHECK-NEXT:            Size: 64
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            StartOffset: 0
-// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            uFlags: (D3D_SVF_USED)
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
@@ -1217,7 +1217,7 @@
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      NumSamples (or stride): 0
 // CHECK-NEXT:      NumSamples (or stride): 0
-// CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:      uFlags: (D3D_SIF_USERPACKED)
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: CBuffer
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: CBuffer
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      uID: 1
 // CHECK-NEXT:      uID: 1
@@ -1227,7 +1227,7 @@
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      NumSamples (or stride): 0
 // CHECK-NEXT:      NumSamples (or stride): 0
-// CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:      uFlags: (D3D_SIF_USERPACKED)
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferArray
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferArray
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      uID: 2
 // CHECK-NEXT:      uID: 2
@@ -1237,7 +1237,7 @@
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      NumSamples (or stride): 0
 // CHECK-NEXT:      NumSamples (or stride): 0
-// CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:      uFlags: (D3D_SIF_USERPACKED)
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferA1
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferA1
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      uID: 3
 // CHECK-NEXT:      uID: 3
@@ -1247,7 +1247,7 @@
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      NumSamples (or stride): 0
 // CHECK-NEXT:      NumSamples (or stride): 0
-// CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:      uFlags: (D3D_SIF_USERPACKED)
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferUnbounded
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferUnbounded
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      uID: 4
 // CHECK-NEXT:      uID: 4
@@ -1257,7 +1257,7 @@
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      ReturnType: <unknown: 0>
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      NumSamples (or stride): 0
 // CHECK-NEXT:      NumSamples (or stride): 0
-// CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:      uFlags: (D3D_SIF_USERPACKED)
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: SamplerUnbounded
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: SamplerUnbounded
 // CHECK-NEXT:      Type: D3D_SIT_SAMPLER
 // CHECK-NEXT:      Type: D3D_SIT_SAMPLER
 // CHECK-NEXT:      uID: 0
 // CHECK-NEXT:      uID: 0

+ 288 - 0
tools/clang/test/HLSLFileCheck/d3dreflect/tbuffer-16bit.hlsl

@@ -0,0 +1,288 @@
+// RUN: %dxc -enable-16bit-types -E main -T ps_6_2 -Vd -validator-version 0.0 %s | %D3DReflect %s | FileCheck %s
+
+// -Vd -validator-version 0.0 is used to keep the reflection information
+// in the actual module containing the cbuffer/tbuffer usage info.
+// This is only necessary for test path at the moment because of the way
+// the IR gets into D3DReflect by way of module disassembly and reassembly.
+// Otherwise the separate reflection blob would correctly contain the usage information,
+// since the metadata there is not gated on the shader target.
+
+tbuffer tb : register(t1)
+{
+  float b;
+  double d;         // aligned at 8 (4-bytes padding)
+  float f;
+  half4 h4;         // 8-bytes at 20
+  // spill vector to new row:
+  float16_t3 f16_3; // 6-bytes at 32 (4-bytes padding)
+  min16float mf1;   // 2-bytes at 38 (must look at shift/trunc to detect use)
+  uint16_t u16;     // 2-bytes at 40
+  int16_t2 i16;     // 4-bytes at 42 (may need to look at multiple extractelement users to detect use of i16.x, if u16 is used)
+  int i;            // 4-bytes at 48 (2-bytes padding)
+  uint16_t4 u16_4;  // 8-bytes at 52
+  half2 h2;         // 4-bytes at 60 (maps to float16_t2, fits in remaining row)
+  float16_t f16;    // 2-bytes at 64
+  int64_t i64;      // 8-bytes at 72 (6-bytes padding)
+  float16_t f16b;   // 2-bytes at 80
+  // overall size should be aligned to 16-byte boundary.
+  // unaligned size = 82
+  // aligned size = 96
+};
+
+float main(int i : A) : SV_TARGET
+{
+  return b + mf1 + h2.y + f16_3.z + (float)(d * i64) + u16 * i16.x;
+}
+
+// CHECK: ID3D12ShaderReflection:
+// CHECK-NEXT:   D3D12_SHADER_BUFFER_DESC:
+// CHECK-NEXT:     Shader Version: Pixel 6.2
+// CHECK:     Flags: 0
+// CHECK-NEXT:     ConstantBuffers: 1
+// CHECK-NEXT:     BoundResources: 1
+// CHECK-NEXT:     InputParameters: 1
+// CHECK-NEXT:     OutputParameters: 1
+// CHECK-NEXT:   Constant Buffers:
+// CHECK-NEXT:     ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: tb
+// CHECK-NEXT:         Type: D3D_CT_TBUFFER
+// CHECK-NEXT:         Size: 96
+// CHECK-NEXT:         uFlags: 0
+// CHECK-NEXT:         Num Variables: 14
+// CHECK-NEXT:       {
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: b
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 0
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: d
+// CHECK-NEXT:             Size: 8
+// CHECK-NEXT:             StartOffset: 8
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: double
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_DOUBLE
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: f
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 16
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: h4
+// CHECK-NEXT:             Size: 8
+// CHECK-NEXT:             StartOffset: 20
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float16_t4
+// CHECK-NEXT:               Class: D3D_SVC_VECTOR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 4
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: f16_3
+// CHECK-NEXT:             Size: 6
+// CHECK-NEXT:             StartOffset: 32
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float16_t3
+// CHECK-NEXT:               Class: D3D_SVC_VECTOR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 3
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: mf1
+// CHECK-NEXT:             Size: 2
+// CHECK-NEXT:             StartOffset: 38
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float16_t
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: u16
+// CHECK-NEXT:             Size: 2
+// CHECK-NEXT:             StartOffset: 40
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: uint16_t
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_UINT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i16
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 42
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: int16_t2
+// CHECK-NEXT:               Class: D3D_SVC_VECTOR
+// CHECK-NEXT:               Type: D3D_SVT_INT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 2
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 48
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: int
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_INT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: u16_4
+// CHECK-NEXT:             Size: 8
+// CHECK-NEXT:             StartOffset: 52
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: uint16_t4
+// CHECK-NEXT:               Class: D3D_SVC_VECTOR
+// CHECK-NEXT:               Type: D3D_SVT_UINT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 4
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: h2
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 60
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float16_t2
+// CHECK-NEXT:               Class: D3D_SVC_VECTOR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 2
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: f16
+// CHECK-NEXT:             Size: 2
+// CHECK-NEXT:             StartOffset: 64
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float16_t
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i64
+// CHECK-NEXT:             Size: 8
+// CHECK-NEXT:             StartOffset: 72
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: int64_t
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_INT64
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: f16b
+// CHECK-NEXT:             Size: 2
+// CHECK-NEXT:             StartOffset: 80
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float16_t
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT16
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:       }
+// CHECK-NEXT:   Bound Resources:
+// CHECK-NEXT:     D3D12_SHADER_BUFFER_DESC: Name: tb
+// CHECK-NEXT:       Type: D3D_SIT_TBUFFER
+// CHECK-NEXT:       uID: 0
+// CHECK-NEXT:       BindCount: 1
+// CHECK-NEXT:       BindPoint: 1
+// CHECK-NEXT:       Space: 0
+// CHECK-NEXT:       ReturnType: <unknown: 0>
+// CHECK-NEXT:       Dimension: D3D_SRV_DIMENSION_UNKNOWN
+// CHECK-NEXT:       NumSamples (or stride): 0
+// CHECK-NEXT:       uFlags: (D3D_SIF_USERPACKED)

+ 236 - 0
tools/clang/test/HLSLFileCheck/d3dreflect/tbuffer.hlsl

@@ -0,0 +1,236 @@
+// RUN: %dxc -E main -T ps_6_0 -Vd -validator-version 0.0 %s | %D3DReflect %s | FileCheck %s
+
+// -Vd -validator-version 0.0 is used to keep the reflection information
+// in the actual module containing the cbuffer/tbuffer usage info.
+// This is only necessary for test path at the moment because of the way
+// the IR gets into D3DReflect by way of module disassembly and reassembly.
+// Otherwise the separate reflection blob would correctly contain the usage information,
+// since the metadata there is not gated on the shader target.
+
+tbuffer tb : register(t1)
+{
+  float b;
+  double d;         // aligned at 8 (4-bytes padding)
+
+  // row
+  float f;
+
+  // row
+  half4 h4;         // aligned at 32 (12-bytes padding, map to float)
+
+  // row
+  // min16float and min16uint on same row
+  min16float mf;    // 4-bytes at 48
+  min16uint mu;     // 4-bytes at 52
+
+  // row (to prevent mixing of min-precision in same register)
+  uint u;           // 4-bytes at 64
+
+  // row (to prevent mixing of min-precision in same register)
+  // spill vector to new row though 16-bit values would fit:
+  min16int2 mi;     // 8-bytes at 80
+
+  int2 i2;          // 8-bytes at 96 (to complete row)
+
+  // row
+  float a;          // 4-bytes on new row
+
+  // overall size should be aligned to 16-byte boundary.
+
+  // unaligned size = 108
+  // aligned size = 112
+};
+
+float main(int i : A) : SV_TARGET
+{
+  return b + mi.y + a + mf * mu;
+}
+
+// CHECK: ID3D12ShaderReflection:
+// CHECK-NEXT:   D3D12_SHADER_BUFFER_DESC:
+// CHECK-NEXT:     Shader Version: Pixel 6.0
+// CHECK:     Flags: 0
+// CHECK-NEXT:     ConstantBuffers: 1
+// CHECK-NEXT:     BoundResources: 1
+// CHECK-NEXT:     InputParameters: 1
+// CHECK-NEXT:     OutputParameters: 1
+// CHECK-NEXT:   Constant Buffers:
+// CHECK-NEXT:     ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: tb
+// CHECK-NEXT:         Type: D3D_CT_TBUFFER
+// CHECK-NEXT:         Size: 112
+// CHECK-NEXT:         uFlags: 0
+// CHECK-NEXT:         Num Variables: 10
+// CHECK-NEXT:       {
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: b
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 0
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: d
+// CHECK-NEXT:             Size: 8
+// CHECK-NEXT:             StartOffset: 8
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: double
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_DOUBLE
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: f
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 16
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: h4
+// CHECK-NEXT:             Size: 16
+// CHECK-NEXT:             StartOffset: 32
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float4
+// CHECK-NEXT:               Class: D3D_SVC_VECTOR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 4
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: mf
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 48
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: min16float
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_MIN16FLOAT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: mu
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 52
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: min16uint
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_MIN16UINT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: u
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 64
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: dword
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_UINT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: mi
+// CHECK-NEXT:             Size: 8
+// CHECK-NEXT:             StartOffset: 80
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: min16int2
+// CHECK-NEXT:               Class: D3D_SVC_VECTOR
+// CHECK-NEXT:               Type: D3D_SVT_MIN16INT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 2
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: i2
+// CHECK-NEXT:             Size: 8
+// CHECK-NEXT:             StartOffset: 96
+// CHECK-NEXT:             uFlags: 0
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: int2
+// CHECK-NEXT:               Class: D3D_SVC_VECTOR
+// CHECK-NEXT:               Type: D3D_SVT_INT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 2
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:         ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:           D3D12_SHADER_VARIABLE_DESC: Name: a
+// CHECK-NEXT:             Size: 4
+// CHECK-NEXT:             StartOffset: 104
+// CHECK-NEXT:             uFlags: (D3D_SVF_USED)
+// CHECK-NEXT:             DefaultValue: <nullptr>
+// CHECK-NEXT:           ID3D12ShaderReflectionType:
+// CHECK-NEXT:             D3D12_SHADER_TYPE_DESC: Name: float
+// CHECK-NEXT:               Class: D3D_SVC_SCALAR
+// CHECK-NEXT:               Type: D3D_SVT_FLOAT
+// CHECK-NEXT:               Elements: 0
+// CHECK-NEXT:               Rows: 1
+// CHECK-NEXT:               Columns: 1
+// CHECK-NEXT:               Members: 0
+// CHECK-NEXT:               Offset: 0
+// CHECK-NEXT:           CBuffer: tb
+// CHECK-NEXT:       }
+// CHECK-NEXT:   Bound Resources:
+// CHECK-NEXT:     D3D12_SHADER_BUFFER_DESC: Name: tb
+// CHECK-NEXT:       Type: D3D_SIT_TBUFFER
+// CHECK-NEXT:       uID: 0
+// CHECK-NEXT:       BindCount: 1
+// CHECK-NEXT:       BindPoint: 1
+// CHECK-NEXT:       Space: 0
+// CHECK-NEXT:       ReturnType: <unknown: 0>
+// CHECK-NEXT:       Dimension: D3D_SRV_DIMENSION_UNKNOWN
+// CHECK-NEXT:       NumSamples (or stride): 0
+// CHECK-NEXT:       uFlags: (D3D_SIF_USERPACKED)

+ 18 - 18
tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferMinPrec.hlsl

@@ -6,43 +6,43 @@
 // CHECK:   struct dx.alignment.legacy.Foo
 // CHECK:   struct dx.alignment.legacy.Foo
 // CHECK:   {
 // CHECK:   {
 // CHECK:       min16float h1;                                ; Offset:    0
 // CHECK:       min16float h1;                                ; Offset:    0
-// CHECK:       float3 f3;                                    ; Offset:    4
-// CHECK:       min16float2 h2;                               ; Offset:   16
-// CHECK:       float3 f3_1;                                  ; Offset:   32
-// CHECK:       float2 f2;                                    ; Offset:   48
-// CHECK:       min16float4 h4;                               ; Offset:   64
-// CHECK:       min16float2 h2_1;                             ; Offset:   80
-// CHECK:       min16float3 h3;                               ; Offset:   96
-// CHECK:       double d1;                                    ; Offset:  112
-// CHECK:   } Foo;                                            ; Offset:    0 Size:   120
+// CHECK:       float3 f3;                                    ; Offset:   16
+// CHECK:       min16float2 h2;                               ; Offset:   32
+// CHECK:       float3 f3_1;                                  ; Offset:   48
+// CHECK:       float2 f2;                                    ; Offset:   64
+// CHECK:       min16float4 h4;                               ; Offset:   80
+// CHECK:       min16float2 h2_1;                             ; Offset:   96
+// CHECK:       min16float3 h3;                               ; Offset:  112
+// CHECK:       double d1;                                    ; Offset:  128
+// CHECK:   } Foo;                                            ; Offset:    0 Size:   136
 // CHECK: }
 // CHECK: }
 
 
 // CHECK: %dx.types.CBufRet.f16 = type { half, half, half, half }
 // CHECK: %dx.types.CBufRet.f16 = type { half, half, half, half }
 
 
 // CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 0)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 0)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
-// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %Foo_cbuffer, i32 0)  ; CBufferLoadLegacy(handle,regIndex)
-// CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f32 {{%[0-9]+}}, 1
-// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 1)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %Foo_cbuffer, i32 1)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f32 {{%[0-9]+}}, 0
+// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 2)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 1
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 1
-// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %Foo_cbuffer, i32 2)  ; CBufferLoadLegacy(handle,regIndex)
-// CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f32 {{%[0-9]+}}, 2
 // CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %Foo_cbuffer, i32 3)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %Foo_cbuffer, i32 3)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f32 {{%[0-9]+}}, 2
+// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %Foo_cbuffer, i32 4)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f32 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f32 {{%[0-9]+}}, 0
-// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 4)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 5)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 1
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 1
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 2
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 2
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 3
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 3
-// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 5)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 6)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 1
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 1
-// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 6)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f16 @dx.op.cbufferLoadLegacy.f16(i32 59, %dx.types.Handle %Foo_cbuffer, i32 7)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 1
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 1
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 2
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f16 {{%[0-9]+}}, 2
-// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f64 @dx.op.cbufferLoadLegacy.f64(i32 59, %dx.types.Handle %Foo_cbuffer, i32 7)  ; CBufferLoadLegacy(handle,regIndex)
+// CHECK: {{%[0-9]+}} = call %dx.types.CBufRet.f64 @dx.op.cbufferLoadLegacy.f64(i32 59, %dx.types.Handle %Foo_cbuffer, i32 8)  ; CBufferLoadLegacy(handle,regIndex)
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f64 {{%[0-9]+}}, 0
 // CHECK: {{%[0-9]+}} = extractvalue %dx.types.CBufRet.f64 {{%[0-9]+}}, 0
 
 
 cbuffer Foo {
 cbuffer Foo {

+ 45 - 17
tools/clang/unittests/HLSL/DxilContainerTest.cpp

@@ -156,9 +156,9 @@ public:
       VERIFY_ARE_EQUAL(pBaseDesc->Type, D3D_SIT_TEXTURE);
       VERIFY_ARE_EQUAL(pBaseDesc->Type, D3D_SIT_TEXTURE);
     } else
     } else
       VERIFY_ARE_EQUAL(pTestDesc->Type, pBaseDesc->Type);
       VERIFY_ARE_EQUAL(pTestDesc->Type, pBaseDesc->Type);
-    // D3D_SIF_USERPACKED is never set in dxil.
+    // D3D_SIF_USERPACKED is not set consistently in fxc (new-style ConstantBuffer).
     UINT unusedFlag = D3D_SIF_USERPACKED;
     UINT unusedFlag = D3D_SIF_USERPACKED;
-    VERIFY_ARE_EQUAL(pTestDesc->uFlags, pBaseDesc->uFlags & ~unusedFlag);
+    VERIFY_ARE_EQUAL(pTestDesc->uFlags & ~unusedFlag, pBaseDesc->uFlags & ~unusedFlag);
     // VERIFY_ARE_EQUAL(pTestDesc->uID, pBaseDesc->uID); // Like register, this can vary.
     // VERIFY_ARE_EQUAL(pTestDesc->uID, pBaseDesc->uID); // Like register, this can vary.
   }
   }
 
 
@@ -197,7 +197,13 @@ public:
 
 
     VERIFY_ARE_EQUAL(testDesc.Offset,   baseDesc.Offset);
     VERIFY_ARE_EQUAL(testDesc.Offset,   baseDesc.Offset);
 
 
-    VERIFY_ARE_EQUAL(0, strcmp(testDesc.Name, baseDesc.Name));
+    // DXIL Reflection doesn't expose half type name,
+    // and that shouldn't matter because this is only
+    // in the case where half maps to float.
+    std::string baseName(baseDesc.Name);
+    if (baseName.compare(0, 4, "half", 4) == 0)
+      baseName = baseName.replace(0, 4, "float", 5);
+    VERIFY_ARE_EQUAL_STR(testDesc.Name, baseName.c_str());
 
 
     for (UINT i = 0; i < baseDesc.Members; ++i) {
     for (UINT i = 0; i < baseDesc.Members; ++i) {
       ID3D12ShaderReflectionType* testMemberType = pTest->GetMemberTypeByIndex(i);
       ID3D12ShaderReflectionType* testMemberType = pTest->GetMemberTypeByIndex(i);
@@ -341,7 +347,8 @@ public:
 #endif // _WIN32 - Reflection unsupported
 #endif // _WIN32 - Reflection unsupported
 
 
 #ifdef _WIN32  // - Reflection unsupported
 #ifdef _WIN32  // - Reflection unsupported
-  HRESULT CompileFromFile(LPCWSTR path, bool useDXBC, IDxcBlob **ppBlob) {
+  HRESULT CompileFromFile(LPCWSTR path, bool useDXBC,
+                          UINT fxcFlags, IDxcBlob **ppBlob) {
     std::vector<FileRunCommandPart> parts;
     std::vector<FileRunCommandPart> parts;
     ParseCommandPartsFromFile(path, parts);
     ParseCommandPartsFromFile(path, parts);
     VERIFY_IS_TRUE(parts.size() > 0);
     VERIFY_IS_TRUE(parts.size() > 0);
@@ -360,14 +367,19 @@ public:
     if (useDXBC) {
     if (useDXBC) {
       // Consider supporting defines and flags if/when needed.
       // Consider supporting defines and flags if/when needed.
       std::string TargetProfile(opts.TargetProfile.str());
       std::string TargetProfile(opts.TargetProfile.str());
-      TargetProfile[3] = '5'; TargetProfile[5] = '1';
+      TargetProfile[3] = '5';
+      // Some shaders may need flags, and /Gec is incompatible with SM 5.1
+      TargetProfile[5] = (fxcFlags & D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY) ? '0' : '1';
       CComPtr<ID3DBlob> pDxbcBlob;
       CComPtr<ID3DBlob> pDxbcBlob;
       CComPtr<ID3DBlob> pDxbcErrors;
       CComPtr<ID3DBlob> pDxbcErrors;
-      UINT unboundDescTab = (1 << 20);
-      IFR(D3DCompileFromFile(path, nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
+      HRESULT hr = D3DCompileFromFile(path, nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
         opts.EntryPoint.str().c_str(),
         opts.EntryPoint.str().c_str(),
         TargetProfile.c_str(),
         TargetProfile.c_str(),
-        unboundDescTab, 0, &pDxbcBlob, &pDxbcErrors));
+        fxcFlags,
+        0, &pDxbcBlob, &pDxbcErrors);
+      LPCSTR errors = pDxbcErrors ? (const char *)pDxbcErrors->GetBufferPointer() : "";
+      (void)errors;
+      IFR(hr);
       IFR(pDxbcBlob.QueryInterface(ppBlob));
       IFR(pDxbcBlob.QueryInterface(ppBlob));
     }
     }
     else {
     else {
@@ -537,7 +549,8 @@ public:
     return result;
     return result;
   }
   }
 
 
-  void ReflectionTest(LPCWSTR name, bool ignoreIfDXBCFails) {
+  void ReflectionTest(LPCWSTR name, bool ignoreIfDXBCFails,
+      UINT fxcFlags = D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES) {
     WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Reflection comparison for %s", name));
     WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Reflection comparison for %s", name));
 
 
     // Skip if unsupported.
     // Skip if unsupported.
@@ -553,13 +566,13 @@ public:
 
 
     CComPtr<IDxcBlob> pProgram;
     CComPtr<IDxcBlob> pProgram;
     CComPtr<IDxcBlob> pProgramDXBC;
     CComPtr<IDxcBlob> pProgramDXBC;
-    HRESULT hrDXBC = CompileFromFile(name, true, &pProgramDXBC);
+    HRESULT hrDXBC = CompileFromFile(name, true, fxcFlags, &pProgramDXBC);
     if (FAILED(hrDXBC)) {
     if (FAILED(hrDXBC)) {
       WEX::Logging::Log::Comment(L"Failed to compile DXBC blob.");
       WEX::Logging::Log::Comment(L"Failed to compile DXBC blob.");
       if (ignoreIfDXBCFails) return;
       if (ignoreIfDXBCFails) return;
       VERIFY_FAIL();
       VERIFY_FAIL();
     }
     }
-    if (FAILED(CompileFromFile(name, false, &pProgram))) {
+    if (FAILED(CompileFromFile(name, false, 0, &pProgram))) {
       WEX::Logging::Log::Comment(L"Failed to compile DXIL blob.");
       WEX::Logging::Log::Comment(L"Failed to compile DXIL blob.");
       VERIFY_FAIL();
       VERIFY_FAIL();
     }
     }
@@ -1781,6 +1794,9 @@ TEST_F(DxilContainerTest, ReflectionMatchesDXBC_CheckIn) {
   ReflectionTest(hlsl_test::GetPathToHlslDataFile(L"..\\CodeGenHLSL\\container\\SimpleBezier11DS.hlsl").c_str(), false);
   ReflectionTest(hlsl_test::GetPathToHlslDataFile(L"..\\CodeGenHLSL\\container\\SimpleBezier11DS.hlsl").c_str(), false);
   ReflectionTest(hlsl_test::GetPathToHlslDataFile(L"..\\CodeGenHLSL\\container\\SubD11_SmoothPS.hlsl").c_str(), false);
   ReflectionTest(hlsl_test::GetPathToHlslDataFile(L"..\\CodeGenHLSL\\container\\SubD11_SmoothPS.hlsl").c_str(), false);
   ReflectionTest(hlsl_test::GetPathToHlslDataFile(L"..\\HLSLFileCheck\\d3dreflect\\structured_buffer_layout.hlsl").c_str(), false);
   ReflectionTest(hlsl_test::GetPathToHlslDataFile(L"..\\HLSLFileCheck\\d3dreflect\\structured_buffer_layout.hlsl").c_str(), false);
+  ReflectionTest(hlsl_test::GetPathToHlslDataFile(L"..\\HLSLFileCheck\\d3dreflect\\cb_sizes.hlsl").c_str(), false);
+  ReflectionTest(hlsl_test::GetPathToHlslDataFile(L"..\\HLSLFileCheck\\d3dreflect\\tbuffer.hlsl").c_str(), false,
+    D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY);
 }
 }
 
 
 TEST_F(DxilContainerTest, ReflectionMatchesDXBC_Full) {
 TEST_F(DxilContainerTest, ReflectionMatchesDXBC_Full) {
@@ -1802,20 +1818,32 @@ TEST_F(DxilContainerTest, ReflectionMatchesDXBC_Full) {
     L"ScreenQuadVS.hlsl",
     L"ScreenQuadVS.hlsl",
     L"SimpleBezier11HS.hlsl"
     L"SimpleBezier11HS.hlsl"
   };
   };
+  // These tests should always be skipped
+  LPCWSTR SkipPaths[] = {
+    L".hlsli",
+    L"TessellatorCS40_defines.h",
+    L"SubD11_SubDToBezierHS",
+    L"ParticleTileCullingCS_fail_unroll.hlsl"
+  };
   for (auto &p: recursive_directory_iterator(path(codeGenPath))) {
   for (auto &p: recursive_directory_iterator(path(codeGenPath))) {
     if (is_regular_file(p)) {
     if (is_regular_file(p)) {
       LPCWSTR fullPath = p.path().c_str();
       LPCWSTR fullPath = p.path().c_str();
-      if (wcsstr(fullPath, L".hlsli") != nullptr) continue;
-      if (wcsstr(fullPath, L"TessellatorCS40_defines.h") != nullptr) continue;
+      auto Matches = [&](LPCWSTR candidate) {
+        LPCWSTR match = wcsstr(fullPath, candidate);
+        return nullptr != match;
+      };
+
       // Skip failed tests.
       // Skip failed tests.
-      if (wcsstr(fullPath, L"SubD11_SubDToBezierHS") != nullptr) continue;
+      LPCWSTR *SkipEnd = SkipPaths + _countof(SkipPaths);
+      if (SkipEnd != std::find_if(SkipPaths, SkipEnd, Matches))
+        continue;
+
       if (!TestAll) {
       if (!TestAll) {
         bool shouldTest = false;
         bool shouldTest = false;
         LPCWSTR *PreApprovedEnd = PreApprovedPaths + _countof(PreApprovedPaths);
         LPCWSTR *PreApprovedEnd = PreApprovedPaths + _countof(PreApprovedPaths);
-        shouldTest = PreApprovedEnd == std::find_if(PreApprovedPaths, PreApprovedEnd,
-          [&](LPCWSTR candidate) { return nullptr != wcsstr(fullPath, candidate); });
+        shouldTest = PreApprovedEnd != std::find_if(PreApprovedPaths, PreApprovedEnd, Matches);
         if (!shouldTest) {
         if (!shouldTest) {
-          break;
+          continue;
         }
         }
       }
       }
       auto start = std::chrono::system_clock::now();
       auto start = std::chrono::system_clock::now();

+ 61 - 4
tools/clang/unittests/HLSLTestLib/D3DReflectionDumper.cpp

@@ -14,6 +14,9 @@
 #include "dxc/DxilContainer/DxilContainer.h"
 #include "dxc/DxilContainer/DxilContainer.h"
 #include <sstream>
 #include <sstream>
 
 
+// Remove this workaround once newer version of d3dcommon.h can be compiled against
+#define ADD_16_64_BIT_TYPES
+
 // Copied from llvm/ADT/StringExtras.h
 // Copied from llvm/ADT/StringExtras.h
 static inline char hexdigit(unsigned X, bool LowerCase = false) {
 static inline char hexdigit(unsigned X, bool LowerCase = false) {
   const char HexChar = LowerCase ? 'a' : 'A';
   const char HexChar = LowerCase ? 'a' : 'A';
@@ -35,6 +38,8 @@ static std::string EscapedString(const char *text) {
   return ss.str();
   return ss.str();
 }
 }
 
 
+namespace refl_dump {
+
 LPCSTR ToString(D3D_CBUFFER_TYPE CBType) {
 LPCSTR ToString(D3D_CBUFFER_TYPE CBType) {
   switch (CBType) {
   switch (CBType) {
   case D3D_CT_CBUFFER: return "D3D_CT_CBUFFER";
   case D3D_CT_CBUFFER: return "D3D_CT_CBUFFER";
@@ -225,6 +230,15 @@ LPCSTR ToString(D3D_SHADER_VARIABLE_CLASS Class) {
   default: return nullptr;
   default: return nullptr;
   }
   }
 }
 }
+
+#ifdef ADD_16_64_BIT_TYPES
+#define D3D_SVT_INT16   ((D3D_SHADER_VARIABLE_TYPE)58)
+#define D3D_SVT_UINT16  ((D3D_SHADER_VARIABLE_TYPE)59)
+#define D3D_SVT_FLOAT16 ((D3D_SHADER_VARIABLE_TYPE)60)
+#define D3D_SVT_INT64   ((D3D_SHADER_VARIABLE_TYPE)61)
+#define D3D_SVT_UINT64  ((D3D_SHADER_VARIABLE_TYPE)62)
+#endif // ADD_16_64_BIT_TYPES
+
 LPCSTR ToString(D3D_SHADER_VARIABLE_TYPE Type) {
 LPCSTR ToString(D3D_SHADER_VARIABLE_TYPE Type) {
   switch (Type) {
   switch (Type) {
   case D3D_SVT_VOID: return "D3D_SVT_VOID";
   case D3D_SVT_VOID: return "D3D_SVT_VOID";
@@ -285,10 +299,52 @@ LPCSTR ToString(D3D_SHADER_VARIABLE_TYPE Type) {
   case D3D_SVT_MIN12INT: return "D3D_SVT_MIN12INT";
   case D3D_SVT_MIN12INT: return "D3D_SVT_MIN12INT";
   case D3D_SVT_MIN16INT: return "D3D_SVT_MIN16INT";
   case D3D_SVT_MIN16INT: return "D3D_SVT_MIN16INT";
   case D3D_SVT_MIN16UINT: return "D3D_SVT_MIN16UINT";
   case D3D_SVT_MIN16UINT: return "D3D_SVT_MIN16UINT";
+  case D3D_SVT_INT16: return "D3D_SVT_INT16";
+  case D3D_SVT_UINT16: return "D3D_SVT_UINT16";
+  case D3D_SVT_FLOAT16: return "D3D_SVT_FLOAT16";
+  case D3D_SVT_INT64: return "D3D_SVT_INT64";
+  case D3D_SVT_UINT64: return "D3D_SVT_UINT64";
   default: return nullptr;
   default: return nullptr;
   }
   }
 }
 }
 
 
+LPCSTR ToString(D3D_SHADER_VARIABLE_FLAGS Flag) {
+  switch (Flag) {
+  case D3D_SVF_USERPACKED: return "D3D_SVF_USERPACKED";
+  case D3D_SVF_USED: return "D3D_SVF_USED";
+  case D3D_SVF_INTERFACE_POINTER: return "D3D_SVF_INTERFACE_POINTER";
+  case D3D_SVF_INTERFACE_PARAMETER: return "D3D_SVF_INTERFACE_PARAMETER";
+  }
+  return nullptr;
+}
+
+LPCSTR ToString(D3D_SHADER_INPUT_FLAGS Flag) {
+  switch (Flag) {
+  case D3D_SIF_USERPACKED: return "D3D_SIF_USERPACKED";
+  case D3D_SIF_COMPARISON_SAMPLER: return "D3D_SIF_COMPARISON_SAMPLER";
+  case D3D_SIF_TEXTURE_COMPONENT_0: return "D3D_SIF_TEXTURE_COMPONENT_0";
+  case D3D_SIF_TEXTURE_COMPONENT_1: return "D3D_SIF_TEXTURE_COMPONENT_1";
+  case D3D_SIF_TEXTURE_COMPONENTS: return "D3D_SIF_TEXTURE_COMPONENTS";
+  case D3D_SIF_UNUSED: return "D3D_SIF_UNUSED";
+  }
+  return nullptr;
+}
+
+LPCSTR ToString(D3D_SHADER_CBUFFER_FLAGS Flag) {
+  switch (Flag) {
+  case D3D_CBF_USERPACKED: return "D3D_CBF_USERPACKED";
+  }
+  return nullptr;
+}
+
+LPCSTR ToString(D3D_PARAMETER_FLAGS Flag) {
+  switch (Flag) {
+  case D3D_PF_IN: return "D3D_PF_IN";
+  case D3D_PF_OUT: return "D3D_PF_OUT";
+  }
+  return nullptr;
+}
+
 void D3DReflectionDumper::DumpDefaultValue(LPCVOID pDefaultValue, UINT Size) {
 void D3DReflectionDumper::DumpDefaultValue(LPCVOID pDefaultValue, UINT Size) {
   WriteLn("DefaultValue: ", pDefaultValue ? "<present>" : "<nullptr>");    // TODO: Dump DefaultValue
   WriteLn("DefaultValue: ", pDefaultValue ? "<present>" : "<nullptr>");    // TODO: Dump DefaultValue
 }
 }
@@ -337,7 +393,7 @@ void D3DReflectionDumper::Dump(D3D12_SHADER_VARIABLE_DESC &varDesc) {
   Indent();
   Indent();
   WriteLn("Size: ", varDesc.Size);
   WriteLn("Size: ", varDesc.Size);
   WriteLn("StartOffset: ", varDesc.StartOffset);
   WriteLn("StartOffset: ", varDesc.StartOffset);
-  WriteLn("uFlags: ", std::hex, std::showbase, varDesc.uFlags);
+  WriteLn("uFlags: ", FlagsValue<D3D_SHADER_VARIABLE_FLAGS>(varDesc.uFlags));
   DumpDefaultValue(varDesc.DefaultValue, varDesc.Size);
   DumpDefaultValue(varDesc.DefaultValue, varDesc.Size);
   Dedent();
   Dedent();
 }
 }
@@ -347,7 +403,7 @@ void D3DReflectionDumper::Dump(D3D12_SHADER_BUFFER_DESC &Desc) {
   Indent();
   Indent();
   DumpEnum("Type", Desc.Type);
   DumpEnum("Type", Desc.Type);
   WriteLn("Size: ", Desc.Size);
   WriteLn("Size: ", Desc.Size);
-  WriteLn("uFlags: ", std::hex, std::showbase, Desc.uFlags);
+  WriteLn("uFlags: ", FlagsValue<D3D_SHADER_CBUFFER_FLAGS>(Desc.uFlags));
   WriteLn("Num Variables: ", Desc.Variables);
   WriteLn("Num Variables: ", Desc.Variables);
   Dedent();
   Dedent();
 }
 }
@@ -363,7 +419,7 @@ void D3DReflectionDumper::Dump(D3D12_SHADER_INPUT_BIND_DESC &resDesc) {
   DumpEnum("ReturnType", resDesc.ReturnType);
   DumpEnum("ReturnType", resDesc.ReturnType);
   DumpEnum("Dimension", resDesc.Dimension);
   DumpEnum("Dimension", resDesc.Dimension);
   WriteLn("NumSamples (or stride): ", resDesc.NumSamples);
   WriteLn("NumSamples (or stride): ", resDesc.NumSamples);
-  WriteLn("uFlags: ", std::hex, std::showbase, resDesc.uFlags);
+  WriteLn("uFlags: ", FlagsValue<D3D_SHADER_INPUT_FLAGS>(resDesc.uFlags));
   Dedent();
   Dedent();
 }
 }
 void D3DReflectionDumper::Dump(D3D12_SHADER_DESC &Desc) {
 void D3DReflectionDumper::Dump(D3D12_SHADER_DESC &Desc) {
@@ -371,7 +427,7 @@ void D3DReflectionDumper::Dump(D3D12_SHADER_DESC &Desc) {
   Indent();
   Indent();
   DumpShaderVersion(Desc.Version);
   DumpShaderVersion(Desc.Version);
   WriteLn("Creator: ", Desc.Creator ? Desc.Creator : "<nullptr>");
   WriteLn("Creator: ", Desc.Creator ? Desc.Creator : "<nullptr>");
-  WriteLn("Flags: ", std::hex, std::showbase, Desc.Flags);
+  WriteLn("Flags: ", std::hex, std::showbase, Desc.Flags);  // TODO: fxc compiler flags
   WriteLn("ConstantBuffers: ", Desc.ConstantBuffers);
   WriteLn("ConstantBuffers: ", Desc.ConstantBuffers);
   WriteLn("BoundResources: ", Desc.BoundResources);
   WriteLn("BoundResources: ", Desc.BoundResources);
   WriteLn("InputParameters: ", Desc.InputParameters);
   WriteLn("InputParameters: ", Desc.InputParameters);
@@ -623,3 +679,4 @@ void D3DReflectionDumper::Dump(ID3D12LibraryReflection *pLibraryReflection) {
   Dedent();
   Dedent();
 }
 }
 
 
+} // namespace refl_dump

+ 1 - 0
tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp

@@ -43,6 +43,7 @@
 
 
 using namespace std;
 using namespace std;
 using namespace hlsl_test;
 using namespace hlsl_test;
+using namespace refl_dump;
 
 
 FileRunCommandPart::FileRunCommandPart(const std::string &command, const std::string &arguments, LPCWSTR commandFileName) :
 FileRunCommandPart::FileRunCommandPart(const std::string &command, const std::string &arguments, LPCWSTR commandFileName) :
   Command(command), Arguments(arguments), CommandFileName(commandFileName) { }
   Command(command), Arguments(arguments), CommandFileName(commandFileName) { }