Jelajahi Sumber

Updated glslang.

Branimir Karadžić 8 tahun lalu
induk
melakukan
0fe39f5cf9
25 mengubah file dengan 1691 tambahan dan 424 penghapusan
  1. 1 1
      3rdparty/glslang/SPIRV/GLSL.ext.AMD.h
  2. 8 28
      3rdparty/glslang/SPIRV/GlslangToSpv.cpp
  3. 232 255
      3rdparty/glslang/StandAlone/StandAlone.cpp
  4. 55 0
      3rdparty/glslang/Test/baseResults/glsl.-D-U.frag.out
  5. 65 0
      3rdparty/glslang/Test/baseResults/hlsl.-D-U.frag.out
  6. 381 0
      3rdparty/glslang/Test/baseResults/hlsl.constructArray.vert.out
  7. 14 10
      3rdparty/glslang/Test/baseResults/hlsl.intrinsics.negative.frag.out
  8. 506 0
      3rdparty/glslang/Test/baseResults/hlsl.scalar2matrix.frag.out
  9. 33 34
      3rdparty/glslang/Test/baseResults/hlsl.type.half.frag.out
  10. 69 42
      3rdparty/glslang/Test/baseResults/hlsl.type.identifier.frag.out
  11. 0 3
      3rdparty/glslang/Test/baseResults/spv.450.tesc.out
  12. 32 0
      3rdparty/glslang/Test/glsl.-D-U.frag
  13. 31 0
      3rdparty/glslang/Test/hlsl.-D-U.frag
  14. 10 0
      3rdparty/glslang/Test/hlsl.constructArray.vert
  15. 28 0
      3rdparty/glslang/Test/hlsl.scalar2matrix.frag
  16. 1 0
      3rdparty/glslang/Test/hlsl.type.identifier.frag
  17. 8 0
      3rdparty/glslang/Test/runtests
  18. 26 0
      3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp
  19. 3 0
      3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
  20. 11 8
      3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp
  21. 2 0
      3rdparty/glslang/gtests/Hlsl.FromFile.cpp
  22. 64 34
      3rdparty/glslang/hlsl/hlslGrammar.cpp
  23. 4 1
      3rdparty/glslang/hlsl/hlslGrammar.h
  24. 106 8
      3rdparty/glslang/hlsl/hlslParseHelper.cpp
  25. 1 0
      3rdparty/glslang/hlsl/hlslParseHelper.h

+ 1 - 1
3rdparty/glslang/SPIRV/GLSL.ext.AMD.h

@@ -117,7 +117,7 @@ static const char* const E_SPV_AMD_gpu_shader_half_float = "SPV_AMD_gpu_shader_h
 // SPV_AMD_texture_gather_bias_lod
 static const char* const E_SPV_AMD_texture_gather_bias_lod = "SPV_AMD_texture_gather_bias_lod";
 
-static const Capability OpCapabilityImageGatherBiasLodAMD = static_cast<Capability>(5009);
+static const Capability CapabilityImageGatherBiasLodAMD = static_cast<Capability>(5009);
 
 // SPV_AMD_gpu_shader_int16
 static const char* const E_SPV_AMD_gpu_shader_int16 = "SPV_AMD_gpu_shader_int16";

+ 8 - 28
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -2431,7 +2431,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
     // Create a vector of struct types for SPIR-V to consume
     std::vector<spv::Id> spvMembers;
     int memberDelta = 0;  // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
-    int locationOffset = 0;  // for use across struct members, when they are called recursively
     for (int i = 0; i < (int)glslangMembers->size(); i++) {
         glslang::TType& glslangMember = *(*glslangMembers)[i].type;
         if (glslangMember.hiddenMember()) {
@@ -2448,11 +2447,9 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
             glslang::TQualifier memberQualifier = glslangMember.getQualifier();
             InheritQualifiers(memberQualifier, qualifier);
 
-            // manually inherit location; it's more complex
+            // manually inherit location
             if (! memberQualifier.hasLocation() && qualifier.hasLocation())
-                memberQualifier.layoutLocation = qualifier.layoutLocation + locationOffset;
-            if (qualifier.hasLocation())
-                locationOffset += glslangIntermediate->computeTypeLocationSize(glslangMember);
+                memberQualifier.layoutLocation = qualifier.layoutLocation;
 
             // recurse
             spvMembers.push_back(convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier));
@@ -2515,29 +2512,12 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
                     addMemberDecoration(spvType, member, memory[i]);
             }
 
-            // Compute location decoration; tricky based on whether inheritance is at play and
-            // what kind of container we have, etc.
-            // TODO: This algorithm (and it's cousin above doing almost the same thing) should
-            //       probably move to the linker stage of the front end proper, and just have the
-            //       answer sitting already distributed throughout the individual member locations.
-            int location = -1;                // will only decorate if present or inherited
+            // Location assignment was already completed correctly by the front end,
+            // just track whether a member needs to be decorated.
             // Ignore member locations if the container is an array, as that's
-            // ill-specified and decisions have been made to not allow this anyway.
-            // The object itself must have a location, and that comes out from decorating the object,
-            // not the type (this code decorates types).
-            if (! type.isArray()) {
-                if (memberQualifier.hasLocation()) { // no inheritance, or override of inheritance
-                    // struct members should not have explicit locations
-                    assert(type.getBasicType() != glslang::EbtStruct);
-                    location = memberQualifier.layoutLocation;
-                } else if (type.getBasicType() != glslang::EbtBlock) {
-                    // If it is a not a Block, (...) Its members are assigned consecutive locations (...)
-                    // The members, and their nested types, must not themselves have Location decorations.
-                } else if (qualifier.hasLocation()) // inheritance
-                    location = qualifier.layoutLocation + locationOffset;
-            }
-            if (location >= 0)
-                builder.addMemberDecoration(spvType, member, spv::DecorationLocation, location);
+            // ill-specified and decisions have been made to not allow this.
+            if (! type.isArray() && memberQualifier.hasLocation())
+                builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
 
             if (qualifier.hasLocation())      // track for upcoming inheritance
                 locationOffset += glslangIntermediate->computeTypeLocationSize(glslangMember);
@@ -3294,7 +3274,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
         if (bias || cracked.lod ||
             sourceExtensions.find(glslang::E_GL_AMD_texture_gather_bias_lod) != sourceExtensions.end()) {
             builder.addExtension(spv::E_SPV_AMD_texture_gather_bias_lod);
-            builder.addCapability(spv::OpCapabilityImageGatherBiasLodAMD);
+            builder.addCapability(spv::CapabilityImageGatherBiasLodAMD);
         }
     }
 #endif

+ 232 - 255
3rdparty/glslang/StandAlone/StandAlone.cpp

@@ -115,18 +115,14 @@ enum TFailCode {
 EShLanguage FindLanguage(const std::string& name, bool parseSuffix=true);
 void CompileFile(const char* fileName, ShHandle);
 void usage();
-void FreeFileData(char** data);
-char** ReadFileData(const char* fileName);
+char* ReadFileData(const char* fileName);
+void FreeFileData(char* data);
 void InfoLogMsg(const char* msg, const char* name, const int num);
 
 // Globally track if any compile or link failure.
 bool CompileFailed = false;
 bool LinkFailed = false;
 
-// Use to test breaking up a single shader file into multiple strings.
-// Set in ReadFileData().
-int NumShaderStrings;
-
 TBuiltInResource Resources;
 std::string ConfigFile;
 
@@ -135,29 +131,13 @@ std::string ConfigFile;
 //
 void ProcessConfigFile()
 {
-    char** configStrings = 0;
-    char* config = 0;
-    if (ConfigFile.size() > 0) {
-        configStrings = ReadFileData(ConfigFile.c_str());
-        if (configStrings)
-            config = *configStrings;
-        else {
-            printf("Error opening configuration file; will instead use the default configuration\n");
-            usage();
-        }
-    }
-
-    if (config == 0) {
+    if (ConfigFile.size() == 0)
         Resources = glslang::DefaultTBuiltInResource;
-        return;
+    else {
+        char* configString = ReadFileData(ConfigFile.c_str());
+        glslang::DecodeResourceLimits(&Resources,  configString);
+        FreeFileData(configString);
     }
-
-    glslang::DecodeResourceLimits(&Resources,  config);
-
-    if (configStrings)
-        FreeFileData(configStrings);
-    else
-        delete[] config;
 }
 
 int Options = 0;
@@ -177,6 +157,53 @@ std::array<unsigned int, EShLangCount> baseSsboBinding;
 std::array<unsigned int, EShLangCount> baseUavBinding;
 std::array<std::vector<std::string>, EShLangCount> baseResourceSetBinding;
 
+
+// Add things like "#define ..." to a preamble to use in the beginning of the shader.
+class TPreamble {
+public:
+    TPreamble() { }
+
+    bool isSet() const { return text.size() > 0; }
+    const char* get() const { return text.c_str(); }
+
+    // #define...
+    void addDef(std::string def)
+    {
+        text.append("#define ");
+        fixLine(def);
+
+        // The first "=" needs to turn into a space
+        int equal = def.find_first_of("=");
+        if (equal != def.npos)
+            def[equal] = ' ';
+
+        text.append(def);
+        text.append("\n");
+    }
+
+    // #undef...
+    void addUndef(std::string undef)
+    {
+        text.append("#undef ");
+        fixLine(undef);
+        text.append(undef);
+        text.append("\n");
+    }
+
+protected:
+    void fixLine(std::string& line)
+    {
+        // Can't go past a newline in the line
+        int end = line.find_first_of("\n");
+        if (end != line.npos)
+            line = line.substr(0, end);
+    }
+
+    std::string text;  // contents of preamble
+};
+
+TPreamble UserPreamble;
+
 //
 // Create the default name for saving a binary if -o is not provided.
 //
@@ -310,6 +337,14 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
     ExecutableName = argv[0];
     workItems.reserve(argc);
 
+    const auto getStringOperand = [&](const char* desc) {
+        if (argv[0][2] == 0) {
+            printf("%s must immediately follow option (no spaces)\n", desc);
+            exit(EFailUsage);
+        }
+        return argv[0] + 2;
+    };
+
     argc--;
     argv++;
     for (; argc >= 1; argc--, argv++) {
@@ -321,18 +356,49 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                     std::transform(lowerword.begin(), lowerword.end(), lowerword.begin(), ::tolower);
 
                     // handle --word style options
-                    if (lowerword == "shift-sampler-bindings" || // synonyms
+                    if (lowerword == "auto-map-bindings" ||  // synonyms
+                               lowerword == "auto-map-binding"  ||
+                               lowerword == "amb") {
+                        Options |= EOptionAutoMapBindings;
+                    } else if (lowerword == "auto-map-locations" || // synonyms
+                               lowerword == "aml") {
+                        Options |= EOptionAutoMapLocations;
+                    } else if (lowerword == "flatten-uniform-arrays" || // synonyms
+                               lowerword == "flatten-uniform-array"  ||
+                               lowerword == "fua") {
+                        Options |= EOptionFlattenUniformArrays;
+                    } else if (lowerword == "hlsl-offsets") {
+                        Options |= EOptionHlslOffsets;
+                    } else if (lowerword == "hlsl-iomap" ||
+                               lowerword == "hlsl-iomapper" ||
+                               lowerword == "hlsl-iomapping") {
+                        Options |= EOptionHlslIoMapping;
+                    } else if (lowerword == "keep-uncalled" || // synonyms
+                               lowerword == "ku") {
+                        Options |= EOptionKeepUncalled;
+                    } else if (lowerword == "no-storage-format" || // synonyms
+                               lowerword == "nsf") {
+                        Options |= EOptionNoStorageFormat;
+                    } else if (lowerword == "resource-set-bindings" ||  // synonyms
+                               lowerword == "resource-set-binding"  ||
+                               lowerword == "rsb") {
+                        ProcessResourceSetBindingBase(argc, argv, baseResourceSetBinding);
+                    } else if (lowerword == "shift-image-bindings" ||  // synonyms
+                               lowerword == "shift-image-binding"  ||
+                               lowerword == "sib") {
+                        ProcessBindingBase(argc, argv, baseImageBinding);
+                    } else if (lowerword == "shift-sampler-bindings" || // synonyms
                         lowerword == "shift-sampler-binding"  ||
                         lowerword == "ssb") {
                         ProcessBindingBase(argc, argv, baseSamplerBinding);
+                    } else if (lowerword == "shift-uav-bindings" ||  // synonyms
+                               lowerword == "shift-uav-binding"  ||
+                               lowerword == "suavb") {
+                        ProcessBindingBase(argc, argv, baseUavBinding);
                     } else if (lowerword == "shift-texture-bindings" ||  // synonyms
                                lowerword == "shift-texture-binding"  ||
                                lowerword == "stb") {
                         ProcessBindingBase(argc, argv, baseTextureBinding);
-                    } else if (lowerword == "shift-image-bindings" ||  // synonyms
-                               lowerword == "shift-image-binding"  ||
-                               lowerword == "sib") {
-                        ProcessBindingBase(argc, argv, baseImageBinding);
                     } else if (lowerword == "shift-ubo-bindings" ||  // synonyms
                                lowerword == "shift-ubo-binding"  ||
                                lowerword == "shift-cbuffer-bindings" ||
@@ -344,61 +410,48 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                                lowerword == "shift-ssbo-binding"  ||
                                lowerword == "sbb") {
                         ProcessBindingBase(argc, argv, baseSsboBinding);
-                    } else if (lowerword == "resource-set-bindings" ||  // synonyms
-                               lowerword == "resource-set-binding"  ||
-                               lowerword == "rsb") {
-                        ProcessResourceSetBindingBase(argc, argv, baseResourceSetBinding);
-                    } else if (lowerword == "shift-uav-bindings" ||  // synonyms
-                               lowerword == "shift-uav-binding"  ||
-                               lowerword == "suavb") {
-                        ProcessBindingBase(argc, argv, baseUavBinding);
-                    } else if (lowerword == "auto-map-bindings" ||  // synonyms
-                               lowerword == "auto-map-binding"  ||
-                               lowerword == "amb") {
-                        Options |= EOptionAutoMapBindings;
-                    } else if (lowerword == "flatten-uniform-arrays" || // synonyms
-                               lowerword == "flatten-uniform-array"  ||
-                               lowerword == "fua") {
-                        Options |= EOptionFlattenUniformArrays;
-                    } else if (lowerword == "no-storage-format" || // synonyms
-                               lowerword == "nsf") {
-                        Options |= EOptionNoStorageFormat;
-                    } else if (lowerword == "variable-name" || // synonyms
-                        lowerword == "vn") {
-                        Options |= EOptionOutputHexadecimal;
-                        variableName = argv[1];
+                    } else if (lowerword == "source-entrypoint" || // synonyms
+                               lowerword == "sep") {
+                        sourceEntryPointName = argv[1];
                         if (argc > 0) {
                             argc--;
                             argv++;
                         } else
-                            Error("no <C-variable-name> provided for --variable-name");
+                            Error("no <entry-point> provided for --source-entrypoint");
                         break;
-                    } else if (lowerword == "source-entrypoint" || // synonyms
-                               lowerword == "sep") {
-                        sourceEntryPointName = argv[1];
+                    } else if (lowerword == "variable-name" || // synonyms
+                        lowerword == "vn") {
+                        Options |= EOptionOutputHexadecimal;
+                        variableName = argv[1];
                         if (argc > 0) {
                             argc--;
                             argv++;
                         } else
-                            Error("no <entry-point> provided for --source-entrypoint");
+                            Error("no <C-variable-name> provided for --variable-name");
                         break;
-                    } else if (lowerword == "keep-uncalled" || // synonyms
-                               lowerword == "ku") {
-                        Options |= EOptionKeepUncalled;
-                    } else if (lowerword == "hlsl-offsets") {
-                        Options |= EOptionHlslOffsets;
-                    } else if (lowerword == "hlsl-iomap" ||
-                               lowerword == "hlsl-iomapper" ||
-                               lowerword == "hlsl-iomapping") {
-                        Options |= EOptionHlslIoMapping;
-                    } else if (lowerword == "auto-map-locations" || // synonyms
-                               lowerword == "aml") {
-                        Options |= EOptionAutoMapLocations;
                     } else {
                         usage();
                     }
                 }
                 break;
+            case 'C':
+                Options |= EOptionCascadingErrors;
+                break;
+            case 'D':
+                if (argv[0][2] == 0)
+                    Options |= EOptionReadHlsl;
+                else
+                    UserPreamble.addDef(getStringOperand("-D<macro> macro name"));
+                break;
+            case 'E':
+                Options |= EOptionOutputPreprocessed;
+                break;
+            case 'G':
+                Options |= EOptionSpv;
+                Options |= EOptionLinkProgram;
+                // undo a -H default to Vulkan
+                Options &= ~EOptionVulkanRules;
+                break;
             case 'H':
                 Options |= EOptionHumanReadableSpv;
                 if ((Options & EOptionSpv) == 0) {
@@ -409,16 +462,7 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                 }
                 break;
             case 'I':
-                if (argv[0][2] == 0) {
-                    printf("include path must immediately follow (no spaces) -I\n");
-                    exit(EFailUsage);
-                }
-                IncludeDirectoryList.push_back(argv[0]+2);
-                break;
-            case 'V':
-                Options |= EOptionSpv;
-                Options |= EOptionVulkanRules;
-                Options |= EOptionLinkProgram;
+                IncludeDirectoryList.push_back(getStringOperand("-I<dir> include path"));
                 break;
             case 'S':
                 shaderStageName = argv[1];
@@ -428,27 +472,20 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                 } else
                     Error("no <stage> specified for -S");
                 break;
-            case 'G':
+            case 'U':
+                UserPreamble.addUndef(getStringOperand("-U<macro>: macro name"));
+                break;
+            case 'V':
                 Options |= EOptionSpv;
+                Options |= EOptionVulkanRules;
                 Options |= EOptionLinkProgram;
-                // undo a -H default to Vulkan
-                Options &= ~EOptionVulkanRules;
-                break;
-            case 'E':
-                Options |= EOptionOutputPreprocessed;
                 break;
             case 'c':
                 Options |= EOptionDumpConfig;
                 break;
-            case 'C':
-                Options |= EOptionCascadingErrors;
-                break;
             case 'd':
                 Options |= EOptionDefaultDesktop;
                 break;
-            case 'D':
-                Options |= EOptionReadHlsl;
-                break;
             case 'e':
                 // HLSL todo: entry point handle needs much more sophistication.
                 // This is okay for one compilation unit with one entry point.
@@ -590,36 +627,41 @@ void PutsIfNonEmpty(const char* str)
 // This prevents erroneous newlines from appearing.
 void StderrIfNonEmpty(const char* str)
 {
-    if (str && str[0]) {
-      fprintf(stderr, "%s\n", str);
-    }
+    if (str && str[0])
+        fprintf(stderr, "%s\n", str);
 }
 
 // Simple bundling of what makes a compilation unit for ease in passing around,
 // and separation of handling file IO versus API (programmatic) compilation.
 struct ShaderCompUnit {
     EShLanguage stage;
-    std::string fileName;
-    char** text;             // memory owned/managed externally
-    const char* fileNameList[1];
+    static const int maxCount = 1;
+    int count;                          // live number of strings/names
+    const char* text[maxCount];         // memory owned/managed externally
+    std::string fileName[maxCount];     // hold's the memory, but...
+    const char* fileNameList[maxCount]; // downstream interface wants pointers
 
-    // Need to have a special constructors to adjust the fileNameList, since back end needs a list of ptrs
-    ShaderCompUnit(EShLanguage istage, std::string &ifileName, char** itext)
-    {
-        stage = istage;
-        fileName = ifileName;
-        text = itext;
-        fileNameList[0] = fileName.c_str();
-    }
+    ShaderCompUnit(EShLanguage stage) : stage(stage), count(0) { }
 
-    ShaderCompUnit(const ShaderCompUnit &rhs)
+    ShaderCompUnit(const ShaderCompUnit& rhs)
     {
         stage = rhs.stage;
-        fileName = rhs.fileName;
-        text = rhs.text;
-        fileNameList[0] = fileName.c_str();
+        count = rhs.count;
+        for (int i = 0; i < count; ++i) {
+            fileName[i] = rhs.fileName[i];
+            text[i] = rhs.text[i];
+            fileNameList[i] = rhs.fileName[i].c_str();
+        }
     }
 
+    void addString(std::string& ifileName, const char* itext)
+    {
+        assert(count < maxCount);
+        fileName[count] = ifileName;
+        text[count] = itext;
+        fileNameList[count] = fileName[count].c_str();
+        ++count;
+    }
 };
 
 //
@@ -646,11 +688,13 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
     for (auto it = compUnits.cbegin(); it != compUnits.cend(); ++it) {
         const auto &compUnit = *it;
         glslang::TShader* shader = new glslang::TShader(compUnit.stage);
-        shader->setStringsWithLengthsAndNames(compUnit.text, NULL, compUnit.fileNameList, 1);
+        shader->setStringsWithLengthsAndNames(compUnit.text, NULL, compUnit.fileNameList, compUnit.count);
         if (entryPointName) // HLSL todo: this needs to be tracked per compUnits
             shader->setEntryPoint(entryPointName);
         if (sourceEntryPointName)
             shader->setSourceEntryPoint(sourceEntryPointName);
+        if (UserPreamble.isSet())
+            shader->setPreamble(UserPreamble.get());
 
         shader->setShiftSamplerBinding(baseSamplerBinding[compUnit.stage]);
         shader->setShiftTextureBinding(baseTextureBinding[compUnit.stage]);
@@ -697,7 +741,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
 
         if (! (Options & EOptionSuppressInfolog) &&
             ! (Options & EOptionMemoryLeakMode)) {
-            PutsIfNonEmpty(compUnit.fileName.c_str());
+            PutsIfNonEmpty(compUnit.fileName[0].c_str());
             PutsIfNonEmpty(shader->getInfoLog());
             PutsIfNonEmpty(shader->getInfoDebugLog());
         }
@@ -798,17 +842,11 @@ void CompileAndLinkShaderFiles(glslang::TWorklist& Worklist)
     // they are all getting linked together.)
     glslang::TWorkItem* workItem;
     while (Worklist.remove(workItem)) {
-        ShaderCompUnit compUnit(
-            FindLanguage(workItem->name),
-            workItem->name,
-            ReadFileData(workItem->name.c_str())
-        );
-
-        if (! compUnit.text) {
+        ShaderCompUnit compUnit(FindLanguage(workItem->name));
+        char* fileText = ReadFileData(workItem->name.c_str());
+        if (fileText == nullptr)
             usage();
-            return;
-        }
-
+        compUnit.addString(workItem->name, fileText);
         compUnits.push_back(compUnit);
     }
 
@@ -823,8 +861,10 @@ void CompileAndLinkShaderFiles(glslang::TWorklist& Worklist)
             glslang::OS_DumpMemoryCounters();
     }
 
+    // free memory from ReadFileData, which got stored in a const char*
+    // as the first string above
     for (auto it = compUnits.begin(); it != compUnits.end(); ++it)
-        FreeFileData(it->text);
+        FreeFileData(const_cast<char*>(it->text[0]));
 }
 
 int C_DECL main(int argc, char* argv[])
@@ -974,29 +1014,22 @@ EShLanguage FindLanguage(const std::string& name, bool parseSuffix)
 void CompileFile(const char* fileName, ShHandle compiler)
 {
     int ret = 0;
-    char** shaderStrings = ReadFileData(fileName);
-    if (! shaderStrings) {
-        usage();
-    }
-
-    int* lengths = new int[NumShaderStrings];
+    char* shaderString = ReadFileData(fileName);
 
     // move to length-based strings, rather than null-terminated strings
-    for (int s = 0; s < NumShaderStrings; ++s)
-        lengths[s] = (int)strlen(shaderStrings[s]);
-
-    if (! shaderStrings) {
-        CompileFailed = true;
-        return;
-    }
+    int* lengths = new int[1];
+    lengths[0] = (int)strlen(shaderString);
 
     EShMessages messages = EShMsgDefault;
     SetMessageOptions(messages);
 
+    if (UserPreamble.isSet())
+        Error("-D and -U options require -l (linking)\n");
+
     for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
         for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
             // ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
-            ret = ShCompile(compiler, shaderStrings, NumShaderStrings, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
+            ret = ShCompile(compiler, &shaderString, 1, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
             // const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err",
             //                         "or should be l", "ine 1", "string 5\n", "float glo", "bal",
             //                         ";\n#error should be line 2\n void main() {", "global = 2.3;}" };
@@ -1009,7 +1042,7 @@ void CompileFile(const char* fileName, ShHandle compiler)
     }
 
     delete [] lengths;
-    FreeFileData(shaderStrings);
+    FreeFileData(shaderString);
 
     if (ret == 0)
         CompileFailed = true;
@@ -1022,8 +1055,8 @@ void usage()
 {
     printf("Usage: glslangValidator [option]... [file]...\n"
            "\n"
-           "Where: each 'file' ends in .<stage>, where <stage> is one of\n"
-           "    .conf   to provide an optional config file that replaces the default configuration\n"
+           "'file' can end in .<stage> for auto-stage classification, where <stage> is:\n"
+           "    .conf   to provide a config file that replaces the default configuration\n"
            "            (see -c option below for generating a template)\n"
            "    .vert   for a vertex shader\n"
            "    .tesc   for a tessellation control shader\n"
@@ -1032,27 +1065,27 @@ void usage()
            "    .frag   for a fragment shader\n"
            "    .comp   for a compute shader\n"
            "\n"
-           "Compilation warnings and errors will be printed to stdout.\n"
-           "\n"
-           "To get other information, use one of the following options:\n"
-           "Each option must be specified separately.\n"
-           "  -V          create SPIR-V binary, under Vulkan semantics; turns on -l;\n"
-           "              default file name is <stage>.spv (-o overrides this)\n"
+           "Options:\n"
+           "  -C          cascading errors; risk crash from accumulation of error recoveries\n"
+           "  -D          input is HLSL\n"
+           "  -D<macro=def>\n"
+           "  -D<macro>   define a pre-processor macro\n"
+           "  -E          print pre-processed GLSL; cannot be used with -l;\n"
+           "              errors will appear on stderr.\n"
            "  -G          create SPIR-V binary, under OpenGL semantics; turns on -l;\n"
            "              default file name is <stage>.spv (-o overrides this)\n"
            "  -H          print human readable form of SPIR-V; turns on -V\n"
            "  -I<dir>     add dir to the include search path; includer's directory\n"
            "              is searched first, followed by left-to-right order of -I\n"
-           "  -E          print pre-processed GLSL; cannot be used with -l;\n"
-           "              errors will appear on stderr.\n"
            "  -S <stage>  uses specified stage rather than parsing the file extension\n"
-           "              valid choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
+           "              choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
+           "  -U<macro>   undefine a pre-precossor macro\n"
+           "  -V          create SPIR-V binary, under Vulkan semantics; turns on -l;\n"
+           "              default file name is <stage>.spv (-o overrides this)\n"
            "  -c          configuration dump;\n"
            "              creates the default configuration file (redirect to a .conf file)\n"
-           "  -C          cascading errors; risks crashes from accumulation of error recoveries\n"
            "  -d          default to desktop (#version 110) when there is no shader #version\n"
            "              (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"
@@ -1066,59 +1099,46 @@ void usage()
            "  -t          multi-threaded mode\n"
            "  -v          print version strings\n"
            "  -w          suppress warnings (except as required by #extension : warn)\n"
-           "  -x          save 32-bit hexadecimal numbers as text, requires a binary option (e.g., -V)\n"
-           "\n"
-           "  --shift-sampler-binding [stage] num     set base binding number for samplers\n"
-           "  --ssb [stage] num                       synonym for --shift-sampler-binding\n"
-           "\n"
-           "  --shift-texture-binding [stage] num     set base binding number for textures\n"
-           "  --stb [stage] num                       synonym for --shift-texture-binding\n"
-           "\n"
-           "  --shift-image-binding [stage] num       set base binding number for images (uav)\n"
-           "  --sib [stage] num                       synonym for --shift-image-binding\n"
+           "  -x          save binary output as text-based 32-bit hexadecimal numbers\n"
+           "  --auto-map-bindings                  automatically bind uniform variables\n"
+           "                                       without explicit bindings.\n"
+           "  --amb                                synonym for --auto-map-bindings\n"
+           "  --auto-map-locations                 automatically locate input/output lacking\n"
+           "                                       'location'\n (fragile, not cross stage)\n"
+           "  --aml                                synonym for --auto-map-locations\n"
+           "  --flatten-uniform-arrays             flatten uniform texture/sampler arrays to\n"
+           "                                       scalars\n"
+           "  --fua                                synonym for --flatten-uniform-arrays\n"
            "\n"
-           "  --shift-UBO-binding [stage] num         set base binding number for UBOs\n"
-           "  --shift-cbuffer-binding [stage] num     synonym for --shift-UBO-binding\n"
-           "  --sub [stage] num                       synonym for --shift-UBO-binding\n"
-           "\n"
-           "  --shift-ssbo-binding [stage] num        set base binding number for SSBOs\n"
-           "  --sbb [stage] num                       synonym for --shift-ssbo-binding\n"
-           "\n"
-           "  --resource-set-binding [stage] num      set descriptor set and binding number for resources\n"
-           "  --rsb [stage] type set binding          synonym for --resource-set-binding\n"
-           "\n"
-           "  --shift-uav-binding [stage] num         set base binding number for UAVs\n"
-           "  --suavb [stage] num                     synonym for --shift-uav-binding\n"
-           "\n"
-           "  --auto-map-bindings                     automatically bind uniform variables without\n"
-           "                                          explicit bindings.\n"
-           "  --amb                                   synonym for --auto-map-bindings\n"
-           "\n"
-           "  --auto-map-locations                    automatically locate input/output lacking 'location'\n"
-           "                                          (fragile, not cross stage: recommend explicit\n"
-           "                                          'location' use in shader)\n"
-           "  --aml                                   synonym for --auto-map-locations\n"
-           "\n"
-           "  --flatten-uniform-arrays                flatten uniform texture & sampler arrays to scalars\n"
-           "  --fua                                   synonym for --flatten-uniform-arrays\n"
-           "\n"
-           "  --no-storage-format                     use Unknown image format\n"
-           "  --nsf                                   synonym for --no-storage-format\n"
-           "\n"
-           "  --source-entrypoint name                the given shader source function is renamed to be the entry point given in -e\n"
-           "  --sep                                   synonym for --source-entrypoint\n"
-           "\n"
-           "  --keep-uncalled                         don't eliminate uncalled functions when linking\n"
-           "  --ku                                    synonym for --keep-uncalled\n"
-           "\n"
-           "  --variable-name <name>                  Creates a C header file that contains a uint32_t array named <name>\n"
-           "                                          initialized with the shader binary code.\n"
-           "  --vn <name>                             synonym for --variable-name <name>\n"
-           "\n"
-           "  --hlsl-offsets                          Allow block offsets to follow HLSL rules instead of GLSL rules.\n"
-           "                                          Works independently of source language.\n"
-           "\n"
-           "  --hlsl-iomap                            Perform IO mapping in HLSL register space.\n"
+           "  --hlsl-offsets                       Allow block offsets to follow HLSL rules\n"
+           "                                       Works independently of source language\n"
+           "  --hlsl-iomap                         Perform IO mapping in HLSL register space\n"
+           "  --keep-uncalled                      don't eliminate uncalled functions\n"
+           "  --ku                                 synonym for --keep-uncalled\n"
+           "  --no-storage-format                  use Unknown image format\n"
+           "  --nsf                                synonym for --no-storage-format\n"
+           "  --resource-set-binding [stage] num   descriptor set and binding for resources\n"
+           "  --rsb [stage] type set binding       synonym for --resource-set-binding\n"
+           "  --shift-image-binding [stage] num    base binding number for images (uav)\n"
+           "  --sib [stage] num                    synonym for --shift-image-binding\n"
+           "  --shift-sampler-binding [stage] num  base binding number for samplers\n"
+           "  --ssb [stage] num                    synonym for --shift-sampler-binding\n"
+           "  --shift-ssbo-binding [stage] num     base binding number for SSBOs\n"
+           "  --sbb [stage] num                    synonym for --shift-ssbo-binding\n"
+           "  --shift-texture-binding [stage] num  base binding number for textures\n"
+           "  --stb [stage] num                    synonym for --shift-texture-binding\n"
+           "  --shift-uav-binding [stage] num      base binding number for UAVs\n"
+           "  --suavb [stage] num                  synonym for --shift-uav-binding\n"
+           "  --shift-UBO-binding [stage] num      base binding number for UBOs\n"
+           "  --shift-cbuffer-binding [stage] num  synonym for --shift-UBO-binding\n"
+           "  --sub [stage] num                    synonym for --shift-UBO-binding\n"
+           "  --source-entrypoint name             the given shader source function is\n"
+           "                                       renamed to be the entry point given in -e\n"
+           "  --sep                                synonym for --source-entrypoint\n"
+           "  --variable-name <name>               Creates a C header file that contains a\n"
+           "                                       uint32_t array named <name>\n"
+           "                                       initialized with the shader binary code.\n"
+           "  --vn <name>                          synonym for --variable-name <name>\n"
            );
 
     exit(EFailUsage);
@@ -1156,76 +1176,33 @@ int fopen_s(
 //
 //   Malloc a string of sufficient size and read a string into it.
 //
-char** ReadFileData(const char* fileName)
+char* ReadFileData(const char* fileName)
 {
     FILE *in = nullptr;
     int errorCode = fopen_s(&in, fileName, "r");
-
-    int count = 0;
-    const int maxSourceStrings = 5;  // for testing splitting shader/tokens across multiple strings
-    char** return_data = (char**)malloc(sizeof(char *) * (maxSourceStrings+1)); // freed in FreeFileData()
-
     if (errorCode || in == nullptr)
         Error("unable to open input file");
 
+    int count = 0;
     while (fgetc(in) != EOF)
         count++;
 
     fseek(in, 0, SEEK_SET);
 
-    char *fdata = (char*)malloc(count+2); // freed before return of this function
-    if (! fdata)
-        Error("can't allocate memory");
-
-    if ((int)fread(fdata, 1, count, in) != count) {
-        free(fdata);
+    char* return_data = (char*)malloc(count + 1);  // freed in FreeFileData()
+    if ((int)fread(return_data, 1, count, in) != count) {
+        free(return_data);
         Error("can't read input file");
     }
 
-    fdata[count] = '\0';
+    return_data[count] = '\0';
     fclose(in);
 
-    if (count == 0) {
-        // recover from empty file
-        return_data[0] = (char*)malloc(count+2);  // freed in FreeFileData()
-        return_data[0][0]='\0';
-        NumShaderStrings = 0;
-        free(fdata);
-
-        return return_data;
-    } else
-        NumShaderStrings = 1;  // Set to larger than 1 for testing multiple strings
-
-    // compute how to split up the file into multiple strings, for testing multiple strings
-    int len = (int)(ceil)((float)count/(float)NumShaderStrings);
-    int ptr_len = 0;
-    int i = 0;
-    while (count > 0) {
-        return_data[i] = (char*)malloc(len + 2);  // freed in FreeFileData()
-        memcpy(return_data[i], fdata + ptr_len, len);
-        return_data[i][len] = '\0';
-        count -= len;
-        ptr_len += len;
-        if (count < len) {
-            if (count == 0) {
-               NumShaderStrings = i + 1;
-               break;
-            }
-            len = count;
-        }
-        ++i;
-    }
-
-    free(fdata);
-
     return return_data;
 }
 
-void FreeFileData(char** data)
+void FreeFileData(char* data)
 {
-    for(int i = 0; i < NumShaderStrings; i++)
-        free(data[i]);
-
     free(data);
 }
 

+ 55 - 0
3rdparty/glslang/Test/baseResults/glsl.-D-U.frag.out

@@ -0,0 +1,55 @@
+glsl.-D-U.frag
+Shader version: 450
+0:? Sequence
+0:7  Function Definition: main( ( global void)
+0:7    Function Parameters: 
+0:10    Sequence
+0:10      move second child to first child ( temp 4-component vector of float)
+0:10        'color' (layout( location=0) out 4-component vector of float)
+0:10        Constant:
+0:10          1.000000
+0:10          1.000000
+0:10          1.000000
+0:10          1.000000
+0:16      Post-Increment ( temp 4-component vector of float)
+0:16        'color' (layout( location=0) out 4-component vector of float)
+0:24      vector scale second child into first child ( temp 4-component vector of float)
+0:24        'color' (layout( location=0) out 4-component vector of float)
+0:24        Constant:
+0:24          3.000000
+0:28      vector scale second child into first child ( temp 4-component vector of float)
+0:28        'color' (layout( location=0) out 4-component vector of float)
+0:28        Constant:
+0:28          400.000000
+0:?   Linker Objects
+0:?     'color' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+0:? Sequence
+0:7  Function Definition: main( ( global void)
+0:7    Function Parameters: 
+0:10    Sequence
+0:10      move second child to first child ( temp 4-component vector of float)
+0:10        'color' (layout( location=0) out 4-component vector of float)
+0:10        Constant:
+0:10          1.000000
+0:10          1.000000
+0:10          1.000000
+0:10          1.000000
+0:16      Post-Increment ( temp 4-component vector of float)
+0:16        'color' (layout( location=0) out 4-component vector of float)
+0:24      vector scale second child into first child ( temp 4-component vector of float)
+0:24        'color' (layout( location=0) out 4-component vector of float)
+0:24        Constant:
+0:24          3.000000
+0:28      vector scale second child into first child ( temp 4-component vector of float)
+0:28        'color' (layout( location=0) out 4-component vector of float)
+0:28        Constant:
+0:28          400.000000
+0:?   Linker Objects
+0:?     'color' (layout( location=0) out 4-component vector of float)
+

+ 65 - 0
3rdparty/glslang/Test/baseResults/hlsl.-D-U.frag.out

@@ -0,0 +1,65 @@
+hlsl.-D-U.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:7  Function Definition: @main( ( temp void)
+0:7    Function Parameters: 
+0:?     Sequence
+0:9      move second child to first child ( temp 4-component vector of float)
+0:9        'color' ( global 4-component vector of float)
+0:9        Constant:
+0:9          1.000000
+0:9          1.000000
+0:9          1.000000
+0:9          1.000000
+0:15      subtract second child into first child ( temp 4-component vector of float)
+0:15        'color' ( global 4-component vector of float)
+0:15        Constant:
+0:15          5.000000
+0:21      Post-Increment ( temp 4-component vector of float)
+0:21        'color' ( global 4-component vector of float)
+0:29      vector scale second child into first child ( temp 4-component vector of float)
+0:29        'color' ( global 4-component vector of float)
+0:29        Constant:
+0:29          3.000000
+0:7  Function Definition: main( ( temp void)
+0:7    Function Parameters: 
+0:?     Sequence
+0:7      Function Call: @main( ( temp void)
+0:?   Linker Objects
+0:?     'color' ( global 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:7  Function Definition: @main( ( temp void)
+0:7    Function Parameters: 
+0:?     Sequence
+0:9      move second child to first child ( temp 4-component vector of float)
+0:9        'color' ( global 4-component vector of float)
+0:9        Constant:
+0:9          1.000000
+0:9          1.000000
+0:9          1.000000
+0:9          1.000000
+0:15      subtract second child into first child ( temp 4-component vector of float)
+0:15        'color' ( global 4-component vector of float)
+0:15        Constant:
+0:15          5.000000
+0:21      Post-Increment ( temp 4-component vector of float)
+0:21        'color' ( global 4-component vector of float)
+0:29      vector scale second child into first child ( temp 4-component vector of float)
+0:29        'color' ( global 4-component vector of float)
+0:29        Constant:
+0:29          3.000000
+0:7  Function Definition: main( ( temp void)
+0:7    Function Parameters: 
+0:?     Sequence
+0:7      Function Call: @main( ( temp void)
+0:?   Linker Objects
+0:?     'color' ( global 4-component vector of float)
+

+ 381 - 0
3rdparty/glslang/Test/baseResults/hlsl.constructArray.vert.out

@@ -0,0 +1,381 @@
+hlsl.constructArray.vert
+Shader version: 500
+0:? Sequence
+0:2  Function Definition: @main( ( temp 4-component vector of float)
+0:2    Function Parameters: 
+0:?     Sequence
+0:4      Sequence
+0:4        move second child to first child ( temp 2-element array of 4-component vector of float)
+0:4          'float4_array_times' ( temp 2-element array of 4-component vector of float)
+0:4          Construct structure ( temp 2-element array of 4-component vector of float)
+0:4            Convert int to float ( temp 4-component vector of float)
+0:4              direct index ( temp 4-component vector of int)
+0:4                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:4                Constant:
+0:4                  0 (const int)
+0:4            Convert int to float ( temp 4-component vector of float)
+0:4              direct index ( temp 4-component vector of int)
+0:4                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:4                Constant:
+0:4                  1 (const int)
+0:5      Sequence
+0:5        move second child to first child ( temp 4-element array of 2-component vector of float)
+0:5          'float2_array_times2' ( temp 4-element array of 2-component vector of float)
+0:5          Construct structure ( temp 4-element array of 2-component vector of float)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    0 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    1 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    2 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    3 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    0 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    1 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    2 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    3 (const int)
+0:6      Sequence
+0:6        move second child to first child ( temp 2-element array of 4-component vector of int)
+0:6          'int4_array2' ( temp 2-element array of 4-component vector of int)
+0:6          Construct structure ( temp 2-element array of 4-component vector of int)
+0:6            direct index ( temp 4-component vector of int)
+0:6              'int4_array' ( temp 3-element array of 4-component vector of int)
+0:6              Constant:
+0:6                0 (const int)
+0:6            direct index ( temp 4-component vector of int)
+0:6              'int4_array' ( temp 3-element array of 4-component vector of int)
+0:6              Constant:
+0:6                1 (const int)
+0:7      Sequence
+0:7        move second child to first child ( temp 2-element array of int)
+0:7          'int1_array' ( temp 2-element array of int)
+0:7          Construct structure ( temp 2-element array of int)
+0:7            direct index ( temp int)
+0:7              direct index ( temp 4-component vector of int)
+0:7                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:7                Constant:
+0:7                  0 (const int)
+0:7              Constant:
+0:7                0 (const int)
+0:7            direct index ( temp int)
+0:7              direct index ( temp 4-component vector of int)
+0:7                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:7                Constant:
+0:7                  0 (const int)
+0:7              Constant:
+0:7                1 (const int)
+0:9      Branch: Return with expression
+0:9        Constant:
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:2  Function Definition: main( ( temp void)
+0:2    Function Parameters: 
+0:?     Sequence
+0:2      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' ( out 4-component vector of float Position)
+0:2        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' ( out 4-component vector of float Position)
+
+
+Linked vertex stage:
+
+
+Shader version: 500
+0:? Sequence
+0:2  Function Definition: @main( ( temp 4-component vector of float)
+0:2    Function Parameters: 
+0:?     Sequence
+0:4      Sequence
+0:4        move second child to first child ( temp 2-element array of 4-component vector of float)
+0:4          'float4_array_times' ( temp 2-element array of 4-component vector of float)
+0:4          Construct structure ( temp 2-element array of 4-component vector of float)
+0:4            Convert int to float ( temp 4-component vector of float)
+0:4              direct index ( temp 4-component vector of int)
+0:4                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:4                Constant:
+0:4                  0 (const int)
+0:4            Convert int to float ( temp 4-component vector of float)
+0:4              direct index ( temp 4-component vector of int)
+0:4                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:4                Constant:
+0:4                  1 (const int)
+0:5      Sequence
+0:5        move second child to first child ( temp 4-element array of 2-component vector of float)
+0:5          'float2_array_times2' ( temp 4-element array of 2-component vector of float)
+0:5          Construct structure ( temp 4-element array of 2-component vector of float)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    0 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    1 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    2 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    3 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    0 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    1 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    2 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    3 (const int)
+0:6      Sequence
+0:6        move second child to first child ( temp 2-element array of 4-component vector of int)
+0:6          'int4_array2' ( temp 2-element array of 4-component vector of int)
+0:6          Construct structure ( temp 2-element array of 4-component vector of int)
+0:6            direct index ( temp 4-component vector of int)
+0:6              'int4_array' ( temp 3-element array of 4-component vector of int)
+0:6              Constant:
+0:6                0 (const int)
+0:6            direct index ( temp 4-component vector of int)
+0:6              'int4_array' ( temp 3-element array of 4-component vector of int)
+0:6              Constant:
+0:6                1 (const int)
+0:7      Sequence
+0:7        move second child to first child ( temp 2-element array of int)
+0:7          'int1_array' ( temp 2-element array of int)
+0:7          Construct structure ( temp 2-element array of int)
+0:7            direct index ( temp int)
+0:7              direct index ( temp 4-component vector of int)
+0:7                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:7                Constant:
+0:7                  0 (const int)
+0:7              Constant:
+0:7                0 (const int)
+0:7            direct index ( temp int)
+0:7              direct index ( temp 4-component vector of int)
+0:7                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:7                Constant:
+0:7                  0 (const int)
+0:7              Constant:
+0:7                1 (const int)
+0:9      Branch: Return with expression
+0:9        Constant:
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:2  Function Definition: main( ( temp void)
+0:2    Function Parameters: 
+0:?     Sequence
+0:2      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' ( out 4-component vector of float Position)
+0:2        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' ( out 4-component vector of float Position)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 89
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 87
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 9  "@main("
+                              Name 15  "float4_array_times"
+                              Name 21  "int4_array"
+                              Name 36  "float2_array_times2"
+                              Name 68  "int4_array2"
+                              Name 76  "int1_array"
+                              Name 87  "@entryPointOutput"
+                              Decorate 87(@entryPointOutput) BuiltIn Position
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeFunction 7(fvec4)
+              11:             TypeInt 32 0
+              12:     11(int) Constant 2
+              13:             TypeArray 7(fvec4) 12
+              14:             TypePointer Function 13
+              16:             TypeInt 32 1
+              17:             TypeVector 16(int) 4
+              18:     11(int) Constant 3
+              19:             TypeArray 17(ivec4) 18
+              20:             TypePointer Function 19
+              22:     16(int) Constant 0
+              23:             TypePointer Function 17(ivec4)
+              27:     16(int) Constant 1
+              32:             TypeVector 6(float) 2
+              33:     11(int) Constant 4
+              34:             TypeArray 32(fvec2) 33
+              35:             TypePointer Function 34
+              37:     11(int) Constant 0
+              38:             TypePointer Function 16(int)
+              41:     11(int) Constant 1
+              44:             TypeVector 16(int) 2
+              66:             TypeArray 17(ivec4) 12
+              67:             TypePointer Function 66
+              74:             TypeArray 16(int) 12
+              75:             TypePointer Function 74
+              82:    6(float) Constant 0
+              83:    7(fvec4) ConstantComposite 82 82 82 82
+              86:             TypePointer Output 7(fvec4)
+87(@entryPointOutput):     86(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              88:    7(fvec4) FunctionCall 9(@main()
+                              Store 87(@entryPointOutput) 88
+                              Return
+                              FunctionEnd
+       9(@main():    7(fvec4) Function None 8
+              10:             Label
+15(float4_array_times):     14(ptr) Variable Function
+  21(int4_array):     20(ptr) Variable Function
+36(float2_array_times2):     35(ptr) Variable Function
+ 68(int4_array2):     67(ptr) Variable Function
+  76(int1_array):     75(ptr) Variable Function
+              24:     23(ptr) AccessChain 21(int4_array) 22
+              25:   17(ivec4) Load 24
+              26:    7(fvec4) ConvertSToF 25
+              28:     23(ptr) AccessChain 21(int4_array) 27
+              29:   17(ivec4) Load 28
+              30:    7(fvec4) ConvertSToF 29
+              31:          13 CompositeConstruct 26 30
+                              Store 15(float4_array_times) 31
+              39:     38(ptr) AccessChain 21(int4_array) 22 37
+              40:     16(int) Load 39
+              42:     38(ptr) AccessChain 21(int4_array) 22 41
+              43:     16(int) Load 42
+              45:   44(ivec2) CompositeConstruct 40 43
+              46:   32(fvec2) ConvertSToF 45
+              47:     38(ptr) AccessChain 21(int4_array) 22 12
+              48:     16(int) Load 47
+              49:     38(ptr) AccessChain 21(int4_array) 22 18
+              50:     16(int) Load 49
+              51:   44(ivec2) CompositeConstruct 48 50
+              52:   32(fvec2) ConvertSToF 51
+              53:     38(ptr) AccessChain 21(int4_array) 27 37
+              54:     16(int) Load 53
+              55:     38(ptr) AccessChain 21(int4_array) 27 41
+              56:     16(int) Load 55
+              57:   44(ivec2) CompositeConstruct 54 56
+              58:   32(fvec2) ConvertSToF 57
+              59:     38(ptr) AccessChain 21(int4_array) 27 12
+              60:     16(int) Load 59
+              61:     38(ptr) AccessChain 21(int4_array) 27 18
+              62:     16(int) Load 61
+              63:   44(ivec2) CompositeConstruct 60 62
+              64:   32(fvec2) ConvertSToF 63
+              65:          34 CompositeConstruct 46 52 58 64
+                              Store 36(float2_array_times2) 65
+              69:     23(ptr) AccessChain 21(int4_array) 22
+              70:   17(ivec4) Load 69
+              71:     23(ptr) AccessChain 21(int4_array) 27
+              72:   17(ivec4) Load 71
+              73:          66 CompositeConstruct 70 72
+                              Store 68(int4_array2) 73
+              77:     38(ptr) AccessChain 21(int4_array) 22 37
+              78:     16(int) Load 77
+              79:     38(ptr) AccessChain 21(int4_array) 22 41
+              80:     16(int) Load 79
+              81:          74 CompositeConstruct 78 80
+                              Store 76(int1_array) 81
+                              ReturnValue 83
+                              FunctionEnd

+ 14 - 10
3rdparty/glslang/Test/baseResults/hlsl.intrinsics.negative.frag.out

@@ -1,10 +1,10 @@
 hlsl.intrinsics.negative.frag
-ERROR: 0:10: 'determinant' : no matching overloaded function found 
+ERROR: 0:10: 'determinant' : ambiguous best function under implicit type conversion 
 ERROR: 0:25: 'normalize' : ambiguous best function under implicit type conversion 
 ERROR: 0:26: 'reflect' : ambiguous best function under implicit type conversion 
 ERROR: 0:27: 'refract' : ambiguous best function under implicit type conversion 
 ERROR: 0:28: 'refract' : no matching overloaded function found 
-ERROR: 0:30: 'transpose' : no matching overloaded function found 
+ERROR: 0:30: 'transpose' : ambiguous best function under implicit type conversion 
 ERROR: 0:39: 'GetRenderTargetSamplePosition' : no matching overloaded function found 
 ERROR: 0:46: 'asdouble' : double2 conversion not implemented 
 ERROR: 0:47: 'CheckAccessFullyMapped' : no matching overloaded function found 
@@ -104,8 +104,9 @@ ERROR: node is still EOpNull!
 0:9                0 (const int)
 0:9              Constant:
 0:9                3 (const int)
-0:10      Constant:
-0:10        0.000000
+0:10      determinant ( temp float)
+ERROR: node is still EOpNull!
+0:10          'inF0' ( in float)
 0:12      direct index ( temp float)
 0:12        unpackHalf2x16 ( temp 2-component vector of float)
 0:12          Convert float to uint ( temp uint)
@@ -150,8 +151,9 @@ ERROR: node is still EOpNull!
 0:29      bitFieldReverse ( temp uint)
 0:29        Convert float to uint ( temp uint)
 0:29          'inF0' ( in float)
-0:30      Constant:
-0:30        0.000000
+0:30      transpose ( temp 1X1 matrix of float)
+ERROR: node is still EOpNull!
+0:30          'inF0' ( in float)
 0:32      Branch: Return with expression
 0:32        Constant:
 0:32          0.000000
@@ -565,8 +567,9 @@ ERROR: node is still EOpNull!
 0:9                0 (const int)
 0:9              Constant:
 0:9                3 (const int)
-0:10      Constant:
-0:10        0.000000
+0:10      determinant ( temp float)
+ERROR: node is still EOpNull!
+0:10          'inF0' ( in float)
 0:12      direct index ( temp float)
 0:12        unpackHalf2x16 ( temp 2-component vector of float)
 0:12          Convert float to uint ( temp uint)
@@ -611,8 +614,9 @@ ERROR: node is still EOpNull!
 0:29      bitFieldReverse ( temp uint)
 0:29        Convert float to uint ( temp uint)
 0:29          'inF0' ( in float)
-0:30      Constant:
-0:30        0.000000
+0:30      transpose ( temp 1X1 matrix of float)
+ERROR: node is still EOpNull!
+0:30          'inF0' ( in float)
 0:32      Branch: Return with expression
 0:32        Constant:
 0:32          0.000000

+ 506 - 0
3rdparty/glslang/Test/baseResults/hlsl.scalar2matrix.frag.out

@@ -0,0 +1,506 @@
+hlsl.scalar2matrix.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:2  Function Definition: Fn1(mf44; ( temp void)
+0:2    Function Parameters: 
+0:2      'p' ( in 4X4 matrix of float)
+0:5  Function Definition: @main( ( temp 4-component vector of float)
+0:5    Function Parameters: 
+0:?     Sequence
+0:10      Sequence
+0:10        move second child to first child ( temp 4X4 matrix of float)
+0:10          'mat1' ( temp 4X4 matrix of float)
+0:10          Constant:
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:11      Sequence
+0:11        move second child to first child ( temp 4X4 matrix of float)
+0:11          'mat2' ( temp 4X4 matrix of float)
+0:11          Constant:
+0:11            3.000000
+0:11            3.100000
+0:11            3.200000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:12      Sequence
+0:12        move second child to first child ( temp 4X4 matrix of float)
+0:12          'mat3' ( temp 4X4 matrix of float)
+0:12          Constant:
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:16      move second child to first child ( temp 4X4 matrix of float)
+0:16        'mat4' ( temp 4X4 matrix of float)
+0:16        Constant:
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:17      move second child to first child ( temp 4X4 matrix of float)
+0:17        'mat4' ( temp 4X4 matrix of float)
+0:?         Constant:
+0:?           4.000000
+0:?           4.100000
+0:?           4.200000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:18      move second child to first child ( temp 4X4 matrix of float)
+0:18        'mat4' ( temp 4X4 matrix of float)
+0:18        Constant:
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:20      matrix scale second child into first child ( temp 4X4 matrix of float)
+0:20        'mat4' ( temp 4X4 matrix of float)
+0:20        Constant:
+0:20          0.750000
+0:21      add second child into first child ( temp 4X4 matrix of float)
+0:21        'mat4' ( temp 4X4 matrix of float)
+0:21        Constant:
+0:21          0.750000
+0:22      subtract second child into first child ( temp 4X4 matrix of float)
+0:22        'mat4' ( temp 4X4 matrix of float)
+0:22        Constant:
+0:22          0.500000
+0:23      divide second child into first child ( temp 4X4 matrix of float)
+0:23        'mat4' ( temp 4X4 matrix of float)
+0:23        Constant:
+0:23          2.000000
+0:25      Function Call: Fn1(mf44; ( temp void)
+0:25        Constant:
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:27      Branch: Return with expression
+0:27        add ( temp 4-component vector of float)
+0:27          add ( temp 4-component vector of float)
+0:27            Constant:
+0:27              0.300000
+0:27              0.300000
+0:27              0.300000
+0:27              0.300000
+0:27            direct index ( temp 4-component vector of float)
+0:27              'mat1' ( temp 4X4 matrix of float)
+0:27              Constant:
+0:27                1 (const int)
+0:27          direct index ( temp 4-component vector of float)
+0:27            'mat4' ( temp 4X4 matrix of float)
+0:27            Constant:
+0:27              2 (const int)
+0:5  Function Definition: main( ( temp void)
+0:5    Function Parameters: 
+0:?     Sequence
+0:5      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:5        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+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:2  Function Definition: Fn1(mf44; ( temp void)
+0:2    Function Parameters: 
+0:2      'p' ( in 4X4 matrix of float)
+0:5  Function Definition: @main( ( temp 4-component vector of float)
+0:5    Function Parameters: 
+0:?     Sequence
+0:10      Sequence
+0:10        move second child to first child ( temp 4X4 matrix of float)
+0:10          'mat1' ( temp 4X4 matrix of float)
+0:10          Constant:
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:10            0.250000
+0:11      Sequence
+0:11        move second child to first child ( temp 4X4 matrix of float)
+0:11          'mat2' ( temp 4X4 matrix of float)
+0:11          Constant:
+0:11            3.000000
+0:11            3.100000
+0:11            3.200000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:11            0.000000
+0:12      Sequence
+0:12        move second child to first child ( temp 4X4 matrix of float)
+0:12          'mat3' ( temp 4X4 matrix of float)
+0:12          Constant:
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:12            0.375000
+0:16      move second child to first child ( temp 4X4 matrix of float)
+0:16        'mat4' ( temp 4X4 matrix of float)
+0:16        Constant:
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:16          0.750000
+0:17      move second child to first child ( temp 4X4 matrix of float)
+0:17        'mat4' ( temp 4X4 matrix of float)
+0:?         Constant:
+0:?           4.000000
+0:?           4.100000
+0:?           4.200000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:18      move second child to first child ( temp 4X4 matrix of float)
+0:18        'mat4' ( temp 4X4 matrix of float)
+0:18        Constant:
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:18          0.500000
+0:20      matrix scale second child into first child ( temp 4X4 matrix of float)
+0:20        'mat4' ( temp 4X4 matrix of float)
+0:20        Constant:
+0:20          0.750000
+0:21      add second child into first child ( temp 4X4 matrix of float)
+0:21        'mat4' ( temp 4X4 matrix of float)
+0:21        Constant:
+0:21          0.750000
+0:22      subtract second child into first child ( temp 4X4 matrix of float)
+0:22        'mat4' ( temp 4X4 matrix of float)
+0:22        Constant:
+0:22          0.500000
+0:23      divide second child into first child ( temp 4X4 matrix of float)
+0:23        'mat4' ( temp 4X4 matrix of float)
+0:23        Constant:
+0:23          2.000000
+0:25      Function Call: Fn1(mf44; ( temp void)
+0:25        Constant:
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:25          5.000000
+0:27      Branch: Return with expression
+0:27        add ( temp 4-component vector of float)
+0:27          add ( temp 4-component vector of float)
+0:27            Constant:
+0:27              0.300000
+0:27              0.300000
+0:27              0.300000
+0:27              0.300000
+0:27            direct index ( temp 4-component vector of float)
+0:27              'mat1' ( temp 4X4 matrix of float)
+0:27              Constant:
+0:27                1 (const int)
+0:27          direct index ( temp 4-component vector of float)
+0:27            'mat4' ( temp 4X4 matrix of float)
+0:27            Constant:
+0:27              2 (const int)
+0:5  Function Definition: main( ( temp void)
+0:5    Function Parameters: 
+0:?     Sequence
+0:5      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:5        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 96
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 94
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 12  "Fn1(mf44;"
+                              Name 11  "p"
+                              Name 15  "@main("
+                              Name 17  "mat1"
+                              Name 21  "mat2"
+                              Name 29  "mat3"
+                              Name 33  "mat4"
+                              Name 77  "param"
+                              Name 94  "@entryPointOutput"
+                              Decorate 94(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeMatrix 7(fvec4) 4
+               9:             TypePointer Function 8
+              10:             TypeFunction 2 9(ptr)
+              14:             TypeFunction 7(fvec4)
+              18:    6(float) Constant 1048576000
+              19:    7(fvec4) ConstantComposite 18 18 18 18
+              20:           8 ConstantComposite 19 19 19 19
+              22:    6(float) Constant 1077936128
+              23:    6(float) Constant 1078355558
+              24:    6(float) Constant 1078774989
+              25:    6(float) Constant 0
+              26:    7(fvec4) ConstantComposite 22 23 24 25
+              27:    7(fvec4) ConstantComposite 25 25 25 25
+              28:           8 ConstantComposite 26 27 27 27
+              30:    6(float) Constant 1052770304
+              31:    7(fvec4) ConstantComposite 30 30 30 30
+              32:           8 ConstantComposite 31 31 31 31
+              34:    6(float) Constant 1061158912
+              35:    7(fvec4) ConstantComposite 34 34 34 34
+              36:           8 ConstantComposite 35 35 35 35
+              37:    6(float) Constant 1082130432
+              38:    6(float) Constant 1082340147
+              39:    6(float) Constant 1082549862
+              40:    7(fvec4) ConstantComposite 37 38 39 25
+              41:           8 ConstantComposite 40 27 27 27
+              42:    6(float) Constant 1056964608
+              43:    7(fvec4) ConstantComposite 42 42 42 42
+              44:           8 ConstantComposite 43 43 43 43
+              69:    6(float) Constant 1073741824
+              71:    6(float) Constant 1065353216
+              74:    6(float) Constant 1084227584
+              75:    7(fvec4) ConstantComposite 74 74 74 74
+              76:           8 ConstantComposite 75 75 75 75
+              79:    6(float) Constant 1050253722
+              80:    7(fvec4) ConstantComposite 79 79 79 79
+              81:             TypeInt 32 1
+              82:     81(int) Constant 1
+              83:             TypePointer Function 7(fvec4)
+              87:     81(int) Constant 2
+              93:             TypePointer Output 7(fvec4)
+94(@entryPointOutput):     93(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              95:    7(fvec4) FunctionCall 15(@main()
+                              Store 94(@entryPointOutput) 95
+                              Return
+                              FunctionEnd
+   12(Fn1(mf44;):           2 Function None 10
+           11(p):      9(ptr) FunctionParameter
+              13:             Label
+                              Return
+                              FunctionEnd
+      15(@main():    7(fvec4) Function None 14
+              16:             Label
+        17(mat1):      9(ptr) Variable Function
+        21(mat2):      9(ptr) Variable Function
+        29(mat3):      9(ptr) Variable Function
+        33(mat4):      9(ptr) Variable Function
+       77(param):      9(ptr) Variable Function
+                              Store 17(mat1) 20
+                              Store 21(mat2) 28
+                              Store 29(mat3) 32
+                              Store 33(mat4) 36
+                              Store 33(mat4) 41
+                              Store 33(mat4) 44
+              45:           8 Load 33(mat4)
+              46:           8 MatrixTimesScalar 45 34
+                              Store 33(mat4) 46
+              47:           8 Load 33(mat4)
+              48:    7(fvec4) CompositeConstruct 34 34 34 34
+              49:    7(fvec4) CompositeExtract 47 0
+              50:    7(fvec4) FAdd 49 48
+              51:    7(fvec4) CompositeExtract 47 1
+              52:    7(fvec4) FAdd 51 48
+              53:    7(fvec4) CompositeExtract 47 2
+              54:    7(fvec4) FAdd 53 48
+              55:    7(fvec4) CompositeExtract 47 3
+              56:    7(fvec4) FAdd 55 48
+              57:           8 CompositeConstruct 50 52 54 56
+                              Store 33(mat4) 57
+              58:           8 Load 33(mat4)
+              59:    7(fvec4) CompositeConstruct 42 42 42 42
+              60:    7(fvec4) CompositeExtract 58 0
+              61:    7(fvec4) FSub 60 59
+              62:    7(fvec4) CompositeExtract 58 1
+              63:    7(fvec4) FSub 62 59
+              64:    7(fvec4) CompositeExtract 58 2
+              65:    7(fvec4) FSub 64 59
+              66:    7(fvec4) CompositeExtract 58 3
+              67:    7(fvec4) FSub 66 59
+              68:           8 CompositeConstruct 61 63 65 67
+                              Store 33(mat4) 68
+              70:           8 Load 33(mat4)
+              72:    6(float) FDiv 71 69
+              73:           8 MatrixTimesScalar 70 72
+                              Store 33(mat4) 73
+                              Store 77(param) 76
+              78:           2 FunctionCall 12(Fn1(mf44;) 77(param)
+              84:     83(ptr) AccessChain 17(mat1) 82
+              85:    7(fvec4) Load 84
+              86:    7(fvec4) FAdd 80 85
+              88:     83(ptr) AccessChain 33(mat4) 87
+              89:    7(fvec4) Load 88
+              90:    7(fvec4) FAdd 86 89
+                              ReturnValue 90
+                              FunctionEnd

+ 33 - 34
3rdparty/glslang/Test/baseResults/hlsl.type.half.frag.out

@@ -49,11 +49,11 @@ gl_FragCoord origin is upper left
 0:16          'h23' ( temp 2X3 matrix of float)
 0:16          Constant:
 0:16            4.900000
-0:16            0.000000
-0:16            0.000000
-0:16            0.000000
 0:16            4.900000
-0:16            0.000000
+0:16            4.900000
+0:16            4.900000
+0:16            4.900000
+0:16            4.900000
 0:27      Branch: Return with expression
 0:27        Construct vec4 ( temp 4-component vector of float)
 0:27          add ( temp float)
@@ -133,11 +133,11 @@ gl_FragCoord origin is upper left
 0:16          'h23' ( temp 2X3 matrix of float)
 0:16          Constant:
 0:16            4.900000
-0:16            0.000000
-0:16            0.000000
-0:16            0.000000
 0:16            4.900000
-0:16            0.000000
+0:16            4.900000
+0:16            4.900000
+0:16            4.900000
+0:16            4.900000
 0:27      Branch: Return with expression
 0:27        Construct vec4 ( temp 4-component vector of float)
 0:27          add ( temp float)
@@ -165,12 +165,12 @@ gl_FragCoord origin is upper left
 
 // Module Version 10000
 // Generated by (magic number): 80001
-// Id's are bound by 61
+// Id's are bound by 60
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 59
+                              EntryPoint Fragment 4  "main" 58
                               ExecutionMode 4 OriginUpperLeft
                               Source HLSL 500
                               Name 4  "main"
@@ -182,8 +182,8 @@ gl_FragCoord origin is upper left
                               Name 27  "h4"
                               Name 32  "h22"
                               Name 38  "h23"
-                              Name 59  "@entryPointOutput"
-                              Decorate 59(@entryPointOutput) Location 0
+                              Name 58  "@entryPointOutput"
+                              Decorate 58(@entryPointOutput) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -211,20 +211,19 @@ gl_FragCoord origin is upper left
               36:             TypeMatrix 21(fvec3) 2
               37:             TypePointer Function 36
               39:    6(float) Constant 1084017869
-              40:   21(fvec3) ConstantComposite 39 13 13
-              41:   21(fvec3) ConstantComposite 13 39 13
-              42:          36 ConstantComposite 40 41
-              43:             TypeInt 32 1
-              44:     43(int) Constant 0
-              45:             TypeInt 32 0
-              46:     45(int) Constant 0
-              49:     45(int) Constant 1
-              58:             TypePointer Output 7(fvec4)
-59(@entryPointOutput):     58(ptr) Variable Output
+              40:   21(fvec3) ConstantComposite 39 39 39
+              41:          36 ConstantComposite 40 40
+              42:             TypeInt 32 1
+              43:     42(int) Constant 0
+              44:             TypeInt 32 0
+              45:     44(int) Constant 0
+              48:     44(int) Constant 1
+              57:             TypePointer Output 7(fvec4)
+58(@entryPointOutput):     57(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
-              60:    7(fvec4) FunctionCall 9(@main()
-                              Store 59(@entryPointOutput) 60
+              59:    7(fvec4) FunctionCall 9(@main()
+                              Store 58(@entryPointOutput) 59
                               Return
                               FunctionEnd
        9(@main():    7(fvec4) Function None 8
@@ -242,14 +241,14 @@ gl_FragCoord origin is upper left
                               Store 23(h3) 25
                               Store 27(h4) 29
                               Store 32(h22) 35
-                              Store 38(h23) 42
-              47:     11(ptr) AccessChain 38(h23) 44 46
-              48:    6(float) Load 47
-              50:     11(ptr) AccessChain 27(h4) 49
-              51:    6(float) Load 50
-              52:    6(float) FAdd 48 51
-              53:    6(float) Load 12(h0)
-              54:    6(float) FAdd 52 53
-              55:    7(fvec4) CompositeConstruct 54 54 54 54
-                              ReturnValue 55
+                              Store 38(h23) 41
+              46:     11(ptr) AccessChain 38(h23) 43 45
+              47:    6(float) Load 46
+              49:     11(ptr) AccessChain 27(h4) 48
+              50:    6(float) Load 49
+              51:    6(float) FAdd 47 50
+              52:    6(float) Load 12(h0)
+              53:    6(float) FAdd 51 52
+              54:    7(fvec4) CompositeConstruct 53 53 53 53
+                              ReturnValue 54
                               FunctionEnd

+ 69 - 42
3rdparty/glslang/Test/baseResults/hlsl.type.identifier.frag.out

@@ -99,17 +99,28 @@ gl_FragCoord origin is upper left
 0:25              'float' ( temp mediump float)
 0:25          Function Call: fn(f1; ( temp mediump float)
 0:25            'float' ( temp mediump float)
-0:29      Branch: Return with expression
-0:29        Construct vec4 ( temp 4-component vector of float)
-0:29          add ( temp float)
-0:29            'float' ( temp float)
-0:29            direct index ( temp float)
-0:29              direct index ( temp 3-component vector of float)
-0:29                'half2x3' ( temp 2X3 matrix of float)
-0:29                Constant:
-0:29                  0 (const int)
-0:29              Constant:
-0:29                0 (const int)
+0:28      move second child to first child ( temp float)
+0:28        direct index ( temp float)
+0:28          direct index ( temp 3-component vector of float)
+0:28            'half2x3' ( temp 2X3 matrix of float)
+0:28            Constant:
+0:28              0 (const int)
+0:28          Constant:
+0:28            0 (const int)
+0:28        component-wise multiply ( temp float)
+0:28          'float' ( temp float)
+0:28          'float' ( temp float)
+0:30      Branch: Return with expression
+0:30        Construct vec4 ( temp 4-component vector of float)
+0:30          add ( temp float)
+0:30            'float' ( temp float)
+0:30            direct index ( temp float)
+0:30              direct index ( temp 3-component vector of float)
+0:30                'half2x3' ( temp 2X3 matrix of float)
+0:30                Constant:
+0:30                  0 (const int)
+0:30              Constant:
+0:30                0 (const int)
 0:9  Function Definition: main( ( temp void)
 0:9    Function Parameters: 
 0:?     Sequence
@@ -223,17 +234,28 @@ gl_FragCoord origin is upper left
 0:25              'float' ( temp mediump float)
 0:25          Function Call: fn(f1; ( temp mediump float)
 0:25            'float' ( temp mediump float)
-0:29      Branch: Return with expression
-0:29        Construct vec4 ( temp 4-component vector of float)
-0:29          add ( temp float)
-0:29            'float' ( temp float)
-0:29            direct index ( temp float)
-0:29              direct index ( temp 3-component vector of float)
-0:29                'half2x3' ( temp 2X3 matrix of float)
-0:29                Constant:
-0:29                  0 (const int)
-0:29              Constant:
-0:29                0 (const int)
+0:28      move second child to first child ( temp float)
+0:28        direct index ( temp float)
+0:28          direct index ( temp 3-component vector of float)
+0:28            'half2x3' ( temp 2X3 matrix of float)
+0:28            Constant:
+0:28              0 (const int)
+0:28          Constant:
+0:28            0 (const int)
+0:28        component-wise multiply ( temp float)
+0:28          'float' ( temp float)
+0:28          'float' ( temp float)
+0:30      Branch: Return with expression
+0:30        Construct vec4 ( temp 4-component vector of float)
+0:30          add ( temp float)
+0:30            'float' ( temp float)
+0:30            direct index ( temp float)
+0:30              direct index ( temp 3-component vector of float)
+0:30                'half2x3' ( temp 2X3 matrix of float)
+0:30                Constant:
+0:30                  0 (const int)
+0:30              Constant:
+0:30                0 (const int)
 0:9  Function Definition: main( ( temp void)
 0:9    Function Parameters: 
 0:?     Sequence
@@ -245,12 +267,12 @@ gl_FragCoord origin is upper left
 
 // Module Version 10000
 // Generated by (magic number): 80001
-// Id's are bound by 105
+// Id's are bound by 109
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 103
+                              EntryPoint Fragment 4  "main" 107
                               ExecutionMode 4 OriginUpperLeft
                               Source HLSL 500
                               Name 4  "main"
@@ -268,8 +290,8 @@ gl_FragCoord origin is upper left
                               MemberName 56(foo_t) 0  "float"
                               Name 58  "float"
                               Name 86  "param"
-                              Name 94  "half2x3"
-                              Name 103  "@entryPointOutput"
+                              Name 93  "half2x3"
+                              Name 107  "@entryPointOutput"
                               Decorate 49(min16float) RelaxedPrecision
                               Decorate 50 RelaxedPrecision
                               Decorate 51 RelaxedPrecision
@@ -294,7 +316,7 @@ gl_FragCoord origin is upper left
                               Decorate 87 RelaxedPrecision
                               Decorate 88 RelaxedPrecision
                               Decorate 89 RelaxedPrecision
-                              Decorate 103(@entryPointOutput) Location 0
+                              Decorate 107(@entryPointOutput) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -319,16 +341,16 @@ gl_FragCoord origin is upper left
        56(foo_t):             TypeStruct 6(float)
               57:             TypePointer Function 56(foo_t)
               59:    6(float) Constant 1109917696
-              91:             TypeVector 6(float) 3
-              92:             TypeMatrix 91(fvec3) 2
-              93:             TypePointer Function 92
-              95:     22(int) Constant 0
-             102:             TypePointer Output 12(fvec4)
-103(@entryPointOutput):    102(ptr) Variable Output
+              90:             TypeVector 6(float) 3
+              91:             TypeMatrix 90(fvec3) 2
+              92:             TypePointer Function 91
+              97:     22(int) Constant 0
+             106:             TypePointer Output 12(fvec4)
+107(@entryPointOutput):    106(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
-             104:   12(fvec4) FunctionCall 14(@main()
-                              Store 103(@entryPointOutput) 104
+             108:   12(fvec4) FunctionCall 14(@main()
+                              Store 107(@entryPointOutput) 108
                               Return
                               FunctionEnd
       10(fn(f1;):    6(float) Function None 8
@@ -349,7 +371,7 @@ gl_FragCoord origin is upper left
        58(float):     57(ptr) Variable Function
               75:      7(ptr) Variable Function
        86(param):      7(ptr) Variable Function
-     94(half2x3):     93(ptr) Variable Function
+     93(half2x3):     92(ptr) Variable Function
                               Store 19(float) 20
               27:    6(float) Load 19(float)
               29:    21(bool) FOrdNotEqual 27 28
@@ -411,10 +433,15 @@ gl_FragCoord origin is upper left
               88:    6(float) FunctionCall 10(fn(f1;) 86(param)
               89:    6(float) FAdd 85 88
                               Store 19(float) 89
-              90:    6(float) Load 19(float)
-              96:      7(ptr) AccessChain 94(half2x3) 40 95
-              97:    6(float) Load 96
-              98:    6(float) FAdd 90 97
-              99:   12(fvec4) CompositeConstruct 98 98 98 98
-                              ReturnValue 99
+              94:    6(float) Load 19(float)
+              95:    6(float) Load 19(float)
+              96:    6(float) FMul 94 95
+              98:      7(ptr) AccessChain 93(half2x3) 40 97
+                              Store 98 96
+              99:    6(float) Load 19(float)
+             100:      7(ptr) AccessChain 93(half2x3) 40 97
+             101:    6(float) Load 100
+             102:    6(float) FAdd 99 101
+             103:   12(fvec4) CompositeConstruct 102 102 102 102
+                              ReturnValue 103
                               FunctionEnd

+ 0 - 3
3rdparty/glslang/Test/baseResults/spv.450.tesc.out

@@ -36,11 +36,8 @@ spv.450.tesc
                               Decorate 11(TheBlock) Block
                               Decorate 16(tcBlock) Location 12
                               MemberDecorate 17(SingleBlock) 0 Patch
-                              MemberDecorate 17(SingleBlock) 0 Location 2
                               MemberDecorate 17(SingleBlock) 1 Patch
-                              MemberDecorate 17(SingleBlock) 1 Location 3
                               MemberDecorate 17(SingleBlock) 2 Patch
-                              MemberDecorate 17(SingleBlock) 2 Location 4
                               Decorate 17(SingleBlock) Block
                               Decorate 19(singleBlock) Location 2
                               MemberDecorate 20(bn) 0 Patch

+ 32 - 0
3rdparty/glslang/Test/glsl.-D-U.frag

@@ -0,0 +1,32 @@
+#version 450
+
+#define IN_SHADER
+
+layout(location=0) out vec4 color;
+
+void main()
+{
+#if FOO==200
+    color = vec4(1.0);
+#else
+    #error expected FOO 200
+#endif
+
+#ifdef IN_SHADER
+    color++;
+#else
+    #error IN_SHADER was undef
+#endif
+
+#ifdef UNDEFED
+    #error UNDEFED defined
+#else
+    color *= 3.0;
+#endif
+
+#if MUL == 400
+    color *= MUL;
+#else
+    #error bad MUL
+#endif
+}

+ 31 - 0
3rdparty/glslang/Test/hlsl.-D-U.frag

@@ -0,0 +1,31 @@
+
+#define IN_SHADER
+
+static float4 color;
+
+void main()
+{
+#if FOO==200
+    color = 1.0;
+#else
+    #error expected FOO 200
+#endif
+
+#ifdef FOO
+    color -= 5.0;
+#else
+    #error expected FOO 200
+#endif
+
+#ifdef IN_SHADER
+    color++;
+#else
+    #error IN_SHADER was undef
+#endif
+
+#ifdef UNDEFED
+    #error UNDEFED defined
+#else
+    color *= 3.0;
+#endif
+}

+ 10 - 0
3rdparty/glslang/Test/hlsl.constructArray.vert

@@ -0,0 +1,10 @@
+float4 main() :  SV_POSITION 
+{
+    int4 int4_array[3];
+    float4 float4_array_times[2] = (float4[2])int4_array;
+    float2 float2_array_times2[4] = (float2[4])int4_array;
+    int4 int4_array2[2] = (int4[2])int4_array;
+    int int1_array[2] = (int[2])int4_array;
+
+    return (float4)0.0;
+}

+ 28 - 0
3rdparty/glslang/Test/hlsl.scalar2matrix.frag

@@ -0,0 +1,28 @@
+
+void Fn1(float4x4 p) { }
+
+float4 main() : SV_TARGET
+{
+    const float4x4 mat1c = 0.20;
+    const float4x4 mat2c = {2, 2.1, 2.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    const float4x4 mat3c = (float4x4)float1(0.1);
+
+    float4x4 mat1 = 0.25;
+    float4x4 mat2 = {3, 3.1, 3.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    float4x4 mat3 = (float4x4)0.375;
+    // float4x4 mat5 = (float4x4)Fn2(); // TODO: enable when compex rvalue handling is in place
+
+    float4x4 mat4;
+    mat4 = 0.75;
+    mat4 = float4x4(4, 4.1, 4.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+    mat4 = (float4x4)0.5;
+
+    mat4 *= 0.75;
+    mat4 += 0.75;
+    mat4 -= 0.5;
+    mat4 /= 2.0;
+
+    Fn1(5.0); // test calling fn accepting matrix with scalar type
+
+    return mat1c[0] + mat3c[0] + mat1[1] + mat4[2];
+}

+ 1 - 0
3rdparty/glslang/Test/hlsl.type.identifier.frag

@@ -25,6 +25,7 @@ float4 main() : SV_Target0
     float = float + int + uint + min16float + min10float + (bool[0] ? int : float) + fn(float);
 
     half2x3 half2x3;
+    half2x3._11 = (float) * float;
 
     return float + half2x3._11;
 }

+ 8 - 0
3rdparty/glslang/Test/runtests

@@ -119,6 +119,14 @@ diff -b $BASEDIR/include.vert.out $TARGETDIR/include.vert.out || HASERROR=1
 $EXE -D -e main -H -Iinc1/path1 -Iinc1/path2 hlsl.dashI.vert > $TARGETDIR/hlsl.dashI.vert.out
 diff -b $BASEDIR/hlsl.dashI.vert.out $TARGETDIR/hlsl.dashI.vert.out || HASERROR=1
 
+#
+# Testing -D and -U
+#
+$EXE -DUNDEFED -UIN_SHADER -DFOO=200 -i -l -UUNDEFED -DMUL=FOO*2 glsl.-D-U.frag > $TARGETDIR/glsl.-D-U.frag.out
+diff -b $BASEDIR/glsl.-D-U.frag.out $TARGETDIR/glsl.-D-U.frag.out || HASERROR=1
+$EXE -D -e main -V -i -DUNDEFED -UIN_SHADER -DFOO=200 -UUNDEFED hlsl.-D-U.frag > $TARGETDIR/hlsl.-D-U.frag.out
+diff -b $BASEDIR/hlsl.-D-U.frag.out $TARGETDIR/hlsl.-D-U.frag.out || HASERROR=1
+
 #
 # Final checking
 #

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

@@ -1043,6 +1043,32 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped*
     // The new node that handles the conversion
     TOperator constructorOp = mapTypeToConstructorOp(type);
 
+    // HLSL has custom semantics for scalar->mat shape conversions.
+    if (source == EShSourceHlsl) {
+        if (node->getType().isScalarOrVec1() && type.isMatrix()) {
+
+            // HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix.  Left to its
+            // own devices, the constructor from a scalar would populate the diagonal.  This forces replication
+            // to every matrix element.
+
+            // Note that if the node is complex (e.g, a function call), we don't want to duplicate it here
+            // repeatedly, so we copy it to a temp, then use the temp.
+            const int matSize = type.getMatrixRows() * type.getMatrixCols();
+            TIntermAggregate* rhsAggregate = new TIntermAggregate();
+
+            const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr);
+
+            if (!isSimple) {
+                assert(0); // TODO: use node replicator service when available.
+            }
+            
+            for (int x=0; x<matSize; ++x)
+                rhsAggregate->getSequence().push_back(node);
+
+            return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc());
+        }
+    }
+
     // scalar -> vector or vec1 -> vector or
     // vector -> scalar or
     // bigger vector -> smaller vector

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

@@ -5425,6 +5425,9 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
 // Test for the correctness of the parameters passed to various constructor functions
 // and also convert them to the right data type, if allowed and required.
 //
+// 'node' is what to construct from.
+// 'type' is what type to construct.
+//
 // Returns nullptr for an error or the constructed node (aggregate or typed) for no error.
 //
 TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type)

+ 11 - 8
3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp

@@ -588,7 +588,7 @@ bool ProcessDeferred(
     const char* customPreamble,
     const EShOptimizationLevel optLevel,
     const TBuiltInResource* resources,
-    int defaultVersion,         // use 100 for ES environment, 110 for desktop; this is the GLSL version, not SPIR-V or Vulkan
+    int defaultVersion,  // use 100 for ES environment, 110 for desktop; this is the GLSL version, not SPIR-V or Vulkan
     EProfile defaultProfile,
     // set version/profile to defaultVersion/defaultProfile regardless of the #version
     // directive in the source code
@@ -628,7 +628,7 @@ bool ProcessDeferred(
     const char** names = new const char*[numTotal];
     for (int s = 0; s < numStrings; ++s) {
         strings[s + numPre] = shaderStrings[s];
-        if (inputLengths == 0 || inputLengths[s] < 0)
+        if (inputLengths == nullptr || inputLengths[s] < 0)
             lengths[s + numPre] = strlen(shaderStrings[s]);
         else
             lengths[s + numPre] = inputLengths[s];
@@ -643,12 +643,14 @@ bool ProcessDeferred(
 
     // First, without using the preprocessor or parser, find the #version, so we know what
     // symbol tables, processing rules, etc. to set up.  This does not need the extra strings
-    // outlined above, just the user shader.
-    glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]);  // no preamble
+    // outlined above, just the user shader, after the system and user preambles.
+    glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]);
     int version = 0;
     EProfile profile = ENoProfile;
     bool versionNotFirstToken = false;
-    bool versionNotFirst = (messages & EShMsgReadHlsl) ? true : userInput.scanVersion(version, profile, versionNotFirstToken);
+    bool versionNotFirst = (messages & EShMsgReadHlsl) ?
+                                true :
+                                userInput.scanVersion(version, profile, versionNotFirstToken);
     bool versionNotFound = version == 0;
     if (forceDefaultVersionAndProfile && (messages & EShMsgReadHlsl) == 0) {
         if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
@@ -675,7 +677,8 @@ bool ProcessDeferred(
         spvVersion.vulkan = 100;     // TODO: eventually have this come from the outside
     else if (spvVersion.spv != 0)
         spvVersion.openGl = 100;     // TODO: eventually have this come from the outside
-    bool goodVersion = DeduceVersionProfile(compiler->infoSink, compiler->getLanguage(), versionNotFirst, defaultVersion, source, version, profile, spvVersion);
+    bool goodVersion = DeduceVersionProfile(compiler->infoSink, compiler->getLanguage(),
+                                            versionNotFirst, defaultVersion, source, version, profile, spvVersion);
     bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
     bool warnVersionNotFirst = false;
     if (! versionWillBeError && versionNotFirstToken) {
@@ -696,7 +699,7 @@ bool ProcessDeferred(
     if (messages & EShMsgDebugInfo) {
         intermediate.setSourceFile(names[numPre]);
         for (int s = 0; s < numStrings; ++s)
-            intermediate.addSourceText(strings[numPre]);
+            intermediate.addSourceText(strings[numPre + s]);
     }
     SetupBuiltinSymbolTable(version, profile, spvVersion, source);
 
@@ -726,7 +729,7 @@ bool ProcessDeferred(
                                                          compiler->getLanguage(), compiler->infoSink,
                                                          spvVersion, forwardCompatible, messages, false, sourceEntryPointName);
 
-    TPpContext ppContext(*parseContext, names[numPre]? names[numPre]: "", includer);
+    TPpContext ppContext(*parseContext, names[numPre] ? names[numPre] : "", includer);
 
     // only GLSL (bison triggered, really) needs an externally set scan context
     glslang::TScanContext scanContext(*parseContext);

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

@@ -100,6 +100,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.comparison.vec.frag", "main"},
         {"hlsl.conditional.frag", "PixelShaderFunction"},
         {"hlsl.constantbuffer.frag", "main"},
+        {"hlsl.constructArray.vert", "main"},
         {"hlsl.constructexpr.frag", "main"},
         {"hlsl.constructimat.frag", "main"},
         {"hlsl.depthGreater.frag", "PixelShaderFunction"},
@@ -284,6 +285,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.max.frag", "PixelShaderFunction"},
         {"hlsl.precedence.frag", "PixelShaderFunction"},
         {"hlsl.precedence2.frag", "PixelShaderFunction"},
+        {"hlsl.scalar2matrix.frag", "main"},
         {"hlsl.semantic.geom", "main"},
         {"hlsl.semantic.vert", "main"},
         {"hlsl.scope.frag", "PixelShaderFunction"},

+ 64 - 34
3rdparty/glslang/hlsl/hlslGrammar.cpp

@@ -107,42 +107,14 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
     // valid identifier, nor is "linear".  This code special cases the known instances of this, so
     // e.g, "int sample;" or "float float;" is accepted.  Other cases can be added here if needed.
 
-    TString* idString = nullptr;
-    switch (peek()) {
-    case EHTokSample:     idString = NewPoolTString("sample");     break;
-    case EHTokHalf:       idString = NewPoolTString("half");       break;
-    case EHTokHalf1x1:    idString = NewPoolTString("half1x1");    break;
-    case EHTokHalf1x2:    idString = NewPoolTString("half1x2");    break;
-    case EHTokHalf1x3:    idString = NewPoolTString("half1x3");    break;
-    case EHTokHalf1x4:    idString = NewPoolTString("half1x4");    break;
-    case EHTokHalf2x1:    idString = NewPoolTString("half2x1");    break;
-    case EHTokHalf2x2:    idString = NewPoolTString("half2x2");    break;
-    case EHTokHalf2x3:    idString = NewPoolTString("half2x3");    break;
-    case EHTokHalf2x4:    idString = NewPoolTString("half2x4");    break;
-    case EHTokHalf3x1:    idString = NewPoolTString("half3x1");    break;
-    case EHTokHalf3x2:    idString = NewPoolTString("half3x2");    break;
-    case EHTokHalf3x3:    idString = NewPoolTString("half3x3");    break;
-    case EHTokHalf3x4:    idString = NewPoolTString("half3x4");    break;
-    case EHTokHalf4x1:    idString = NewPoolTString("half4x1");    break;
-    case EHTokHalf4x2:    idString = NewPoolTString("half4x2");    break;
-    case EHTokHalf4x3:    idString = NewPoolTString("half4x3");    break;
-    case EHTokHalf4x4:    idString = NewPoolTString("half4x4");    break;
-    case EHTokBool:       idString = NewPoolTString("bool");       break;
-    case EHTokFloat:      idString = NewPoolTString("float");      break;
-    case EHTokDouble:     idString = NewPoolTString("double");     break;
-    case EHTokInt:        idString = NewPoolTString("int");        break;
-    case EHTokUint:       idString = NewPoolTString("uint");       break;
-    case EHTokMin16float: idString = NewPoolTString("min16float"); break;
-    case EHTokMin10float: idString = NewPoolTString("min10float"); break;
-    case EHTokMin16int:   idString = NewPoolTString("min16int");   break;
-    case EHTokMin12int:   idString = NewPoolTString("min12int");   break;
-    default:
+    const char* idString = getTypeString(peek());
+    if (idString == nullptr)
         return false;
-    }
 
-    token.string     = idString;
+    token.string     = NewPoolTString(idString);
     token.tokenClass = EHTokIdentifier;
-    idToken          = token;
+    idToken = token;
+    typeIdentifiers = true;
 
     advanceToken();
 
@@ -1311,6 +1283,18 @@ bool HlslGrammar::acceptType(TType& type, TIntermNode*& nodeList)
     static const TBasicType min12int_bt   = EbtInt;
     static const TBasicType min16uint_bt  = EbtUint;
 
+    // Some types might have turned into identifiers. Take the hit for checking
+    // when this has happened.
+    if (typeIdentifiers) {
+        const char* identifierString = getTypeString(peek());
+        if (identifierString != nullptr) {
+            TString name = identifierString;
+            // if it's an identifier, it's not a type
+            if (parseContext.symbolTable.find(name) != nullptr)
+                return false;
+        }
+    }
+
     switch (peek()) {
     case EHTokVector:
         return acceptVectorTemplateType(type);
@@ -2748,9 +2732,14 @@ bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
     if (acceptTokenClass(EHTokLeftParen)) {
         TType castType;
         if (acceptType(castType)) {
+            // recognize any array_specifier as part of the type
+            TArraySizes* arraySizes = nullptr;
+            acceptArraySpecifier(arraySizes);
+            if (arraySizes != nullptr)
+                castType.newArraySizes(*arraySizes);
+            TSourceLoc loc = token.loc;
             if (acceptTokenClass(EHTokRightParen)) {
                 // We've matched "(type)" now, get the expression to cast
-                TSourceLoc loc = token.loc;
                 if (! acceptUnaryExpression(node))
                     return false;
 
@@ -2770,6 +2759,11 @@ bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
                 // the '(int' part.  We must back up twice.
                 recedeToken();
                 recedeToken();
+
+                // Note, there are no array constructors like
+                //   (float[2](...))
+                if (arraySizes != nullptr)
+                    parseContext.error(loc, "parenthesized array constructor not allowed", "([]())", "", "");
             }
         } else {
             // This isn't a type cast, but it still started "(", so if it is a
@@ -3840,4 +3834,40 @@ bool HlslGrammar::captureBlockTokens(TVector<HlslToken>& tokens)
     return true;
 }
 
+// Return a string for just the types that can also be declared as an identifier.
+const char* HlslGrammar::getTypeString(EHlslTokenClass tokenClass) const
+{
+    switch (tokenClass) {
+    case EHTokSample:     return "sample";
+    case EHTokHalf:       return "half";
+    case EHTokHalf1x1:    return "half1x1";
+    case EHTokHalf1x2:    return "half1x2";
+    case EHTokHalf1x3:    return "half1x3";
+    case EHTokHalf1x4:    return "half1x4";
+    case EHTokHalf2x1:    return "half2x1";
+    case EHTokHalf2x2:    return "half2x2";
+    case EHTokHalf2x3:    return "half2x3";
+    case EHTokHalf2x4:    return "half2x4";
+    case EHTokHalf3x1:    return "half3x1";
+    case EHTokHalf3x2:    return "half3x2";
+    case EHTokHalf3x3:    return "half3x3";
+    case EHTokHalf3x4:    return "half3x4";
+    case EHTokHalf4x1:    return "half4x1";
+    case EHTokHalf4x2:    return "half4x2";
+    case EHTokHalf4x3:    return "half4x3";
+    case EHTokHalf4x4:    return "half4x4";
+    case EHTokBool:       return "bool";
+    case EHTokFloat:      return "float";
+    case EHTokDouble:     return "double";
+    case EHTokInt:        return "int";
+    case EHTokUint:       return "uint";
+    case EHTokMin16float: return "min16float";
+    case EHTokMin10float: return "min10float";
+    case EHTokMin16int:   return "min16int";
+    case EHTokMin12int:   return "min12int";
+    default:
+        return nullptr;
+    }
+}
+
 } // end namespace glslang

+ 4 - 1
3rdparty/glslang/hlsl/hlslGrammar.h

@@ -52,7 +52,8 @@ namespace glslang {
     class HlslGrammar : public HlslTokenStream {
     public:
         HlslGrammar(HlslScanContext& scanner, HlslParseContext& parseContext)
-            : HlslTokenStream(scanner), parseContext(parseContext), intermediate(parseContext.intermediate) { }
+            : HlslTokenStream(scanner), parseContext(parseContext), intermediate(parseContext.intermediate),
+              typeIdentifiers(false) { }
         virtual ~HlslGrammar() { }
 
         bool parse();
@@ -126,9 +127,11 @@ namespace glslang {
         bool acceptDefaultParameterDeclaration(const TType&, TIntermTyped*&);
 
         bool captureBlockTokens(TVector<HlslToken>& tokens);
+        const char* getTypeString(EHlslTokenClass tokenClass) const;
 
         HlslParseContext& parseContext;  // state of parsing and helper functions for building the intermediate
         TIntermediate& intermediate;     // the final product, the intermediate representation, includes the AST
+        bool typeIdentifiers;            // shader uses some types as identifiers
     };
 
 } // end namespace glslang

+ 106 - 8
3rdparty/glslang/hlsl/hlslParseHelper.cpp

@@ -1165,7 +1165,7 @@ bool HlslParseContext::shouldFlatten(const TType& type) const
     const TStorageQualifier qualifier = type.getQualifier().storage;
 
     return (qualifier == EvqUniform && type.isArray() && intermediate.getFlattenUniformArrays()) ||
-           type.isStruct() && type.containsOpaque();
+           (type.isStruct() && type.containsOpaque());
 }
 
 // Top level variable flattening: construct data
@@ -5401,7 +5401,8 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
         if (type.isImplicitlySizedArray()) {
             // auto adapt the constructor type to the number of arguments
             type.changeOuterArraySize(function.getParamCount());
-        } else if (type.getOuterArraySize() != function.getParamCount()) {
+        } else if (type.getOuterArraySize() != function.getParamCount() &&
+                   type.computeNumComponents() > size) {
             error(loc, "array constructor needs one argument per array element", "constructor", "");
             return true;
         }
@@ -5430,6 +5431,12 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
         }
     }
 
+    // Some array -> array type casts are okay
+    if (arrayArg && function.getParamCount() == 1 && op != EOpConstructStruct && type.isArray() &&
+        !type.isArrayOfArrays() && !function[0].type->isArrayOfArrays() &&
+        type.getVectorSize() >= 1 && function[0].type->getVectorSize() >= 1)
+        return false;
+
     if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
         error(loc, "constructing non-array constituent from array argument", "constructor", "");
         return true;
@@ -6609,6 +6616,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
         // shapes have to be convertible
         if ((from.isScalarOrVec1() && to.isScalarOrVec1()) ||
             (from.isScalarOrVec1() && to.isVector())    ||
+            (from.isScalarOrVec1() && to.isMatrix())    ||
             (from.isVector() && to.isVector() && from.getVectorSize() >= to.getVectorSize()))
             return true;
 
@@ -7343,17 +7351,20 @@ TIntermTyped* HlslParseContext::handleConstructor(const TSourceLoc& loc, TInterm
 
 // Add a constructor, either from the grammar, or other programmatic reasons.
 //
+// 'node' is what to construct from.
+// 'type' is what type to construct.
+//
+// Returns the constructed object.
 // Return nullptr if it can't be done.
 //
 TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyped* node, const TType& type)
 {
-    TIntermAggregate* aggrNode = node->getAsAggregate();
     TOperator op = intermediate.mapTypeToConstructorOp(type);
 
     // Combined texture-sampler constructors are completely semantic checked
     // in constructorTextureSamplerError()
     if (op == EOpConstructTextureSampler)
-        return intermediate.setAggregateOperator(aggrNode, op, type, loc);
+        return intermediate.setAggregateOperator(node->getAsAggregate(), op, type, loc);
 
     TTypeList::const_iterator memberTypes;
     if (op == EOpConstructStruct)
@@ -7367,7 +7378,8 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyp
         elementType.shallowCopy(type);
 
     bool singleArg;
-    if (aggrNode) {
+    TIntermAggregate* aggrNode = node->getAsAggregate();
+    if (aggrNode != nullptr) {
         if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
             singleArg = true;
         else
@@ -7377,14 +7389,27 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyp
 
     TIntermTyped *newNode;
     if (singleArg) {
+        // Handle array -> array conversion
+        // Constructing an array of one type from an array of another type is allowed,
+        // assuming there are enough components available (semantic-checked earlier).
+        if (type.isArray() && node->isArray())
+            newNode = convertArray(node, type);
+
         // If structure constructor or array constructor is being called
         // for only one parameter inside the structure, we need to call constructAggregate function once.
-        if (type.isArray())
+        else if (type.isArray())
             newNode = constructAggregate(node, elementType, 1, node->getLoc());
         else if (op == EOpConstructStruct)
             newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
-        else
+        else {
+            // shape conversion for matrix constructor from scalar.  HLSL semantics are: scalar
+            // is replicated into every element of the matrix (not just the diagnonal), so
+            // that is handled specially here.
+            if (type.isMatrix() && node->getType().isScalarOrVec1())
+                node = intermediate.addShapeConversion(type, node);
+
             newNode = constructBuiltIn(type, op, node, node->getLoc(), false);
+        }
 
         if (newNode && (type.isArray() || op == EOpConstructStruct))
             newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
@@ -7544,13 +7569,86 @@ TIntermTyped* HlslParseContext::constructBuiltIn(const TType& type, TOperator op
     return intermediate.setAggregateOperator(newNode, op, type, loc);
 }
 
+// Convert the array in node to the requested type, which is also an array.
+// Returns nullptr on failure, otherwise returns aggregate holding the list of
+// elements needed to construct the array.
+TIntermTyped* HlslParseContext::convertArray(TIntermTyped* node, const TType& type)
+{
+    assert(node->isArray() && type.isArray());
+    if (node->getType().computeNumComponents() < type.computeNumComponents())
+        return nullptr;
+
+    // TODO: write an argument replicator, for the case the argument should not be
+    // executed multiple times, yet multiple copies are needed.
+
+    TIntermTyped* constructee = node->getAsTyped();
+    // track where we are in consuming the argument
+    int constructeeElement = 0;
+    int constructeeComponent = 0;
+
+    // bump up to the next component to consume
+    const auto getNextComponent = [&]() {
+        TIntermTyped* component;
+        component = handleBracketDereference(node->getLoc(), constructee, 
+                                             intermediate.addConstantUnion(constructeeElement, node->getLoc()));
+        if (component->isVector())
+            component = handleBracketDereference(node->getLoc(), component,
+                                                 intermediate.addConstantUnion(constructeeComponent, node->getLoc()));
+        // bump component pointer up
+        ++constructeeComponent;
+        if (constructeeComponent == constructee->getVectorSize()) {
+            constructeeComponent = 0;
+            ++constructeeElement;
+        }
+        return component;
+    };
+
+    // make one subnode per constructed array element
+    TIntermAggregate* constructor = nullptr;
+    TType derefType(type, 0);
+    TType speculativeComponentType(derefType, 0);
+    TType* componentType = derefType.isVector() ? &speculativeComponentType : &derefType;
+    TOperator componentOp = intermediate.mapTypeToConstructorOp(*componentType);
+    TType crossType(node->getBasicType(), EvqTemporary, type.getVectorSize());
+    for (int e = 0; e < type.getOuterArraySize(); ++e) {
+        // construct an element
+        TIntermTyped* elementArg;
+        if (type.getVectorSize() == constructee->getVectorSize()) {
+            // same element shape
+            elementArg = handleBracketDereference(node->getLoc(), constructee,
+                                                  intermediate.addConstantUnion(e, node->getLoc()));
+        } else {
+            // mismatched element shapes
+            if (type.getVectorSize() == 1)
+                elementArg = getNextComponent();
+            else {
+                // make a vector
+                TIntermAggregate* elementConstructee = nullptr;
+                for (int c = 0; c < type.getVectorSize(); ++c)
+                    elementConstructee = intermediate.growAggregate(elementConstructee, getNextComponent());
+                elementArg = addConstructor(node->getLoc(), elementConstructee, crossType);
+            }
+        }
+        // convert basic types
+        elementArg = intermediate.addConversion(componentOp, derefType, elementArg);
+        if (elementArg == nullptr)
+            return nullptr;
+        // combine with top-level constructor
+        constructor = intermediate.growAggregate(constructor, elementArg);
+    }
+
+    return constructor;
+}
+
 // This function tests for the type of the parameters to the structure or array constructor. Raises
 // an error message if the expected type does not match the parameter passed to the constructor.
 //
 // Returns nullptr for an error or the input node itself if the expected and the given parameter types match.
 //
-TIntermTyped* HlslParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
+TIntermTyped* HlslParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount,
+                                                   const TSourceLoc& loc)
 {
+    // Handle cases that map more 1:1 between constructor arguments and constructed.
     TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
     if (! converted || converted->getType() != type) {
         error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,

+ 1 - 0
3rdparty/glslang/hlsl/hlslParseHelper.h

@@ -146,6 +146,7 @@ public:
     void lengthenList(const TSourceLoc&, TIntermSequence& list, int size, TIntermTyped* scalarInit);
     TIntermTyped* handleConstructor(const TSourceLoc&, TIntermTyped*, const TType&);
     TIntermTyped* addConstructor(const TSourceLoc&, TIntermTyped*, const TType&);
+    TIntermTyped* convertArray(TIntermTyped*, const TType&);
     TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
     TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
     void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0, TArraySizes* arraySizes = 0);