Implement GL_EXT_scalar_block_layout

This commit is contained in:
Jeff Bolz 2018-11-14 09:30:53 -06:00
parent 7274bbc27c
commit 7da39ed968
19 changed files with 356 additions and 45 deletions

View file

@ -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)) {
@ -6784,8 +6790,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;
}
}
@ -6834,8 +6842,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
@ -6946,7 +6956,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");
@ -7145,7 +7155,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;
@ -7159,8 +7169,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."