SPV: Only decorate array and matrix strides for transparent types requiring explicit layouts.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index f6f99a4..302db80 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -88,6 +88,8 @@
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
spv::Id getSampledType(const glslang::TSampler&);
spv::Id convertGlslangToSpvType(const glslang::TType& type);
+ spv::Id convertGlslangToSpvType(const glslang::TType& type, bool explicitLayout);
+ bool requiresExplicitLayout(const glslang::TType& type) const;
int getArrayStride(const glslang::TType& arrayType);
int getMatrixStride(const glslang::TType& matrixType);
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset);
@@ -1318,9 +1320,17 @@
}
}
-// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
+// Convert from a glslang type to an SPV type, by calling into
+// recursive version of this function.
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
{
+ return convertGlslangToSpvType(type, requiresExplicitLayout(type));
+}
+
+// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
+// explicitLayout can be kept the same throughout the heirarchical recursive walk.
+spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, bool explicitLayout)
+{
spv::Id spvType = 0;
switch (type.getBasicType()) {
@@ -1383,7 +1393,7 @@
} else {
if (type.getBasicType() == glslang::EbtBlock)
memberRemapper[glslangStruct][i] = i - memberDelta;
- structFields.push_back(convertGlslangToSpvType(glslangType));
+ structFields.push_back(convertGlslangToSpvType(glslangType, explicitLayout));
}
}
@@ -1411,7 +1421,7 @@
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent);
if (glslangType.getQualifier().hasXfbOffset())
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset);
- else {
+ else if (explicitLayout) {
// figure out what to do with offset, which is accumulating
int nextOffset;
updateMemberOffset(type, glslangType, offset, nextOffset);
@@ -1420,7 +1430,7 @@
offset = nextOffset;
}
- if (glslangType.isMatrix()) {
+ if (glslangType.isMatrix() && explicitLayout) {
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangType));
}
@@ -1465,12 +1475,23 @@
} else
arraySize = type.getOuterArraySize();
spvType = builder.makeArrayType(spvType, arraySize);
- builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type));
+
+ if (explicitLayout)
+ builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type));
}
return spvType;
}
+bool TGlslangToSpvTraverser::requiresExplicitLayout(const glslang::TType& type) const
+{
+ return type.getBasicType() == glslang::EbtBlock &&
+ type.getQualifier().layoutPacking != glslang::ElpShared &&
+ type.getQualifier().layoutPacking != glslang::ElpPacked &&
+ (type.getQualifier().storage == glslang::EvqUniform ||
+ type.getQualifier().storage == glslang::EvqBuffer);
+}
+
// Given an array type, returns the integer stride required for that array
int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType)
{