Browse Source

Updated glslang.

Branimir Karadžić 8 years ago
parent
commit
7fc0b67b34
49 changed files with 1918 additions and 175 deletions
  1. 43 12
      3rdparty/glslang/SPIRV/GlslangToSpv.cpp
  2. 9 2
      3rdparty/glslang/SPIRV/GlslangToSpv.h
  3. 67 17
      3rdparty/glslang/SPIRV/SpvBuilder.cpp
  4. 22 2
      3rdparty/glslang/SPIRV/SpvBuilder.h
  5. 0 3
      3rdparty/glslang/SPIRV/spvIR.h
  6. 1 2
      3rdparty/glslang/StandAlone/CMakeLists.txt
  7. 125 0
      3rdparty/glslang/StandAlone/DirStackFileIncluder.h
  8. 15 3
      3rdparty/glslang/StandAlone/StandAlone.cpp
  9. 1 0
      3rdparty/glslang/Test/bar.h
  10. 174 0
      3rdparty/glslang/Test/baseResults/hlsl.aliasOpaque.frag.out
  11. 297 0
      3rdparty/glslang/Test/baseResults/hlsl.flattenOpaque.frag.out
  12. 75 0
      3rdparty/glslang/Test/baseResults/hlsl.include.vert.out
  13. 10 0
      3rdparty/glslang/Test/baseResults/hlsl.includeNegative.vert.out
  14. 69 0
      3rdparty/glslang/Test/baseResults/include.vert.out
  15. 272 0
      3rdparty/glslang/Test/baseResults/spv.debugInfo.frag.out
  16. 88 0
      3rdparty/glslang/Test/baseResults/spv.ssboAlias.frag.out
  17. 38 0
      3rdparty/glslang/Test/baseResults/spv.texture.sampler.transform.frag.out
  18. 1 0
      3rdparty/glslang/Test/foo.h
  19. 29 0
      3rdparty/glslang/Test/hlsl.aliasOpaque.frag
  20. 40 0
      3rdparty/glslang/Test/hlsl.flattenOpaque.frag
  21. 8 0
      3rdparty/glslang/Test/hlsl.include.vert
  22. 8 0
      3rdparty/glslang/Test/hlsl.includeNegative.vert
  23. 1 0
      3rdparty/glslang/Test/inc1/badInc.h
  24. 3 0
      3rdparty/glslang/Test/inc1/bar.h
  25. 3 0
      3rdparty/glslang/Test/inc1/foo.h
  26. 2 0
      3rdparty/glslang/Test/inc2/bar.h
  27. 1 0
      3rdparty/glslang/Test/inc2/foo.h
  28. 16 0
      3rdparty/glslang/Test/include.vert
  29. 1 0
      3rdparty/glslang/Test/parent.h
  30. 3 0
      3rdparty/glslang/Test/parentBad
  31. 20 2
      3rdparty/glslang/Test/runtests
  32. 52 0
      3rdparty/glslang/Test/spv.debugInfo.frag
  33. 10 0
      3rdparty/glslang/Test/spv.ssboAlias.frag
  34. 13 0
      3rdparty/glslang/Test/spv.texture.sampler.transform.frag
  35. 1 0
      3rdparty/glslang/glslang/Include/Types.h
  36. 45 0
      3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp
  37. 11 0
      3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
  38. 6 5
      3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp
  39. 7 35
      3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
  40. 15 1
      3rdparty/glslang/glslang/MachineIndependent/localintermediate.h
  41. 5 5
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp
  42. 24 5
      3rdparty/glslang/glslang/Public/ShaderLang.h
  43. 2 0
      3rdparty/glslang/gtests/Hlsl.FromFile.cpp
  44. 19 0
      3rdparty/glslang/gtests/Spv.FromFile.cpp
  45. 28 1
      3rdparty/glslang/gtests/TestFixture.h
  46. 230 68
      3rdparty/glslang/hlsl/hlslParseHelper.cpp
  47. 6 3
      3rdparty/glslang/hlsl/hlslParseHelper.h
  48. 1 1
      3rdparty/glslang/hlsl/hlslParseables.cpp
  49. 1 8
      tools/shaderc/shaderc_spirv.cpp

+ 43 - 12
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -101,7 +101,7 @@ private:
 //
 class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
 public:
-    TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger);
+    TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger, glslang::SpvOptions& options);
     virtual ~TGlslangToSpvTraverser() { }
 
     bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
@@ -179,6 +179,7 @@ protected:
     spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
     spv::Id getExtBuiltins(const char* name);
 
+    glslang::SpvOptions& options;
     spv::Function* shaderEntry;
     spv::Function* currentFunction;
     spv::Instruction* entryPoint;
@@ -851,8 +852,11 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie
 // Implement the TGlslangToSpvTraverser class.
 //
 
-TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate, spv::SpvBuildLogger* buildLogger)
-    : TIntermTraverser(true, false, true), shaderEntry(nullptr), currentFunction(nullptr),
+TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate,
+                                               spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options)
+    : TIntermTraverser(true, false, true),
+      options(options),
+      shaderEntry(nullptr), currentFunction(nullptr),
       sequenceDepth(0), logger(buildLogger),
       builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion, logger),
       inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
@@ -862,6 +866,11 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
 
     builder.clearAccessChain();
     builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
+    if (options.generateDebugInfo) {
+        builder.setSourceFile(glslangIntermediate->getSourceFile());
+        builder.setSourceText(glslangIntermediate->getSourceText());
+        builder.setEmitOpLines();
+    }
     stdBuiltins = builder.import("GLSL.std.450");
     builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
     shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
@@ -1069,6 +1078,8 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
 
 bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
 {
+    builder.setLine(node->getLoc().line);
+
     SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
     if (node->getType().getQualifier().isSpecConstant())
         spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
@@ -1256,6 +1267,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
 
 bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node)
 {
+    builder.setLine(node->getLoc().line);
+
     SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
     if (node->getType().getQualifier().isSpecConstant())
         spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
@@ -1499,6 +1512,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         return false;
     case glslang::EOpFunctionCall:
     {
+        builder.setLine(node->getLoc().line);
         if (node->isUserDefined())
             result = handleUserFunctionCall(node);
         // assert(result);  // this can happen for bad shaders because the call graph completeness checking is not yet done
@@ -1605,6 +1619,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     case glslang::EOpConstructStruct:
     case glslang::EOpConstructTextureSampler:
     {
+        builder.setLine(node->getLoc().line);
         std::vector<spv::Id> arguments;
         translateArguments(*node, arguments);
         spv::Id constructed;
@@ -1715,6 +1730,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         right->traverse(this);
         spv::Id rightId = accessChainLoad(right->getType());
 
+        builder.setLine(node->getLoc().line);
         result = createBinaryOperation(binOp, precision, TranslateNoContractionDecoration(node->getType().getQualifier()),
                                        resultType(), leftId, rightId,
                                        left->getType().getBasicType(), reduceComparison);
@@ -1787,10 +1803,13 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
             glslangOperands[arg]->traverse(this);
         if (lvalue)
             operands.push_back(builder.accessChainGetLValue());
-        else
+        else {
+            builder.setLine(node->getLoc().line);
             operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
+        }
     }
 
+    builder.setLine(node->getLoc().line);
     if (atomic) {
         // Handle all atomics
         result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
@@ -1872,6 +1891,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
         node->getFalseBlock()->traverse(this);
         spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
 
+        builder.setLine(node->getLoc().line);
+
         // smear condition to vector, if necessary (AST is always scalar)
         if (builder.isVector(trueValue))
             condition = builder.smearScalar(spv::NoPrecision, condition, 
@@ -2014,6 +2035,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
     // by a block-ending branch.  But we don't want to put any other body/test
     // instructions in it, since the body/test may have arbitrary instructions,
     // including merges of its own.
+    builder.setLine(node->getLoc().line);
     builder.setBuildPoint(&blocks.head);
     builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control);
     if (node->testFirst() && node->getTest()) {
@@ -2022,8 +2044,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
 
         builder.setBuildPoint(&test);
         node->getTest()->traverse(this);
-        spv::Id condition =
-            accessChainLoad(node->getTest()->getType());
+        spv::Id condition = accessChainLoad(node->getTest()->getType());
         builder.createConditionalBranch(condition, &blocks.body, &blocks.merge);
 
         builder.setBuildPoint(&blocks.body);
@@ -2038,6 +2059,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
             node->getTerminal()->traverse(this);
         builder.createBranch(&blocks.head);
     } else {
+        builder.setLine(node->getLoc().line);
         builder.createBranch(&blocks.body);
 
         breakForLoop.push(true);
@@ -2072,6 +2094,8 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
     if (node->getExpression())
         node->getExpression()->traverse(this);
 
+    builder.setLine(node->getLoc().line);
+
     switch (node->getFlowOp()) {
     case glslang::EOpKill:
         builder.makeDiscard();
@@ -3049,9 +3073,11 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std
 
 spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
 {
-    if (! node->isImage() && ! node->isTexture()) {
+    if (! node->isImage() && ! node->isTexture())
         return spv::NoResult;
-    }
+
+    builder.setLine(node->getLoc().line);
+
     auto resultType = [&node,this]{ return convertGlslangToSpvType(node->getType()); };
 
     // Process a GLSL texturing op (will be SPV image)
@@ -5561,22 +5587,27 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
 //
 // Set up the glslang traversal
 //
-void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv)
+void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, SpvOptions* options)
 {
     spv::SpvBuildLogger logger;
-    GlslangToSpv(intermediate, spirv, &logger);
+    GlslangToSpv(intermediate, spirv, &logger, options);
 }
 
-void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger)
+void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+                  spv::SpvBuildLogger* logger, SpvOptions* options)
 {
     TIntermNode* root = intermediate.getTreeRoot();
 
     if (root == 0)
         return;
 
+    glslang::SpvOptions defaultOptions;
+    if (options == nullptr)
+        options = &defaultOptions;
+
     glslang::GetThreadPoolAllocator().push();
 
-    TGlslangToSpvTraverser it(&intermediate, logger);
+    TGlslangToSpvTraverser it(&intermediate, logger, *options);
     root->traverse(&it);
     it.finishSpv();
     it.dumpSpv(spirv);

+ 9 - 2
3rdparty/glslang/SPIRV/GlslangToSpv.h

@@ -47,9 +47,16 @@
 
 namespace glslang {
 
+struct SpvOptions {
+    SpvOptions() : generateDebugInfo(false) { }
+    bool generateDebugInfo;
+};
+
 void GetSpirvVersion(std::string&);
-void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv);
-void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger);
+void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+                  SpvOptions* options = nullptr);
+void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+                  spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
 void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
 void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
 

+ 67 - 17
3rdparty/glslang/SPIRV/SpvBuilder.cpp

@@ -59,6 +59,9 @@ namespace spv {
 Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
     source(SourceLanguageUnknown),
     sourceVersion(0),
+    sourceFileStringId(NoResult),
+    currentLine(0),
+    emitOpLines(false),
     addressModel(AddressingModelLogical),
     memoryModel(MemoryModelGLSL450),
     builderNumber(magicNumber),
@@ -84,6 +87,26 @@ Id Builder::import(const char* name)
     return import->getResultId();
 }
 
+// Emit an OpLine if we've been asked to emit OpLines and the line number
+// has changed since the last time, and is a valid line number.
+void Builder::setLine(int lineNum)
+{
+    if (lineNum != 0 && lineNum != currentLine) {
+        currentLine = lineNum;
+        if (emitOpLines)
+            addLine(sourceFileStringId, currentLine, 0);
+    }
+}
+
+void Builder::addLine(Id fileName, int lineNum, int column)
+{
+    Instruction* line = new Instruction(OpLine);
+    line->addIdOperand(fileName);
+    line->addImmediateOperand(lineNum);
+    line->addImmediateOperand(column);
+    buildPoint->addInstruction(std::unique_ptr<Instruction>(line));
+}
+
 // For creating new groupedTypes (will return old type if the requested one was already made).
 Id Builder::makeVoidType()
 {
@@ -928,17 +951,6 @@ void Builder::addMemberName(Id id, int memberNumber, const char* string)
     names.push_back(std::unique_ptr<Instruction>(name));
 }
 
-void Builder::addLine(Id target, Id fileName, int lineNum, int column)
-{
-    Instruction* line = new Instruction(OpLine);
-    line->addIdOperand(target);
-    line->addIdOperand(fileName);
-    line->addImmediateOperand(lineNum);
-    line->addImmediateOperand(column);
-
-    lines.push_back(std::unique_ptr<Instruction>(line));
-}
-
 void Builder::addDecoration(Id id, Decoration decoration, int num)
 {
     if (decoration == spv::DecorationMax)
@@ -2411,12 +2423,8 @@ void Builder::dump(std::vector<unsigned int>& out) const
     dumpInstructions(out, executionModes);
 
     // Debug instructions
-    if (source != SourceLanguageUnknown) {
-        Instruction sourceInst(0, 0, OpSource);
-        sourceInst.addImmediateOperand(source);
-        sourceInst.addImmediateOperand(sourceVersion);
-        sourceInst.dump(out);
-    }
+    dumpInstructions(out, strings);
+    dumpSourceInstructions(out);
     for (int e = 0; e < (int)sourceExtensions.size(); ++e) {
         Instruction sourceExtInst(0, 0, OpSourceExtension);
         sourceExtInst.addStringOperand(sourceExtensions[e]);
@@ -2574,6 +2582,48 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
     elseBlock->addPredecessor(buildPoint);
 }
 
+// OpSource
+// [OpSourceContinued]
+// ...
+void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
+{
+    const int maxWordCount = 0xFFFF;
+    const int opSourceWordCount = 4;
+    const int nonNullBytesPerInstruction = 4 * (maxWordCount - opSourceWordCount) - 1;
+
+    if (source != SourceLanguageUnknown) {
+        // OpSource Language Version File Source
+        Instruction sourceInst(NoResult, NoType, OpSource);
+        sourceInst.addImmediateOperand(source);
+        sourceInst.addImmediateOperand(sourceVersion);
+        // File operand
+        if (sourceFileStringId != NoResult) {
+            sourceInst.addIdOperand(sourceFileStringId);
+            // Source operand
+            if (sourceText.size() > 0) {
+                int nextByte = 0;
+                std::string subString;
+                while ((int)sourceText.size() - nextByte > 0) {
+                    subString = sourceText.substr(nextByte, nonNullBytesPerInstruction);
+                    if (nextByte == 0) {
+                        // OpSource
+                        sourceInst.addStringOperand(subString.c_str());
+                        sourceInst.dump(out);
+                    } else {
+                        // OpSourcContinued
+                        Instruction sourceContinuedInst(OpSourceContinued);
+                        sourceContinuedInst.addStringOperand(subString.c_str());
+                        sourceContinuedInst.dump(out);
+                    }
+                    nextByte += nonNullBytesPerInstruction;
+                }
+            } else
+                sourceInst.dump(out);
+        } else
+            sourceInst.dump(out);
+    }
+}
+
 void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
 {
     for (int i = 0; i < (int)instructions.size(); ++i) {

+ 22 - 2
3rdparty/glslang/SPIRV/SpvBuilder.h

@@ -70,7 +70,16 @@ public:
         source = lang;
         sourceVersion = version;
     }
+    void setSourceFile(const std::string& file)
+    {
+        Instruction* fileString = new Instruction(getUniqueId(), NoType, OpString);
+        fileString->addStringOperand(file.c_str());
+        sourceFileStringId = fileString->getResultId();
+        strings.push_back(std::unique_ptr<Instruction>(fileString));
+    }
+    void setSourceText(const std::string& text) { sourceText = text; }
     void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
+    void setEmitOpLines() { emitOpLines = true; }
     void addExtension(const char* ext) { extensions.insert(ext); }
     Id import(const char*);
     void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
@@ -92,6 +101,12 @@ public:
         return id;
     }
 
+    // Log the current line, and if different than the last one,
+    // issue a new OpLine, using the current file name.
+    void setLine(int line);
+    // Low-level OpLine. See setLine() for a layered helper.
+    void addLine(Id fileName, int line, int column);
+
     // For creating new types (will return old type if the requested one was already made).
     Id makeVoidType();
     Id makeBoolType();
@@ -213,7 +228,6 @@ public:
     void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
     void addName(Id, const char* name);
     void addMemberName(Id, int member, const char* name);
-    void addLine(Id target, Id fileName, int line, int column);
     void addDecoration(Id, Decoration, int num = -1);
     void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
 
@@ -561,10 +575,15 @@ public:
     void simplifyAccessChainSwizzle();
     void createAndSetNoPredecessorBlock(const char*);
     void createSelectionMerge(Block* mergeBlock, unsigned int control);
+    void dumpSourceInstructions(std::vector<unsigned int>&) const;
     void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
 
     SourceLanguage source;
     int sourceVersion;
+    spv::Id sourceFileStringId;
+    std::string sourceText;
+    int currentLine;
+    bool emitOpLines;
     std::set<std::string> extensions;
     std::vector<const char*> sourceExtensions;
     AddressingModel addressModel;
@@ -579,6 +598,7 @@ public:
     AccessChain accessChain;
 
     // special blocks of instructions for output
+    std::vector<std::unique_ptr<Instruction> > strings;
     std::vector<std::unique_ptr<Instruction> > imports;
     std::vector<std::unique_ptr<Instruction> > entryPoints;
     std::vector<std::unique_ptr<Instruction> > executionModes;
@@ -599,7 +619,7 @@ public:
     // Our loop stack.
     std::stack<LoopBlocks> loops;
 
-    // The stream for outputing warnings and errors.
+    // The stream for outputting warnings and errors.
     SpvBuildLogger* logger;
 };  // end Builder class
 

+ 0 - 3
3rdparty/glslang/SPIRV/spvIR.h

@@ -87,7 +87,6 @@ public:
     void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
     void addStringOperand(const char* str)
     {
-        originalString = str;
         unsigned int word;
         char* wordString = (char*)&word;
         char* wordPtr = wordString;
@@ -120,7 +119,6 @@ public:
     Id getTypeId() const { return typeId; }
     Id getIdOperand(int op) const { return operands[op]; }
     unsigned int getImmediateOperand(int op) const { return operands[op]; }
-    const char* getStringOperand() const { return originalString.c_str(); }
 
     // Write out the binary form.
     void dump(std::vector<unsigned int>& out) const
@@ -151,7 +149,6 @@ protected:
     Id typeId;
     Op opCode;
     std::vector<Id> operands;
-    std::string originalString;        // could be optimized away; convenience for getting string operand
     Block* block;
 };
 

+ 1 - 2
3rdparty/glslang/StandAlone/CMakeLists.txt

@@ -6,7 +6,7 @@ target_include_directories(glslang-default-resource-limits
                            PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
                            PUBLIC ${PROJECT_SOURCE_DIR})
 
-set(SOURCES StandAlone.cpp)
+set(SOURCES StandAlone.cpp DirStackFileIncluder.h)
 set(REMAPPER_SOURCES spirv-remap.cpp)
 
 add_executable(glslangValidator ${SOURCES})
@@ -22,7 +22,6 @@ set(LIBRARIES
     SPVRemapper
     glslang-default-resource-limits)
 
-
 if(WIN32)
     set(LIBRARIES ${LIBRARIES} psapi)
 elseif(UNIX)

+ 125 - 0
3rdparty/glslang/StandAlone/DirStackFileIncluder.h

@@ -0,0 +1,125 @@
+//
+// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
+// Copyright (C) 2017 Google, Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//    Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+//    Redistributions in binary form must reproduce the above
+//    copyright notice, this list of conditions and the following
+//    disclaimer in the documentation and/or other materials provided
+//    with the distribution.
+//
+//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+
+#pragma once
+
+#include <vector>
+#include <string>
+#include <fstream>
+#include <algorithm>
+
+#include "./../glslang/Public/ShaderLang.h"
+
+// Default include class for normal include convention of search backward
+// through the stack of active include paths (for nested includes).
+// Can be overridden to customize.
+class DirStackFileIncluder : public glslang::TShader::Includer {
+public:
+    virtual IncludeResult* includeLocal(const char* headerName,
+                                        const char* includerName,
+                                        size_t inclusionDepth) override
+    {
+        return readLocalPath(headerName, includerName, inclusionDepth);
+    }
+
+    virtual IncludeResult* includeSystem(const char* headerName,
+                                         const char* /*includerName*/,
+                                         size_t /*inclusionDepth*/) override
+    {
+        return readSystemPath(headerName);
+    }
+
+    virtual void releaseInclude(IncludeResult* result) override
+    {
+        if (result != nullptr) {
+            delete [] static_cast<tUserDataElement*>(result->userData);
+            delete result;
+        }
+    }
+
+    virtual ~DirStackFileIncluder() override { }
+
+protected:
+    typedef char tUserDataElement;
+    std::vector<std::string> directoryStack;
+
+    // Search for a valid "local" path based on combining the stack of include
+    // directories and the nominal name of the header.
+    virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth)
+    {
+        // Discard popped include directories, and if first level, initialize.
+        directoryStack.resize(depth);
+        if (depth == 1)
+            directoryStack.front() = getDirectory(includerName);
+
+        // find a directory that works, reverse search of include stack
+        for (auto it = directoryStack.rbegin(); it != directoryStack.rend(); ++it) {
+            std::string path = *it + '/' + headerName;
+            std::replace(path.begin(), path.end(), '\\', '/');
+            std::ifstream file(path, std::ios_base::binary | std::ios_base::ate);
+            if (file) {
+                directoryStack.push_back(getDirectory(path));
+                return newIncludeResult(path, file, (int)file.tellg());
+            }
+        }
+
+        return nullptr;
+    }
+
+    // Search for a valid <system> path.
+    // Not implemented yet; returning nullptr signals failure to find.
+    virtual IncludeResult* readSystemPath(const char* /*headerName*/) const
+    {
+        return nullptr;
+    }
+
+    // Do actual reading of the file, filling in a new include result.
+    virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const
+    {
+        char* content = new tUserDataElement [length];
+        file.seekg(0, file.beg);
+        file.read(content, length);
+        return new IncludeResult(path, content, length, content);
+    }
+
+    // If no path markers, return current working directory.
+    // Otherwise, strip file name and return path leading up to it.
+    virtual std::string getDirectory(const std::string path) const
+    {
+        size_t last = path.find_last_of("/\\");
+        return last == std::string::npos ? "." : path.substr(0, last);
+    }
+};

+ 15 - 3
3rdparty/glslang/StandAlone/StandAlone.cpp

@@ -41,6 +41,7 @@
 
 #include "ResourceLimits.h"
 #include "Worklist.h"
+#include "DirStackFileIncluder.h"
 #include "./../glslang/Include/ShHandle.h"
 #include "./../glslang/Include/revision.h"
 #include "./../glslang/Public/ShaderLang.h"
@@ -48,6 +49,7 @@
 #include "../SPIRV/GLSL.std.450.h"
 #include "../SPIRV/doc.h"
 #include "../SPIRV/disassemble.h"
+
 #include <cstring>
 #include <cstdlib>
 #include <cctype>
@@ -91,6 +93,7 @@ enum TOptions {
     EOptionHlslOffsets          = (1 << 23),
     EOptionHlslIoMapping        = (1 << 24),
     EOptionAutoMapLocations     = (1 << 25),
+    EOptionDebug                = (1 << 26),
 };
 
 //
@@ -448,6 +451,9 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                 } else
                     Error("no <entry-point> provided for -e");
                 break;
+            case 'g':
+                Options |= EOptionDebug;
+                break;
             case 'h':
                 usage();
                 break;
@@ -539,6 +545,8 @@ void SetMessageOptions(EShMessages& messages)
         messages = (EShMessages)(messages | EShMsgKeepUncalled);
     if (Options & EOptionHlslOffsets)
         messages = (EShMessages)(messages | EShMsgHlslOffsets);
+    if (Options & EOptionDebug)
+        messages = (EShMessages)(messages | EShMsgDebugInfo);
 }
 
 //
@@ -659,9 +667,9 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
 
         const int defaultVersion = Options & EOptionDefaultDesktop? 110: 100;
 
+        DirStackFileIncluder includer;
         if (Options & EOptionOutputPreprocessed) {
             std::string str;
-            glslang::TShader::ForbidIncluder includer;
             if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false,
                                    messages, &str, includer)) {
                 PutsIfNonEmpty(str.c_str());
@@ -672,7 +680,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
             StderrIfNonEmpty(shader->getInfoDebugLog());
             continue;
         }
-        if (! shader->parse(&Resources, defaultVersion, false, messages))
+        if (! shader->parse(&Resources, defaultVersion, false, messages, includer))
             CompileFailed = true;
 
         program.addShader(shader);
@@ -722,7 +730,10 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
                     std::vector<unsigned int> spirv;
                     std::string warningsErrors;
                     spv::SpvBuildLogger logger;
-                    glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger);
+                    glslang::SpvOptions spvOptions;
+                    if (Options & EOptionDebug)
+                        spvOptions.generateDebugInfo = true;
+                    glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions);
 
                     // Dump the spv to a file or stdout, etc., but only if not doing
                     // memory/perf testing, as it's not internal to programmatic use.
@@ -1031,6 +1042,7 @@ void usage()
            "              (default is ES version 100)\n"
            "  -D          input is HLSL\n"
            "  -e          specify entry-point name\n"
+           "  -g          generate debug information\n"
            "  -h          print this usage message\n"
            "  -i          intermediate tree (glslang AST) is printed out\n"
            "  -l          link all input files together to form a single module\n"

+ 1 - 0
3rdparty/glslang/Test/bar.h

@@ -0,0 +1 @@
+float4 i1;

+ 174 - 0
3rdparty/glslang/Test/baseResults/hlsl.aliasOpaque.frag.out

@@ -0,0 +1,174 @@
+hlsl.aliasOpaque.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: osCall(struct-OS-p1-f1-t211; ( temp 4-component vector of float)
+0:12    Function Parameters: 
+0:?       'ss' ( in sampler)
+0:?       'a' ( in float)
+0:?       'tex' ( in texture2D)
+0:?     Sequence
+0:13      Branch: Return with expression
+0:13        vector-scale ( temp 4-component vector of float)
+0:?           'a' ( in float)
+0:13          texture ( temp 4-component vector of float)
+0:13            Construct combined texture-sampler ( temp sampler2D)
+0:?               'tex' ( in texture2D)
+0:?               'ss' ( in sampler)
+0:?             Constant:
+0:?               0.200000
+0:?               0.300000
+0:17  Function Definition: @main( ( temp 4-component vector of float)
+0:17    Function Parameters: 
+0:?     Sequence
+0:19      'gss2' ( uniform sampler)
+0:20      'gss' ( uniform sampler)
+0:21      'gtex' ( uniform texture2D)
+0:22      move second child to first child ( temp float)
+0:?         'a' ( temp float)
+0:22        Constant:
+0:22          3.000000
+0:28      Branch: Return with expression
+0:28        Function Call: osCall(struct-OS-p1-f1-t211; ( temp 4-component vector of float)
+0:?           'gss' ( uniform sampler)
+0:?           'a' ( temp float)
+0:?           'gtex' ( uniform texture2D)
+0:17  Function Definition: main( ( temp void)
+0:17    Function Parameters: 
+0:?     Sequence
+0:17      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:17        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'gss' ( uniform sampler)
+0:?     'gss2' ( uniform sampler)
+0:?     'gtex' ( uniform texture2D)
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: osCall(struct-OS-p1-f1-t211; ( temp 4-component vector of float)
+0:12    Function Parameters: 
+0:?       'ss' ( in sampler)
+0:?       'a' ( in float)
+0:?       'tex' ( in texture2D)
+0:?     Sequence
+0:13      Branch: Return with expression
+0:13        vector-scale ( temp 4-component vector of float)
+0:?           'a' ( in float)
+0:13          texture ( temp 4-component vector of float)
+0:13            Construct combined texture-sampler ( temp sampler2D)
+0:?               'tex' ( in texture2D)
+0:?               'ss' ( in sampler)
+0:?             Constant:
+0:?               0.200000
+0:?               0.300000
+0:17  Function Definition: @main( ( temp 4-component vector of float)
+0:17    Function Parameters: 
+0:?     Sequence
+0:19      'gss2' ( uniform sampler)
+0:20      'gss' ( uniform sampler)
+0:21      'gtex' ( uniform texture2D)
+0:22      move second child to first child ( temp float)
+0:?         'a' ( temp float)
+0:22        Constant:
+0:22          3.000000
+0:28      Branch: Return with expression
+0:28        Function Call: osCall(struct-OS-p1-f1-t211; ( temp 4-component vector of float)
+0:?           'gss' ( uniform sampler)
+0:?           'a' ( temp float)
+0:?           'gtex' ( uniform texture2D)
+0:17  Function Definition: main( ( temp void)
+0:17    Function Parameters: 
+0:?     Sequence
+0:17      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:17        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'gss' ( uniform sampler)
+0:?     'gss2' ( uniform sampler)
+0:?     'gtex' ( uniform texture2D)
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 48
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 46
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 17  "osCall(struct-OS-p1-f1-t211;"
+                              Name 14  "ss"
+                              Name 15  "a"
+                              Name 16  "tex"
+                              Name 20  "@main("
+                              Name 35  "gss2"
+                              Name 36  "gss"
+                              Name 37  "gtex"
+                              Name 38  "a"
+                              Name 40  "param"
+                              Name 46  "@entryPointOutput"
+                              Decorate 35(gss2) DescriptorSet 0
+                              Decorate 36(gss) DescriptorSet 0
+                              Decorate 37(gtex) DescriptorSet 0
+                              Decorate 46(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeSampler
+               7:             TypePointer UniformConstant 6
+               8:             TypeFloat 32
+               9:             TypePointer Function 8(float)
+              10:             TypeImage 8(float) 2D sampled format:Unknown
+              11:             TypePointer UniformConstant 10
+              12:             TypeVector 8(float) 4
+              13:             TypeFunction 12(fvec4) 7(ptr) 9(ptr) 11(ptr)
+              19:             TypeFunction 12(fvec4)
+              25:             TypeSampledImage 10
+              27:             TypeVector 8(float) 2
+              28:    8(float) Constant 1045220557
+              29:    8(float) Constant 1050253722
+              30:   27(fvec2) ConstantComposite 28 29
+        35(gss2):      7(ptr) Variable UniformConstant
+         36(gss):      7(ptr) Variable UniformConstant
+        37(gtex):     11(ptr) Variable UniformConstant
+              39:    8(float) Constant 1077936128
+              45:             TypePointer Output 12(fvec4)
+46(@entryPointOutput):     45(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              47:   12(fvec4) FunctionCall 20(@main()
+                              Store 46(@entryPointOutput) 47
+                              Return
+                              FunctionEnd
+17(osCall(struct-OS-p1-f1-t211;):   12(fvec4) Function None 13
+          14(ss):      7(ptr) FunctionParameter
+           15(a):      9(ptr) FunctionParameter
+         16(tex):     11(ptr) FunctionParameter
+              18:             Label
+              22:    8(float) Load 15(a)
+              23:          10 Load 16(tex)
+              24:           6 Load 14(ss)
+              26:          25 SampledImage 23 24
+              31:   12(fvec4) ImageSampleImplicitLod 26 30
+              32:   12(fvec4) VectorTimesScalar 31 22
+                              ReturnValue 32
+                              FunctionEnd
+      20(@main():   12(fvec4) Function None 19
+              21:             Label
+           38(a):      9(ptr) Variable Function
+       40(param):      9(ptr) Variable Function
+                              Store 38(a) 39
+              41:    8(float) Load 38(a)
+                              Store 40(param) 41
+              42:   12(fvec4) FunctionCall 17(osCall(struct-OS-p1-f1-t211;) 36(gss) 40(param) 37(gtex)
+                              ReturnValue 42
+                              FunctionEnd

+ 297 - 0
3rdparty/glslang/Test/baseResults/hlsl.flattenOpaque.frag.out

@@ -0,0 +1,297 @@
+hlsl.flattenOpaque.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:15  Function Definition: osCall1(struct-os-p11; ( temp 4-component vector of float)
+0:15    Function Parameters: 
+0:?       's2D' ( in sampler)
+0:?     Sequence
+0:16      Branch: Return with expression
+0:16        texture ( temp 4-component vector of float)
+0:16          Construct combined texture-sampler ( temp sampler2D)
+0:16            'tex' ( uniform texture2D)
+0:?             's2D' ( in sampler)
+0:?           Constant:
+0:?             0.200000
+0:?             0.300000
+0:20  Function Definition: osCall2(struct-os-p11;vf2; ( temp 4-component vector of float)
+0:20    Function Parameters: 
+0:?       's2D' ( in sampler)
+0:20      'f2' ( in 2-component vector of float)
+0:?     Sequence
+0:21      Branch: Return with expression
+0:21        texture ( temp 4-component vector of float)
+0:21          Construct combined texture-sampler ( temp sampler2D)
+0:21            'tex' ( uniform texture2D)
+0:?             's2D' ( in sampler)
+0:21          'f2' ( in 2-component vector of float)
+0:25  Function Definition: os2Call1(struct-os2-p1-t211; ( temp 4-component vector of float)
+0:25    Function Parameters: 
+0:?       's2D' ( in sampler)
+0:?       'tex' ( in texture2D)
+0:?     Sequence
+0:26      Branch: Return with expression
+0:26        texture ( temp 4-component vector of float)
+0:26          Construct combined texture-sampler ( temp sampler2D)
+0:?             'tex' ( in texture2D)
+0:?             's2D' ( in sampler)
+0:?           Constant:
+0:?             0.200000
+0:?             0.300000
+0:30  Function Definition: os2Call2(struct-os2-p1-t211;vf2; ( temp 4-component vector of float)
+0:30    Function Parameters: 
+0:?       's2D' ( in sampler)
+0:?       'tex' ( in texture2D)
+0:30      'f2' ( in 2-component vector of float)
+0:?     Sequence
+0:31      Branch: Return with expression
+0:31        texture ( temp 4-component vector of float)
+0:31          Construct combined texture-sampler ( temp sampler2D)
+0:?             'tex' ( in texture2D)
+0:?             's2D' ( in sampler)
+0:31          'f2' ( in 2-component vector of float)
+0:35  Function Definition: @main( ( temp 4-component vector of float)
+0:35    Function Parameters: 
+0:?     Sequence
+0:39      Branch: Return with expression
+0:38        add ( temp 4-component vector of float)
+0:37          add ( temp 4-component vector of float)
+0:36            add ( temp 4-component vector of float)
+0:36              Function Call: osCall1(struct-os-p11; ( temp 4-component vector of float)
+0:?                 's2D' ( uniform sampler)
+0:37              Function Call: osCall2(struct-os-p11;vf2; ( temp 4-component vector of float)
+0:?                 's2D' ( uniform sampler)
+0:?                 Constant:
+0:?                   0.200000
+0:?                   0.300000
+0:38            Function Call: os2Call1(struct-os2-p1-t211; ( temp 4-component vector of float)
+0:?               's2D' ( uniform sampler)
+0:?               'tex' ( uniform texture2D)
+0:39          Function Call: os2Call2(struct-os2-p1-t211;vf2; ( temp 4-component vector of float)
+0:?             's2D' ( uniform sampler)
+0:?             'tex' ( uniform texture2D)
+0:?             Constant:
+0:?               0.200000
+0:?               0.300000
+0:35  Function Definition: main( ( temp void)
+0:35    Function Parameters: 
+0:?     Sequence
+0:35      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:35        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'tex' ( uniform texture2D)
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:15  Function Definition: osCall1(struct-os-p11; ( temp 4-component vector of float)
+0:15    Function Parameters: 
+0:?       's2D' ( in sampler)
+0:?     Sequence
+0:16      Branch: Return with expression
+0:16        texture ( temp 4-component vector of float)
+0:16          Construct combined texture-sampler ( temp sampler2D)
+0:16            'tex' ( uniform texture2D)
+0:?             's2D' ( in sampler)
+0:?           Constant:
+0:?             0.200000
+0:?             0.300000
+0:20  Function Definition: osCall2(struct-os-p11;vf2; ( temp 4-component vector of float)
+0:20    Function Parameters: 
+0:?       's2D' ( in sampler)
+0:20      'f2' ( in 2-component vector of float)
+0:?     Sequence
+0:21      Branch: Return with expression
+0:21        texture ( temp 4-component vector of float)
+0:21          Construct combined texture-sampler ( temp sampler2D)
+0:21            'tex' ( uniform texture2D)
+0:?             's2D' ( in sampler)
+0:21          'f2' ( in 2-component vector of float)
+0:25  Function Definition: os2Call1(struct-os2-p1-t211; ( temp 4-component vector of float)
+0:25    Function Parameters: 
+0:?       's2D' ( in sampler)
+0:?       'tex' ( in texture2D)
+0:?     Sequence
+0:26      Branch: Return with expression
+0:26        texture ( temp 4-component vector of float)
+0:26          Construct combined texture-sampler ( temp sampler2D)
+0:?             'tex' ( in texture2D)
+0:?             's2D' ( in sampler)
+0:?           Constant:
+0:?             0.200000
+0:?             0.300000
+0:30  Function Definition: os2Call2(struct-os2-p1-t211;vf2; ( temp 4-component vector of float)
+0:30    Function Parameters: 
+0:?       's2D' ( in sampler)
+0:?       'tex' ( in texture2D)
+0:30      'f2' ( in 2-component vector of float)
+0:?     Sequence
+0:31      Branch: Return with expression
+0:31        texture ( temp 4-component vector of float)
+0:31          Construct combined texture-sampler ( temp sampler2D)
+0:?             'tex' ( in texture2D)
+0:?             's2D' ( in sampler)
+0:31          'f2' ( in 2-component vector of float)
+0:35  Function Definition: @main( ( temp 4-component vector of float)
+0:35    Function Parameters: 
+0:?     Sequence
+0:39      Branch: Return with expression
+0:38        add ( temp 4-component vector of float)
+0:37          add ( temp 4-component vector of float)
+0:36            add ( temp 4-component vector of float)
+0:36              Function Call: osCall1(struct-os-p11; ( temp 4-component vector of float)
+0:?                 's2D' ( uniform sampler)
+0:37              Function Call: osCall2(struct-os-p11;vf2; ( temp 4-component vector of float)
+0:?                 's2D' ( uniform sampler)
+0:?                 Constant:
+0:?                   0.200000
+0:?                   0.300000
+0:38            Function Call: os2Call1(struct-os2-p1-t211; ( temp 4-component vector of float)
+0:?               's2D' ( uniform sampler)
+0:?               'tex' ( uniform texture2D)
+0:39          Function Call: os2Call2(struct-os2-p1-t211;vf2; ( temp 4-component vector of float)
+0:?             's2D' ( uniform sampler)
+0:?             'tex' ( uniform texture2D)
+0:?             Constant:
+0:?               0.200000
+0:?               0.300000
+0:35  Function Definition: main( ( temp void)
+0:35    Function Parameters: 
+0:?     Sequence
+0:35      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:35        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     'tex' ( uniform texture2D)
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 85
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 83
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 12  "osCall1(struct-os-p11;"
+                              Name 11  "s2D"
+                              Name 19  "osCall2(struct-os-p11;vf2;"
+                              Name 17  "s2D"
+                              Name 18  "f2"
+                              Name 26  "os2Call1(struct-os2-p1-t211;"
+                              Name 24  "s2D"
+                              Name 25  "tex"
+                              Name 32  "os2Call2(struct-os2-p1-t211;vf2;"
+                              Name 29  "s2D"
+                              Name 30  "tex"
+                              Name 31  "f2"
+                              Name 35  "@main("
+                              Name 37  "tex"
+                              Name 68  "s2D"
+                              Name 70  "param"
+                              Name 73  "s2D"
+                              Name 74  "tex"
+                              Name 77  "param"
+                              Name 83  "@entryPointOutput"
+                              Decorate 37(tex) DescriptorSet 0
+                              Decorate 68(s2D) DescriptorSet 0
+                              Decorate 73(s2D) DescriptorSet 0
+                              Decorate 74(tex) DescriptorSet 0
+                              Decorate 83(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeSampler
+               7:             TypePointer UniformConstant 6
+               8:             TypeFloat 32
+               9:             TypeVector 8(float) 4
+              10:             TypeFunction 9(fvec4) 7(ptr)
+              14:             TypeVector 8(float) 2
+              15:             TypePointer Function 14(fvec2)
+              16:             TypeFunction 9(fvec4) 7(ptr) 15(ptr)
+              21:             TypeImage 8(float) 2D sampled format:Unknown
+              22:             TypePointer UniformConstant 21
+              23:             TypeFunction 9(fvec4) 7(ptr) 22(ptr)
+              28:             TypeFunction 9(fvec4) 7(ptr) 22(ptr) 15(ptr)
+              34:             TypeFunction 9(fvec4)
+         37(tex):     22(ptr) Variable UniformConstant
+              40:             TypeSampledImage 21
+              42:    8(float) Constant 1045220557
+              43:    8(float) Constant 1050253722
+              44:   14(fvec2) ConstantComposite 42 43
+         68(s2D):      7(ptr) Variable UniformConstant
+         73(s2D):      7(ptr) Variable UniformConstant
+         74(tex):     22(ptr) Variable UniformConstant
+              82:             TypePointer Output 9(fvec4)
+83(@entryPointOutput):     82(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              84:    9(fvec4) FunctionCall 35(@main()
+                              Store 83(@entryPointOutput) 84
+                              Return
+                              FunctionEnd
+12(osCall1(struct-os-p11;):    9(fvec4) Function None 10
+         11(s2D):      7(ptr) FunctionParameter
+              13:             Label
+              38:          21 Load 37(tex)
+              39:           6 Load 11(s2D)
+              41:          40 SampledImage 38 39
+              45:    9(fvec4) ImageSampleImplicitLod 41 44
+                              ReturnValue 45
+                              FunctionEnd
+19(osCall2(struct-os-p11;vf2;):    9(fvec4) Function None 16
+         17(s2D):      7(ptr) FunctionParameter
+          18(f2):     15(ptr) FunctionParameter
+              20:             Label
+              48:          21 Load 37(tex)
+              49:           6 Load 17(s2D)
+              50:          40 SampledImage 48 49
+              51:   14(fvec2) Load 18(f2)
+              52:    9(fvec4) ImageSampleImplicitLod 50 51
+                              ReturnValue 52
+                              FunctionEnd
+26(os2Call1(struct-os2-p1-t211;):    9(fvec4) Function None 23
+         24(s2D):      7(ptr) FunctionParameter
+         25(tex):     22(ptr) FunctionParameter
+              27:             Label
+              55:          21 Load 25(tex)
+              56:           6 Load 24(s2D)
+              57:          40 SampledImage 55 56
+              58:    9(fvec4) ImageSampleImplicitLod 57 44
+                              ReturnValue 58
+                              FunctionEnd
+32(os2Call2(struct-os2-p1-t211;vf2;):    9(fvec4) Function None 28
+         29(s2D):      7(ptr) FunctionParameter
+         30(tex):     22(ptr) FunctionParameter
+          31(f2):     15(ptr) FunctionParameter
+              33:             Label
+              61:          21 Load 30(tex)
+              62:           6 Load 29(s2D)
+              63:          40 SampledImage 61 62
+              64:   14(fvec2) Load 31(f2)
+              65:    9(fvec4) ImageSampleImplicitLod 63 64
+                              ReturnValue 65
+                              FunctionEnd
+      35(@main():    9(fvec4) Function None 34
+              36:             Label
+       70(param):     15(ptr) Variable Function
+       77(param):     15(ptr) Variable Function
+              69:    9(fvec4) FunctionCall 12(osCall1(struct-os-p11;) 68(s2D)
+                              Store 70(param) 44
+              71:    9(fvec4) FunctionCall 19(osCall2(struct-os-p11;vf2;) 68(s2D) 70(param)
+              72:    9(fvec4) FAdd 69 71
+              75:    9(fvec4) FunctionCall 26(os2Call1(struct-os2-p1-t211;) 73(s2D) 74(tex)
+              76:    9(fvec4) FAdd 72 75
+                              Store 77(param) 44
+              78:    9(fvec4) FunctionCall 32(os2Call2(struct-os2-p1-t211;vf2;) 73(s2D) 74(tex) 77(param)
+              79:    9(fvec4) FAdd 76 78
+                              ReturnValue 79
+                              FunctionEnd

+ 75 - 0
3rdparty/glslang/Test/baseResults/hlsl.include.vert.out

@@ -0,0 +1,75 @@
+../Test/hlsl.include.vert
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 44
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 42
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 9  "@main("
+                              Name 11  "$Global"
+                              MemberName 11($Global) 0  "i1"
+                              MemberName 11($Global) 1  "i2"
+                              MemberName 11($Global) 2  "i4"
+                              MemberName 11($Global) 3  "i3"
+                              MemberName 11($Global) 4  "i6"
+                              MemberName 11($Global) 5  "i5"
+                              Name 13  ""
+                              Name 42  "@entryPointOutput"
+                              MemberDecorate 11($Global) 0 Offset 0
+                              MemberDecorate 11($Global) 1 Offset 16
+                              MemberDecorate 11($Global) 2 Offset 32
+                              MemberDecorate 11($Global) 3 Offset 48
+                              MemberDecorate 11($Global) 4 Offset 64
+                              MemberDecorate 11($Global) 5 Offset 80
+                              Decorate 11($Global) Block
+                              Decorate 13 DescriptorSet 0
+                              Decorate 42(@entryPointOutput) BuiltIn Position
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeFunction 7(fvec4)
+     11($Global):             TypeStruct 7(fvec4) 7(fvec4) 7(fvec4) 7(fvec4) 7(fvec4) 7(fvec4)
+              12:             TypePointer Uniform 11($Global)
+              13:     12(ptr) Variable Uniform
+              14:             TypeInt 32 1
+              15:     14(int) Constant 0
+              16:             TypePointer Uniform 7(fvec4)
+              19:     14(int) Constant 1
+              23:     14(int) Constant 3
+              27:     14(int) Constant 2
+              31:     14(int) Constant 5
+              35:     14(int) Constant 4
+              41:             TypePointer Output 7(fvec4)
+42(@entryPointOutput):     41(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              43:    7(fvec4) FunctionCall 9(@main()
+                              Store 42(@entryPointOutput) 43
+                              Return
+                              FunctionEnd
+       9(@main():    7(fvec4) Function None 8
+              10:             Label
+              17:     16(ptr) AccessChain 13 15
+              18:    7(fvec4) Load 17
+              20:     16(ptr) AccessChain 13 19
+              21:    7(fvec4) Load 20
+              22:    7(fvec4) FAdd 18 21
+              24:     16(ptr) AccessChain 13 23
+              25:    7(fvec4) Load 24
+              26:    7(fvec4) FAdd 22 25
+              28:     16(ptr) AccessChain 13 27
+              29:    7(fvec4) Load 28
+              30:    7(fvec4) FAdd 26 29
+              32:     16(ptr) AccessChain 13 31
+              33:    7(fvec4) Load 32
+              34:    7(fvec4) FAdd 30 33
+              36:     16(ptr) AccessChain 13 35
+              37:    7(fvec4) Load 36
+              38:    7(fvec4) FAdd 34 37
+                              ReturnValue 38
+                              FunctionEnd

+ 10 - 0
3rdparty/glslang/Test/baseResults/hlsl.includeNegative.vert.out

@@ -0,0 +1,10 @@
+hlsl.includeNegative.vert
+ERROR: ./foo.h:1: '#error' : should not be included  
+ERROR: ./inc2/../foo.h:1: '#error' : should not be included  
+ERROR: ./parentBad:3: '#error' : bad parent  
+ERROR: hlsl.includeNegative.vert:7: '#error' : in main  
+hlsl.includeNegative.vert(8): error at column 0, HLSL parsing failed.
+ERROR: 5 compilation errors.  No code generated.
+
+
+SPIR-V is not generated for failed compile or link

+ 69 - 0
3rdparty/glslang/Test/baseResults/include.vert.out

@@ -0,0 +1,69 @@
+include.vert
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+Shader version: 450
+Requested GL_GOOGLE_cpp_style_line_directive
+Requested GL_GOOGLE_include_directive
+0:? Sequence
+0:13  Function Definition: main( ( global void)
+0:13    Function Parameters: 
+0:15    Sequence
+0:15      move second child to first child ( temp 4-component vector of float)
+0:15        'color' ( smooth out 4-component vector of float)
+0:15        add ( temp 4-component vector of float)
+0:15          add ( temp 4-component vector of float)
+0:15            add ( temp 4-component vector of float)
+0:15              add ( temp 4-component vector of float)
+0:15                add ( temp 4-component vector of float)
+0:15                  'i1' ( global 4-component vector of float)
+0:15                  'i2' ( global 4-component vector of float)
+0:15                'i3' ( global 4-component vector of float)
+0:15              'i4' ( global 4-component vector of float)
+0:15            'i5' ( global 4-component vector of float)
+0:15          'i6' ( global 4-component vector of float)
+0:?   Linker Objects
+0:?     'i1' ( global 4-component vector of float)
+0:?     'i2' ( global 4-component vector of float)
+0:?     'i4' ( global 4-component vector of float)
+0:?     'i3' ( global 4-component vector of float)
+0:?     'i6' ( global 4-component vector of float)
+0:?     'i5' ( global 4-component vector of float)
+0:?     'color' ( smooth out 4-component vector of float)
+0:?     'gl_VertexID' ( gl_VertexId int VertexId)
+0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
+
+
+Linked vertex stage:
+
+
+Shader version: 450
+Requested GL_GOOGLE_cpp_style_line_directive
+Requested GL_GOOGLE_include_directive
+0:? Sequence
+0:13  Function Definition: main( ( global void)
+0:13    Function Parameters: 
+0:15    Sequence
+0:15      move second child to first child ( temp 4-component vector of float)
+0:15        'color' ( smooth out 4-component vector of float)
+0:15        add ( temp 4-component vector of float)
+0:15          add ( temp 4-component vector of float)
+0:15            add ( temp 4-component vector of float)
+0:15              add ( temp 4-component vector of float)
+0:15                add ( temp 4-component vector of float)
+0:15                  'i1' ( global 4-component vector of float)
+0:15                  'i2' ( global 4-component vector of float)
+0:15                'i3' ( global 4-component vector of float)
+0:15              'i4' ( global 4-component vector of float)
+0:15            'i5' ( global 4-component vector of float)
+0:15          'i6' ( global 4-component vector of float)
+0:?   Linker Objects
+0:?     'i1' ( global 4-component vector of float)
+0:?     'i2' ( global 4-component vector of float)
+0:?     'i4' ( global 4-component vector of float)
+0:?     'i3' ( global 4-component vector of float)
+0:?     'i6' ( global 4-component vector of float)
+0:?     'i5' ( global 4-component vector of float)
+0:?     'color' ( smooth out 4-component vector of float)
+0:?     'gl_VertexID' ( gl_VertexId int VertexId)
+0:?     'gl_InstanceID' ( gl_InstanceId int InstanceId)
+

+ 272 - 0
3rdparty/glslang/Test/baseResults/spv.debugInfo.frag.out

@@ -0,0 +1,272 @@
+spv.debugInfo.frag
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 126
+
+                              Capability Shader
+               2:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 5  "main" 24 52
+                              ExecutionMode 5 OriginUpperLeft
+               1:             String  "spv.debugInfo.frag"
+                              Source GLSL 450 1  "#version 450
+
+struct S {
+    int a;
+};
+
+uniform ubuf {
+    S s;
+};
+
+uniform sampler2D s2d;
+
+layout(location = 0) in vec4 inv;
+layout(location = 0) out vec4 outv;
+
+vec4 foo(S s)
+{
+    vec4 r = s.a * inv;
+    ++r;
+    if (r.x > 3.0)
+        --r;
+    else
+        r *= 2;
+
+    return r;
+}
+
+void main()
+{
+    outv = foo(s);
+    outv += texture(s2d, vec2(0.5));
+
+    switch (s.a) {
+    case 10:
+        ++outv;
+        break;
+    case 20:
+        outv = 2 * outv;
+        ++outv;
+        break;
+    default:
+        --outv;
+        break;
+    }
+
+    for (int i = 0; i < 10; ++i)
+        outv *= 3.0;
+
+    outv.x < 10.0 ?
+        outv = sin(outv) :
+        outv = cos(outv);
+}"
+                              Name 5  "main"
+                              Name 8  "S"
+                              MemberName 8(S) 0  "a"
+                              Name 14  "foo(struct-S-i11;"
+                              Name 13  "s"
+                              Name 17  "r"
+                              Name 24  "inv"
+                              Name 52  "outv"
+                              Name 53  "S"
+                              MemberName 53(S) 0  "a"
+                              Name 54  "ubuf"
+                              MemberName 54(ubuf) 0  "s"
+                              Name 56  ""
+                              Name 57  "S"
+                              MemberName 57(S) 0  "a"
+                              Name 59  "param"
+                              Name 69  "s2d"
+                              Name 99  "i"
+                              Decorate 24(inv) Location 0
+                              Decorate 52(outv) Location 0
+                              MemberDecorate 53(S) 0 Offset 0
+                              MemberDecorate 54(ubuf) 0 Offset 0
+                              Decorate 54(ubuf) Block
+                              Decorate 56 DescriptorSet 0
+                              Decorate 69(s2d) DescriptorSet 0
+               3:             TypeVoid
+               4:             TypeFunction 3
+               7:             TypeInt 32 1
+            8(S):             TypeStruct 7(int)
+               9:             TypePointer Function 8(S)
+              10:             TypeFloat 32
+              11:             TypeVector 10(float) 4
+              12:             TypeFunction 11(fvec4) 9(ptr)
+              16:             TypePointer Function 11(fvec4)
+              18:      7(int) Constant 0
+              19:             TypePointer Function 7(int)
+              23:             TypePointer Input 11(fvec4)
+         24(inv):     23(ptr) Variable Input
+              28:   10(float) Constant 1065353216
+              31:             TypeInt 32 0
+              32:     31(int) Constant 0
+              33:             TypePointer Function 10(float)
+              36:   10(float) Constant 1077936128
+              37:             TypeBool
+              45:   10(float) Constant 1073741824
+              51:             TypePointer Output 11(fvec4)
+        52(outv):     51(ptr) Variable Output
+           53(S):             TypeStruct 7(int)
+        54(ubuf):             TypeStruct 53(S)
+              55:             TypePointer Uniform 54(ubuf)
+              56:     55(ptr) Variable Uniform
+           57(S):             TypeStruct 7(int)
+              58:             TypePointer Function 57(S)
+              60:             TypePointer Uniform 53(S)
+              66:             TypeImage 10(float) 2D sampled format:Unknown
+              67:             TypeSampledImage 66
+              68:             TypePointer UniformConstant 67
+         69(s2d):     68(ptr) Variable UniformConstant
+              71:             TypeVector 10(float) 2
+              72:   10(float) Constant 1056964608
+              73:   71(fvec2) ConstantComposite 72 72
+              77:             TypePointer Uniform 7(int)
+             106:      7(int) Constant 10
+             111:      7(int) Constant 1
+             114:             TypePointer Output 10(float)
+             117:   10(float) Constant 1092616192
+         5(main):           3 Function None 4
+               6:             Label
+       59(param):     58(ptr) Variable Function
+           99(i):     19(ptr) Variable Function
+             113:     16(ptr) Variable Function
+                              Line 1 30 0
+              61:     60(ptr) AccessChain 56 18
+              62:       53(S) Load 61
+              63:      7(int) CompositeExtract 62 0
+              64:     19(ptr) AccessChain 59(param) 18
+                              Store 64 63
+              65:   11(fvec4) FunctionCall 14(foo(struct-S-i11;) 59(param)
+                              Store 52(outv) 65
+                              Line 1 31 0
+              70:          67 Load 69(s2d)
+              74:   11(fvec4) ImageSampleImplicitLod 70 73
+              75:   11(fvec4) Load 52(outv)
+              76:   11(fvec4) FAdd 75 74
+                              Store 52(outv) 76
+                              Line 1 33 0
+              78:     77(ptr) AccessChain 56 18 18
+              79:      7(int) Load 78
+                              SelectionMerge 83 None
+                              Switch 79 82 
+                                     case 10: 80
+                                     case 20: 81
+              82:               Label
+                                Line 1 42 0
+              94:   11(fvec4)   Load 52(outv)
+              95:   11(fvec4)   CompositeConstruct 28 28 28 28
+              96:   11(fvec4)   FSub 94 95
+                                Store 52(outv) 96
+                                Line 1 43 0
+                                Branch 83
+              80:               Label
+                                Line 1 35 0
+              84:   11(fvec4)   Load 52(outv)
+              85:   11(fvec4)   CompositeConstruct 28 28 28 28
+              86:   11(fvec4)   FAdd 84 85
+                                Store 52(outv) 86
+                                Line 1 36 0
+                                Branch 83
+              81:               Label
+                                Line 1 38 0
+              88:   11(fvec4)   Load 52(outv)
+              89:   11(fvec4)   VectorTimesScalar 88 45
+                                Store 52(outv) 89
+                                Line 1 39 0
+              90:   11(fvec4)   Load 52(outv)
+              91:   11(fvec4)   CompositeConstruct 28 28 28 28
+              92:   11(fvec4)   FAdd 90 91
+                                Store 52(outv) 92
+                                Line 1 40 0
+                                Branch 83
+              83:             Label
+                              Line 1 46 0
+                              Store 99(i) 18
+                              Branch 100
+             100:             Label
+                              LoopMerge 102 103 None
+                              Branch 104
+             104:             Label
+             105:      7(int) Load 99(i)
+             107:    37(bool) SLessThan 105 106
+                              BranchConditional 107 101 102
+             101:               Label
+                                Line 1 47 0
+             108:   11(fvec4)   Load 52(outv)
+             109:   11(fvec4)   VectorTimesScalar 108 36
+                                Store 52(outv) 109
+                                Branch 103
+             103:               Label
+                                Line 1 46 0
+             110:      7(int)   Load 99(i)
+             112:      7(int)   IAdd 110 111
+                                Store 99(i) 112
+                                Branch 100
+             102:             Label
+                              Line 1 49 0
+             115:    114(ptr) AccessChain 52(outv) 32
+             116:   10(float) Load 115
+             118:    37(bool) FOrdLessThan 116 117
+                              SelectionMerge 120 None
+                              BranchConditional 118 119 123
+             119:               Label
+                                Line 1 50 0
+             121:   11(fvec4)   Load 52(outv)
+             122:   11(fvec4)   ExtInst 2(GLSL.std.450) 13(Sin) 121
+                                Store 52(outv) 122
+                                Store 113 122
+                                Branch 120
+             123:               Label
+                                Line 1 51 0
+             124:   11(fvec4)   Load 52(outv)
+             125:   11(fvec4)   ExtInst 2(GLSL.std.450) 14(Cos) 124
+                                Store 52(outv) 125
+                                Store 113 125
+                                Branch 120
+             120:             Label
+                              Return
+                              FunctionEnd
+14(foo(struct-S-i11;):   11(fvec4) Function None 12
+           13(s):      9(ptr) FunctionParameter
+              15:             Label
+           17(r):     16(ptr) Variable Function
+                              Line 1 18 0
+              20:     19(ptr) AccessChain 13(s) 18
+              21:      7(int) Load 20
+              22:   10(float) ConvertSToF 21
+              25:   11(fvec4) Load 24(inv)
+              26:   11(fvec4) VectorTimesScalar 25 22
+                              Store 17(r) 26
+                              Line 1 19 0
+              27:   11(fvec4) Load 17(r)
+              29:   11(fvec4) CompositeConstruct 28 28 28 28
+              30:   11(fvec4) FAdd 27 29
+                              Store 17(r) 30
+                              Line 1 20 0
+              34:     33(ptr) AccessChain 17(r) 32
+              35:   10(float) Load 34
+              38:    37(bool) FOrdGreaterThan 35 36
+                              SelectionMerge 40 None
+                              BranchConditional 38 39 44
+              39:               Label
+                                Line 1 21 0
+              41:   11(fvec4)   Load 17(r)
+              42:   11(fvec4)   CompositeConstruct 28 28 28 28
+              43:   11(fvec4)   FSub 41 42
+                                Store 17(r) 43
+                                Branch 40
+              44:               Label
+                                Line 1 23 0
+              46:   11(fvec4)   Load 17(r)
+              47:   11(fvec4)   VectorTimesScalar 46 45
+                                Store 17(r) 47
+                                Branch 40
+              40:             Label
+                              Line 1 25 0
+              48:   11(fvec4) Load 17(r)
+                              ReturnValue 48
+                              FunctionEnd

+ 88 - 0
3rdparty/glslang/Test/baseResults/spv.ssboAlias.frag.out

@@ -0,0 +1,88 @@
+spv.ssboAlias.frag
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 46
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 43
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 9  "@main("
+                              Name 13  "Buf1"
+                              MemberName 13(Buf1) 0  "@data"
+                              Name 15  "Buf1"
+                              Name 18  "Buf1@count"
+                              MemberName 18(Buf1@count) 0  "@count"
+                              Name 20  "Buf1@count"
+                              Name 30  "Buf2"
+                              Name 31  "Buf2@count"
+                              Name 43  "@entryPointOutput"
+                              Name 45  "Buf3"
+                              Decorate 12 ArrayStride 4
+                              MemberDecorate 13(Buf1) 0 Offset 0
+                              Decorate 13(Buf1) BufferBlock
+                              Decorate 15(Buf1) DescriptorSet 0
+                              Decorate 15(Buf1) Binding 84
+                              MemberDecorate 18(Buf1@count) 0 Offset 0
+                              Decorate 18(Buf1@count) BufferBlock
+                              Decorate 20(Buf1@count) DescriptorSet 0
+                              Decorate 20(Buf1@count) Binding 83
+                              Decorate 30(Buf2) DescriptorSet 0
+                              Decorate 30(Buf2) Binding 85
+                              Decorate 31(Buf2@count) DescriptorSet 0
+                              Decorate 31(Buf2@count) Binding 86
+                              Decorate 43(@entryPointOutput) Location 0
+                              Decorate 45(Buf3) DescriptorSet 0
+                              Decorate 45(Buf3) Binding 84
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeFunction 7(fvec4)
+              11:             TypeInt 32 0
+              12:             TypeRuntimeArray 11(int)
+        13(Buf1):             TypeStruct 12
+              14:             TypePointer Uniform 13(Buf1)
+        15(Buf1):     14(ptr) Variable Uniform
+              16:             TypeInt 32 1
+              17:     16(int) Constant 0
+  18(Buf1@count):             TypeStruct 16(int)
+              19:             TypePointer Uniform 18(Buf1@count)
+  20(Buf1@count):     19(ptr) Variable Uniform
+              21:             TypePointer Uniform 16(int)
+              23:     16(int) Constant 1
+              24:     11(int) Constant 1
+              25:     11(int) Constant 0
+              27:     11(int) Constant 10
+              28:             TypePointer Uniform 11(int)
+        30(Buf2):     14(ptr) Variable Uniform
+  31(Buf2@count):     19(ptr) Variable Uniform
+              34:     11(int) Constant 20
+              36:    6(float) Constant 1065353216
+              37:    6(float) Constant 1077936128
+              38:    6(float) Constant 1084227584
+              39:    7(fvec4) ConstantComposite 36 37 38 36
+              42:             TypePointer Output 7(fvec4)
+43(@entryPointOutput):     42(ptr) Variable Output
+        45(Buf3):     14(ptr) Variable Uniform
+         4(main):           2 Function None 3
+               5:             Label
+              44:    7(fvec4) FunctionCall 9(@main()
+                              Store 43(@entryPointOutput) 44
+                              Return
+                              FunctionEnd
+       9(@main():    7(fvec4) Function None 8
+              10:             Label
+              22:     21(ptr) AccessChain 20(Buf1@count) 17
+              26:     11(int) AtomicIAdd 22 24 25 23
+              29:     28(ptr) AccessChain 15(Buf1) 17 26
+                              Store 29 27
+              32:     21(ptr) AccessChain 31(Buf2@count) 17
+              33:     11(int) AtomicIAdd 32 24 25 23
+              35:     28(ptr) AccessChain 30(Buf2) 17 33
+                              Store 35 34
+                              ReturnValue 39
+                              FunctionEnd

+ 38 - 0
3rdparty/glslang/Test/baseResults/spv.texture.sampler.transform.frag.out

@@ -0,0 +1,38 @@
+spv.texture.sampler.transform.frag
+Warning, version 440 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 19
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 9 16
+                              ExecutionMode 4 OriginUpperLeft
+                              Source GLSL 440
+                              Name 4  "main"
+                              Name 9  "color"
+                              Name 12  "tex"
+                              Name 16  "coord"
+                              Decorate 12(tex) DescriptorSet 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypePointer Output 7(fvec4)
+        9(color):      8(ptr) Variable Output
+              10:             TypeImage 6(float) 2D sampled format:Unknown
+              11:             TypePointer UniformConstant 10
+         12(tex):     11(ptr) Variable UniformConstant
+              14:             TypeVector 6(float) 2
+              15:             TypePointer Input 14(fvec2)
+       16(coord):     15(ptr) Variable Input
+         4(main):           2 Function None 3
+               5:             Label
+              13:          10 Load 12(tex)
+              17:   14(fvec2) Load 16(coord)
+              18:    7(fvec4) ImageSampleImplicitLod 13 17
+                              Store 9(color) 18
+                              Return
+                              FunctionEnd

+ 1 - 0
3rdparty/glslang/Test/foo.h

@@ -0,0 +1 @@
+#error should not be included

+ 29 - 0
3rdparty/glslang/Test/hlsl.aliasOpaque.frag

@@ -0,0 +1,29 @@
+struct OS {
+    SamplerState ss;
+    float a;
+    Texture2D tex;
+};
+
+SamplerState gss;
+SamplerState gss2;
+Texture2D gtex;
+
+float4 osCall(OS s)
+{
+    return s.a * s.tex.Sample(s.ss, float2(0.2, 0.3));
+}
+
+float4 main() : SV_TARGET0
+{
+    OS os;
+    os.ss = gss2;
+    os.ss = gss;
+    os.tex = gtex;
+    os.a = 3.0;
+
+    // this should give an error
+    //SamplerState localss;
+    //localss = gss2;
+
+    return osCall(os);
+}

+ 40 - 0
3rdparty/glslang/Test/hlsl.flattenOpaque.frag

@@ -0,0 +1,40 @@
+struct os {
+    sampler2D s2D;
+};
+
+struct os2 {
+    sampler2D s2D;
+    Texture2D tex;
+};
+
+Texture2D tex;
+os s;
+os2 s2;
+
+float4 osCall1(os s)
+{
+    return tex.Sample(s.s2D, float2(0.2, 0.3));
+}
+
+float4 osCall2(os s, float2 f2)
+{
+    return tex.Sample(s.s2D, f2);
+}
+
+float4 os2Call1(os2 s)
+{
+    return s.tex.Sample(s.s2D, float2(0.2, 0.3));
+}
+
+float4 os2Call2(os2 s, float2 f2)
+{
+    return s.tex.Sample(s.s2D, f2);
+}
+
+float4 main() : SV_TARGET0
+{
+    return osCall1(s) +
+           osCall2(s, float2(0.2, 0.3)) +
+           os2Call1(s2) +
+           os2Call2(s2, float2(0.2, 0.3));
+}

+ 8 - 0
3rdparty/glslang/Test/hlsl.include.vert

@@ -0,0 +1,8 @@
+#include "bar.h"
+#include "./inc1/bar.h"
+#include "inc2\bar.h"
+
+float4 main() : SV_Position
+{
+    return i1 + i2 + i3 + i4 + i5 + i6;
+}

+ 8 - 0
3rdparty/glslang/Test/hlsl.includeNegative.vert

@@ -0,0 +1,8 @@
+#include "foo.h"
+#include "inc2/../foo.h"
+#include "inc1/badInc.h"
+
+float4 main() : SV_Position
+{
+#error in main
+}

+ 1 - 0
3rdparty/glslang/Test/inc1/badInc.h

@@ -0,0 +1 @@
+#include "parentBad"

+ 3 - 0
3rdparty/glslang/Test/inc1/bar.h

@@ -0,0 +1,3 @@
+float4 i2;
+
+#include "foo.h"

+ 3 - 0
3rdparty/glslang/Test/inc1/foo.h

@@ -0,0 +1,3 @@
+#include "parent.h"
+
+float4 i3;

+ 2 - 0
3rdparty/glslang/Test/inc2/bar.h

@@ -0,0 +1,2 @@
+#include "foo.h"
+float4 i5;

+ 1 - 0
3rdparty/glslang/Test/inc2/foo.h

@@ -0,0 +1 @@
+float4 i6;

+ 16 - 0
3rdparty/glslang/Test/include.vert

@@ -0,0 +1,16 @@
+#version 450
+
+#extension GL_GOOGLE_include_directive : enable
+
+#define float4 vec4
+
+#include "bar.h"
+#include "./inc1/bar.h"
+#include "inc2\bar.h"
+
+out vec4 color;
+
+void main()
+{
+    color = i1 + i2 + i3 + i4 + i5 + i6;
+}

+ 1 - 0
3rdparty/glslang/Test/parent.h

@@ -0,0 +1 @@
+float4 i4;

+ 3 - 0
3rdparty/glslang/Test/parentBad

@@ -0,0 +1,3 @@
+int a;
+
+#error bad parent

+ 20 - 2
3rdparty/glslang/Test/runtests

@@ -90,14 +90,32 @@ diff -b $BASEDIR/hlsl.hlslOffset.vert.out $TARGETDIR/hlsl.hlslOffset.vert.out ||
 #
 echo Configuring HLSL descriptor set and binding number manually
 $EXE -V -D -e main -H hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out
-diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out
+diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out || HASERROR=1
 
 #
 # Testing location error
 #
 echo Testing SPV no location
 $EXE -V -C spv.noLocation.vert > $TARGETDIR/spv.noLocation.vert.out
-diff -b $BASEDIR/spv.noLocation.vert.out $TARGETDIR/spv.noLocation.vert.out
+diff -b $BASEDIR/spv.noLocation.vert.out $TARGETDIR/spv.noLocation.vert.out || HASERROR=1
+
+#
+# Testing debug information
+#
+echo Testing SPV Debug Information
+$EXE -g -H spv.debugInfo.frag > $TARGETDIR/spv.debugInfo.frag.out
+diff -b $BASEDIR/spv.debugInfo.frag.out $TARGETDIR/spv.debugInfo.frag.out || HASERROR=1
+
+#
+# Testing Includer
+#
+echo Testing Includer
+$EXE -D -e main -H ../Test/hlsl.include.vert > $TARGETDIR/hlsl.include.vert.out
+diff -b $BASEDIR/hlsl.include.vert.out $TARGETDIR/hlsl.include.vert.out || HASERROR=1
+$EXE -D -e main -H hlsl.includeNegative.vert > $TARGETDIR/hlsl.includeNegative.vert.out
+diff -b $BASEDIR/hlsl.includeNegative.vert.out $TARGETDIR/hlsl.includeNegative.vert.out || HASERROR=1
+$EXE -l -i include.vert > $TARGETDIR/include.vert.out
+diff -b $BASEDIR/include.vert.out $TARGETDIR/include.vert.out || HASERROR=1
 
 #
 # Final checking

+ 52 - 0
3rdparty/glslang/Test/spv.debugInfo.frag

@@ -0,0 +1,52 @@
+#version 450
+
+struct S {
+    int a;
+};
+
+uniform ubuf {
+    S s;
+};
+
+uniform sampler2D s2d;
+
+layout(location = 0) in vec4 inv;
+layout(location = 0) out vec4 outv;
+
+vec4 foo(S s)
+{
+    vec4 r = s.a * inv;
+    ++r;
+    if (r.x > 3.0)
+        --r;
+    else
+        r *= 2;
+
+    return r;
+}
+
+void main()
+{
+    outv = foo(s);
+    outv += texture(s2d, vec2(0.5));
+
+    switch (s.a) {
+    case 10:
+        ++outv;
+        break;
+    case 20:
+        outv = 2 * outv;
+        ++outv;
+        break;
+    default:
+        --outv;
+        break;
+    }
+
+    for (int i = 0; i < 10; ++i)
+        outv *= 3.0;
+
+    outv.x < 10.0 ?
+        outv = sin(outv) :
+        outv = cos(outv);
+}

+ 10 - 0
3rdparty/glslang/Test/spv.ssboAlias.frag

@@ -0,0 +1,10 @@
+AppendStructuredBuffer<uint> Buf1 : register(u1);
+AppendStructuredBuffer<uint> Buf2 : register(u2);
+AppendStructuredBuffer<uint> Buf3 : register(u1);
+
+float4 main() : SV_Target
+{
+	Buf1.Append(10u);
+	Buf2.Append(20u);
+	return float4(1.0, 3.0, 5.0, 1.0);
+}

+ 13 - 0
3rdparty/glslang/Test/spv.texture.sampler.transform.frag

@@ -0,0 +1,13 @@
+#version 440
+
+uniform sampler smp;
+uniform texture2D tex;
+
+in vec2 coord;
+
+out vec4 color;
+
+void main()
+{
+  color = texture(sampler2D(tex, smp), coord);
+}

+ 1 - 0
3rdparty/glslang/glslang/Include/Types.h

@@ -1310,6 +1310,7 @@ public:
 
     virtual TBasicType getBasicType() const { return basicType; }
     virtual const TSampler& getSampler() const { return sampler; }
+    virtual TSampler& getSampler() { return sampler; }
 
     virtual       TQualifier& getQualifier()       { return qualifier; }
     virtual const TQualifier& getQualifier() const { return qualifier; }

+ 45 - 0
3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -1776,6 +1776,14 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
     // Propagate 'noContraction' label in backward from 'precise' variables.
     glslang::PropagateNoContraction(*this);
 
+    switch (textureSamplerTransformMode) {
+    case EShTexSampTransKeep:
+        break;
+    case EShTexSampTransUpgradeTextureRemoveSampler:
+        performTextureUpgradeAndSamplerRemovalTransformation(root);
+        break;
+    }
+
     return true;
 }
 
@@ -2943,4 +2951,41 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt
            (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
 }
 
+struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
+    bool visitAggregate(TVisit, TIntermAggregate* ag) override {
+        using namespace std;
+        TIntermSequence& seq = ag->getSequence();
+        // remove pure sampler variables
+        TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) {
+            TIntermSymbol* symbol = node->getAsSymbolNode();
+            if (!symbol)
+                return false;
+
+            return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler());
+        });
+        seq.erase(newEnd, seq.end());
+        // replace constructors with sampler/textures
+        // update textures into sampled textures
+        for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
+            TIntermSymbol* symbol = node->getAsSymbolNode();
+            if (!symbol) {
+                TIntermAggregate *constructor = node->getAsAggregate();
+                if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
+                    if (!constructor->getSequence().empty())
+                        node = constructor->getSequence()[0];
+                }
+            } else if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
+                symbol->getWritableType().getSampler().combined = true;
+            }
+        });
+        return true;
+    }
+};
+
+void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root)
+{
+    TextureUpgradeAndSamplerRemovalTransform transform;
+    root->traverse(&transform);
+}
+
 } // end namespace glslang

+ 11 - 0
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -2102,6 +2102,17 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
     case EOpConstructDMat4x2:
     case EOpConstructDMat4x3:
     case EOpConstructDMat4x4:
+#ifdef AMD_EXTENSIONS
+    case EOpConstructF16Mat2x2:
+    case EOpConstructF16Mat2x3:
+    case EOpConstructF16Mat2x4:
+    case EOpConstructF16Mat3x2:
+    case EOpConstructF16Mat3x3:
+    case EOpConstructF16Mat3x4:
+    case EOpConstructF16Mat4x2:
+    case EOpConstructF16Mat4x3:
+    case EOpConstructF16Mat4x4:
+#endif
         constructingMatrix = true;
         break;
     default:

+ 6 - 5
3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp

@@ -728,6 +728,11 @@ bool ProcessDeferred(
         intermediate.setOriginUpperLeft();
     if ((messages & EShMsgHlslOffsets) || (messages & EShMsgReadHlsl))
         intermediate.setHlslOffsets();
+    if (messages & EShMsgDebugInfo) {
+        intermediate.setSourceFile(names[numPre]);
+        for (int s = 0; s < numStrings; ++s)
+            intermediate.addSourceText(strings[numPre]);
+    }
     SetupBuiltinSymbolTable(version, profile, spvVersion, source);
 
     TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
@@ -1578,6 +1583,7 @@ void TShader::setHlslIoMapping(bool hlslIoMap)          { intermediate->setHlslI
 void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlattenUniformArrays(flatten); }
 void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
 void TShader::setResourceSetBinding(const std::vector<std::string>& base)   { intermediate->setResourceSetBinding(base); }
+void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
 
 //
 // Turn the shader strings into a parse tree in the TIntermediate.
@@ -1601,11 +1607,6 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
                            forwardCompatible, messages, *intermediate, includer, sourceEntryPointName);
 }
 
-bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
-{
-    return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
-}
-
 // Fill in a string with the result of preprocessing ShaderStrings
 // Returns true if all extensions, pragmas and version strings were valid.
 bool TShader::preprocess(const TBuiltInResource* builtInResources,

+ 7 - 35
3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -374,7 +374,12 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
     int reserveSlot(int set, int slot)
     {
         TSlotSet::iterator at = findSlot(set, slot);
-        slots[set].insert(at, slot);
+
+        // tolerate aliasing, by not double-recording aliases
+        // (policy about appropriateness of the alias is higher up)
+        if (at == slots[set].end() || *at != slot)
+            slots[set].insert(at, slot);
+
         return slot;
     }
 
@@ -468,24 +473,6 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
 {
     bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
     {
-        if (type.getQualifier().hasBinding()) {
-            const int set = getLayoutSet(type);
-
-            if (isImageType(type))
-                return checkEmpty(set, baseImageBinding + type.getQualifier().layoutBinding);
-
-            if (isTextureType(type))
-                return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
-
-            if (isSsboType(type))
-                return checkEmpty(set, baseSsboBinding + type.getQualifier().layoutBinding);
-
-            if (isSamplerType(type))
-                return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
-
-            if (isUboType(type))
-                return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
-        }
         return true;
     }
 
@@ -496,7 +483,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
         if (type.getQualifier().hasBinding()) {
             if (isImageType(type))
                 return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
-                
+
             if (isTextureType(type))
                 return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
 
@@ -588,21 +575,6 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
 {
     bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
     {
-        if (type.getQualifier().hasBinding()) {
-            const int set = getLayoutSet(type);
-
-            if (isUavType(type))
-                return checkEmpty(set, baseUavBinding + type.getQualifier().layoutBinding);
-
-            if (isSrvType(type))
-                return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
-
-            if (isSamplerType(type))
-                return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
-
-            if (isUboType(type))
-                return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
-        }
         return true;
     }
 

+ 15 - 1
3rdparty/glslang/glslang/MachineIndependent/localintermediate.h

@@ -182,7 +182,8 @@ public:
         useUnknownFormat(false),
         hlslOffsets(false),
         useStorageBuffer(false),
-        hlslIoMapping(false)
+        hlslIoMapping(false),
+        textureSamplerTransformMode(EShTexSampTransKeep)
     {
         localSize[0] = 1;
         localSize[1] = 1;
@@ -233,6 +234,7 @@ public:
     bool usingStorageBuffer() const { return useStorageBuffer; }
     void setHlslIoMapping(bool b) { hlslIoMapping = b; }
     bool usingHlslIoMapping()     { return hlslIoMapping; }
+    void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
 
     void setVersion(int v) { version = v; }
     int getVersion() const { return version; }
@@ -449,6 +451,11 @@ public:
         return semanticNameSet.insert(name).first->c_str();
     }
 
+    void setSourceFile(const char* file) { sourceFile = file; }
+    const std::string& getSourceFile() const { return sourceFile; }
+    void addSourceText(const char* text) { sourceText = sourceText + text; }
+    const std::string& getSourceText() const { return sourceText; }
+
     const char* const implicitThisName = "@this";
 
 protected:
@@ -472,6 +479,7 @@ protected:
     void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
     void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
     bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
+    void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
 
     const EShLanguage language;  // stage, known at construction time
     EShSource source;            // source language, known a bit later
@@ -536,6 +544,12 @@ protected:
     std::unordered_set<int> usedConstantId; // specialization constant ids used
     std::set<TString> semanticNameSet;
 
+    EShTextureSamplerTransformMode textureSamplerTransformMode;
+
+    // source code of shader, useful as part of debug information
+    std::string sourceFile;
+    std::string sourceText;
+
 private:
     void operator=(TIntermediate&); // prevent assignments
 };

+ 5 - 5
3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp

@@ -613,14 +613,14 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
     TShader::Includer::IncludeResult* res = nullptr;
     if (startWithLocalSearch)
         res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
-    if (! res || res->headerName.empty()) {
+    if (res == nullptr || res->headerName.empty()) {
         includer.releaseInclude(res);
         res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
     }
 
     // Process the results
-    if (res && !res->headerName.empty()) {
-        if (res->headerData && res->headerLength) {
+    if (res != nullptr && !res->headerName.empty()) {
+        if (res->headerData != nullptr && res->headerLength > 0) {
             // path for processing one or more tokens from an included header, hand off 'res'
             const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
             std::ostringstream prologue;
@@ -638,8 +638,8 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
     } else {
         // error path, clean up
         std::string message =
-            res ? std::string(res->headerData, res->headerLength)
-                : std::string("Could not process include directive");
+            res != nullptr ? std::string(res->headerData, res->headerLength)
+                           : std::string("Could not process include directive");
         parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
         includer.releaseInclude(res);
     }

+ 24 - 5
3rdparty/glslang/glslang/Public/ShaderLang.h

@@ -134,6 +134,14 @@ typedef enum {
     EShOptFull,         // Optimizations that will take more time
 } EShOptimizationLevel;
 
+//
+// Texture and Sampler transformation mode.
+//
+typedef enum {
+    EShTexSampTransKeep,   // keep textures and samplers as is (default)
+    EShTexSampTransUpgradeTextureRemoveSampler,  // change texture w/o embeded sampler into sampled texture and throw away all samplers
+} EShTextureSamplerTransformMode;
+
 //
 // Message choices for what errors and warnings are given.
 //
@@ -149,6 +157,7 @@ enum EShMessages {
     EShMsgCascadingErrors  = (1 << 7),  // get cascading errors; risks error-recovery issues, instead of an early exit
     EShMsgKeepUncalled     = (1 << 8),  // for testing, don't eliminate uncalled functions
     EShMsgHlslOffsets      = (1 << 9),  // allow block offsets to follow HLSL rules instead of GLSL rules
+    EShMsgDebugInfo        = (1 << 10), // save debug information
 };
 
 //
@@ -313,6 +322,7 @@ public:
     void setHlslIoMapping(bool hlslIoMap);
     void setFlattenUniformArrays(bool flatten);
     void setNoStorageFormat(bool useUnknownFormat);
+    void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
 
     // Interface to #include handlers.
     //
@@ -397,6 +407,9 @@ public:
         virtual void releaseInclude(IncludeResult*) override { }
     };
 
+    bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
+               bool forwardCompatible, EShMessages, Includer&);
+
     bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                bool forwardCompatible, EShMessages messages)
     {
@@ -404,12 +417,18 @@ public:
         return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
     }
 
-    bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
-               bool forwardCompatible, EShMessages, Includer&);
-
     // Equivalent to parse() without a default profile and without forcing defaults.
-    // Provided for backwards compatibility.
-    bool parse(const TBuiltInResource*, int defaultVersion, bool forwardCompatible, EShMessages);
+    bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
+    {
+        return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
+    }
+
+    bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages,
+               Includer& includer)
+    {
+        return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
+    }
+
     bool preprocess(const TBuiltInResource* builtInResources,
                     int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                     bool forwardCompatible, EShMessages message, std::string* outputString,

+ 2 - 0
3rdparty/glslang/gtests/Hlsl.FromFile.cpp

@@ -81,6 +81,7 @@ INSTANTIATE_TEST_CASE_P(
     ToSpirv, HlslCompileTest,
     ::testing::ValuesIn(std::vector<FileNameEntryPointPair>{
         {"hlsl.amend.frag", "f1"},
+        {"hlsl.aliasOpaque.frag", "main"},
         {"hlsl.array.frag", "PixelShaderFunction"},
         {"hlsl.array.implicit-size.frag", "PixelShaderFunction"},
         {"hlsl.array.multidim.frag", "main"},
@@ -114,6 +115,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.float1.frag", "PixelShaderFunction"},
         {"hlsl.float4.frag", "PixelShaderFunction"},
         {"hlsl.flatten.return.frag", "main"},
+        {"hlsl.flattenOpaque.frag", "main"},
         {"hlsl.forLoop.frag", "PixelShaderFunction"},
         {"hlsl.gather.array.dx10.frag", "main"},
         {"hlsl.gather.basic.dx10.frag", "main"},

+ 19 - 0
3rdparty/glslang/gtests/Spv.FromFile.cpp

@@ -75,6 +75,7 @@ using CompileVulkanToSpirvTestAMD = GlslangTest<::testing::TestWithParam<std::st
 #ifdef NV_EXTENSIONS
 using CompileVulkanToSpirvTestNV = GlslangTest<::testing::TestWithParam<std::string>>;
 #endif
+using CompileUpgradeTextureToSampledTextureAndDropSamplersTest = GlslangTest<::testing::TestWithParam<std::string>>;
 
 // Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully
 // generate SPIR-V.
@@ -172,6 +173,15 @@ TEST_P(CompileVulkanToSpirvTestNV, FromFile)
 }
 #endif
 
+TEST_P(CompileUpgradeTextureToSampledTextureAndDropSamplersTest, FromFile)
+{
+    loadCompileUpgradeTextureToSampledTextureAndDropSamplersAndCheck(GlobalTestSettings.testRoot,
+                                                                     GetParam(),
+                                                                     Source::GLSL,
+                                                                     Semantics::Vulkan,
+                                                                     Target::Spv);
+}
+
 // clang-format off
 INSTANTIATE_TEST_CASE_P(
     Glsl, CompileVulkanToSpirvTest,
@@ -320,6 +330,7 @@ INSTANTIATE_TEST_CASE_P(
         { "spv.register.autoassign-2.frag", "main", 5, 10, 0, 15, 30, true, true },
         { "spv.buffer.autoassign.frag", "main", 5, 10, 0, 15, 30, true, true },
         { "spv.ssbo.autoassign.frag", "main", 5, 10, 0, 15, 30, true, true },
+        { "spv.ssboAlias.frag", "main", 0, 0, 0, 0, 83, true, false },
         { "spv.rw.autoassign.frag", "main", 5, 10, 20, 15, 30, true, true },
         { "spv.register.autoassign.rangetest.frag", "main", 
                 glslang::TQualifier::layoutBindingEnd-2,
@@ -407,6 +418,14 @@ INSTANTIATE_TEST_CASE_P(
 FileNameAsCustomTestSuffix
 );
 #endif
+
+INSTANTIATE_TEST_CASE_P(
+    Glsl, CompileUpgradeTextureToSampledTextureAndDropSamplersTest,
+    ::testing::ValuesIn(std::vector<std::string>({
+      "spv.texture.sampler.transform.frag",
+    })),
+    FileNameAsCustomTestSuffix
+);
 // clang-format on
 
 }  // anonymous namespace

+ 28 - 1
3rdparty/glslang/gtests/TestFixture.h

@@ -197,12 +197,14 @@ public:
     GlslangResult compileAndLink(
             const std::string shaderName, const std::string& code,
             const std::string& entryPointName, EShMessages controls,
-            bool flattenUniformArrays = false)
+            bool flattenUniformArrays = false,
+            EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep)
     {
         const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
 
         glslang::TShader shader(kind);
         shader.setAutoMapLocations(true);
+        shader.setTextureSamplerTransformMode(texSampTransMode);
         shader.setFlattenUniformArrays(flattenUniformArrays);
 
         bool success = compile(&shader, code, entryPointName, controls);
@@ -570,6 +572,31 @@ public:
                                     expectedErrorFname);
     }
 
+    void loadCompileUpgradeTextureToSampledTextureAndDropSamplersAndCheck(const std::string& testDir,
+                                                                          const std::string& testName,
+                                                                          Source source,
+                                                                          Semantics semantics,
+                                                                          Target target,
+                                                                          const std::string& entryPointName = "")
+    {
+        const std::string inputFname = testDir + "/" + testName;
+        const std::string expectedOutputFname = testDir + "/baseResults/" + testName + ".out";
+        std::string input, expectedOutput;
+
+        tryLoadFile(inputFname, "input", &input);
+        tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
+
+        const EShMessages controls = DeriveOptions(source, semantics, target);
+        GlslangResult result = compileAndLink(testName, input, entryPointName, controls, false, EShTexSampTransUpgradeTextureRemoveSampler);
+
+        // Generate the hybrid output in the way of glslangValidator.
+        std::ostringstream stream;
+        outputResultToStream(&stream, result, controls);
+
+        checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
+                                    expectedOutputFname);
+    }
+
 private:
     const int defaultVersion;
     const EProfile defaultProfile;

+ 230 - 68
3rdparty/glslang/hlsl/hlslParseHelper.cpp

@@ -147,7 +147,7 @@ bool HlslParseContext::parseShaderStrings(TPpContext& ppContext, TInputScanner&
 //
 bool HlslParseContext::shouldConvertLValue(const TIntermNode* node) const
 {
-    if (node == nullptr)
+    if (node == nullptr || node->getAsTyped() == nullptr)
         return false;
 
     const TIntermAggregate* lhsAsAggregate = node->getAsAggregate();
@@ -157,10 +157,14 @@ bool HlslParseContext::shouldConvertLValue(const TIntermNode* node) const
     if (lhsAsBinary != nullptr &&
         (lhsAsBinary->getOp() == EOpVectorSwizzle || lhsAsBinary->getOp() == EOpIndexDirect))
         lhsAsAggregate = lhsAsBinary->getLeft()->getAsAggregate();
-
     if (lhsAsAggregate != nullptr && lhsAsAggregate->getOp() == EOpImageLoad)
         return true;
 
+    // If it's a syntactic write to a sampler, we will use that to establish
+    // a compile-time alias.
+    if (node->getAsTyped()->getBasicType() == EbtSampler)
+        return true;
+
     return false;
 }
 
@@ -233,7 +237,7 @@ bool HlslParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, T
 //
 // Most things are passed through unmodified, except for error checking.
 //
-TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char* op, TIntermTyped* node)
+TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char* op, TIntermTyped*& node)
 {
     if (node == nullptr)
         return nullptr;
@@ -256,6 +260,10 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
 
     // *** If we get here, we're going to apply some conversion to an l-value.
 
+    // Spin off sampler aliasing
+    if (node->getAsTyped()->getBasicType() == EbtSampler)
+        return handleSamplerLvalue(loc, op, node);
+
     // Helper to create a load.
     const auto makeLoad = [&](TIntermSymbol* rhsTmp, TIntermTyped* object, TIntermTyped* coord, const TType& derefType) {
         TIntermAggregate* loadOp = new TIntermAggregate(EOpImageLoad);
@@ -500,6 +508,42 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
     return node;
 }
 
+// Deal with sampler aliasing: turning assignments into aliases
+TIntermTyped* HlslParseContext::handleSamplerLvalue(const TSourceLoc& loc, const char* op, TIntermTyped*& node)
+{
+    // Can only alias an assignment:  "s1 = s2"
+    TIntermBinary* binary = node->getAsBinaryNode();
+    if (binary == nullptr || node->getAsOperator()->getOp() != EOpAssign ||
+        binary->getLeft() ->getAsSymbolNode() == nullptr ||
+        binary->getRight()->getAsSymbolNode() == nullptr) {
+        error(loc, "can't modify sampler", op, "");
+        return node;
+    }
+
+    // Best is if we are aliasing a flattened struct member "S.s1 = s2",
+    // in which case we want to update the flattening information with the alias,
+    // making everything else work seamlessly.
+    TIntermSymbol* left = binary->getLeft()->getAsSymbolNode();
+    TIntermSymbol* right = binary->getRight()->getAsSymbolNode();
+    for (auto fit = flattenMap.begin(); fit != flattenMap.end(); ++fit) {
+        for (auto mit = fit->second.members.begin(); mit != fit->second.members.end(); ++mit) {
+            if ((*mit)->getUniqueId() == left->getId()) {
+                // found it: update with alias to the existing variable, and don't emit any code
+                (*mit) = new TVariable(&right->getName(), right->getType());
+                (*mit)->setUniqueId(right->getId());
+                // replace node (rest of compiler expects either an error or code to generate)
+                // with pointless access
+                node = binary->getRight();
+                return node;
+            }
+        }
+    }
+
+    warn(loc, "could not create alias for sampler", op, "");
+
+    return node;
+}
+
 void HlslParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
 {
     if (pragmaCallback)
@@ -774,7 +818,7 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
     else {
         // at least one of base and index is variable...
 
-        if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlattenUniform(base->getType()))) {
+        if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlatten(base->getType()))) {
             if (index->getQualifier().storage != EvqConst)
                 error(loc, "Invalid variable index to flattened array", base->getAsSymbolNode()->getName().c_str(), "");
 
@@ -981,7 +1025,7 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
             }
         }
         if (fieldFound) {
-            if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlattenUniform(base->getType()))) {
+            if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlatten(base->getType()))) {
                 result = flattenAccess(base, member);
             } else {
                 // Update the base and member to access if this was a split structure.
@@ -1115,14 +1159,13 @@ TType& HlslParseContext::split(TType& type, TString name, const TType* outerStru
     return type;
 }
 
-// Is this a uniform array which should be flattened?
-bool HlslParseContext::shouldFlattenUniform(const TType& type) const
+// Is this a uniform array or structure which should be flattened?
+bool HlslParseContext::shouldFlatten(const TType& type) const
 {
     const TStorageQualifier qualifier = type.getQualifier().storage;
 
-    return qualifier == EvqUniform &&
-        ((type.isArray() && intermediate.getFlattenUniformArrays()) || type.isStruct()) &&
-        type.containsOpaque();
+    return (qualifier == EvqUniform && type.isArray() && intermediate.getFlattenUniformArrays()) ||
+           type.isStruct() && type.containsOpaque();
 }
 
 // Top level variable flattening: construct data
@@ -1285,16 +1328,22 @@ bool HlslParseContext::wasSplit(const TIntermTyped* node) const
 // Turn an access into an aggregate that was flattened to instead be
 // an access to the individual variable the member was flattened to.
 // Assumes shouldFlatten() or equivalent was called first.
+// Also assumes that initFlattening() and finalizeFlattening() bracket the usage.
 TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member)
 {
     const TType dereferencedType(base->getType(), member);  // dereferenced type
-
     const TIntermSymbol& symbolNode = *base->getAsSymbolNode();
 
-    const auto flattenData = flattenMap.find(symbolNode.getId());
+    TIntermTyped* flattened = flattenAccess(symbolNode.getId(), member, dereferencedType);
+
+    return flattened ? flattened : base;
+}
+TIntermTyped* HlslParseContext::flattenAccess(int uniqueId, int member, const TType& dereferencedType)
+{
+    const auto flattenData = flattenMap.find(uniqueId);
 
     if (flattenData == flattenMap.end())
-        return base;
+        return nullptr;
 
     // Calculate new cumulative offset from the packed tree
     flattenOffset.back() = flattenData->second.offsets[flattenOffset.back() + member];
@@ -1307,7 +1356,7 @@ TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member)
     } else {
         // If this is not the final flattening, accumulate the position and return
         // an object of the partially dereferenced type.
-        return new TIntermSymbol(symbolNode.getId(), "flattenShadow", dereferencedType);
+        return new TIntermSymbol(uniqueId, "flattenShadow", dereferencedType);
     }
 }
 
@@ -1663,15 +1712,32 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
                 symbolTable.makeInternalVariable(*variable);
                 pushImplicitThis(variable);
             }
+
             // Insert the parameters with name in the symbol table.
             if (! symbolTable.insert(*variable))
                 error(loc, "redefinition", variable->getName().c_str(), "");
-            // Add the parameter to the AST
-            paramNodes = intermediate.growAggregate(paramNodes,
-                                                    intermediate.addSymbol(*variable, loc),
-                                                    loc);
 
-            // Add hidden parameter for struct buffer counters, if needed.
+            // Add parameters to the AST list.
+            if (shouldFlatten(variable->getType())) {
+                // Expand the AST parameter nodes (but not the name mangling or symbol table view)
+                // for structures that need to be flattened.
+                flatten(loc, *variable);
+                const TTypeList* structure = variable->getType().getStruct();
+                for (int mem = 0; mem < (int)structure->size(); ++mem) {
+                    initFlattening();
+                    paramNodes = intermediate.growAggregate(paramNodes,
+                                                            flattenAccess(variable->getUniqueId(), mem, *(*structure)[mem].type),
+                                                            loc);
+                    finalizeFlattening();
+                }
+            } else {
+                // Add the parameter to the AST
+                paramNodes = intermediate.growAggregate(paramNodes,
+                                                        intermediate.addSymbol(*variable, loc),
+                                                        loc);
+            }
+
+            // Add hidden AST parameter for struct buffer counters, if needed.
             addStructBufferHiddenCounterParam(loc, param, paramNodes);
         } else
             paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc);
@@ -2265,7 +2331,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
         const bool flattened      = isLeft ? isFlattenLeft : isFlattenRight;
         const bool split          = isLeft ? isSplitLeft : isSplitRight;
         const TIntermTyped* outer = isLeft ? outerLeft   : outerRight;
-        const TVector<TVariable*>& flatVariables      = isLeft ? *leftVariables : *rightVariables;
+        const TVector<TVariable*>& flatVariables = isLeft ? *leftVariables : *rightVariables;
 
         // Index operator if it's an aggregate, else EOpNull
         const TOperator op = node->getType().isArray()  ? EOpIndexDirect : 
@@ -2320,7 +2386,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
             const int elementsToCopy = std::min(elementsL, elementsR);
 
             // array case
-            for (int element=0; element < elementsToCopy; ++element) {
+            for (int element = 0; element < elementsToCopy; ++element) {
                 arrayElement.push_back(element);
 
                 // Add a new AST symbol node if we have a temp variable holding a complex RHS.
@@ -2511,7 +2577,7 @@ bool HlslParseContext::hasStructBuffCounter(const TType& type) const
     case EbvRWStructuredBuffer:  // ...
         return true;
     default:
-        return false; // the other structuredbfufer types do not have a counter.
+        return false; // the other structuredbuffer types do not have a counter.
     }
 }
 
@@ -4419,14 +4485,18 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
                 pushFrontArguments(intermediate.addSymbol(*getImplicitThis(thisDepth)), arguments);
             }
 
-            // Convert 'in' arguments
+            // Convert 'in' arguments, so that types match.
+            // However, skip those that need expansion, that is covered next.
             if (arguments)
                 addInputArgumentConversions(*fnCandidate, arguments);
 
-            // If any argument is a pass-by-reference struct buffer with an associated counter
-            // buffer, we have to add another hidden parameter for that counter.
-            if (aggregate && !builtIn)
-                addStructBuffArguments(loc, aggregate);
+            // Expand arguments.  Some arguments must physically expand to a different set
+            // than what the shader declared and passes.
+            if (arguments && !builtIn)
+                expandArguments(loc, *fnCandidate, arguments);
+
+            // Expansion may have changed the form of arguments
+            aggregate = arguments ? arguments->getAsAggregate() : nullptr;
 
             op = fnCandidate->getBuiltInOp();
             if (builtIn && op != EOpNull) {
@@ -4464,24 +4534,35 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
             decomposeSampleMethods(loc, result, arguments);       // HLSL->AST sample method decompositions
             decomposeGeometryMethods(loc, result, arguments);     // HLSL->AST geometry method decompositions
 
-            // Convert 'out' arguments.  If it was a constant folded built-in, it won't be an aggregate anymore.
-            // Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
-            // Also, build the qualifier list for user function calls, which are always called with an aggregate.
-            // We don't do this is if there has been a decomposition, which will have added its own conversions
-            // for output parameters.
+            // Create the qualifier list, carried in the AST for the call.
+            // Because some arguments expand to multiple arguments, the qualifier list will
+            // be longer than the formal parameter list.
             if (result == fnNode && result->getAsAggregate()) {
                 TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
                 for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
                     TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
-                    qualifierList.push_back(qual);
-
-                    // add counter buffer argument qualifier
-                    if (hasStructBuffCounter(*(*fnCandidate)[i].type))
+                    if (hasStructBuffCounter(*(*fnCandidate)[i].type)) {
+                        // add buffer and counter buffer argument qualifier
+                        qualifierList.push_back(qual);
+                        qualifierList.push_back(qual);
+                    } else if (shouldFlatten(*(*fnCandidate)[i].type)) {
+                        // add structure member expansion
+                        for (int memb = 0; memb < (int)(*fnCandidate)[i].type->getStruct()->size(); ++memb)
+                            qualifierList.push_back(qual);
+                    } else {
+                        // Normal 1:1 case
                         qualifierList.push_back(qual);
+                    }
                 }
+            }
 
+            // Convert 'out' arguments.  If it was a constant folded built-in, it won't be an aggregate anymore.
+            // Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
+            // Also, build the qualifier list for user function calls, which are always called with an aggregate.
+            // We don't do this is if there has been a decomposition, which will have added its own conversions
+            // for output parameters.
+            if (result == fnNode && result->getAsAggregate())
                 result = addOutputArgumentConversions(*fnCandidate, *result->getAsOperator());
-            }
         }
     }
 
@@ -4512,20 +4593,22 @@ void HlslParseContext::pushFrontArguments(TIntermTyped* front, TIntermTyped*& ar
 void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermTyped*& arguments)
 {
     TIntermAggregate* aggregate = arguments->getAsAggregate();
-    const auto setArg = [&](int argNum, TIntermTyped* arg) {
+
+    // Replace a single argument with a single argument.
+    const auto setArg = [&](int paramNum, TIntermTyped* arg) {
         if (function.getParamCount() == 1)
             arguments = arg;
         else {
-            if (aggregate)
-                aggregate->getSequence()[argNum] = arg;
-            else
+            if (aggregate == nullptr)
                 arguments = arg;
+            else
+                aggregate->getSequence()[paramNum] = arg;
         }
     };
 
     // Process each argument's conversion
-    for (int i = 0; i < function.getParamCount(); ++i) {
-        if (! function[i].type->getQualifier().isParamInput())
+    for (int param = 0; param < function.getParamCount(); ++param) {
+        if (! function[param].type->getQualifier().isParamInput())
             continue;
 
         // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
@@ -4533,40 +4616,119 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
         // means take 'arguments' itself as the one argument.
         TIntermTyped* arg = function.getParamCount() == 1
                                    ? arguments->getAsTyped()
-                                   : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
-        if (*function[i].type != arg->getType()) {
+                                   : (aggregate ? 
+                                        aggregate->getSequence()[param]->getAsTyped() :
+                                        arguments->getAsTyped());
+        if (*function[param].type != arg->getType()) {
             // In-qualified arguments just need an extra node added above the argument to
             // convert to the correct type.
-            TIntermTyped* convArg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
+            TIntermTyped* convArg = intermediate.addConversion(EOpFunctionCall, *function[param].type, arg);
             if (convArg != nullptr)
-                convArg = intermediate.addUniShapeConversion(EOpFunctionCall, *function[i].type, convArg);
+                convArg = intermediate.addUniShapeConversion(EOpFunctionCall, *function[param].type, convArg);
             if (convArg != nullptr)
-                setArg(i, convArg);
+                setArg(param, convArg);
             else
-                error(arg->getLoc(), "cannot convert input argument, argument", "", "%d", i);
+                error(arg->getLoc(), "cannot convert input argument, argument", "", "%d", param);
         } else {
             if (wasFlattened(arg) || wasSplit(arg)) {
-                // Will make a two-level subtree.
-                // The deepest will copy member-by-member to build the structure to pass.
-                // The level above that will be a two-operand EOpComma sequence that follows the copy by the
-                // object itself.
-                TVariable* internalAggregate = makeInternalVariable("aggShadow", *function[i].type);
-                internalAggregate->getWritableType().getQualifier().makeTemporary();
-                TIntermSymbol* internalSymbolNode = new TIntermSymbol(internalAggregate->getUniqueId(),
-                                                                      internalAggregate->getName(),
-                                                                      internalAggregate->getType());
-                internalSymbolNode->setLoc(arg->getLoc());
-                // This makes the deepest level, the member-wise copy
-                TIntermAggregate* assignAgg = handleAssign(arg->getLoc(), EOpAssign, internalSymbolNode, arg)->getAsAggregate();
+                // If both formal and calling arg are to be flattened, leave that to argument
+                // expansion, not conversion.
+                if (!shouldFlatten(*function[param].type)) {
+                    // Will make a two-level subtree.
+                    // The deepest will copy member-by-member to build the structure to pass.
+                    // The level above that will be a two-operand EOpComma sequence that follows the copy by the
+                    // object itself.
+                    TVariable* internalAggregate = makeInternalVariable("aggShadow", *function[param].type);
+                    internalAggregate->getWritableType().getQualifier().makeTemporary();
+                    TIntermSymbol* internalSymbolNode = new TIntermSymbol(internalAggregate->getUniqueId(),
+                                                                          internalAggregate->getName(),
+                                                                          internalAggregate->getType());
+                    internalSymbolNode->setLoc(arg->getLoc());
+                    // This makes the deepest level, the member-wise copy
+                    TIntermAggregate* assignAgg = handleAssign(arg->getLoc(), EOpAssign, internalSymbolNode, arg)->getAsAggregate();
+
+                    // Now, pair that with the resulting aggregate.
+                    assignAgg = intermediate.growAggregate(assignAgg, internalSymbolNode, arg->getLoc());
+                    assignAgg->setOperator(EOpComma);
+                    assignAgg->setType(internalAggregate->getType());
+                    setArg(param, assignAgg);
+                }
+            }
+        }
+    }
+}
+
+//
+// Add any needed implicit expansion of calling arguments from what the shader listed to what's
+// internally needed for the AST (given the constraints downstream).
+//
+void HlslParseContext::expandArguments(const TSourceLoc& loc, const TFunction& function, TIntermTyped*& arguments)
+{
+    TIntermAggregate* aggregate = arguments->getAsAggregate();
+    int functionParamNumberOffset = 0;
 
-                // Now, pair that with the resulting aggregate.
-                assignAgg = intermediate.growAggregate(assignAgg, internalSymbolNode, arg->getLoc());
-                assignAgg->setOperator(EOpComma);
-                assignAgg->setType(internalAggregate->getType());
-                setArg(i, assignAgg);
+    // Replace a single argument with a single argument.
+    const auto setArg = [&](int paramNum, TIntermTyped* arg) {
+        if (function.getParamCount() + functionParamNumberOffset == 1)
+            arguments = arg;
+        else {
+            if (aggregate == nullptr)
+                arguments = arg;
+            else
+                aggregate->getSequence()[paramNum] = arg;
+        }
+    };
+
+    // Replace a single argument with a list of arguments
+    const auto setArgList = [&](int paramNum, const TVector<TIntermTyped*>& args) {
+        if (args.size() == 1)
+            setArg(paramNum, args.front());
+        else {
+            if (function.getParamCount() + functionParamNumberOffset == 1) {
+                arguments = intermediate.makeAggregate(args.front());
+                std::for_each(args.begin() + 1, args.end(), 
+                    [&](TIntermTyped* arg) {
+                        arguments = intermediate.growAggregate(arguments, arg);
+                    });
+            } else {
+                auto it = aggregate->getSequence().erase(aggregate->getSequence().begin() + paramNum);
+                aggregate->getSequence().insert(it, args.begin(), args.end());
+            }
+        }
+        functionParamNumberOffset += (args.size() - 1);
+    };
+
+    // Process each argument's conversion
+    for (int param = 0; param < function.getParamCount(); ++param) {
+        // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
+        // is the single argument itself or its children are the arguments.  Only one argument
+        // means take 'arguments' itself as the one argument.
+        TIntermTyped* arg = function.getParamCount() == 1
+                                   ? arguments->getAsTyped()
+                                   : (aggregate ? 
+                                        aggregate->getSequence()[param + functionParamNumberOffset]->getAsTyped() :
+                                        arguments->getAsTyped());
+
+        if (wasFlattened(arg) && shouldFlatten(*function[param].type)) {
+            // Need to pass the structure members instead of the structure.
+            TVector<TIntermTyped*> memberArgs;
+            for (int memb = 0; memb < (int)arg->getType().getStruct()->size(); ++memb) {
+                initFlattening();
+                memberArgs.push_back(flattenAccess(arg, memb));
+                finalizeFlattening();
             }
+            setArgList(param + functionParamNumberOffset, memberArgs);
         }
     }
+
+    // TODO: if we need both hidden counter args (below) and struct expansion (above)
+    // the two algorithms need to be merged: Each assumes the list starts out 1:1 between
+    // parameters and arguments.
+
+    // If any argument is a pass-by-reference struct buffer with an associated counter
+    // buffer, we have to add another hidden parameter for that counter.
+    if (aggregate)
+        addStructBuffArguments(loc, aggregate);
 }
 
 //
@@ -4682,7 +4844,7 @@ void HlslParseContext::addStructBuffArguments(const TSourceLoc& loc, TIntermAggr
 
     TIntermSequence argsWithCounterBuffers;
 
-    for (int param=0; param<int(aggregate->getSequence().size()); ++param) {
+    for (int param = 0; param < int(aggregate->getSequence().size()); ++param) {
         argsWithCounterBuffers.push_back(aggregate->getSequence()[param]);
 
         if (hasStructBuffCounter(aggregate->getSequence()[param]->getAsTyped()->getType())) {
@@ -6769,7 +6931,7 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, const TStr
 
     inheritGlobalDefaults(type.getQualifier());
 
-    const bool flattenVar = shouldFlattenUniform(type);
+    const bool flattenVar = shouldFlatten(type);
 
     // correct IO in the type
     switch (type.getQualifier().storage) {

+ 6 - 3
3rdparty/glslang/hlsl/hlslParseHelper.h

@@ -96,6 +96,7 @@ public:
     void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
     void pushFrontArguments(TIntermTyped* front, TIntermTyped*& arguments);
     void addInputArgumentConversions(const TFunction&, TIntermTyped*&);
+    void expandArguments(const TSourceLoc&, const TFunction&, TIntermTyped*&);
     TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
     void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
     TFunction* makeConstructorCall(const TSourceLoc&, const TType&);
@@ -186,7 +187,8 @@ public:
     virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
 
     // Apply L-value conversions.  E.g, turning a write to a RWTexture into an ImageStore.
-    TIntermTyped* handleLvalue(const TSourceLoc&, const char* op, TIntermTyped* node);
+    TIntermTyped* handleLvalue(const TSourceLoc&, const char* op, TIntermTyped*& node);
+    TIntermTyped* handleSamplerLvalue(const TSourceLoc&, const char* op, TIntermTyped*& node);
     bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
 
     TLayoutFormat getLayoutFromTxType(const TSourceLoc&, const TType&);
@@ -236,13 +238,14 @@ protected:
 
     // Array and struct flattening
     TIntermTyped* flattenAccess(TIntermTyped* base, int member);
-    bool shouldFlattenUniform(const TType&) const;
+    TIntermTyped* flattenAccess(int uniqueId, int member, const TType&);
+    bool shouldFlatten(const TType&) const;
     bool wasFlattened(const TIntermTyped* node) const;
     bool wasFlattened(int id) const { return flattenMap.find(id) != flattenMap.end(); }
     int  addFlattenedMember(const TSourceLoc& loc, const TVariable&, const TType&, TFlattenData&, const TString& name, bool track);
     bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); }
 
-    // Structure splitting (splits interstage builtin types into its own struct)
+    // Structure splitting (splits interstage built-in types into its own struct)
     TIntermTyped* splitAccessStruct(const TSourceLoc& loc, TIntermTyped*& base, int& member);
     void splitAccessArray(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index);
     TType& split(TType& type, TString name, const TType* outerStructType = nullptr);

+ 1 - 1
3rdparty/glslang/hlsl/hlslParseables.cpp

@@ -502,7 +502,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
     static const EShLanguageMask EShLangAll    = EShLanguageMask(EShLangCount - 1);
 
     // These are the actual stage masks defined in the documentation, in case they are
-    // needed for furture validation.  For now, they are commented out, and set below
+    // needed for future validation.  For now, they are commented out, and set below
     // to EShLangAll, to allow any intrinsic to be used in any shader, which is legal
     // if it is not called.
     //

+ 1 - 8
tools/shaderc/shaderc_spirv.cpp

@@ -12,8 +12,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
 #include <ShaderLang.h>
 #include <ResourceLimits.h>
 #include <SPIRV/SPVRemapper.h>
-//#include <spirv-tools/libspirv.hpp>
-//#include <spirv-tools/optimizer.hpp>
+#include <SPIRV/GlslangToSpv.h>
 BX_PRAGMA_DIAGNOSTIC_POP()
 
 namespace bgfx
@@ -50,12 +49,6 @@ namespace stl = tinystl;
 
 #include "../../src/shader_spirv.h"
 
-namespace glslang
-{
-	void GlslangToSpv(const glslang::TIntermediate& _intermediate, std::vector<uint32_t>& _spirv);
-
-} // namespace glslang
-
 namespace bgfx { namespace spirv
 {
 	const TBuiltInResource resourceLimits =