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)
 {