Merge branch 'scalar_block_layout' of https://github.com/jeffbolznv/glslang into jeffbolznv-scalar_block_layout
This commit is contained in:
commit
e3b76ed608
19 changed files with 356 additions and 45 deletions
|
|
@ -277,6 +277,7 @@ enum TLayoutPacking {
|
|||
ElpStd140,
|
||||
ElpStd430,
|
||||
ElpPacked,
|
||||
ElpScalar,
|
||||
ElpCount // If expanding, see bitfield width below
|
||||
};
|
||||
|
||||
|
|
@ -951,6 +952,7 @@ public:
|
|||
case ElpShared: return "shared";
|
||||
case ElpStd140: return "std140";
|
||||
case ElpStd430: return "std430";
|
||||
case ElpScalar: return "scalar";
|
||||
default: return "none";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4611,6 +4611,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
publicType.qualifier.layoutPacking = ElpStd430;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getLayoutPackingString(ElpScalar)) {
|
||||
requireVulkan(loc, "scalar");
|
||||
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "scalar block layout");
|
||||
publicType.qualifier.layoutPacking = ElpScalar;
|
||||
return;
|
||||
}
|
||||
// TODO: compile-time performance: may need to stop doing linear searches
|
||||
for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) {
|
||||
if (id == TQualifier::getLayoutFormatString(format)) {
|
||||
|
|
@ -6786,8 +6792,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||
|
||||
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
||||
if (currentBlockQualifier.hasAlign()) {
|
||||
if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
|
||||
error(loc, "can only be used with std140 or std430 layout packing", "align", "");
|
||||
if (defaultQualification.layoutPacking != ElpStd140 &&
|
||||
defaultQualification.layoutPacking != ElpStd430 &&
|
||||
defaultQualification.layoutPacking != ElpScalar) {
|
||||
error(loc, "can only be used with std140, std430, or scalar layout packing", "align", "");
|
||||
defaultQualification.layoutAlign = -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -6836,8 +6844,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||
// "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
|
||||
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
||||
if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) {
|
||||
if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
|
||||
error(memberLoc, "can only be used with std140 or std430 layout packing", "offset/align", "");
|
||||
if (defaultQualification.layoutPacking != ElpStd140 &&
|
||||
defaultQualification.layoutPacking != ElpStd430 &&
|
||||
defaultQualification.layoutPacking != ElpScalar)
|
||||
error(memberLoc, "can only be used with std140, std430, or scalar layout packing", "offset/align", "");
|
||||
}
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
|
|
@ -6948,7 +6958,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
|
|||
profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
|
||||
profileRequires(loc, ENoProfile, 140, nullptr, "uniform block");
|
||||
if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.layoutPushConstant)
|
||||
error(loc, "requires the 'buffer' storage qualifier", "std430", "");
|
||||
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier");
|
||||
break;
|
||||
case EvqBuffer:
|
||||
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
|
||||
|
|
@ -7147,7 +7157,7 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
|
|||
{
|
||||
if (!qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory())
|
||||
return;
|
||||
if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430)
|
||||
if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar)
|
||||
return;
|
||||
|
||||
int offset = 0;
|
||||
|
|
@ -7161,8 +7171,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 dummyStride;
|
||||
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking == ElpStd140,
|
||||
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
|
||||
int memberAlignment = intermediate.getMemberAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking,
|
||||
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
|
||||
if (memberQualifier.hasOffset()) {
|
||||
// "The specified offset must be a multiple
|
||||
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable;
|
||||
|
||||
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
||||
|
|
@ -378,6 +379,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
"#define GL_EXT_shader_16bit_storage 1\n"
|
||||
"#define GL_EXT_shader_8bit_storage 1\n"
|
||||
"#define GL_EXT_samplerless_texture_functions 1\n"
|
||||
"#define GL_EXT_scalar_block_layout 1\n"
|
||||
|
||||
// GL_KHR_shader_subgroup
|
||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth
|
|||
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
|
||||
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
|
||||
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
|
||||
const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout";
|
||||
|
||||
// Arrays of extensions for the above viewportEXTs duplications
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -634,7 +634,9 @@ public:
|
|||
int addXfbBufferOffset(const TType&);
|
||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
||||
static int getBaseAlignmentScalar(const TType&, int& size);
|
||||
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
||||
static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||
static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
|
||||
static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||
static bool improperStraddle(const TType& type, int size, int offset);
|
||||
bool promote(TIntermOperator*);
|
||||
|
||||
|
|
|
|||
|
|
@ -131,11 +131,11 @@ public:
|
|||
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, dummyStride,
|
||||
type.getQualifier().layoutPacking == ElpStd140,
|
||||
subMatrixLayout != ElmNone
|
||||
? subMatrixLayout == ElmRowMajor
|
||||
: type.getQualifier().layoutMatrix == ElmRowMajor);
|
||||
int memberAlignment = intermediate.getMemberAlignment(*memberList[m].type, memberSize, dummyStride,
|
||||
type.getQualifier().layoutPacking,
|
||||
subMatrixLayout != ElmNone
|
||||
? subMatrixLayout == ElmRowMajor
|
||||
: type.getQualifier().layoutMatrix == ElmRowMajor);
|
||||
RoundToPow2(offset, memberAlignment);
|
||||
if (m < index)
|
||||
offset += memberSize;
|
||||
|
|
@ -154,9 +154,9 @@ public:
|
|||
|
||||
int lastMemberSize;
|
||||
int dummyStride;
|
||||
intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride,
|
||||
blockType.getQualifier().layoutPacking == ElpStd140,
|
||||
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
||||
intermediate.getMemberAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride,
|
||||
blockType.getQualifier().layoutPacking,
|
||||
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
||||
|
||||
return lastOffset + lastMemberSize;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue