Browse Source

Fix more: array[1] and unbounded cases, address feedback

- Array of [1] would crash in UpdateStructTypeForLegacyLayout
  since IsResourceArray would be false.
- Unbounded array has weird quirk in D3DCompiler reflection:
  all resources report BindCount == 0, except cbuffer reports UINT_MAX.
  Added simple unbounded cases for other resource types to verify.
- Fxc has some auto-binding bugs.
  Worked around in the test with explicit binding.
- Added suggested helper functions for strip/wrap array types.
  Used in code that's part of this change, but didn't search for other
  places to replace yet.
Tex Riddell 6 năm trước cách đây
mục cha
commit
03ecd7d3d7

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

@@ -110,6 +110,9 @@ namespace dxilutil {
   bool IsHLSLResourceType(llvm::Type *Ty);
   bool IsHLSLObjectType(llvm::Type *Ty);
   bool IsSplat(llvm::ConstantDataVector *cdv);
+
+  llvm::Type* StripArrayTypes(llvm::Type *Ty, llvm::SmallVectorImpl<unsigned> *OuterToInnerLengths = nullptr);
+  llvm::Type* WrapInArrayTypes(llvm::Type *Ty, llvm::ArrayRef<unsigned> OuterToInnerLengths);
 }
 
 }

+ 18 - 0
lib/DXIL/DxilUtil.cpp

@@ -591,6 +591,24 @@ bool IsSplat(llvm::ConstantDataVector *cdv) {
   return true;
 }
 
+llvm::Type* StripArrayTypes(llvm::Type *Ty, llvm::SmallVectorImpl<unsigned> *OuterToInnerLengths) {
+  DXASSERT_NOMSG(Ty);
+  while (Ty->isArrayTy()) {
+    if (OuterToInnerLengths) {
+      OuterToInnerLengths->push_back(Ty->getArrayNumElements());
+    }
+    Ty = Ty->getArrayElementType();
+  }
+  return Ty;
+}
+llvm::Type* WrapInArrayTypes(llvm::Type *Ty, llvm::ArrayRef<unsigned> OuterToInnerLengths) {
+  DXASSERT_NOMSG(Ty);
+  for (auto it = OuterToInnerLengths.rbegin(), E = OuterToInnerLengths.rend(); it != E; ++it) {
+    Ty = ArrayType::get(Ty, *it);
+  }
+  return Ty;
+}
+
 }
 }
 

+ 5 - 14
lib/HLSL/DxilCondenseResources.cpp

@@ -1635,15 +1635,9 @@ void UpdateStructTypeForLegacyLayout(DxilResourceBase &Res,
                                      DxilTypeSystem &TypeSys, Module &M) {
   Constant *Symbol = Res.GetGlobalSymbol();
   Type *ElemTy = Symbol->getType()->getPointerElementType();
-  bool IsResourceArray = Res.GetRangeSize() != 1;
-  std::vector<unsigned> arrayDims;
-  if (IsResourceArray) {
-    // Support Array of ConstantBuffer.
-    while (ElemTy->isArrayTy()) {
-      arrayDims.push_back((unsigned)ElemTy->getArrayNumElements());
-      ElemTy = ElemTy->getArrayElementType();
-    }
-  }
+  // Support Array of ConstantBuffer/StructuredBuffer.
+  llvm::SmallVector<unsigned, 4> arrayDims;
+  ElemTy = dxilutil::StripArrayTypes(ElemTy, &arrayDims);
   StructType *ST = cast<StructType>(ElemTy);
   if (ST->isOpaque()) {
     DXASSERT(Res.GetClass() == DxilResourceBase::Class::CBuffer,
@@ -1654,11 +1648,8 @@ void UpdateStructTypeForLegacyLayout(DxilResourceBase &Res,
   Type *UpdatedST =
       UpdateStructTypeForLegacyLayout(ST, TypeSys, M);
   if (ST != UpdatedST) {
-    if (IsResourceArray) {
-      // Support Array of ConstantBuffer.
-      for (auto it = arrayDims.rbegin(), E = arrayDims.rend(); it != E; ++it)
-        UpdatedST = ArrayType::get(UpdatedST, *it);
-    }
+    // Support Array of ConstantBuffer/StructuredBuffer.
+    UpdatedST = dxilutil::WrapInArrayTypes(UpdatedST, arrayDims);
     GlobalVariable *NewGV = cast<GlobalVariable>(
         M.getOrInsertGlobal(Symbol->getName().str() + "_legacy", UpdatedST));
     Res.SetGlobalSymbol(NewGV);

+ 11 - 16
lib/HLSL/DxilContainerReflection.cpp

@@ -26,6 +26,7 @@
 #include "dxc/Support/dxcapi.impl.h"
 #include "dxc/DXIL/DxilFunctionProps.h"
 #include "dxc/DXIL/DxilPDB.h"
+#include "dxc/DXIL/DxilUtil.h"
 
 #include <unordered_set>
 #include "llvm/ADT/SetVector.h"
@@ -1108,14 +1109,10 @@ void CShaderReflectionConstantBuffer::Initialize(
   m_Desc.Size = (m_Desc.Size + 0x0f) & ~(0x0f); // Round up to 16 bytes for reflection.
   m_Desc.Type = D3D_CT_CBUFFER;
   m_Desc.uFlags = 0;
-  Type *Ty = CB.GetGlobalSymbol()->getType()->getPointerElementType();
   // For ConstantBuffer<> buf[2], the array size is in Resource binding count
   // part.
-  unsigned resArrayDims = 0;
-  while (Ty->isArrayTy()) {
-    Ty = Ty->getArrayElementType();
-    resArrayDims += 1;
-  }
+  Type *Ty = dxilutil::StripArrayTypes(
+    CB.GetGlobalSymbol()->getType()->getPointerElementType());
 
   DxilTypeSystem &typeSys = M.GetTypeSystem();
   StructType *ST = cast<StructType>(Ty);
@@ -1127,7 +1124,7 @@ void CShaderReflectionConstantBuffer::Initialize(
 
   m_Desc.Variables = ST->getNumContainedTypes();
 
-  if (resArrayDims) {
+  if (CB.GetRangeSize() > 1) {
     DXASSERT(m_Desc.Variables == 1, "otherwise, assumption is wrong");
   }
 
@@ -1144,7 +1141,7 @@ void CShaderReflectionConstantBuffer::Initialize(
     pVarType->Initialize(M, ST->getContainedType(i), fieldAnnotation, fieldAnnotation.GetCBufferOffset(), allTypes, true);
 
     // Replicate fxc bug, where Elements == 1 for inner struct of CB array, instead of 0.
-    if (resArrayDims) {
+    if (CB.GetRangeSize() > 1) {
       DXASSERT(pVarType->m_Desc.Elements == 0, "otherwise, assumption is wrong");
       pVarType->m_Desc.Elements = 1;
     }
@@ -1192,8 +1189,7 @@ static unsigned CalcResTypeSize(DxilModule &M, DxilResource &R) {
   UNREFERENCED_PARAMETER(M);
   Type *Ty = R.GetGlobalSymbol()->getType()->getPointerElementType();
   if (R.IsStructuredBuffer()) {
-    while (Ty->isArrayTy())
-      Ty = Ty->getArrayElementType();
+    Ty = dxilutil::StripArrayTypes(Ty);
   }
   return CalcTypeSize(Ty);
 }
@@ -1222,11 +1218,9 @@ void CShaderReflectionConstantBuffer::InitializeStructuredBuffer(
 
   // Extract the `struct` that wraps element type of the buffer resource
   Type *Ty = R.GetGlobalSymbol()->getType()->getPointerElementType();
-  unsigned resArrayDims = 0;
-  while (Ty->isArrayTy()) {
-    Ty = Ty->getArrayElementType();
-    resArrayDims += 1;
-    // Replicate fxc bug, where Name gets [0] appended for each resource array dimension.
+  SmallVector<unsigned, 4> arrayDims;
+  Ty = dxilutil::StripArrayTypes(Ty, &arrayDims);
+  for (unsigned i = 0; i < arrayDims.size(); ++i) {
     m_ReflectionName += "[0]";
   }
   m_Desc.Name = m_ReflectionName.c_str();
@@ -1426,7 +1420,8 @@ void DxilModuleReflection::CreateReflectionObjectForResource(DxilResourceBase *R
   D3D12_SHADER_INPUT_BIND_DESC inputBind;
   ZeroMemory(&inputBind, sizeof(inputBind));
   inputBind.BindCount = RB->GetRangeSize();
-  if (RB->GetRangeSize() == UINT_MAX)
+  // FXC Bug: For Unbounded range, CBuffers say bind count is UINT_MAX, but all others report 0!
+  if (RB->GetRangeSize() == UINT_MAX && C != DXIL::ResourceClass::CBuffer)
     inputBind.BindCount = 0;
   inputBind.BindPoint = RB->GetLowerBound();
   inputBind.Dimension = ResourceToDimension(RB);

+ 584 - 22
tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/structured_buffer_layout.hlsl

@@ -124,7 +124,7 @@
 // CHECK-NEXT:          CBuffer: CB
 // CHECK-NEXT:      }
 // CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
-// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: CB1
+// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: CBuffer
 // CHECK-NEXT:        Type: D3D_CT_CBUFFER
 // CHECK-NEXT:        Size: 208
 // CHECK-NEXT:        uFlags: 0
@@ -239,12 +239,12 @@
 // CHECK-NEXT:                  Members: 0
 // CHECK-NEXT:                  Offset: 96
 // CHECK-NEXT:            }
-// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:          CBuffer: CBuffer
 // CHECK-NEXT:        ID3D12ShaderReflectionVariable:
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: s2
 // CHECK-NEXT:            Size: 4
 // CHECK-NEXT:            StartOffset: 128
-// CHECK-NEXT:            uFlags: 0
+// CHECK-NEXT:            uFlags: 0x2
 // CHECK-NEXT:            DefaultValue: <nullptr>
 // CHECK-NEXT:          ID3D12ShaderReflectionType:
 // CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S2
@@ -266,7 +266,7 @@
 // CHECK-NEXT:                  Members: 0
 // CHECK-NEXT:                  Offset: 0
 // CHECK-NEXT:            }
-// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:          CBuffer: CBuffer
 // CHECK-NEXT:        ID3D12ShaderReflectionVariable:
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: s3
 // CHECK-NEXT:            Size: 4
@@ -293,7 +293,7 @@
 // CHECK-NEXT:                  Members: 0
 // CHECK-NEXT:                  Offset: 0
 // CHECK-NEXT:            }
-// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:          CBuffer: CBuffer
 // CHECK-NEXT:        ID3D12ShaderReflectionVariable:
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: c
 // CHECK-NEXT:            Size: 12
@@ -309,7 +309,7 @@
 // CHECK-NEXT:              Columns: 3
 // CHECK-NEXT:              Members: 0
 // CHECK-NEXT:              Offset: 0
-// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:          CBuffer: CBuffer
 // CHECK-NEXT:        ID3D12ShaderReflectionVariable:
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: k
 // CHECK-NEXT:            Size: 4
@@ -325,7 +325,7 @@
 // CHECK-NEXT:              Columns: 1
 // CHECK-NEXT:              Members: 0
 // CHECK-NEXT:              Offset: 0
-// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:          CBuffer: CBuffer
 // CHECK-NEXT:        ID3D12ShaderReflectionVariable:
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: f2x1
 // CHECK-NEXT:            Size: 8
@@ -341,7 +341,7 @@
 // CHECK-NEXT:              Columns: 1
 // CHECK-NEXT:              Members: 0
 // CHECK-NEXT:              Offset: 0
-// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:          CBuffer: CBuffer
 // CHECK-NEXT:        ID3D12ShaderReflectionVariable:
 // CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: f1x2
 // CHECK-NEXT:            Size: 20
@@ -357,17 +357,17 @@
 // CHECK-NEXT:              Columns: 2
 // CHECK-NEXT:              Members: 0
 // CHECK-NEXT:              Offset: 0
-// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:          CBuffer: CBuffer
 // CHECK-NEXT:      }
 // CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
-// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: CBArray
+// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferArray
 // CHECK-NEXT:        Type: D3D_CT_CBUFFER
 // CHECK-NEXT:        Size: 256
 // CHECK-NEXT:        uFlags: 0
 // CHECK-NEXT:        Num Variables: 1
 // CHECK-NEXT:      {
 // CHECK-NEXT:        ID3D12ShaderReflectionVariable:
-// CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: CBArray
+// CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: ConstantBufferArray
 // CHECK-NEXT:            Size: 244
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            uFlags: 0x2
@@ -486,7 +486,243 @@
 // CHECK-NEXT:                      Offset: 96
 // CHECK-NEXT:                }
 // CHECK-NEXT:            }
-// CHECK-NEXT:          CBuffer: CBArray
+// CHECK-NEXT:          CBuffer: ConstantBufferArray
+// CHECK-NEXT:      }
+// CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferA1
+// 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: ConstantBufferA1
+// CHECK-NEXT:            Size: 116
+// CHECK-NEXT:            StartOffset: 0
+// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            DefaultValue: <nullptr>
+// CHECK-NEXT:          ID3D12ShaderReflectionType:
+// CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
+// CHECK-NEXT:              Class: D3D_SVC_STRUCT
+// CHECK-NEXT:              Type: D3D_SVT_VOID
+// CHECK-NEXT:              Elements: 1
+// CHECK-NEXT:              Rows: 1
+// CHECK-NEXT:              Columns: 16
+// CHECK-NEXT:              Members: 8
+// CHECK-NEXT:              Offset: 0
+// CHECK-NEXT:            {
+// 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:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: S0
+// CHECK-NEXT:                  Class: D3D_SVC_STRUCT
+// CHECK-NEXT:                  Type: D3D_SVT_VOID
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 3
+// CHECK-NEXT:                  Members: 2
+// CHECK-NEXT:                  Offset: 16
+// CHECK-NEXT:                {
+// 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:                  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: 8
+// CHECK-NEXT:                }
+// 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: 32
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float3
+// CHECK-NEXT:                  Class: D3D_SVC_VECTOR
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 3
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 48
+// 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: 64
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float2x1
+// CHECK-NEXT:                  Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 2
+// CHECK-NEXT:                  Columns: 1
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 72
+// 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: 80
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float1x2
+// CHECK-NEXT:                  Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 2
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 96
+// CHECK-NEXT:            }
+// CHECK-NEXT:          CBuffer: ConstantBufferA1
+// CHECK-NEXT:      }
+// CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferUnbounded
+// 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: ConstantBufferUnbounded
+// CHECK-NEXT:            Size: 116
+// CHECK-NEXT:            StartOffset: 0
+// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            DefaultValue: <nullptr>
+// CHECK-NEXT:          ID3D12ShaderReflectionType:
+// CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
+// CHECK-NEXT:              Class: D3D_SVC_STRUCT
+// CHECK-NEXT:              Type: D3D_SVT_VOID
+// CHECK-NEXT:              Elements: 1
+// CHECK-NEXT:              Rows: 1
+// CHECK-NEXT:              Columns: 16
+// CHECK-NEXT:              Members: 8
+// CHECK-NEXT:              Offset: 0
+// CHECK-NEXT:            {
+// 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:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: S0
+// CHECK-NEXT:                  Class: D3D_SVC_STRUCT
+// CHECK-NEXT:                  Type: D3D_SVT_VOID
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 3
+// CHECK-NEXT:                  Members: 2
+// CHECK-NEXT:                  Offset: 16
+// CHECK-NEXT:                {
+// 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:                  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: 8
+// CHECK-NEXT:                }
+// 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: 32
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float3
+// CHECK-NEXT:                  Class: D3D_SVC_VECTOR
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 3
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 48
+// 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: 64
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float2x1
+// CHECK-NEXT:                  Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 2
+// CHECK-NEXT:                  Columns: 1
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 72
+// 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: 80
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float1x2
+// CHECK-NEXT:                  Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 2
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 96
+// CHECK-NEXT:            }
+// CHECK-NEXT:          CBuffer: ConstantBufferUnbounded
 // CHECK-NEXT:      }
 // CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
 // CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: SB
@@ -607,7 +843,7 @@
 // CHECK-NEXT:          CBuffer: SB
 // CHECK-NEXT:      }
 // CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
-// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: SBArray
+// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: StructuredBufferArray[0][0]
 // CHECK-NEXT:        Type: D3D_CT_RESOURCE_BIND_INFO
 // CHECK-NEXT:        Size: 128
 // CHECK-NEXT:        uFlags: 0
@@ -733,7 +969,243 @@
 // CHECK-NEXT:                      Offset: 56
 // CHECK-NEXT:                }
 // CHECK-NEXT:            }
-// CHECK-NEXT:          CBuffer: SBArray
+// CHECK-NEXT:          CBuffer: StructuredBufferArray[0][0]
+// CHECK-NEXT:      }
+// CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: StructuredBufferA1[0]
+// CHECK-NEXT:        Type: D3D_CT_RESOURCE_BIND_INFO
+// CHECK-NEXT:        Size: 64
+// 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: 64
+// CHECK-NEXT:            StartOffset: 0
+// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            DefaultValue: <nullptr>
+// CHECK-NEXT:          ID3D12ShaderReflectionType:
+// CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
+// CHECK-NEXT:              Class: D3D_SVC_STRUCT
+// CHECK-NEXT:              Type: D3D_SVT_VOID
+// CHECK-NEXT:              Elements: 0
+// CHECK-NEXT:              Rows: 1
+// CHECK-NEXT:              Columns: 16
+// CHECK-NEXT:              Members: 8
+// CHECK-NEXT:              Offset: 0
+// CHECK-NEXT:            {
+// 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:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: S0
+// CHECK-NEXT:                  Class: D3D_SVC_STRUCT
+// CHECK-NEXT:                  Type: D3D_SVT_VOID
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 3
+// CHECK-NEXT:                  Members: 2
+// CHECK-NEXT:                  Offset: 4
+// CHECK-NEXT:                {
+// 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:                  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: 8
+// CHECK-NEXT:                }
+// 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: 16
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float3
+// CHECK-NEXT:                  Class: D3D_SVC_VECTOR
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 3
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 24
+// 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: 36
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float2x1
+// CHECK-NEXT:                  Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 2
+// CHECK-NEXT:                  Columns: 1
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 44
+// 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: 52
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float1x2
+// CHECK-NEXT:                  Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 2
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 56
+// CHECK-NEXT:            }
+// CHECK-NEXT:          CBuffer: StructuredBufferA1[0]
+// CHECK-NEXT:      }
+// CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: StructuredBufferUnbounded[0]
+// CHECK-NEXT:        Type: D3D_CT_RESOURCE_BIND_INFO
+// CHECK-NEXT:        Size: 64
+// 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: 64
+// CHECK-NEXT:            StartOffset: 0
+// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            DefaultValue: <nullptr>
+// CHECK-NEXT:          ID3D12ShaderReflectionType:
+// CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S1
+// CHECK-NEXT:              Class: D3D_SVC_STRUCT
+// CHECK-NEXT:              Type: D3D_SVT_VOID
+// CHECK-NEXT:              Elements: 0
+// CHECK-NEXT:              Rows: 1
+// CHECK-NEXT:              Columns: 16
+// CHECK-NEXT:              Members: 8
+// CHECK-NEXT:              Offset: 0
+// CHECK-NEXT:            {
+// 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:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: S0
+// CHECK-NEXT:                  Class: D3D_SVC_STRUCT
+// CHECK-NEXT:                  Type: D3D_SVT_VOID
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 3
+// CHECK-NEXT:                  Members: 2
+// CHECK-NEXT:                  Offset: 4
+// CHECK-NEXT:                {
+// 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:                  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: 8
+// CHECK-NEXT:                }
+// 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: 16
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float3
+// CHECK-NEXT:                  Class: D3D_SVC_VECTOR
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 3
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 24
+// 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: 36
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float2x1
+// CHECK-NEXT:                  Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 2
+// CHECK-NEXT:                  Columns: 1
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 44
+// 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: 52
+// CHECK-NEXT:              ID3D12ShaderReflectionType:
+// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float1x2
+// CHECK-NEXT:                  Class: D3D_SVC_MATRIX_COLUMNS
+// CHECK-NEXT:                  Type: D3D_SVT_FLOAT
+// CHECK-NEXT:                  Elements: 0
+// CHECK-NEXT:                  Rows: 1
+// CHECK-NEXT:                  Columns: 2
+// CHECK-NEXT:                  Members: 0
+// CHECK-NEXT:                  Offset: 56
+// CHECK-NEXT:            }
+// CHECK-NEXT:          CBuffer: StructuredBufferUnbounded[0]
 // CHECK-NEXT:      }
 // CHECK-NEXT:  Bound Resources:
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: CB
@@ -746,7 +1218,7 @@
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      NumSamples (or stride): 0
 // CHECK-NEXT:      uFlags: 0
-// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: CB1
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: CBuffer
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      uID: 1
 // CHECK-NEXT:      BindCount: 1
@@ -756,7 +1228,7 @@
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      NumSamples (or stride): 0
 // CHECK-NEXT:      uFlags: 0
-// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: CBArray
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferArray
 // CHECK-NEXT:      Type: D3D_SIT_CBUFFER
 // CHECK-NEXT:      uID: 2
 // CHECK-NEXT:      BindCount: 6
@@ -766,6 +1238,36 @@
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
 // CHECK-NEXT:      NumSamples (or stride): 0
 // CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferA1
+// CHECK-NEXT:      Type: D3D_SIT_CBUFFER
+// CHECK-NEXT:      uID: 3
+// CHECK-NEXT:      BindCount: 1
+// CHECK-NEXT:      BindPoint: 8
+// 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: 0
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: ConstantBufferUnbounded
+// CHECK-NEXT:      Type: D3D_SIT_CBUFFER
+// CHECK-NEXT:      uID: 4
+// CHECK-NEXT:      BindCount: 4294967295
+// CHECK-NEXT:      BindPoint: 9
+// 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: 0
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: SamplerUnbounded
+// CHECK-NEXT:      Type: D3D_SIT_SAMPLER
+// CHECK-NEXT:      uID: 0
+// CHECK-NEXT:      BindCount: 0
+// CHECK-NEXT:      BindPoint: 0
+// CHECK-NEXT:      Space: 1
+// CHECK-NEXT:      ReturnType: <unknown: 0>
+// CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_UNKNOWN
+// CHECK-NEXT:      NumSamples (or stride): 0
+// CHECK-NEXT:      uFlags: 0
 // CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: SB
 // CHECK-NEXT:      Type: D3D_SIT_STRUCTURED
 // CHECK-NEXT:      uID: 0
@@ -776,7 +1278,7 @@
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_BUFFER
 // CHECK-NEXT:      NumSamples (or stride): 64
 // CHECK-NEXT:      uFlags: 0
-// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: SBArray
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: StructuredBufferArray
 // CHECK-NEXT:      Type: D3D_SIT_STRUCTURED
 // CHECK-NEXT:      uID: 1
 // CHECK-NEXT:      BindCount: 6
@@ -786,6 +1288,46 @@
 // CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_BUFFER
 // CHECK-NEXT:      NumSamples (or stride): 128
 // CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: StructuredBufferA1
+// CHECK-NEXT:      Type: D3D_SIT_STRUCTURED
+// CHECK-NEXT:      uID: 2
+// CHECK-NEXT:      BindCount: 1
+// CHECK-NEXT:      BindPoint: 7
+// CHECK-NEXT:      Space: 0
+// CHECK-NEXT:      ReturnType: D3D_RETURN_TYPE_MIXED
+// CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_BUFFER
+// CHECK-NEXT:      NumSamples (or stride): 64
+// CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: StructuredBufferUnbounded
+// CHECK-NEXT:      Type: D3D_SIT_STRUCTURED
+// CHECK-NEXT:      uID: 3
+// CHECK-NEXT:      BindCount: 0
+// CHECK-NEXT:      BindPoint: 8
+// CHECK-NEXT:      Space: 0
+// CHECK-NEXT:      ReturnType: D3D_RETURN_TYPE_MIXED
+// CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_BUFFER
+// CHECK-NEXT:      NumSamples (or stride): 64
+// CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: Texture2DUnbounded
+// CHECK-NEXT:      Type: D3D_SIT_TEXTURE
+// CHECK-NEXT:      uID: 4
+// CHECK-NEXT:      BindCount: 0
+// CHECK-NEXT:      BindPoint: 0
+// CHECK-NEXT:      Space: 1
+// CHECK-NEXT:      ReturnType: D3D_RETURN_TYPE_FLOAT
+// CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_TEXTURE2D
+// CHECK-NEXT:      NumSamples (or stride): 4294967295
+// CHECK-NEXT:      uFlags: 0
+// CHECK-NEXT:    D3D12_SHADER_BUFFER_DESC: Name: RWBufferUnbounded
+// CHECK-NEXT:      Type: D3D_SIT_UAV_RWTYPED
+// CHECK-NEXT:      uID: 0
+// CHECK-NEXT:      BindCount: 0
+// CHECK-NEXT:      BindPoint: 0
+// CHECK-NEXT:      Space: 1
+// CHECK-NEXT:      ReturnType: D3D_RETURN_TYPE_FLOAT
+// CHECK-NEXT:      Dimension: D3D_SRV_DIMENSION_BUFFER
+// CHECK-NEXT:      NumSamples (or stride): 4294967295
+// CHECK-NEXT:      uFlags: 0
 
 #endif
 
@@ -812,7 +1354,7 @@ struct S2 {
   int i;
 };
 
-cbuffer CB1 {
+cbuffer CBuffer {
   S1 s1;          // CB: 0
   S2 s2;          // CB: 128 (new row for struct)
   S2 s3;          // CB: 144 (new row for struct)
@@ -826,10 +1368,30 @@ struct SA {
   S1 s1[2];
 };
 
-StructuredBuffer<SA> SBArray[2][3];
-ConstantBuffer<SA> CBArray[2][3];
+// fxc bug: auro-binds StructuredBufferA1 before StructuredBufferArray for seemingly no reason.
+StructuredBuffer<SA> StructuredBufferArray[2][3] : register(t1);
+ConstantBuffer<SA> ConstantBufferArray[2][3];
+
+StructuredBuffer<S1> StructuredBufferA1[1];
+ConstantBuffer<S1> ConstantBufferA1[1];
+
+// fxc bug: can't automatically allocate unbounded StructuredBuffer array in same space
+StructuredBuffer<S1> StructuredBufferUnbounded[] : register(t8);
+ConstantBuffer<S1> ConstantBufferUnbounded[];
+
+Texture2D<float> Texture2DUnbounded[] : register(t0, space1);
+RWBuffer<float> RWBufferUnbounded[] : register(u0, space1);
+SamplerState SamplerUnbounded[] : register(s0, space1);
 
 float3 main() : OUT {
-  return SB[CB.s0.i2.x + s3.i].c
-         + SBArray[1][2][CBArray[1][2].s1[1].s0.i2.x + s3.i].s1[1].c;
+  float3 result = 0
+         + SB[CB.s0.i2.x + s3.i].c
+         + StructuredBufferA1[0][ConstantBufferA1[0].s0.i2.x + s3.i].c
+         + StructuredBufferArray[1][2][ConstantBufferArray[1][2].s1[1].s0.i2.x + s3.i].s1[1].c
+         + StructuredBufferUnbounded[s2.i][ConstantBufferUnbounded[s3.i].s0.i2.x + s3.i].c
+         ;
+  RWBufferUnbounded[s2.i][s3.i] =
+    Texture2DUnbounded[s2.i].SampleLevel(
+      SamplerUnbounded[s2.i], float2(0.5, 0.5), 0).x;
+  return result;
 }