瀏覽代碼

Updated glslang.

Бранимир Караџић 2 年之前
父節點
當前提交
0c8292f2af

+ 68 - 73
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -43,6 +43,7 @@
 #include "spirv.hpp"
 #include "spirv.hpp"
 #include "GlslangToSpv.h"
 #include "GlslangToSpv.h"
 #include "SpvBuilder.h"
 #include "SpvBuilder.h"
+#include "SpvTools.h"
 namespace spv {
 namespace spv {
     #include "GLSL.std.450.h"
     #include "GLSL.std.450.h"
     #include "GLSL.ext.KHR.h"
     #include "GLSL.ext.KHR.h"
@@ -66,6 +67,7 @@ namespace spv {
 #include <iomanip>
 #include <iomanip>
 #include <list>
 #include <list>
 #include <map>
 #include <map>
+#include <optional>
 #include <stack>
 #include <stack>
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
@@ -164,6 +166,7 @@ protected:
     spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false);
     spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false);
     spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
     spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&,
         bool lastBufferBlockMember, bool forwardReferenceOnly = false);
         bool lastBufferBlockMember, bool forwardReferenceOnly = false);
+    void applySpirvDecorate(const glslang::TType& type, spv::Id id, std::optional<int> member);
     bool filterMember(const glslang::TType& member);
     bool filterMember(const glslang::TType& member);
     spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
     spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
                                           glslang::TLayoutPacking, const glslang::TQualifier&);
                                           glslang::TLayoutPacking, const glslang::TQualifier&);
@@ -4705,6 +4708,64 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
     return spvType;
     return spvType;
 }
 }
 
 
+// Apply SPIR-V decorations to the SPIR-V object (provided by SPIR-V ID). If member index is provided, the
+// decorations are applied to this member.
+void TGlslangToSpvTraverser::applySpirvDecorate(const glslang::TType& type, spv::Id id, std::optional<int> member)
+{
+    assert(type.getQualifier().hasSpirvDecorate());
+
+    const glslang::TSpirvDecorate& spirvDecorate = type.getQualifier().getSpirvDecorate();
+
+    // Add spirv_decorate
+    for (auto& decorate : spirvDecorate.decorates) {
+        if (!decorate.second.empty()) {
+            std::vector<unsigned> literals;
+            TranslateLiterals(decorate.second, literals);
+            if (member.has_value())
+                builder.addMemberDecoration(id, *member, static_cast<spv::Decoration>(decorate.first), literals);
+            else
+                builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
+        } else {
+            if (member.has_value())
+                builder.addMemberDecoration(id, *member, static_cast<spv::Decoration>(decorate.first));
+            else
+                builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
+        }
+    }
+
+    // Add spirv_decorate_id
+    if (member.has_value()) {
+        // spirv_decorate_id not applied to members
+        assert(spirvDecorate.decorateIds.empty());
+    } else {
+        for (auto& decorateId : spirvDecorate.decorateIds) {
+            std::vector<spv::Id> operandIds;
+            assert(!decorateId.second.empty());
+            for (auto extraOperand : decorateId.second) {
+                if (extraOperand->getQualifier().isFrontEndConstant())
+                    operandIds.push_back(createSpvConstant(*extraOperand));
+                else
+                    operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
+            }
+            builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
+        }
+    }
+
+    // Add spirv_decorate_string
+    for (auto& decorateString : spirvDecorate.decorateStrings) {
+        std::vector<const char*> strings;
+        assert(!decorateString.second.empty());
+        for (auto extraOperand : decorateString.second) {
+            const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
+            strings.push_back(string);
+        }
+        if (member.has_value())
+            builder.addMemberDecoration(id, *member, static_cast<spv::Decoration>(decorateString.first), strings);
+        else
+            builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
+    }
+}
+
 // TODO: this functionality should exist at a higher level, in creating the AST
 // TODO: this functionality should exist at a higher level, in creating the AST
 //
 //
 // Identify interface members that don't have their required extension turned on.
 // Identify interface members that don't have their required extension turned on.
@@ -4943,37 +5004,9 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
             builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
             builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
         }
         }
 
 
-        //
-        // Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics)
-        //
-        if (glslangMember.getQualifier().hasSprivDecorate()) {
-            const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate();
-
-            // Add spirv_decorate
-            for (auto& decorate : spirvDecorate.decorates) {
-                if (!decorate.second.empty()) {
-                    std::vector<unsigned> literals;
-                    TranslateLiterals(decorate.second, literals);
-                    builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first), literals);
-                }
-                else
-                    builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first));
-            }
-
-            // spirv_decorate_id not applied to members
-            assert(spirvDecorate.decorateIds.empty());
-
-            // Add spirv_decorate_string
-            for (auto& decorateString : spirvDecorate.decorateStrings) {
-                std::vector<const char*> strings;
-                assert(!decorateString.second.empty());
-                for (auto extraOperand : decorateString.second) {
-                    const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
-                    strings.push_back(string);
-                }
-                builder.addDecoration(spvType, static_cast<spv::Decoration>(decorateString.first), strings);
-            }
-        }
+        // Add SPIR-V decorations (GL_EXT_spirv_intrinsics)
+        if (glslangMember.getQualifier().hasSpirvDecorate())
+            applySpirvDecorate(glslangMember, spvType, member);
     }
     }
 
 
     // Decorate the structure
     // Decorate the structure
@@ -5462,7 +5495,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
         spv::Function* function = builder.makeFunctionEntry(
         spv::Function* function = builder.makeFunctionEntry(
             TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()),
             TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()),
             glslFunction->getName().c_str(), convertGlslangLinkageToSpv(glslFunction->getLinkType()), paramTypes,
             glslFunction->getName().c_str(), convertGlslangLinkageToSpv(glslFunction->getLinkType()), paramTypes,
-            paramNames, paramDecorations, &functionBlock);
+            paramDecorations, &functionBlock);
         builder.setupDebugFunctionEntry(function, glslFunction->getName().c_str(), glslFunction->getLoc().line,
         builder.setupDebugFunctionEntry(function, glslFunction->getName().c_str(), glslFunction->getLoc().line,
                                         paramTypes, paramNames);
                                         paramTypes, paramNames);
         if (implicitThis)
         if (implicitThis)
@@ -9598,47 +9631,9 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
             spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
             spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
     }
     }
 
 
-    //
-    // Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics)
-    //
-    if (symbol->getType().getQualifier().hasSprivDecorate()) {
-        const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate();
-
-        // Add spirv_decorate
-        for (auto& decorate : spirvDecorate.decorates) {
-            if (!decorate.second.empty()) {
-                std::vector<unsigned> literals;
-                TranslateLiterals(decorate.second, literals);
-                builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
-            }
-            else
-                builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
-        }
-
-        // Add spirv_decorate_id
-        for (auto& decorateId : spirvDecorate.decorateIds) {
-            std::vector<spv::Id> operandIds;
-            assert(!decorateId.second.empty());
-            for (auto extraOperand : decorateId.second) {
-                if (extraOperand->getQualifier().isFrontEndConstant())
-                    operandIds.push_back(createSpvConstant(*extraOperand));
-                else
-                    operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
-            }
-            builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
-        }
-
-        // Add spirv_decorate_string
-        for (auto& decorateString : spirvDecorate.decorateStrings) {
-            std::vector<const char*> strings;
-            assert(!decorateString.second.empty());
-            for (auto extraOperand : decorateString.second) {
-                const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
-                strings.push_back(string);
-            }
-            builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
-        }
-    }
+    // Add SPIR-V decorations (GL_EXT_spirv_intrinsics)
+    if (symbol->getType().getQualifier().hasSpirvDecorate())
+        applySpirvDecorate(symbol->getType(), id, {});
 
 
     return id;
     return id;
 }
 }

+ 13 - 7
3rdparty/glslang/SPIRV/GlslangToSpv.h

@@ -35,19 +35,25 @@
 
 
 #pragma once
 #pragma once
 
 
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-    #pragma warning(disable : 4464) // relative include path contains '..'
-#endif
-
-#include "SpvTools.h"
-#include "glslang/Include/intermediate.h"
-
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 
 
 #include "Logger.h"
 #include "Logger.h"
 
 
 namespace glslang {
 namespace glslang {
+class TIntermediate;
+
+struct SpvOptions {
+    bool generateDebugInfo {false};
+    bool stripDebugInfo {false};
+    bool disableOptimizer {true};
+    bool optimizeSize {false};
+    bool disassemble {false};
+    bool validate {false};
+    bool emitNonSemanticShaderDebugInfo {false};
+    bool emitNonSemanticShaderDebugSource{ false };
+    bool compileOnly{false};
+};
 
 
 void GetSpirvVersion(std::string&);
 void GetSpirvVersion(std::string&);
 int GetSpirvGeneratorVersion();
 int GetSpirvGeneratorVersion();

+ 1 - 1
3rdparty/glslang/SPIRV/SPVRemapper.h

@@ -77,9 +77,9 @@ public:
 #include <cassert>
 #include <cassert>
 
 
 #include "spirv.hpp"
 #include "spirv.hpp"
-#include "spvIR.h"
 
 
 namespace spv {
 namespace spv {
+const Id NoResult = 0;
 
 
 // class to hold SPIR-V binary data for remapping, DCE, and debug stripping
 // class to hold SPIR-V binary data for remapping, DCE, and debug stripping
 class spirvbin_t : public spirvbin_base_t
 class spirvbin_t : public spirvbin_base_t

+ 36 - 22
3rdparty/glslang/SPIRV/SpvBuilder.cpp

@@ -1182,13 +1182,26 @@ Id Builder::makeDebugExpression()
     return debugExpression;
     return debugExpression;
 }
 }
 
 
-Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const localVariable)
+Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const pointer)
 {
 {
     Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
     Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
     inst->addIdOperand(nonSemanticShaderDebugInfo);
     inst->addIdOperand(nonSemanticShaderDebugInfo);
     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugDeclare);
     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugDeclare);
     inst->addIdOperand(debugLocalVariable); // debug local variable id
     inst->addIdOperand(debugLocalVariable); // debug local variable id
-    inst->addIdOperand(localVariable); // local variable id
+    inst->addIdOperand(pointer); // pointer to local variable id
+    inst->addIdOperand(makeDebugExpression()); // expression id
+    buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
+
+    return inst->getResultId();
+}
+
+Id Builder::makeDebugValue(Id const debugLocalVariable, Id const value)
+{
+    Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
+    inst->addIdOperand(nonSemanticShaderDebugInfo);
+    inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugValue);
+    inst->addIdOperand(debugLocalVariable); // debug local variable id
+    inst->addIdOperand(value); // value of local variable id
     inst->addIdOperand(makeDebugExpression()); // expression id
     inst->addIdOperand(makeDebugExpression()); // expression id
     buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
     buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
 
 
@@ -2061,11 +2074,6 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
 {
 {
     assert(! entryPointFunction);
     assert(! entryPointFunction);
 
 
-    Block* entry;
-    std::vector<Id> paramsTypes;
-    std::vector<char const*> paramNames;
-    std::vector<std::vector<Decoration>> decorations;
-
     auto const returnType = makeVoidType();
     auto const returnType = makeVoidType();
 
 
     restoreNonSemanticShaderDebugInfo = emitNonSemanticShaderDebugInfo;
     restoreNonSemanticShaderDebugInfo = emitNonSemanticShaderDebugInfo;
@@ -2073,7 +2081,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
         emitNonSemanticShaderDebugInfo = false;
         emitNonSemanticShaderDebugInfo = false;
     }
     }
 
 
-    entryPointFunction = makeFunctionEntry(NoPrecision, returnType, entryPoint, LinkageTypeMax, paramsTypes, paramNames, decorations, &entry);
+    Block* entry = nullptr;
+    entryPointFunction = makeFunctionEntry(NoPrecision, returnType, entryPoint, LinkageTypeMax, {}, {}, &entry);
 
 
     emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo;
     emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo;
 
 
@@ -2082,8 +2091,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
 
 
 // Comments in header
 // Comments in header
 Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType,
 Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType,
-                                     const std::vector<Id>& paramTypes, const std::vector<char const*>& paramNames,
-                                     const std::vector<std::vector<Decoration>>& decorations, Block **entry)
+                                     const std::vector<Id>& paramTypes,
+                                     const std::vector<std::vector<Decoration>>& decorations, Block** entry)
 {
 {
     // Make the function and initial instructions in it
     // Make the function and initial instructions in it
     Id typeId = makeFunctionType(returnType, paramTypes);
     Id typeId = makeFunctionType(returnType, paramTypes);
@@ -2148,20 +2157,25 @@ void Builder::setupDebugFunctionEntry(Function* function, const char* name, int
         Id firstParamId = function->getParamId(0);
         Id firstParamId = function->getParamId(0);
 
 
         for (size_t p = 0; p < paramTypes.size(); ++p) {
         for (size_t p = 0; p < paramTypes.size(); ++p) {
-            auto getParamTypeId = [this](Id const& typeId) {
-                if (isPointerType(typeId) || isArrayType(typeId)) {
-                    return getContainedTypeId(typeId);
-                } else {
-                    return typeId;
-                }
-            };
-            auto const& paramName = paramNames[p];
-            auto const debugLocalVariableId =
-                createDebugLocalVariable(debugId[getParamTypeId(paramTypes[p])], paramName, p + 1);
+            bool passByRef = false;
+            Id paramTypeId = paramTypes[p];
 
 
-            debugId[firstParamId + p] = debugLocalVariableId;
+            // For pointer-typed parameters, they are actually passed by reference and we need unwrap the pointer to get the actual parameter type.
+            if (isPointerType(paramTypeId) || isArrayType(paramTypeId)) {
+                passByRef = true;
+                paramTypeId = getContainedTypeId(paramTypeId);
+            }
 
 
-            makeDebugDeclare(debugLocalVariableId, firstParamId + p);
+            auto const& paramName = paramNames[p];
+            auto const debugLocalVariableId = createDebugLocalVariable(debugId[paramTypeId], paramName, p + 1);
+            auto const paramId = static_cast<Id>(firstParamId + p);
+            debugId[paramId] = debugLocalVariableId;
+
+            if (passByRef) {
+                makeDebugDeclare(debugLocalVariableId, paramId);
+            } else {
+                makeDebugValue(debugLocalVariableId, paramId);
+            }
         }
         }
     }
     }
 
 

+ 4 - 5
3rdparty/glslang/SPIRV/SpvBuilder.h

@@ -231,7 +231,7 @@ public:
     Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable);
     Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable);
     Id createDebugLocalVariable(Id type, char const*const name, size_t const argNumber = 0);
     Id createDebugLocalVariable(Id type, char const*const name, size_t const argNumber = 0);
     Id makeDebugExpression();
     Id makeDebugExpression();
-    Id makeDebugDeclare(Id const debugLocalVariable, Id const localVariable);
+    Id makeDebugDeclare(Id const debugLocalVariable, Id const pointer);
     Id makeDebugValue(Id const debugLocalVariable, Id const value);
     Id makeDebugValue(Id const debugLocalVariable, Id const value);
     Id makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes);
     Id makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes);
     Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
     Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
@@ -420,10 +420,9 @@ public:
     // Make a shader-style function, and create its entry block if entry is non-zero.
     // Make a shader-style function, and create its entry block if entry is non-zero.
     // Return the function, pass back the entry.
     // Return the function, pass back the entry.
     // The returned pointer is only valid for the lifetime of this builder.
     // The returned pointer is only valid for the lifetime of this builder.
-    Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
-        LinkageType linkType, const std::vector<Id>& paramTypes,
-        const std::vector<char const*>& paramNames,
-        const std::vector<std::vector<Decoration>>& precisions, Block **entry = nullptr);
+    Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType,
+                                const std::vector<Id>& paramTypes,
+                                const std::vector<std::vector<Decoration>>& precisions, Block** entry = nullptr);
 
 
     // Create a return. An 'implicit' return is one not appearing in the source
     // Create a return. An 'implicit' return is one not appearing in the source
     // code.  In the case of an implicit return, no post-return block is inserted.
     // code.  In the case of an implicit return, no post-return block is inserted.

+ 1 - 12
3rdparty/glslang/SPIRV/SpvTools.h

@@ -48,22 +48,11 @@
 #endif
 #endif
 
 
 #include "glslang/MachineIndependent/localintermediate.h"
 #include "glslang/MachineIndependent/localintermediate.h"
+#include "GlslangToSpv.h"
 #include "Logger.h"
 #include "Logger.h"
 
 
 namespace glslang {
 namespace glslang {
 
 
-struct SpvOptions {
-    bool generateDebugInfo {false};
-    bool stripDebugInfo {false};
-    bool disableOptimizer {true};
-    bool optimizeSize {false};
-    bool disassemble {false};
-    bool validate {false};
-    bool emitNonSemanticShaderDebugInfo {false};
-    bool emitNonSemanticShaderDebugSource{ false };
-    bool compileOnly{false};
-};
-
 #if ENABLE_OPT
 #if ENABLE_OPT
 
 
 // Translate glslang's view of target versioning to what SPIRV-Tools uses.
 // Translate glslang's view of target versioning to what SPIRV-Tools uses.

+ 1 - 0
3rdparty/glslang/StandAlone/StandAlone.cpp

@@ -46,6 +46,7 @@
 #include "DirStackFileIncluder.h"
 #include "DirStackFileIncluder.h"
 #include "./../glslang/Include/ShHandle.h"
 #include "./../glslang/Include/ShHandle.h"
 #include "./../glslang/Public/ShaderLang.h"
 #include "./../glslang/Public/ShaderLang.h"
+#include "../glslang/MachineIndependent/localintermediate.h"
 #include "../SPIRV/GlslangToSpv.h"
 #include "../SPIRV/GlslangToSpv.h"
 #include "../SPIRV/GLSL.std.450.h"
 #include "../SPIRV/GLSL.std.450.h"
 #include "../SPIRV/doc.h"
 #include "../SPIRV/doc.h"

+ 2 - 0
3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp

@@ -9551,6 +9551,8 @@ bool HlslParseContext::isInputBuiltIn(const TQualifier& qualifier) const
         return language == EShLangTessEvaluation;
         return language == EShLangTessEvaluation;
     case EbvTessCoord:
     case EbvTessCoord:
         return language == EShLangTessEvaluation;
         return language == EShLangTessEvaluation;
+    case EbvViewIndex:
+        return language != EShLangCompute;
     default:
     default:
         return false;
         return false;
     }
     }

+ 1 - 0
3rdparty/glslang/glslang/HLSL/hlslScanContext.cpp

@@ -512,6 +512,7 @@ void HlslScanContext::fillInKeywordMap()
     (*SemanticMap)["SV_PRIMITIVEID"] =            EbvPrimitiveId;
     (*SemanticMap)["SV_PRIMITIVEID"] =            EbvPrimitiveId;
     (*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] =   EbvInvocationId;
     (*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] =   EbvInvocationId;
     (*SemanticMap)["SV_ISFRONTFACE"] =            EbvFace;
     (*SemanticMap)["SV_ISFRONTFACE"] =            EbvFace;
+    (*SemanticMap)["SV_VIEWID"] =                 EbvViewIndex;
     (*SemanticMap)["SV_INSTANCEID"] =             EbvInstanceIndex;
     (*SemanticMap)["SV_INSTANCEID"] =             EbvInstanceIndex;
     (*SemanticMap)["SV_INSIDETESSFACTOR"] =       EbvTessLevelInner;
     (*SemanticMap)["SV_INSIDETESSFACTOR"] =       EbvTessLevelInner;
     (*SemanticMap)["SV_GSINSTANCEID"] =           EbvInvocationId;
     (*SemanticMap)["SV_GSINSTANCEID"] =           EbvInvocationId;

+ 0 - 28
3rdparty/glslang/glslang/Include/Common.h

@@ -294,34 +294,6 @@ template <class T> int IntLog2(T n)
     return result;
     return result;
 }
 }
 
 
-inline bool IsInfinity(double x) {
-#ifdef _MSC_VER
-    switch (_fpclass(x)) {
-    case _FPCLASS_NINF:
-    case _FPCLASS_PINF:
-        return true;
-    default:
-        return false;
-    }
-#else
-    return std::isinf(x);
-#endif
-}
-
-inline bool IsNan(double x) {
-#ifdef _MSC_VER
-    switch (_fpclass(x)) {
-    case _FPCLASS_SNAN:
-    case _FPCLASS_QNAN:
-        return true;
-    default:
-        return false;
-    }
-#else
-  return std::isnan(x);
-#endif
-}
-
 } // end namespace glslang
 } // end namespace glslang
 
 
 #endif // _COMMON_INCLUDED_
 #endif // _COMMON_INCLUDED_

+ 2 - 2
3rdparty/glslang/glslang/Include/Types.h

@@ -1075,7 +1075,7 @@ public:
     }
     }
 
 
     // GL_EXT_spirv_intrinsics
     // GL_EXT_spirv_intrinsics
-    bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
+    bool hasSpirvDecorate() const { return spirvDecorate != nullptr; }
     void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
     void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
     void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
     void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
     void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
     void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
@@ -2096,7 +2096,7 @@ public:
         const auto appendInt  = [&](int i)          { typeString.append(std::to_string(i).c_str()); };
         const auto appendInt  = [&](int i)          { typeString.append(std::to_string(i).c_str()); };
 
 
         if (getQualifiers) {
         if (getQualifiers) {
-          if (qualifier.hasSprivDecorate())
+          if (qualifier.hasSpirvDecorate())
             appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
             appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
 
 
           if (qualifier.hasLayout()) {
           if (qualifier.hasLayout()) {

+ 2 - 2
3rdparty/glslang/glslang/MachineIndependent/Constant.cpp

@@ -628,12 +628,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
 
 
         case EOpIsNan:
         case EOpIsNan:
         {
         {
-            newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
+            newConstArray[i].setBConst(std::isnan(unionArray[i].getDConst()));
             break;
             break;
         }
         }
         case EOpIsInf:
         case EOpIsInf:
         {
         {
-            newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
+            newConstArray[i].setBConst(std::isinf(unionArray[i].getDConst()));
             break;
             break;
         }
         }
 
 

+ 11 - 11
3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp

@@ -144,10 +144,10 @@ EProfile EDesktopProfile = static_cast<EProfile>(ENoProfile | ECoreProfile | ECo
                                                   { EBadProfile } };
                                                   { EBadProfile } };
     const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
     const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
 
 
-    const Versioning Es310Desktop420Version[] = { { EEsProfile,      0, 310, 0, nullptr },
-                                                  { EDesktopProfile, 0, 420, 0, nullptr },
+    const Versioning Es310Desktop400Version[] = { { EEsProfile,      0, 310, 0, nullptr },
+                                                  { EDesktopProfile, 0, 400, 0, nullptr },
                                                   { EBadProfile } };
                                                   { EBadProfile } };
-    const Versioning* Es310Desktop420 = &Es310Desktop420Version[0];
+    const Versioning* Es310Desktop400 = &Es310Desktop400Version[0];
 
 
     const Versioning Es310Desktop450Version[] = { { EEsProfile,      0, 310, 0, nullptr },
     const Versioning Es310Desktop450Version[] = { { EEsProfile,      0, 310, 0, nullptr },
                                                   { EDesktopProfile, 0, 450, 0, nullptr },
                                                   { EDesktopProfile, 0, 450, 0, nullptr },
@@ -246,14 +246,14 @@ const BuiltInFunction BaseFunctions[] = {
     { EOpGreaterThanEqual, "greaterThanEqual", 2,   TypeU,     ClassBNS,     Es300Desktop130 },
     { EOpGreaterThanEqual, "greaterThanEqual", 2,   TypeU,     ClassBNS,     Es300Desktop130 },
     { EOpVectorEqual,      "equal",            2,   TypeU,     ClassBNS,     Es300Desktop130 },
     { EOpVectorEqual,      "equal",            2,   TypeU,     ClassBNS,     Es300Desktop130 },
     { EOpVectorNotEqual,   "notEqual",         2,   TypeU,     ClassBNS,     Es300Desktop130 },
     { EOpVectorNotEqual,   "notEqual",         2,   TypeU,     ClassBNS,     Es300Desktop130 },
-    { EOpAtomicAdd,        "atomicAdd",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop420 },
-    { EOpAtomicMin,        "atomicMin",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop420 },
-    { EOpAtomicMax,        "atomicMax",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop420 },
-    { EOpAtomicAnd,        "atomicAnd",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop420 },
-    { EOpAtomicOr,         "atomicOr",         2,   TypeIU,    ClassV1FIOCV, Es310Desktop420 },
-    { EOpAtomicXor,        "atomicXor",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop420 },
-    { EOpAtomicExchange,   "atomicExchange",   2,   TypeIU,    ClassV1FIOCV, Es310Desktop420 },
-    { EOpAtomicCompSwap,   "atomicCompSwap",   3,   TypeIU,    ClassV1FIOCV, Es310Desktop420 },
+    { EOpAtomicAdd,        "atomicAdd",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
+    { EOpAtomicMin,        "atomicMin",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
+    { EOpAtomicMax,        "atomicMax",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
+    { EOpAtomicAnd,        "atomicAnd",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
+    { EOpAtomicOr,         "atomicOr",         2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
+    { EOpAtomicXor,        "atomicXor",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
+    { EOpAtomicExchange,   "atomicExchange",   2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
+    { EOpAtomicCompSwap,   "atomicCompSwap",   3,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
     { EOpMix,              "mix",              3,   TypeB,     ClassRegular, Es310Desktop450 },
     { EOpMix,              "mix",              3,   TypeB,     ClassRegular, Es310Desktop450 },
     { EOpMix,              "mix",              3,   TypeIU,    ClassLB,      Es310Desktop450 },
     { EOpMix,              "mix",              3,   TypeIU,    ClassLB,      Es310Desktop450 },
 
 

+ 33 - 7
3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -2590,6 +2590,18 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
 {
 {
     assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
     assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
 
 
+    if (isEsProfile() && (baseType == EbtFloat || baseType == EbtFloat16)) {
+        int exponent = 0;
+        frexp(d, &exponent);
+        int minExp = baseType == EbtFloat ? -126 : -14;
+        int maxExp = baseType == EbtFloat ? 127 : 15;
+        if (exponent > maxExp) { //overflow, d = inf
+            d = std::numeric_limits<double>::infinity();
+        } else if (exponent < minExp) { //underflow, d = 0.0;
+            d = 0.0;
+        }
+    }
+
     TConstUnionArray unionArray(1);
     TConstUnionArray unionArray(1);
     unionArray[0].setDConst(d);
     unionArray[0].setDConst(d);
 
 
@@ -2647,28 +2659,42 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selecto
 // 'swizzleOkay' says whether or not it is okay to consider a swizzle
 // 'swizzleOkay' says whether or not it is okay to consider a swizzle
 // a valid part of the dereference chain.
 // a valid part of the dereference chain.
 //
 //
-// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node.
+// 'bufferReferenceOk' says if type is buffer_reference, the routine will stop to find the most left node.
 //
 //
+// 'proc' is an optional function to run on each node that is processed during the traversal. 'proc' must
+// return true to continue the traversal, or false to end the traversal early.
 //
 //
 
 
-const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk)
+const TIntermTyped* TIntermediate::traverseLValueBase(const TIntermTyped* node, bool swizzleOkay,
+                                                      bool bufferReferenceOk,
+                                                      std::function<bool(const TIntermNode&)> proc)
 {
 {
     do {
     do {
         const TIntermBinary* binary = node->getAsBinaryNode();
         const TIntermBinary* binary = node->getAsBinaryNode();
-        if (binary == nullptr)
+        if (binary == nullptr) {
+            if (proc) {
+                proc(*node);
+            }
             return node;
             return node;
+        }
         TOperator op = binary->getOp();
         TOperator op = binary->getOp();
-        if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle)
+        if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle &&
+            op != EOpMatrixSwizzle)
             return nullptr;
             return nullptr;
-        if (! swizzleOkay) {
+        if (!swizzleOkay) {
             if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
             if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
                 return nullptr;
                 return nullptr;
             if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
             if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
                 (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
                 (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
-                ! binary->getLeft()->getType().isArray())
+                !binary->getLeft()->getType().isArray())
                 return nullptr;
                 return nullptr;
         }
         }
-        node = node->getAsBinaryNode()->getLeft();
+        if (proc) {
+            if (!proc(*node)) {
+                return node;
+            }
+        }
+        node = binary->getLeft();
         if (bufferReferenceOk && node->isReference())
         if (bufferReferenceOk && node->isReference())
             return node;
             return node;
     } while (true);
     } while (true);

+ 2 - 2
3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp

@@ -208,7 +208,7 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
     //
     //
     // If we get here, we have an error and a message.
     // If we get here, we have an error and a message.
     //
     //
-    const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
+    const TIntermTyped* leftMostTypeNode = TIntermediate::traverseLValueBase(node, true);
 
 
     if (symNode)
     if (symNode)
         error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
         error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
@@ -234,7 +234,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
     const TIntermSymbol* symNode = node->getAsSymbolNode();
     const TIntermSymbol* symNode = node->getAsSymbolNode();
 
 
     if (node->getQualifier().isWriteOnly()) {
     if (node->getQualifier().isWriteOnly()) {
-        const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
+        const TIntermTyped* leftMostTypeNode = TIntermediate::traverseLValueBase(node, true);
 
 
         if (symNode != nullptr)
         if (symNode != nullptr)
             error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
             error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());

+ 54 - 18
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -2571,7 +2571,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
             requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
             requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
         }
         }
 
 
-        const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true);
+        const TIntermTyped* base = TIntermediate::traverseLValueBase(arg0, true, true);
         const char* errMsg = "Only l-values corresponding to shader block storage or shared variables can be used with "
         const char* errMsg = "Only l-values corresponding to shader block storage or shared variables can be used with "
                              "atomic memory functions.";
                              "atomic memory functions.";
         if (base) {
         if (base) {
@@ -2591,20 +2591,57 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
     case EOpInterpolateAtCentroid:
     case EOpInterpolateAtCentroid:
     case EOpInterpolateAtSample:
     case EOpInterpolateAtSample:
     case EOpInterpolateAtOffset:
     case EOpInterpolateAtOffset:
-    case EOpInterpolateAtVertex:
-        // Make sure the first argument is an interpolant, or an array element of an interpolant
+    case EOpInterpolateAtVertex: {
         if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
         if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
-            // It might still be an array element.
+            // Traverse down the left branch of arg0 to ensure this argument is a valid interpolant.
             //
             //
-            // We could check more, but the semantics of the first argument are already met; the
-            // only way to turn an array into a float/vec* is array dereference and swizzle.
+            // For desktop GL >4.3 we effectively only need to ensure that arg0 represents an l-value from an
+            // input declaration.
             //
             //
-            // ES and desktop 4.3 and earlier:  swizzles may not be used
-            // desktop 4.4 and later: swizzles may be used
-            bool swizzleOkay = (!isEsProfile()) && (version >= 440);
-            const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay);
-            if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
-                error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), "");
+            // For desktop GL <= 4.3 and ES, we must also ensure that swizzling is not used
+            //
+            // For ES, we must also ensure that a field selection operator (i.e., '.') is not used on a named
+            // struct.
+
+            const bool esProfile = isEsProfile();
+            const bool swizzleOkay = !esProfile && (version >= 440);
+
+            std::string interpolantErrorMsg = "first argument must be an interpolant, or interpolant-array element";
+            bool isValid = true; // Assume that the interpolant is valid until we find a condition making it invalid
+            bool isIn = false;   // Checks whether or not the interpolant is a shader input
+            bool structAccessOp = false; // Whether or not the previous node in the chain is a struct accessor
+            TIntermediate::traverseLValueBase(
+                arg0, swizzleOkay, false,
+                [&isValid, &isIn, &interpolantErrorMsg, esProfile, &structAccessOp](const TIntermNode& n) -> bool {
+                    auto* type = n.getAsTyped();
+                    if (type) {
+                        if (type->getType().getQualifier().storage == EvqVaryingIn) {
+                            isIn = true;
+                        }
+                        // If a field accessor was used, it can only be used to access a field with an input block, not a struct.
+                        if (structAccessOp && (type->getType().getBasicType() != EbtBlock)) {
+                            interpolantErrorMsg +=
+                                ". Using the field of a named struct as an interpolant argument is not "
+                                "allowed (ES-only).";
+                            isValid = false;
+                        }
+                    }
+
+                    // ES has different requirements for interpolants than GL
+                    if (esProfile) {
+                        // Swizzling will be taken care of by the 'swizzleOkay' argument passsed to traverseLValueBase,
+                        // so we only ned to check whether or not a field accessor has been used with a named struct.
+                        auto* binary = n.getAsBinaryNode();
+                        if (binary && (binary->getOp() == EOpIndexDirectStruct)) {
+                            structAccessOp = true;
+                        }
+                    }
+                    // Don't continue traversing if we know we have an invalid interpolant at this point.
+                    return isValid;
+                });
+            if (!isIn || !isValid) {
+                error(loc, interpolantErrorMsg.c_str(), fnCandidate.getName().c_str(), "");
+            }
         }
         }
 
 
         if (callNode.getOp() == EOpInterpolateAtVertex) {
         if (callNode.getOp() == EOpInterpolateAtVertex) {
@@ -2620,7 +2657,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
                 }
                 }
             }
             }
         }
         }
-        break;
+    } break;
 
 
     case EOpEmitStreamVertex:
     case EOpEmitStreamVertex:
     case EOpEndStreamPrimitive:
     case EOpEndStreamPrimitive:
@@ -4191,8 +4228,8 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
     dst.spirvStorageClass = src.spirvStorageClass;
     dst.spirvStorageClass = src.spirvStorageClass;
 
 
     // SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics)
     // SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics)
-    if (src.hasSprivDecorate()) {
-        if (dst.hasSprivDecorate()) {
+    if (src.hasSpirvDecorate()) {
+        if (dst.hasSpirvDecorate()) {
             const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate();
             const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate();
             TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate();
             TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate();
             for (auto& decorate : srcSpirvDecorate.decorates) {
             for (auto& decorate : srcSpirvDecorate.decorates) {
@@ -6326,8 +6363,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
         switch (qualifier.storage) {
         switch (qualifier.storage) {
         case EvqVaryingIn:
         case EvqVaryingIn:
         case EvqVaryingOut:
         case EvqVaryingOut:
-            if (!type.getQualifier().isTaskMemory() &&
-                !type.getQualifier().hasSprivDecorate() &&
+            if (!type.getQualifier().isTaskMemory() && !type.getQualifier().hasSpirvDecorate() &&
                 (type.getBasicType() != EbtBlock ||
                 (type.getBasicType() != EbtBlock ||
                  (!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
                  (!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
                    (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
                    (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
@@ -8540,7 +8576,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
             memberQualifier.storage = EvqtaskPayloadSharedEXT;
             memberQualifier.storage = EvqtaskPayloadSharedEXT;
         if (memberQualifier.storage == EvqSpirvStorageClass)
         if (memberQualifier.storage == EvqSpirvStorageClass)
             error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
             error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
-        if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
+        if (memberQualifier.hasSpirvDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
             error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), "");
             error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), "");
         if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
         if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
             error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
             error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");

+ 2 - 2
3rdparty/glslang/glslang/MachineIndependent/intermOut.cpp

@@ -1208,12 +1208,12 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
 //   - shows all digits, no premature rounding
 //   - shows all digits, no premature rounding
 static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra)
 static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra)
 {
 {
-    if (IsInfinity(value)) {
+    if (std::isinf(value)) {
         if (value < 0)
         if (value < 0)
             out.debug << "-1.#INF";
             out.debug << "-1.#INF";
         else
         else
             out.debug << "+1.#INF";
             out.debug << "+1.#INF";
-    } else if (IsNan(value))
+    } else if (std::isnan(value))
         out.debug << "1.#IND";
         out.debug << "1.#IND";
     else {
     else {
         const int maxSize = 340;
         const int maxSize = 340;

+ 2 - 2
3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -866,7 +866,7 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf
     }
     }
 
 
     // no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
     // no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
-    if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
+    if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSpirvDecorate()) {
         return ent.newLocation = -1;
         return ent.newLocation = -1;
     }
     }
 
 
@@ -953,7 +953,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
         return ent.newLocation = type.getQualifier().layoutLocation;
         return ent.newLocation = type.getQualifier().layoutLocation;
     }
     }
     // no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
     // no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
-    if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
+    if (type.isBuiltIn() || type.getQualifier().hasSpirvDecorate()) {
         return ent.newLocation = -1;
         return ent.newLocation = -1;
     }
     }
     // no locations on blocks of built-in variables
     // no locations on blocks of built-in variables

+ 6 - 4
3rdparty/glslang/glslang/MachineIndependent/localintermediate.h

@@ -43,11 +43,12 @@
 #include "../Public/ShaderLang.h"
 #include "../Public/ShaderLang.h"
 #include "Versions.h"
 #include "Versions.h"
 
 
-#include <string>
-#include <vector>
 #include <algorithm>
 #include <algorithm>
-#include <set>
 #include <array>
 #include <array>
+#include <functional>
+#include <set>
+#include <string>
+#include <vector>
 
 
 class TInfoSink;
 class TInfoSink;
 
 
@@ -572,7 +573,8 @@ public:
     TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
     TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
 
 
     // Tree ops
     // Tree ops
-    static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false);
+    static const TIntermTyped* traverseLValueBase(const TIntermTyped*, bool swizzleOkay, bool bufferReferenceOk = false,
+                                                  std::function<bool(const TIntermNode&)> proc = {});
 
 
     // Linkage related
     // Linkage related
     void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
     void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);

+ 4 - 3
tools/shaderc/shaderc_metal.cpp

@@ -5,6 +5,8 @@
 
 
 #include "shaderc.h"
 #include "shaderc.h"
 
 
+#include <iostream> // std::cout
+
 BX_PRAGMA_DIAGNOSTIC_PUSH()
 BX_PRAGMA_DIAGNOSTIC_PUSH()
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: 'inclusionDepth' : unreferenced formal parameter
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: 'inclusionDepth' : unreferenced formal parameter
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4265) // error C4265: 'spv::spirvbin_t': class has virtual functions, but destructor is not virtual
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4265) // error C4265: 'spv::spirvbin_t': class has virtual functions, but destructor is not virtual
@@ -15,8 +17,9 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
 #define ENABLE_OPT 1
 #define ENABLE_OPT 1
 #include <ShaderLang.h>
 #include <ShaderLang.h>
 #include <ResourceLimits.h>
 #include <ResourceLimits.h>
-#include <SPIRV/SPVRemapper.h>
 #include <SPIRV/GlslangToSpv.h>
 #include <SPIRV/GlslangToSpv.h>
+#include <SPIRV/SPVRemapper.h>
+#include <SPIRV/SpvTools.h>
 #define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
 #define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
 #include <spirv_msl.hpp>
 #include <spirv_msl.hpp>
 #include <spirv_reflect.hpp>
 #include <spirv_reflect.hpp>
@@ -489,8 +492,6 @@ namespace bgfx { namespace metal
 					program->dumpReflection();
 					program->dumpReflection();
 				}
 				}
 
 
-				BX_UNUSED(spv::MemorySemanticsAllMemory);
-
 				glslang::TIntermediate* intermediate = program->getIntermediate(stage);
 				glslang::TIntermediate* intermediate = program->getIntermediate(stage);
 				std::vector<uint32_t> spirv;
 				std::vector<uint32_t> spirv;
 
 

+ 3 - 2
tools/shaderc/shaderc_spirv.cpp

@@ -5,6 +5,8 @@
 
 
 #include "shaderc.h"
 #include "shaderc.h"
 
 
+#include <iostream> // std::cout
+
 BX_PRAGMA_DIAGNOSTIC_PUSH()
 BX_PRAGMA_DIAGNOSTIC_PUSH()
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: 'inclusionDepth' : unreferenced formal parameter
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: 'inclusionDepth' : unreferenced formal parameter
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4265) // error C4265: 'spv::spirvbin_t': class has virtual functions, but destructor is not virtual
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4265) // error C4265: 'spv::spirvbin_t': class has virtual functions, but destructor is not virtual
@@ -17,6 +19,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
 #include <ResourceLimits.h>
 #include <ResourceLimits.h>
 #include <SPIRV/SPVRemapper.h>
 #include <SPIRV/SPVRemapper.h>
 #include <SPIRV/GlslangToSpv.h>
 #include <SPIRV/GlslangToSpv.h>
+#include <SPIRV/SpvTools.h>
 #define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
 #define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
 #include <spirv_msl.hpp>
 #include <spirv_msl.hpp>
 #include <spirv_reflect.hpp>
 #include <spirv_reflect.hpp>
@@ -698,8 +701,6 @@ namespace bgfx { namespace spirv
 					program->dumpReflection();
 					program->dumpReflection();
 				}
 				}
 
 
-				BX_UNUSED(spv::MemorySemanticsAllMemory);
-
 				glslang::TIntermediate* intermediate = program->getIntermediate(stage);
 				glslang::TIntermediate* intermediate = program->getIntermediate(stage);
 				std::vector<uint32_t> spirv;
 				std::vector<uint32_t> spirv;