mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-09 12:00:05 +00:00
SPV: Fix array strides by explicitly computing them in the getBaseAlignment() algorithm.
This commit is contained in:
parent
e0b6cad44f
commit
4998789d4e
@ -1707,25 +1707,25 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
|
|||||||
int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
|
int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
int stride = glslangIntermediate->getBaseAlignment(arrayType, size, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
int stride;
|
||||||
if (arrayType.isMatrix()) {
|
glslangIntermediate->getBaseAlignment(arrayType, size, stride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
||||||
// GLSL strides are set to alignments of the matrix flattened to individual rows/cols,
|
|
||||||
// but SPV needs an array stride for the whole matrix, not the rows/cols
|
|
||||||
if (matrixLayout == glslang::ElmRowMajor)
|
|
||||||
stride *= arrayType.getMatrixRows();
|
|
||||||
else
|
|
||||||
stride *= arrayType.getMatrixCols();
|
|
||||||
}
|
|
||||||
|
|
||||||
return stride;
|
return stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a matrix type, returns the integer stride required for that matrix
|
// Given a matrix type, or array (of array) of matrixes type, returns the integer stride required for that matrix
|
||||||
// when used as a member of an interface block
|
// when used as a member of an interface block
|
||||||
int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
|
int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
|
||||||
{
|
{
|
||||||
|
glslang::TType elementType;
|
||||||
|
elementType.shallowCopy(matrixType);
|
||||||
|
elementType.clearArraySizes();
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
return glslangIntermediate->getBaseAlignment(matrixType, size, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
int stride;
|
||||||
|
glslangIntermediate->getBaseAlignment(elementType, size, stride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
||||||
|
|
||||||
|
return stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a member type of a struct, realign the current offset for it, and compute
|
// Given a member type of a struct, realign the current offset for it, and compute
|
||||||
@ -1764,7 +1764,8 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
|
|||||||
// but possibly not yet correctly aligned.
|
// but possibly not yet correctly aligned.
|
||||||
|
|
||||||
int memberSize;
|
int memberSize;
|
||||||
int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
int dummyStride;
|
||||||
|
int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, dummyStride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
||||||
glslang::RoundToPow2(currentOffset, memberAlignment);
|
glslang::RoundToPow2(currentOffset, memberAlignment);
|
||||||
nextOffset = currentOffset + memberSize;
|
nextOffset = currentOffset + memberSize;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ Linked vertex stage:
|
|||||||
MemberDecorate 14(S) 1 Offset 16
|
MemberDecorate 14(S) 1 Offset 16
|
||||||
MemberDecorate 14(S) 1 MatrixStride 16
|
MemberDecorate 14(S) 1 MatrixStride 16
|
||||||
MemberDecorate 14(S) 2 Offset 144
|
MemberDecorate 14(S) 2 Offset 144
|
||||||
Decorate 18 ArrayStride 16
|
Decorate 18 ArrayStride 480
|
||||||
MemberDecorate 19(Block140) 0 Offset 0
|
MemberDecorate 19(Block140) 0 Offset 0
|
||||||
MemberDecorate 19(Block140) 1 Offset 16
|
MemberDecorate 19(Block140) 1 Offset 16
|
||||||
MemberDecorate 19(Block140) 2 Offset 976
|
MemberDecorate 19(Block140) 2 Offset 976
|
||||||
@ -113,7 +113,7 @@ Linked vertex stage:
|
|||||||
MemberDecorate 22(S) 1 Offset 16
|
MemberDecorate 22(S) 1 Offset 16
|
||||||
MemberDecorate 22(S) 1 MatrixStride 8
|
MemberDecorate 22(S) 1 MatrixStride 8
|
||||||
MemberDecorate 22(S) 2 Offset 80
|
MemberDecorate 22(S) 2 Offset 80
|
||||||
Decorate 24 ArrayStride 16
|
Decorate 24 ArrayStride 288
|
||||||
MemberDecorate 25(Block430) 0 Offset 0
|
MemberDecorate 25(Block430) 0 Offset 0
|
||||||
MemberDecorate 25(Block430) 1 Offset 16
|
MemberDecorate 25(Block430) 1 Offset 16
|
||||||
MemberDecorate 25(Block430) 2 Offset 592
|
MemberDecorate 25(Block430) 2 Offset 592
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#### BEGIN COMPILER 0 INFO LOG ####
|
#### BEGIN COMPILER 0 INFO LOG ####
|
||||||
0:? Sequence
|
0:? Sequence
|
||||||
0:37 Function Definition: main( (void)
|
0:37 Function Definition: main( (void)
|
||||||
0:37 Function Parameters:
|
0:37 Function Parameters:
|
||||||
0:39 Sequence
|
0:39 Sequence
|
||||||
0:39 move second child to first child (4-component vector of float)
|
0:39 move second child to first child (4-component vector of float)
|
||||||
0:39 'gl_FragColor' (FragColor 4-component vector of float)
|
0:39 'gl_FragColor' (FragColor 4-component vector of float)
|
||||||
0:39 Construct vec4 (4-component vector of float)
|
0:39 Construct vec4 (4-component vector of float)
|
||||||
0:39 'color' (varying in 3-component vector of float)
|
0:39 'color' (varying in 3-component vector of float)
|
||||||
0:39 1.000000 (const float)
|
0:39 1.000000 (const float)
|
||||||
|
|
||||||
#### END COMPILER 0 INFO LOG ####
|
#### END COMPILER 0 INFO LOG ####
|
||||||
#### BEGIN LINKER INFO LOG ####
|
#### BEGIN LINKER INFO LOG ####
|
||||||
|
|
||||||
#### END LINKER INFO LOG ####
|
#### END LINKER INFO LOG ####
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
#### BEGIN COMPILER 0 INFO LOG ####
|
#### BEGIN COMPILER 0 INFO LOG ####
|
||||||
0:? Sequence
|
0:? Sequence
|
||||||
0:37 Function Definition: main( (void)
|
0:37 Function Definition: main( (void)
|
||||||
0:37 Function Parameters:
|
0:37 Function Parameters:
|
||||||
0:39 Sequence
|
0:39 Sequence
|
||||||
0:39 move second child to first child (3-component vector of float)
|
0:39 move second child to first child (3-component vector of float)
|
||||||
0:39 'color' (varying out 3-component vector of float)
|
0:39 'color' (varying out 3-component vector of float)
|
||||||
0:39 1.000000 (const float)
|
0:39 1.000000 (const float)
|
||||||
0:39 1.000000 (const float)
|
0:39 1.000000 (const float)
|
||||||
0:39 1.000000 (const float)
|
0:39 1.000000 (const float)
|
||||||
0:41 move second child to first child (4-component vector of float)
|
0:41 move second child to first child (4-component vector of float)
|
||||||
0:41 'gl_Position' (Position 4-component vector of float)
|
0:41 'gl_Position' (Position 4-component vector of float)
|
||||||
0:41 matrix-times-vector (4-component vector of float)
|
0:41 matrix-times-vector (4-component vector of float)
|
||||||
0:41 'gl_ModelViewProjectionMatrix' (uniform 4X4 matrix of float)
|
0:41 'gl_ModelViewProjectionMatrix' (uniform 4X4 matrix of float)
|
||||||
0:41 'gl_Vertex' (attribute 4-component vector of float)
|
0:41 'gl_Vertex' (attribute 4-component vector of float)
|
||||||
|
|
||||||
#### END COMPILER 0 INFO LOG ####
|
#### END COMPILER 0 INFO LOG ####
|
||||||
#### BEGIN LINKER INFO LOG ####
|
#### BEGIN LINKER INFO LOG ####
|
||||||
|
|
||||||
#### END LINKER INFO LOG ####
|
#### END LINKER INFO LOG ####
|
||||||
|
@ -1206,6 +1206,10 @@ public:
|
|||||||
arraySizes = new TArraySizes;
|
arraySizes = new TArraySizes;
|
||||||
*arraySizes = s;
|
*arraySizes = s;
|
||||||
}
|
}
|
||||||
|
void clearArraySizes()
|
||||||
|
{
|
||||||
|
arraySizes = 0;
|
||||||
|
}
|
||||||
void addArrayOuterSizes(const TArraySizes& s)
|
void addArrayOuterSizes(const TArraySizes& s)
|
||||||
{
|
{
|
||||||
if (arraySizes == nullptr)
|
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
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
|
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);
|
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
|
||||||
if (memberQualifier.hasOffset()) {
|
if (memberQualifier.hasOffset()) {
|
||||||
// "The specified offset must be a multiple
|
// "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.
|
// otherwise it does not, yielding std430 rules.
|
||||||
//
|
//
|
||||||
// The size is returned in the 'size' parameter
|
// 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.
|
// 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;
|
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
|
// 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).
|
// 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()) {
|
if (type.isArray()) {
|
||||||
// TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
TType derefType(type, 0);
|
TType derefType(type, 0);
|
||||||
alignment = getBaseAlignment(derefType, size, std140, rowMajor);
|
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
||||||
if (std140)
|
if (std140)
|
||||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
RoundToPow2(size, 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;
|
return alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -939,7 +952,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140, b
|
|||||||
int memberSize;
|
int memberSize;
|
||||||
// modify just the children's view of matrix layout, if there is one for this member
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
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);
|
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||||
maxAlignment = std::max(maxAlignment, memberAlignment);
|
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||||
RoundToPow2(size, 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
|
// 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);
|
TType derefType(type, 0, type.getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
|
|
||||||
alignment = getBaseAlignment(derefType, size, std140, rowMajor);
|
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
||||||
if (std140)
|
if (std140)
|
||||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
RoundToPow2(size, alignment);
|
RoundToPow2(size, alignment);
|
||||||
|
stride = size; // use intra-matrix stride for stride of a just a matrix
|
||||||
if (rowMajor)
|
if (rowMajor)
|
||||||
size *= type.getMatrixRows();
|
size = stride * type.getMatrixRows();
|
||||||
else
|
else
|
||||||
size *= type.getMatrixCols();
|
size = stride * type.getMatrixCols();
|
||||||
|
|
||||||
return alignment;
|
return alignment;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ public:
|
|||||||
}
|
}
|
||||||
int addXfbBufferOffset(const TType&);
|
int addXfbBufferOffset(const TType&);
|
||||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
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:
|
protected:
|
||||||
void error(TInfoSink& infoSink, const char*);
|
void error(TInfoSink& infoSink, const char*);
|
||||||
|
@ -121,11 +121,12 @@ public:
|
|||||||
return memberList[index].type->getQualifier().layoutOffset;
|
return memberList[index].type->getQualifier().layoutOffset;
|
||||||
|
|
||||||
int memberSize;
|
int memberSize;
|
||||||
|
int dummyStride;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (int m = 0; m <= index; ++m) {
|
for (int m = 0; m <= index; ++m) {
|
||||||
// modify just the children's view of matrix layout, if there is one for this member
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
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);
|
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : type.getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
RoundToPow2(offset, memberAlignment);
|
RoundToPow2(offset, memberAlignment);
|
||||||
if (m < index)
|
if (m < index)
|
||||||
@ -144,7 +145,8 @@ public:
|
|||||||
int lastOffset = getOffset(blockType, lastIndex);
|
int lastOffset = getOffset(blockType, lastIndex);
|
||||||
|
|
||||||
int lastMemberSize;
|
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);
|
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
|
|
||||||
return lastOffset + lastMemberSize;
|
return lastOffset + lastMemberSize;
|
||||||
|
Loading…
Reference in New Issue
Block a user