Fix reflection of ConstantBuffer/StructuredBuffer arrays, nested arrays

Bugs for arrays:
- Size incorrect for ConstantBuffer type
  (should not be divided by array size)
- Size incorrect for StructuredBuffer element
  (was calculated with array dimensions multiplied in)
- Nested arrays would assert (ConstantBuffer) or
  fail to count/unwrap all resource dims (StructuredBuffer)

Match fxc weirdness:
- ConstantBuffer array has Elements == 1 for inner element type
  instead of 0, which would be consistent with everything else.
- StructuredBuffer array has "[0]" appended to the Name
  for each array dimension of the buffer...
This commit is contained in:
Tex Riddell 2019-07-05 19:17:48 -07:00
Родитель b6d67a3851
Коммит 2165224f0e
4 изменённых файлов: 358 добавлений и 15 удалений

Просмотреть файл

@ -1636,10 +1636,13 @@ void UpdateStructTypeForLegacyLayout(DxilResourceBase &Res,
Constant *Symbol = Res.GetGlobalSymbol();
Type *ElemTy = Symbol->getType()->getPointerElementType();
bool IsResourceArray = Res.GetRangeSize() != 1;
std::vector<unsigned> arrayDims;
if (IsResourceArray) {
// Support Array of ConstantBuffer.
if (ElemTy->isArrayTy())
while (ElemTy->isArrayTy()) {
arrayDims.push_back((unsigned)ElemTy->getArrayNumElements());
ElemTy = ElemTy->getArrayElementType();
}
}
StructType *ST = cast<StructType>(ElemTy);
if (ST->isOpaque()) {
@ -1651,12 +1654,10 @@ void UpdateStructTypeForLegacyLayout(DxilResourceBase &Res,
Type *UpdatedST =
UpdateStructTypeForLegacyLayout(ST, TypeSys, M);
if (ST != UpdatedST) {
Type *Ty = Symbol->getType()->getPointerElementType();
if (IsResourceArray) {
// Support Array of ConstantBuffer.
if (Ty->isArrayTy()) {
UpdatedST = ArrayType::get(UpdatedST, Ty->getArrayNumElements());
}
for (auto it = arrayDims.rbegin(), E = arrayDims.rend(); it != E; ++it)
UpdatedST = ArrayType::get(UpdatedST, *it);
}
GlobalVariable *NewGV = cast<GlobalVariable>(
M.getOrInsertGlobal(Symbol->getName().str() + "_legacy", UpdatedST));

Просмотреть файл

@ -357,6 +357,7 @@ class CShaderReflection;
struct D3D11_INTERNALSHADER_RESOURCE_DEF;
class CShaderReflectionType : public ID3D12ShaderReflectionType
{
friend class CShaderReflectionConstantBuffer;
protected:
D3D12_SHADER_TYPE_DESC m_Desc;
UINT m_SizeInCBuffer;
@ -429,6 +430,8 @@ class CShaderReflectionConstantBuffer : public ID3D12ShaderReflectionConstantBuf
protected:
D3D12_SHADER_BUFFER_DESC m_Desc;
std::vector<CShaderReflectionVariable> m_Variables;
// For StructuredBuffer arrays, Name will have [0] appended for each dimension to match fxc behavior.
std::string m_ReflectionName;
public:
CShaderReflectionConstantBuffer() = default;
@ -1101,15 +1104,18 @@ void CShaderReflectionConstantBuffer::Initialize(
std::vector<std::unique_ptr<CShaderReflectionType>>& allTypes) {
ZeroMemory(&m_Desc, sizeof(m_Desc));
m_Desc.Name = CB.GetGlobalName().c_str();
m_Desc.Size = CB.GetSize() / CB.GetRangeSize();
m_Desc.Size = CB.GetSize();
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.
if (Ty->isArrayTy())
unsigned resArrayDims = 0;
while (Ty->isArrayTy()) {
Ty = Ty->getArrayElementType();
resArrayDims += 1;
}
DxilTypeSystem &typeSys = M.GetTypeSystem();
StructType *ST = cast<StructType>(Ty);
@ -1121,6 +1127,10 @@ void CShaderReflectionConstantBuffer::Initialize(
m_Desc.Variables = ST->getNumContainedTypes();
if (resArrayDims) {
DXASSERT(m_Desc.Variables == 1, "otherwise, assumption is wrong");
}
for (unsigned i = 0; i < ST->getNumContainedTypes(); ++i) {
DxilFieldAnnotation &fieldAnnotation = annotation->GetFieldAnnotation(i);
@ -1133,6 +1143,12 @@ void CShaderReflectionConstantBuffer::Initialize(
allTypes.push_back(std::unique_ptr<CShaderReflectionType>(pVarType));
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) {
DXASSERT(pVarType->m_Desc.Elements == 0, "otherwise, assumption is wrong");
pVarType->m_Desc.Elements = 1;
}
BYTE *pDefaultValue = nullptr;
VarDesc.Name = fieldAnnotation.GetFieldName().c_str();
@ -1175,6 +1191,10 @@ static unsigned CalcTypeSize(Type *Ty) {
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();
}
return CalcTypeSize(Ty);
}
@ -1183,8 +1203,7 @@ void CShaderReflectionConstantBuffer::InitializeStructuredBuffer(
DxilResource &R,
std::vector<std::unique_ptr<CShaderReflectionType>>& allTypes) {
ZeroMemory(&m_Desc, sizeof(m_Desc));
m_Desc.Name = R.GetGlobalName().c_str();
//m_Desc.Size = R.GetSize();
m_ReflectionName = R.GetGlobalName();
m_Desc.Type = D3D11_CT_RESOURCE_BIND_INFO;
m_Desc.uFlags = 0;
m_Desc.Variables = 1;
@ -1192,7 +1211,7 @@ void CShaderReflectionConstantBuffer::InitializeStructuredBuffer(
D3D12_SHADER_VARIABLE_DESC VarDesc;
ZeroMemory(&VarDesc, sizeof(VarDesc));
VarDesc.Name = "$Element";
VarDesc.Size = CalcResTypeSize(M, R); // aligned bytes
VarDesc.Size = CalcResTypeSize(M, R);
VarDesc.StartTexture = UINT_MAX;
VarDesc.StartSampler = UINT_MAX;
VarDesc.uFlags |= D3D_SVF_USED; // TODO: not necessarily true
@ -1203,8 +1222,14 @@ void CShaderReflectionConstantBuffer::InitializeStructuredBuffer(
// Extract the `struct` that wraps element type of the buffer resource
Type *Ty = R.GetGlobalSymbol()->getType()->getPointerElementType();
if(Ty->isArrayTy())
Ty = Ty->getArrayElementType();
unsigned resArrayDims = 0;
while (Ty->isArrayTy()) {
Ty = Ty->getArrayElementType();
resArrayDims += 1;
// Replicate fxc bug, where Name gets [0] appended for each resource array dimension.
m_ReflectionName += "[0]";
}
m_Desc.Name = m_ReflectionName.c_str();
StructType *ST = cast<StructType>(Ty);
// Look up struct type annotation on the element type

Просмотреть файл

@ -27,4 +27,4 @@ uint UseBuf(int2 idx) {
// CHECK: BindPoint: 0
// CHECK: ReturnType: D3D_RETURN_TYPE_MIXED
// CHECK: Dimension: D3D_SRV_DIMENSION_BUFFER
// CHECK: NumSamples (or stride): 40
// CHECK: NumSamples (or stride): 20

Просмотреть файл

@ -4,7 +4,7 @@
// even when structure is shared with a ConstantBuffer.
#if 0
// CHECK: Constant Buffers:
// CHECK: Constant Buffers:
// CHECK-NEXT: ID3D12ShaderReflectionConstantBuffer:
// CHECK-NEXT: D3D12_SHADER_BUFFER_DESC: Name: CB
// CHECK-NEXT: Type: D3D_CT_CBUFFER
@ -360,6 +360,135 @@
// CHECK-NEXT: CBuffer: CB1
// CHECK-NEXT: }
// CHECK-NEXT: ID3D12ShaderReflectionConstantBuffer:
// CHECK-NEXT: D3D12_SHADER_BUFFER_DESC: Name: CBArray
// 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: Size: 244
// CHECK-NEXT: StartOffset: 0
// CHECK-NEXT: uFlags: 0x2
// CHECK-NEXT: DefaultValue: <nullptr>
// CHECK-NEXT: ID3D12ShaderReflectionType:
// CHECK-NEXT: D3D12_SHADER_TYPE_DESC: Name: SA
// CHECK-NEXT: Class: D3D_SVC_STRUCT
// CHECK-NEXT: Type: D3D_SVT_VOID
// CHECK-NEXT: Elements: 1
// CHECK-NEXT: Rows: 1
// CHECK-NEXT: Columns: 32
// CHECK-NEXT: Members: 1
// CHECK-NEXT: Offset: 0
// CHECK-NEXT: {
// 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: 2
// 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: }
// CHECK-NEXT: CBuffer: CBArray
// CHECK-NEXT: }
// CHECK-NEXT: ID3D12ShaderReflectionConstantBuffer:
// CHECK-NEXT: D3D12_SHADER_BUFFER_DESC: Name: SB
// CHECK-NEXT: Type: D3D_CT_RESOURCE_BIND_INFO
// CHECK-NEXT: Size: 64
@ -477,6 +606,186 @@
// CHECK-NEXT: }
// CHECK-NEXT: CBuffer: SB
// CHECK-NEXT: }
// CHECK-NEXT: ID3D12ShaderReflectionConstantBuffer:
// CHECK-NEXT: D3D12_SHADER_BUFFER_DESC: Name: SBArray
// CHECK-NEXT: Type: D3D_CT_RESOURCE_BIND_INFO
// 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: $Element
// CHECK-NEXT: Size: 128
// CHECK-NEXT: StartOffset: 0
// CHECK-NEXT: uFlags: 0x2
// CHECK-NEXT: DefaultValue: <nullptr>
// CHECK-NEXT: ID3D12ShaderReflectionType:
// CHECK-NEXT: D3D12_SHADER_TYPE_DESC: Name: SA
// CHECK-NEXT: Class: D3D_SVC_STRUCT
// CHECK-NEXT: Type: D3D_SVT_VOID
// CHECK-NEXT: Elements: 0
// CHECK-NEXT: Rows: 1
// CHECK-NEXT: Columns: 32
// CHECK-NEXT: Members: 1
// CHECK-NEXT: Offset: 0
// CHECK-NEXT: {
// 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: 2
// 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: }
// CHECK-NEXT: CBuffer: SBArray
// CHECK-NEXT: }
// CHECK-NEXT: Bound Resources:
// CHECK-NEXT: D3D12_SHADER_BUFFER_DESC: Name: CB
// CHECK-NEXT: Type: D3D_SIT_CBUFFER
// CHECK-NEXT: uID: 0
// CHECK-NEXT: BindCount: 1
// CHECK-NEXT: BindPoint: 0
// 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: CB1
// CHECK-NEXT: Type: D3D_SIT_CBUFFER
// CHECK-NEXT: uID: 1
// 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: 0
// CHECK-NEXT: D3D12_SHADER_BUFFER_DESC: Name: CBArray
// CHECK-NEXT: Type: D3D_SIT_CBUFFER
// CHECK-NEXT: uID: 2
// CHECK-NEXT: BindCount: 6
// CHECK-NEXT: BindPoint: 2
// 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: SB
// CHECK-NEXT: Type: D3D_SIT_STRUCTURED
// CHECK-NEXT: uID: 0
// CHECK-NEXT: BindCount: 1
// CHECK-NEXT: BindPoint: 0
// 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: SBArray
// CHECK-NEXT: Type: D3D_SIT_STRUCTURED
// CHECK-NEXT: uID: 1
// CHECK-NEXT: BindCount: 6
// CHECK-NEXT: BindPoint: 1
// CHECK-NEXT: Space: 0
// CHECK-NEXT: ReturnType: D3D_RETURN_TYPE_MIXED
// CHECK-NEXT: Dimension: D3D_SRV_DIMENSION_BUFFER
// CHECK-NEXT: NumSamples (or stride): 128
// CHECK-NEXT: uFlags: 0
#endif
@ -513,6 +822,14 @@ cbuffer CB1 {
float1x2 f1x2; // CB: 176 (new rows for multi-row matrix in col_major)
}
struct SA {
S1 s1[2];
};
StructuredBuffer<SA> SBArray[2][3];
ConstantBuffer<SA> CBArray[2][3];
float3 main() : OUT {
return SB[CB.s0.i2.x + s3.i].c;
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;
}