Browse Source

Fix CBuffer and StructuredBuffer offsets for packing and reflection.

- Added test with a number of apparently untested cases
- Updated some tests used for the more exhaustive reflection test
  which were failing to compile on fxc due to utf-8 bom and bool `|=`.
- Don't ignore dxc failures with ignore dxbc fails flag.
Tex Riddell 6 years ago
parent
commit
c5985f483c

+ 1 - 2
lib/HLSL/DxilContainerReflection.cpp

@@ -1002,8 +1002,7 @@ HRESULT CShaderReflectionType::Initialize(
         fieldReflectionType = new CShaderReflectionType();
         allTypes.push_back(std::unique_ptr<CShaderReflectionType>(fieldReflectionType));
 
-        unsigned int elementOffset = structLayout ?
-          baseOffset + (unsigned int)structLayout->getElementOffset(ff) : 0;
+        unsigned int elementOffset = structLayout ? (unsigned int)structLayout->getElementOffset(ff) : 0;
 
         fieldReflectionType->Initialize(M, fieldType, fieldAnnotation, elementOffset, allTypes, isCBuffer);
 

+ 25 - 7
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -581,6 +581,8 @@ static unsigned AlignBaseOffset(unsigned baseOffset, unsigned size,
 
     needNewAlign |= !bRowMajor && col > 1;
     needNewAlign |= bRowMajor && row > 1;
+  } else if (Ty->isStructureOrClassType() && ! hlsl::IsHLSLVecType(Ty)) {
+    needNewAlign = true;
   }
 
   unsigned scalarSizeInBytes = 4;
@@ -3000,16 +3002,27 @@ void CGMSHLSLRuntime::SetEntryFunction() {
   m_pHLModule->SetEntryFunction(Entry.Func);
 }
 
-// Here the size is CB size. So don't need check type.
-static unsigned AlignCBufferOffset(unsigned offset, unsigned size, llvm::Type *Ty) {
+// Here the size is CB size.
+// Offset still needs to be aligned based on type since this
+// is the legacy cbuffer global path.
+static unsigned AlignCBufferOffset(unsigned offset, unsigned size, llvm::Type *Ty, bool bRowMajor) {
   DXASSERT(!(offset & 1), "otherwise we have an invalid offset.");
   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;
+    } else {
+      bNeedNewRow = true;
+    }
+  }
   unsigned scalarSizeInBytes = Ty->getScalarSizeInBits() / 8;
 
   return AlignBufferOffsetInLegacy(offset, size, scalarSizeInBytes, bNeedNewRow);
 }
 
-static unsigned AllocateDxilConstantBuffer(HLCBuffer &CB) {
+static unsigned AllocateDxilConstantBuffer(HLCBuffer &CB,
+  std::unordered_map<Constant*, DxilFieldAnnotation> &constVarAnnotationMap) {
   unsigned offset = 0;
 
   // Scan user allocated constants first.
@@ -3030,8 +3043,12 @@ static unsigned AllocateDxilConstantBuffer(HLCBuffer &CB) {
 
     unsigned size = C->GetRangeSize();
     llvm::Type *Ty = C->GetGlobalSymbol()->getType()->getPointerElementType();
+    auto fieldAnnotation = constVarAnnotationMap[C->GetGlobalSymbol()];
+    bool bRowMajor = HLMatrixType::isa(Ty)
+      ? fieldAnnotation.GetMatrixAnnotation().Orientation == MatrixOrientation::RowMajor
+      : false;
     // Align offset.
-    offset = AlignCBufferOffset(offset, size, Ty);
+    offset = AlignCBufferOffset(offset, size, Ty, bRowMajor);
     if (C->GetLowerBound() == UINT_MAX) {
       C->SetLowerBound(offset);
     }
@@ -3040,10 +3057,11 @@ static unsigned AllocateDxilConstantBuffer(HLCBuffer &CB) {
   return offset;
 }
 
-static void AllocateDxilConstantBuffers(HLModule *pHLModule) {
+static void AllocateDxilConstantBuffers(HLModule *pHLModule,
+  std::unordered_map<Constant*, DxilFieldAnnotation> &constVarAnnotationMap) {
   for (unsigned i = 0; i < pHLModule->GetCBuffers().size(); i++) {
     HLCBuffer &CB = *static_cast<HLCBuffer*>(&(pHLModule->GetCBuffer(i)));
-    unsigned size = AllocateDxilConstantBuffer(CB);
+    unsigned size = AllocateDxilConstantBuffer(CB, constVarAnnotationMap);
     CB.SetSize(size);
   }
 }
@@ -4837,7 +4855,7 @@ void CGMSHLSLRuntime::FinishCodeGen() {
   }
 
   // Allocate constant buffers.
-  AllocateDxilConstantBuffers(m_pHLModule);
+  AllocateDxilConstantBuffers(m_pHLModule, m_ConstVarAnnotationMap);
   // TODO: create temp variable for constant which has store use.
 
   // Create Global variable and type annotation for each CBuffer.

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/BC6HEncode_EncodeBlockCS.hlsl

@@ -929,7 +929,7 @@ void finish_quantize_0( inout bool bBadQuantize, inout int2x3 endPoint, uint4 pr
     {
         bool3 bBadComponent = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? true : false )
             : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
-        bBadQuantize |= any(bBadComponent);
+        bBadQuantize = bBadQuantize || any(bBadComponent);
 
         endPoint[0] = endPoint[0] & ( ( 1 << prec.x ) - 1 );
         endPoint[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[1] )
@@ -949,7 +949,7 @@ void finish_quantize_1( inout bool bBadQuantize, inout int2x3 endPoint, uint4 pr
             : ( ( -endPoint[0] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
         bBadComponent[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? true : false )
             : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
-        bBadQuantize |= any(bBadComponent);
+        bBadQuantize = bBadQuantize || any(bBadComponent);
 
         endPoint[0] = ( endPoint[0] >= 0 ) ? ( ( endPoint[0] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[0] )
             : ( ( -endPoint[0] > ( 1 << ( prec.yzw - 1 ) ) ) ? ( 1 << ( prec.yzw - 1 ) ) : ( endPoint[0] & ( ( 1 << prec.yzw ) - 1 ) ) );

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/BC6HEncode_TryModeG10CS.hlsl

@@ -929,7 +929,7 @@ void finish_quantize_0( inout bool bBadQuantize, inout int2x3 endPoint, uint4 pr
     {
         bool3 bBadComponent = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? true : false )
             : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
-        bBadQuantize |= any(bBadComponent);
+        bBadQuantize = bBadQuantize || any(bBadComponent);
 
         endPoint[0] = endPoint[0] & ( ( 1 << prec.x ) - 1 );
         endPoint[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[1] )
@@ -949,7 +949,7 @@ void finish_quantize_1( inout bool bBadQuantize, inout int2x3 endPoint, uint4 pr
             : ( ( -endPoint[0] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
         bBadComponent[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? true : false )
             : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
-        bBadQuantize |= any(bBadComponent);
+        bBadQuantize = bBadQuantize || any(bBadComponent);
 
         endPoint[0] = ( endPoint[0] >= 0 ) ? ( ( endPoint[0] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[0] )
             : ( ( -endPoint[0] > ( 1 << ( prec.yzw - 1 ) ) ) ? ( 1 << ( prec.yzw - 1 ) ) : ( endPoint[0] & ( ( 1 << prec.yzw ) - 1 ) ) );

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/BC6HEncode_TryModeLE10CS.hlsl

@@ -929,7 +929,7 @@ void finish_quantize_0( inout bool bBadQuantize, inout int2x3 endPoint, uint4 pr
     {
         bool3 bBadComponent = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? true : false )
             : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
-        bBadQuantize |= any(bBadComponent);
+        bBadQuantize = bBadQuantize || any(bBadComponent);
 
         endPoint[0] = endPoint[0] & ( ( 1 << prec.x ) - 1 );
         endPoint[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[1] )
@@ -949,7 +949,7 @@ void finish_quantize_1( inout bool bBadQuantize, inout int2x3 endPoint, uint4 pr
             : ( ( -endPoint[0] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
         bBadComponent[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? true : false )
             : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? true : false );
-        bBadQuantize |= any(bBadComponent);
+        bBadQuantize = bBadQuantize || any(bBadComponent);
 
         endPoint[0] = ( endPoint[0] >= 0 ) ? ( ( endPoint[0] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[0] )
             : ( ( -endPoint[0] > ( 1 << ( prec.yzw - 1 ) ) ) ? ( 1 << ( prec.yzw - 1 ) ) : ( endPoint[0] & ( ( 1 << prec.yzw ) - 1 ) ) );

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_BuildGridCS.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferLoad
@@ -16,7 +16,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_BuildGridIndicesCS.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferLoad
@@ -13,7 +13,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_ClearGridIndicesCS.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferStore
@@ -12,7 +12,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_DensityCS_Grid.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferLoad
@@ -17,7 +17,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_DensityCS_Shared.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: flattenedThreadIdInGroup
@@ -20,7 +20,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_DensityCS_Simple.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferLoad
@@ -14,7 +14,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_ForceCS_Grid.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferLoad
@@ -21,7 +21,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_ForceCS_Shared.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: flattenedThreadIdInGroup
@@ -20,7 +20,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_ForceCS_Simple.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferLoad
@@ -18,7 +18,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_IntegrateCS.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferLoad
@@ -15,7 +15,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 2 - 2
tools/clang/test/CodeGenHLSL/Samples/DX11/FluidCS11_RearrangeParticlesCS.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
 
 // CHECK: threadId
 // CHECK: bufferLoad
@@ -13,7 +13,7 @@
 //--------------------------------------------------------------------------------------
 // Smoothed Particle Hydrodynamics Algorithm Based Upon:
 // Particle-Based Fluid Simulation for Interactive Applications
-// Matthias Müller
+// Matthias Müller
 //--------------------------------------------------------------------------------------
 
 //--------------------------------------------------------------------------------------

+ 410 - 20
tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/structured_buffer_layout.hlsl

@@ -8,13 +8,13 @@
 // CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
 // CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: CB
 // CHECK-NEXT:        Type: D3D_CT_CBUFFER
-// CHECK-NEXT:        Size: 32
+// 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: CB
-// CHECK-NEXT:            Size: 28
+// CHECK-NEXT:            Size: 116
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            uFlags: 0x2
 // CHECK-NEXT:            DefaultValue: <nullptr>
@@ -24,8 +24,8 @@
 // CHECK-NEXT:              Type: D3D_SVT_VOID
 // CHECK-NEXT:              Elements: 0
 // CHECK-NEXT:              Rows: 1
-// CHECK-NEXT:              Columns: 5
-// CHECK-NEXT:              Members: 3
+// CHECK-NEXT:              Columns: 16
+// CHECK-NEXT:              Members: 8
 // CHECK-NEXT:              Offset: 0
 // CHECK-NEXT:            {
 // CHECK-NEXT:              ID3D12ShaderReflectionType:
@@ -38,6 +38,71 @@
 // 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
@@ -45,7 +110,89 @@
 // CHECK-NEXT:                  Rows: 1
 // CHECK-NEXT:                  Columns: 1
 // CHECK-NEXT:                  Members: 0
-// CHECK-NEXT:                  Offset: 4
+// 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: CB
+// CHECK-NEXT:      }
+// CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: CB1
+// CHECK-NEXT:        Type: D3D_CT_CBUFFER
+// CHECK-NEXT:        Size: 208
+// CHECK-NEXT:        uFlags: 0
+// CHECK-NEXT:        Num Variables: 7
+// CHECK-NEXT:      {
+// CHECK-NEXT:        ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: s1
+// CHECK-NEXT:            Size: 116
+// CHECK-NEXT:            StartOffset: 0
+// CHECK-NEXT:            uFlags: 0
+// 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: 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
@@ -54,20 +201,174 @@
 // CHECK-NEXT:                  Rows: 1
 // CHECK-NEXT:                  Columns: 3
 // CHECK-NEXT:                  Members: 0
-// CHECK-NEXT:                  Offset: 16
+// 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: CB
+// CHECK-NEXT:          CBuffer: CB1
+// 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:            DefaultValue: <nullptr>
+// CHECK-NEXT:          ID3D12ShaderReflectionType:
+// CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S2
+// CHECK-NEXT:              Class: D3D_SVC_STRUCT
+// CHECK-NEXT:              Type: D3D_SVT_VOID
+// CHECK-NEXT:              Elements: 0
+// CHECK-NEXT:              Rows: 1
+// CHECK-NEXT:              Columns: 1
+// CHECK-NEXT:              Members: 1
+// 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:            }
+// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:        ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: s3
+// CHECK-NEXT:            Size: 4
+// CHECK-NEXT:            StartOffset: 144
+// CHECK-NEXT:            uFlags: 0x2
+// CHECK-NEXT:            DefaultValue: <nullptr>
+// CHECK-NEXT:          ID3D12ShaderReflectionType:
+// CHECK-NEXT:            D3D12_SHADER_TYPE_DESC: Name: S2
+// CHECK-NEXT:              Class: D3D_SVC_STRUCT
+// CHECK-NEXT:              Type: D3D_SVT_VOID
+// CHECK-NEXT:              Elements: 0
+// CHECK-NEXT:              Rows: 1
+// CHECK-NEXT:              Columns: 1
+// CHECK-NEXT:              Members: 1
+// 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:            }
+// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:        ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: c
+// CHECK-NEXT:            Size: 12
+// CHECK-NEXT:            StartOffset: 148
+// CHECK-NEXT:            uFlags: 0
+// CHECK-NEXT:            DefaultValue: <nullptr>
+// 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: 0
+// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:        ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: k
+// CHECK-NEXT:            Size: 4
+// CHECK-NEXT:            StartOffset: 160
+// 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: CB1
+// CHECK-NEXT:        ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: f2x1
+// CHECK-NEXT:            Size: 8
+// CHECK-NEXT:            StartOffset: 164
+// CHECK-NEXT:            uFlags: 0
+// CHECK-NEXT:            DefaultValue: <nullptr>
+// 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: 0
+// CHECK-NEXT:          CBuffer: CB1
+// CHECK-NEXT:        ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:          D3D12_SHADER_VARIABLE_DESC: Name: f1x2
+// CHECK-NEXT:            Size: 20
+// CHECK-NEXT:            StartOffset: 176
+// CHECK-NEXT:            uFlags: 0
+// CHECK-NEXT:            DefaultValue: <nullptr>
+// 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: 0
+// CHECK-NEXT:          CBuffer: CB1
 // CHECK-NEXT:      }
 // CHECK-NEXT:    ID3D12ShaderReflectionConstantBuffer:
 // CHECK-NEXT:      D3D12_SHADER_BUFFER_DESC: Name: SB
 // CHECK-NEXT:        Type: D3D_CT_RESOURCE_BIND_INFO
-// CHECK-NEXT:        Size: 20
+// 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: 20
+// CHECK-NEXT:            Size: 64
 // CHECK-NEXT:            StartOffset: 0
 // CHECK-NEXT:            uFlags: 0x2
 // CHECK-NEXT:            DefaultValue: <nullptr>
@@ -77,8 +378,8 @@
 // CHECK-NEXT:              Type: D3D_SVT_VOID
 // CHECK-NEXT:              Elements: 0
 // CHECK-NEXT:              Rows: 1
-// CHECK-NEXT:              Columns: 5
-// CHECK-NEXT:              Members: 3
+// CHECK-NEXT:              Columns: 16
+// CHECK-NEXT:              Members: 8
 // CHECK-NEXT:              Offset: 0
 // CHECK-NEXT:            {
 // CHECK-NEXT:              ID3D12ShaderReflectionType:
@@ -91,14 +392,43 @@
 // CHECK-NEXT:                  Members: 0
 // CHECK-NEXT:                  Offset: 0
 // CHECK-NEXT:              ID3D12ShaderReflectionType:
-// CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: int
-// CHECK-NEXT:                  Class: D3D_SVC_SCALAR
+// 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: 1
+// CHECK-NEXT:                  Columns: 2
 // CHECK-NEXT:                  Members: 0
-// CHECK-NEXT:                  Offset: 4
+// CHECK-NEXT:                  Offset: 16
 // CHECK-NEXT:              ID3D12ShaderReflectionType:
 // CHECK-NEXT:                D3D12_SHADER_TYPE_DESC: Name: float3
 // CHECK-NEXT:                  Class: D3D_SVC_VECTOR
@@ -107,22 +437,82 @@
 // CHECK-NEXT:                  Rows: 1
 // CHECK-NEXT:                  Columns: 3
 // CHECK-NEXT:                  Members: 0
-// CHECK-NEXT:                  Offset: 8
+// 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: SB
 // CHECK-NEXT:      }
 
 #endif
 
+struct S0 {
+  int2 i2;    // CB: 16, SB: 4
+  float f;    // CB: 24, SB: 12
+};
+
 struct S1 {
-  int i;
-  int j;
-  float3 c;
+  int i;          // CB: 0,  SB: 0
+  S0 s0;          // CB: 16, SB: 4  (new row for CB)
+  int2 j;         // CB: 32, SB: 16 (new row for CB)
+  float3 c;       // CB: 48, SB: 24 (new row for CB)
+  int2 k;         // CB: 64, SB: 36 (new row for CB)
+  float2x1 f2x1;  // CB: 72, SB: 44 pack with previous
+  int l;          // CB: 80, SB: 52
+  float1x2 f1x2;  // CB: 96, SB: 56 (new rows for CB)
 };
 
 StructuredBuffer<S1> SB;
 ConstantBuffer<S1> CB;
 
+struct S2 {
+  int i;
+};
+
+cbuffer CB1 {
+  S1 s1;          // CB: 0
+  S2 s2;          // CB: 128 (new row for struct)
+  S2 s3;          // CB: 144 (new row for struct)
+  float3 c;       // CB: 148 (fits into last row)
+  int k;          // CB: 160 (new row for CB)
+  float2x1 f2x1;  // CB: 164 pack with previous
+  float1x2 f1x2;  // CB: 176 (new rows for multi-row matrix in col_major)
+}
+
 float3 main() : OUT {
-  return SB[CB.i].c;
+  return SB[CB.s0.i2.x + s3.i].c;
 }

+ 5 - 26
tools/clang/unittests/HLSL/DxilContainerTest.cpp

@@ -169,8 +169,7 @@ public:
   }
 
   void CompareType(ID3D12ShaderReflectionType *pTest,
-                   ID3D12ShaderReflectionType *pBase,
-                   bool shouldSuppressOffsetChecks = false)
+                   ID3D12ShaderReflectionType *pBase)
   {
     D3D12_SHADER_TYPE_DESC testDesc, baseDesc;
     VERIFY_SUCCEEDED(pTest->GetDesc(&testDesc));
@@ -183,10 +182,7 @@ public:
     VERIFY_ARE_EQUAL(testDesc.Elements, baseDesc.Elements);
     VERIFY_ARE_EQUAL(testDesc.Members,  baseDesc.Members);
 
-    if(!shouldSuppressOffsetChecks)
-    {
-      VERIFY_ARE_EQUAL(testDesc.Offset,   baseDesc.Offset);
-    }
+    VERIFY_ARE_EQUAL(testDesc.Offset,   baseDesc.Offset);
 
     VERIFY_ARE_EQUAL(0, strcmp(testDesc.Name, baseDesc.Name));
 
@@ -196,7 +192,7 @@ public:
       VERIFY_IS_NOT_NULL(testMemberType);
       VERIFY_IS_NOT_NULL(baseMemberType);
 
-      CompareType(testMemberType, baseMemberType, shouldSuppressOffsetChecks);
+      CompareType(testMemberType, baseMemberType);
 
       LPCSTR testMemberName = pTest->GetMemberTypeName(i);
       LPCSTR baseMemberName = pBase->GetMemberTypeName(i);
@@ -297,24 +293,7 @@ public:
           VERIFY_ARE_EQUAL(variableTypeMap.count(testConst.Name), 1);
           ID3D12ShaderReflectionType* pBaseType = variableTypeMap[testConst.Name];
 
-          // Note: we suppress comparing offsets for structured buffers, because dxc and fxc don't
-          // seem to agree in that case.
-          //
-          // The information in the `D3D12_SHADER_BUFFER_DESC` doesn't give us enough to
-          // be able to isolate structured buffers, so we do the test negatively: suppress
-          // offset checks *unless* we are looking at a `cbuffer` or `tbuffer`.
-          bool shouldSuppressOffsetChecks = true;
-          switch( baseCB.Type )
-          {
-          default:
-            break;
-
-          case D3D_CT_CBUFFER:
-          case D3D_CT_TBUFFER:
-            shouldSuppressOffsetChecks = false;
-            break;
-          }
-          CompareType(pTestType, pBaseType, shouldSuppressOffsetChecks);
+          CompareType(pTestType, pBaseType);
         }
       }
     }
@@ -531,7 +510,6 @@ public:
     }
     if (FAILED(CompileFromFile(name, false, &pProgram))) {
       WEX::Logging::Log::Comment(L"Failed to compile DXIL blob.");
-      if (ignoreIfDXBCFails) return;
       VERIFY_FAIL();
     }
     
@@ -1490,6 +1468,7 @@ TEST_F(DxilContainerTest, ReflectionMatchesDXBC_CheckIn) {
   WEX::TestExecution::SetVerifyOutput verifySettings(WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
   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\\batch\\misc\\d3dreflect\\structured_buffer_layout.hlsl").c_str(), false);
 }
 
 TEST_F(DxilContainerTest, ReflectionMatchesDXBC_Full) {