Implement GL_EXT_scalar_block_layout
This commit is contained in:
parent
7274bbc27c
commit
7da39ed968
19 changed files with 356 additions and 45 deletions
|
|
@ -1372,10 +1372,11 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
|||
// stride comes from the flattening down to vectors.
|
||||
//
|
||||
// Return value is the alignment of the type.
|
||||
int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, bool std140, bool rowMajor)
|
||||
int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor)
|
||||
{
|
||||
int alignment;
|
||||
|
||||
bool std140 = layoutPacking == glslang::ElpStd140;
|
||||
// When using the std140 storage layout, structures will be laid out in buffer
|
||||
// storage with its members stored in monotonically increasing order based on their
|
||||
// location in the declaration. A structure and each structure member have a base
|
||||
|
|
@ -1439,7 +1440,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
|||
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, dummyStride, std140, rowMajor);
|
||||
alignment = getBaseAlignment(derefType, size, dummyStride, layoutPacking, rowMajor);
|
||||
if (std140)
|
||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||
RoundToPow2(size, alignment);
|
||||
|
|
@ -1459,7 +1460,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, 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, dummyStride, std140,
|
||||
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, layoutPacking,
|
||||
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||
RoundToPow2(size, memberAlignment);
|
||||
|
|
@ -1498,7 +1499,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, 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, rowMajor);
|
||||
|
||||
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
||||
alignment = getBaseAlignment(derefType, size, dummyStride, layoutPacking, rowMajor);
|
||||
if (std140)
|
||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||
RoundToPow2(size, alignment);
|
||||
|
|
@ -1526,4 +1527,79 @@ bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
|
|||
: offset % 16 != 0;
|
||||
}
|
||||
|
||||
int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride, bool rowMajor)
|
||||
{
|
||||
int alignment;
|
||||
|
||||
stride = 0;
|
||||
int dummyStride;
|
||||
|
||||
if (type.isArray()) {
|
||||
TType derefType(type, 0);
|
||||
alignment = getScalarAlignment(derefType, size, dummyStride, rowMajor);
|
||||
|
||||
stride = size;
|
||||
RoundToPow2(stride, alignment);
|
||||
|
||||
size = stride * (type.getOuterArraySize() - 1) + size;
|
||||
return alignment;
|
||||
}
|
||||
|
||||
if (type.getBasicType() == EbtStruct) {
|
||||
const TTypeList& memberList = *type.getStruct();
|
||||
|
||||
size = 0;
|
||||
int maxAlignment = 0;
|
||||
for (size_t m = 0; m < memberList.size(); ++m) {
|
||||
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 = getScalarAlignment(*memberList[m].type, memberSize, dummyStride,
|
||||
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||
RoundToPow2(size, memberAlignment);
|
||||
size += memberSize;
|
||||
}
|
||||
|
||||
return maxAlignment;
|
||||
}
|
||||
|
||||
if (type.isScalar())
|
||||
return getBaseAlignmentScalar(type, size);
|
||||
|
||||
if (type.isVector()) {
|
||||
int scalarAlign = getBaseAlignmentScalar(type, size);
|
||||
|
||||
size *= type.getVectorSize();
|
||||
return scalarAlign;
|
||||
}
|
||||
|
||||
if (type.isMatrix()) {
|
||||
TType derefType(type, 0, rowMajor);
|
||||
|
||||
alignment = getScalarAlignment(derefType, size, dummyStride, rowMajor);
|
||||
|
||||
stride = size; // use intra-matrix stride for stride of a just a matrix
|
||||
if (rowMajor)
|
||||
size = stride * type.getMatrixRows();
|
||||
else
|
||||
size = stride * type.getMatrixCols();
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
assert(0); // all cases should be covered above
|
||||
size = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TIntermediate::getMemberAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor)
|
||||
{
|
||||
if (layoutPacking == glslang::ElpScalar) {
|
||||
return getScalarAlignment(type, size, stride, rowMajor);
|
||||
} else {
|
||||
return getBaseAlignment(type, size, stride, layoutPacking, rowMajor);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue