Better follow HLSL offsets rules (#3575)

Matrices consuming one vector are treated like vectors for alignment, and
there is no "trailing padding" for matrices and arrays.
This commit is contained in:
Pavel Asyutchenko 2024-04-18 01:34:28 +02:00 committed by GitHub
parent 9001ec9aa5
commit 593dbafd0d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 229 additions and 8 deletions

View file

@ -5377,17 +5377,34 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout,
matrixLayout == glslang::ElmRowMajor);
bool isVectorLike = memberType.isVector();
if (memberType.isMatrix()) {
if (matrixLayout == glslang::ElmRowMajor)
isVectorLike = memberType.getMatrixRows() == 1;
else
isVectorLike = memberType.getMatrixCols() == 1;
}
// Adjust alignment for HLSL rules
// TODO: make this consistent in early phases of code:
// adjusting this late means inconsistencies with earlier code, which for reflection is an issue
// Until reflection is brought in sync with these adjustments, don't apply to $Global,
// which is the most likely to rely on reflection, and least likely to rely implicit layouts
if (glslangIntermediate->usingHlslOffsets() &&
! memberType.isArray() && memberType.isVector() && structType.getTypeName().compare("$Global") != 0) {
int dummySize;
int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, dummySize);
if (componentAlignment <= 4)
! memberType.isStruct() && structType.getTypeName().compare("$Global") != 0) {
int componentSize;
int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, componentSize);
if (! memberType.isArray() && isVectorLike && componentAlignment <= 4)
memberAlignment = componentAlignment;
// Don't add unnecessary padding after this member
if (memberType.isMatrix()) {
if (matrixLayout == glslang::ElmRowMajor)
memberSize -= componentSize * (4 - memberType.getMatrixCols());
else
memberSize -= componentSize * (4 - memberType.getMatrixRows());
} else if (memberType.isArray())
memberSize -= componentSize * (4 - memberType.getVectorSize());
}
// Bump up to member alignment
@ -5395,7 +5412,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
// Bump up to vec4 if there is a bad straddle
if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize,
currentOffset))
currentOffset, isVectorLike))
glslang::RoundToPow2(currentOffset, 16);
nextOffset = currentOffset + memberSize;