SPV: Fix array strides by explicitly computing them in the getBaseAlignment() algorithm.
This commit is contained in:
parent
e0b6cad44f
commit
4998789d4e
9 changed files with 83 additions and 61 deletions
|
|
@ -1206,6 +1206,10 @@ public:
|
|||
arraySizes = new TArraySizes;
|
||||
*arraySizes = s;
|
||||
}
|
||||
void clearArraySizes()
|
||||
{
|
||||
arraySizes = 0;
|
||||
}
|
||||
void addArrayOuterSizes(const TArraySizes& s)
|
||||
{
|
||||
if (arraySizes == nullptr)
|
||||
|
|
|
|||
|
|
@ -5353,7 +5353,8 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
|
|||
|
||||
// modify just the children's view of matrix layout, if there is one for this member
|
||||
TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
|
||||
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, qualifier.layoutPacking == ElpStd140,
|
||||
int dummyStride;
|
||||
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking == ElpStd140,
|
||||
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
|
||||
if (memberQualifier.hasOffset()) {
|
||||
// "The specified offset must be a multiple
|
||||
|
|
|
|||
|
|
@ -858,8 +858,14 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
|||
// otherwise it does not, yielding std430 rules.
|
||||
//
|
||||
// The size is returned in the 'size' parameter
|
||||
//
|
||||
// The stride is only non-0 for arrays or matrices, and is the stride of the
|
||||
// top-level object nested within the type. E.g., for an array of matrices,
|
||||
// it is the distances needed between matrices, despite the rules saying the
|
||||
// stride comes from the flattening down to vectors.
|
||||
//
|
||||
// Return value is the alignment of the type.
|
||||
int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140, bool rowMajor)
|
||||
int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, bool std140, bool rowMajor)
|
||||
{
|
||||
int alignment;
|
||||
|
||||
|
|
@ -916,16 +922,23 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140, b
|
|||
//
|
||||
// 10. If the member is an array of S structures, the S elements of the array are laid
|
||||
// out in order, according to rule (9).
|
||||
//
|
||||
// Assuming, for rule 10: The stride is the same as the size of an element.
|
||||
|
||||
// rules 4, 6, and 8
|
||||
stride = 0;
|
||||
int dummyStride;
|
||||
|
||||
// rules 4, 6, 8, and 10
|
||||
if (type.isArray()) {
|
||||
// TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||
TType derefType(type, 0);
|
||||
alignment = getBaseAlignment(derefType, size, std140, rowMajor);
|
||||
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
||||
if (std140)
|
||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||
RoundToPow2(size, alignment);
|
||||
size *= type.getOuterArraySize();
|
||||
stride = size; // uses full matrix size for stride of an array of matrices (not quite what rule 6/8, but what's expected)
|
||||
// uses the assumption for rule 10 in the comment above
|
||||
size = stride * type.getOuterArraySize();
|
||||
return alignment;
|
||||
}
|
||||
|
||||
|
|
@ -939,7 +952,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140, b
|
|||
int memberSize;
|
||||
// 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 = getBaseAlignment(*memberList[m].type, memberSize, std140,
|
||||
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140,
|
||||
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||
RoundToPow2(size, memberAlignment);
|
||||
|
|
@ -971,14 +984,15 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140, b
|
|||
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
||||
TType derefType(type, 0, type.getQualifier().layoutMatrix == ElmRowMajor);
|
||||
|
||||
alignment = getBaseAlignment(derefType, size, std140, rowMajor);
|
||||
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
||||
if (std140)
|
||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||
RoundToPow2(size, alignment);
|
||||
stride = size; // use intra-matrix stride for stride of a just a matrix
|
||||
if (rowMajor)
|
||||
size *= type.getMatrixRows();
|
||||
size = stride * type.getMatrixRows();
|
||||
else
|
||||
size *= type.getMatrixCols();
|
||||
size = stride * type.getMatrixCols();
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ public:
|
|||
}
|
||||
int addXfbBufferOffset(const TType&);
|
||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
||||
static int getBaseAlignment(const TType&, int& size, bool std140, bool rowMajor);
|
||||
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
||||
|
||||
protected:
|
||||
void error(TInfoSink& infoSink, const char*);
|
||||
|
|
|
|||
|
|
@ -121,11 +121,12 @@ public:
|
|||
return memberList[index].type->getQualifier().layoutOffset;
|
||||
|
||||
int memberSize;
|
||||
int dummyStride;
|
||||
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.getBaseAlignment(*memberList[m].type, memberSize, type.getQualifier().layoutPacking == ElpStd140,
|
||||
int memberAlignment = intermediate.getBaseAlignment(*memberList[m].type, memberSize, dummyStride, type.getQualifier().layoutPacking == ElpStd140,
|
||||
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : type.getQualifier().layoutMatrix == ElmRowMajor);
|
||||
RoundToPow2(offset, memberAlignment);
|
||||
if (m < index)
|
||||
|
|
@ -144,7 +145,8 @@ public:
|
|||
int lastOffset = getOffset(blockType, lastIndex);
|
||||
|
||||
int lastMemberSize;
|
||||
intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, blockType.getQualifier().layoutPacking == ElpStd140,
|
||||
int dummyStride;
|
||||
intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride, blockType.getQualifier().layoutPacking == ElpStd140,
|
||||
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
||||
|
||||
return lastOffset + lastMemberSize;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue