foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1
foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1
foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1
-deepA.d2.d1[2].va: offset 376, type 8b50, size 2, index 1, binding -1, stages 1
+deepA.d2.d1[2].va: offset 440, type 8b50, size 2, index 1, binding -1, stages 1
deepB.d2.d1.va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1
deepB.d2.d1[0].va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1
-deepB.d2.d1[1].va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1
-deepB.d2.d1[2].va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1
-deepB.d2.d1[3].va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1
+deepB.d2.d1[1].va: offset 1016, type 8b50, size 2, index 1, binding -1, stages 1
+deepB.d2.d1[2].va: offset 1048, type 8b50, size 2, index 1, binding -1, stages 1
+deepB.d2.d1[3].va: offset 1080, type 8b50, size 2, index 1, binding -1, stages 1
deepC.iv4: offset 1568, type 8b52, size 1, index 1, binding -1, stages 1
-deepC.d2.i: offset 1568, type 1404, size 1, index 1, binding -1, stages 1
-deepC.d2.d1[0].va: offset 1568, type 8b50, size 3, index 1, binding -1, stages 1
-deepC.d2.d1[0].b: offset 1568, type 8b56, size 1, index 1, binding -1, stages 1
-deepC.d2.d1[1].va: offset 1568, type 8b50, size 3, index 1, binding -1, stages 1
-deepC.d2.d1[1].b: offset 1568, type 8b56, size 1, index 1, binding -1, stages 1
-deepC.d2.d1[2].va: offset 1568, type 8b50, size 3, index 1, binding -1, stages 1
-deepC.d2.d1[2].b: offset 1568, type 8b56, size 1, index 1, binding -1, stages 1
-deepC.d2.d1[3].va: offset 1568, type 8b50, size 3, index 1, binding -1, stages 1
-deepC.d2.d1[3].b: offset 1568, type 8b56, size 1, index 1, binding -1, stages 1
-deepC.v3: offset 1568, type 8b54, size 1, index 1, binding -1, stages 1
+deepC.d2.i: offset 1584, type 1404, size 1, index 1, binding -1, stages 1
+deepC.d2.d1[0].va: offset 1592, type 8b50, size 3, index 1, binding -1, stages 1
+deepC.d2.d1[0].b: offset 1616, type 8b56, size 1, index 1, binding -1, stages 1
+deepC.d2.d1[1].va: offset 1624, type 8b50, size 3, index 1, binding -1, stages 1
+deepC.d2.d1[1].b: offset 1648, type 8b56, size 1, index 1, binding -1, stages 1
+deepC.d2.d1[2].va: offset 1656, type 8b50, size 3, index 1, binding -1, stages 1
+deepC.d2.d1[2].b: offset 1680, type 8b56, size 1, index 1, binding -1, stages 1
+deepC.d2.d1[3].va: offset 1688, type 8b50, size 3, index 1, binding -1, stages 1
+deepC.d2.d1[3].b: offset 1712, type 8b56, size 1, index 1, binding -1, stages 1
+deepC.v3: offset 1728, type 8b54, size 1, index 1, binding -1, stages 1
deepD[0].iv4: offset 2480, type 8b52, size 1, index 1, binding -1, stages 1
-deepD[0].d2.i: offset 2480, type 1404, size 1, index 1, binding -1, stages 1
-deepD[0].d2.d1[0].va: offset 2480, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[0].d2.d1[0].b: offset 2480, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[0].d2.d1[1].va: offset 2480, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[0].d2.d1[1].b: offset 2480, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[0].d2.d1[2].va: offset 2480, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[0].d2.d1[2].b: offset 2480, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[0].d2.d1[3].va: offset 2480, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[0].d2.d1[3].b: offset 2480, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[0].v3: offset 2480, type 8b54, size 1, index 1, binding -1, stages 1
-deepD[1].iv4: offset 2480, type 8b52, size 1, index 1, binding -1, stages 1
-deepD[1].d2.i: offset 2480, type 1404, size 1, index 1, binding -1, stages 1
-deepD[1].d2.d1[0].va: offset 2480, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[1].d2.d1[0].b: offset 2480, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[1].d2.d1[1].va: offset 2480, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[1].d2.d1[1].b: offset 2480, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[1].d2.d1[2].va: offset 2480, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[1].d2.d1[2].b: offset 2480, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[1].d2.d1[3].va: offset 2480, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[1].d2.d1[3].b: offset 2480, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[1].v3: offset 2480, type 8b54, size 1, index 1, binding -1, stages 1
+deepD[0].d2.i: offset 2496, type 1404, size 1, index 1, binding -1, stages 1
+deepD[0].d2.d1[0].va: offset 2504, type 8b50, size 3, index 1, binding -1, stages 1
+deepD[0].d2.d1[0].b: offset 2528, type 8b56, size 1, index 1, binding -1, stages 1
+deepD[0].d2.d1[1].va: offset 2536, type 8b50, size 3, index 1, binding -1, stages 1
+deepD[0].d2.d1[1].b: offset 2560, type 8b56, size 1, index 1, binding -1, stages 1
+deepD[0].d2.d1[2].va: offset 2568, type 8b50, size 3, index 1, binding -1, stages 1
+deepD[0].d2.d1[2].b: offset 2592, type 8b56, size 1, index 1, binding -1, stages 1
+deepD[0].d2.d1[3].va: offset 2600, type 8b50, size 3, index 1, binding -1, stages 1
+deepD[0].d2.d1[3].b: offset 2624, type 8b56, size 1, index 1, binding -1, stages 1
+deepD[0].v3: offset 2640, type 8b54, size 1, index 1, binding -1, stages 1
+deepD[1].iv4: offset 2784, type 8b52, size 1, index 1, binding -1, stages 1
+deepD[1].d2.i: offset 2800, type 1404, size 1, index 1, binding -1, stages 1
+deepD[1].d2.d1[0].va: offset 2808, type 8b50, size 3, index 1, binding -1, stages 1
+deepD[1].d2.d1[0].b: offset 2832, type 8b56, size 1, index 1, binding -1, stages 1
+deepD[1].d2.d1[1].va: offset 2840, type 8b50, size 3, index 1, binding -1, stages 1
+deepD[1].d2.d1[1].b: offset 2864, type 8b56, size 1, index 1, binding -1, stages 1
+deepD[1].d2.d1[2].va: offset 2872, type 8b50, size 3, index 1, binding -1, stages 1
+deepD[1].d2.d1[2].b: offset 2896, type 8b56, size 1, index 1, binding -1, stages 1
+deepD[1].d2.d1[3].va: offset 2904, type 8b50, size 3, index 1, binding -1, stages 1
+deepD[1].d2.d1[3].b: offset 2928, type 8b56, size 1, index 1, binding -1, stages 1
+deepD[1].v3: offset 2944, type 8b54, size 1, index 1, binding -1, stages 1
foo1: offset 0, type 1406, size 1, index 4, binding -1, stages 1
foo2: offset 0, type 1406, size 1, index 5, binding -1, stages 1
anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
buf2.runtimeArray.c: offset 8, type 1406, size 1, index 13, binding -1, stages 1
buf3.runtimeArray: offset 4, type 1406, size 0, index 14, binding -1, stages 1
buf4.runtimeArray.c: offset 8, type 1406, size 1, index 15, binding -1, stages 1
+nested2.a.n1.a: offset 16, type 1406, size 1, index 16, binding -1, stages 1
+nested2.a.n2.b: offset 32, type 1406, size 1, index 16, binding -1, stages 1
+nested2.a.n2.c: offset 36, type 1406, size 1, index 16, binding -1, stages 1
+nested2.a.n2.d: offset 40, type 1406, size 1, index 16, binding -1, stages 1
+nested2.b[0].a: offset 48, type 1406, size 1, index 16, binding -1, stages 1
+nested2.b[1].a: offset 64, type 1406, size 1, index 16, binding -1, stages 1
+nested2.b[2].a: offset 80, type 1406, size 1, index 16, binding -1, stages 1
+nested2.b[3].a: offset 96, type 1406, size 1, index 16, binding -1, stages 1
+nested2.c.a: offset 112, type 1406, size 1, index 16, binding -1, stages 1
+nested2.d.a: offset 144, type 1406, size 1, index 16, binding -1, stages 1
anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1
uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1
buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
+nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 0
Vertex attribute reflection:
attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0
}
}
+ // shared calculation by getOffset and getOffsets
+ void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize)
+ {
+ int dummyStride;
+
+ // modify just the children's view of matrix layout, if there is one for this member
+ TLayoutMatrix subMatrixLayout = memberType.getQualifier().layoutMatrix;
+ int memberAlignment = intermediate.getMemberAlignment(memberType, memberSize, dummyStride,
+ parentType.getQualifier().layoutPacking,
+ subMatrixLayout != ElmNone
+ ? subMatrixLayout == ElmRowMajor
+ : parentType.getQualifier().layoutMatrix == ElmRowMajor);
+ RoundToPow2(offset, memberAlignment);
+ }
+
// Lookup or calculate the offset of a block member, using the recursively
// defined block offset rules.
int getOffset(const TType& type, int index)
if (memberList[index].type->getQualifier().hasOffset())
return memberList[index].type->getQualifier().layoutOffset;
- int memberSize;
- int dummyStride;
+ int memberSize = 0;
int offset = 0;
for (int m = 0; m <= index; ++m) {
- // modify just the children's view of matrix layout, if there is one for this member
- TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
- int memberAlignment = intermediate.getMemberAlignment(*memberList[m].type, memberSize, dummyStride,
- type.getQualifier().layoutPacking,
- subMatrixLayout != ElmNone
- ? subMatrixLayout == ElmRowMajor
- : type.getQualifier().layoutMatrix == ElmRowMajor);
- RoundToPow2(offset, memberAlignment);
+ updateOffset(type, *memberList[m].type, offset, memberSize);
+
if (m < index)
offset += memberSize;
}
return offset;
}
+ // Lookup or calculate the offset of all block members at once, using the recursively
+ // defined block offset rules.
+ void getOffsets(const TType& type, TVector<int>& offsets)
+ {
+ const TTypeList& memberList = *type.getStruct();
+
+ int memberSize = 0;
+ int offset = 0;
+ for (size_t m = 0; m < offsets.size(); ++m) {
+ // if the user supplied an offset, snap to it now
+ if (memberList[m].type->getQualifier().hasOffset())
+ offset = memberList[m].type->getQualifier().layoutOffset;
+
+ // calculate the offset of the next member and align the current offset to this member
+ updateOffset(type, *memberList[m].type, offset, memberSize);
+
+ // save the offset of this member
+ offsets[m] = offset;
+
+ // update for the next member
+ offset += memberSize;
+ }
+ }
+
+ // Calculate the stride of an array type
+ int getArrayStride(const TType& baseType, const TType& type)
+ {
+ int dummySize;
+ int stride;
+
+ // consider blocks to have 0 stride, so that all offsets are relative to the start of their block
+ if (type.getBasicType() == EbtBlock)
+ return 0;
+
+ TLayoutMatrix subMatrixLayout = type.getQualifier().layoutMatrix;
+ intermediate.getMemberAlignment(type, dummySize, stride,
+ baseType.getQualifier().layoutPacking,
+ subMatrixLayout != ElmNone
+ ? subMatrixLayout == ElmRowMajor
+ : baseType.getQualifier().layoutMatrix == ElmRowMajor);
+
+ return stride;
+ }
+
// Calculate the block data size.
// Block arrayness is not taken into account, each element is backed by a separate buffer.
int getBlockSize(const TType& blockType)
terminalType = &visitNode->getType();
int index;
switch (visitNode->getOp()) {
- case EOpIndexIndirect:
+ case EOpIndexIndirect: {
+ int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
+
// Visit all the indices of this array, and for each one add on the remaining dereferencing
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
TString newBaseName = name;
++nextDeref;
TType derefType(*terminalType, 0);
blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize);
+
+ if (offset >= 0)
+ offset += stride;
}
// it was all completed in the recursive calls above
return;
+ }
case EOpIndexDirect:
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
- if (baseType.getBasicType() != EbtBlock)
+ if (baseType.getBasicType() != EbtBlock) {
name.append(TString("[") + String(index) + "]");
+
+ if (offset >= 0)
+ offset += getArrayStride(baseType, visitNode->getLeft()->getType()) * index;
+ }
break;
case EOpIndexDirectStruct:
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
// if the terminalType is still too coarse a granularity, this is still an aggregate to expand, expand it...
if (! isReflectionGranularity(*terminalType)) {
+ // the base offset of this node, that children are relative to
+ int baseOffset = offset;
+
if (terminalType->isArray()) {
// Visit all the indices of this array, and for each one,
// fully explode the remaining aggregate to dereference
+
+ int stride = 0;
+ if (offset >= 0)
+ stride = getArrayStride(baseType, *terminalType);
+
for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) {
TString newBaseName = name;
newBaseName.append(TString("[") + String(i) + "]");
TType derefType(*terminalType, 0);
+ if (offset >= 0)
+ offset = baseOffset + stride * i;
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0);
}
} else {
// Visit all members of this aggregate, and for each one,
// fully explode the remaining aggregate to dereference
const TTypeList& typeList = *terminalType->getStruct();
+
+ TVector<int> memberOffsets;
+
+ if (baseOffset >= 0) {
+ memberOffsets.resize(typeList.size());
+ getOffsets(*terminalType, memberOffsets);
+ }
+
for (int i = 0; i < (int)typeList.size(); ++i) {
TString newBaseName = name;
newBaseName.append(TString(".") + typeList[i].type->getFieldName());
TType derefType(*terminalType, i);
+ if (offset >= 0)
+ offset = baseOffset + memberOffsets[i];
blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0);
}
}