Branimir Karadžić преди 7 години
родител
ревизия
f7c00fd8b2

+ 10 - 1
3rdparty/glslang/CMakeLists.txt

@@ -21,6 +21,7 @@ option(SKIP_GLSLANG_INSTALL "Skip installation" ${SKIP_GLSLANG_INSTALL})
 if(NOT ${SKIP_GLSLANG_INSTALL})
   set(ENABLE_GLSLANG_INSTALL ON)
 endif()
+option(ENABLE_SPVREMAPPER "Enables building of SPVRemapper" ON)
 
 option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON)
 option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" ON)
@@ -35,6 +36,14 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND WIN32)
     set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "..." FORCE)
 endif()
 
+option(USE_CCACHE "Use ccache" OFF)
+if(USE_CCACHE)
+    find_program(CCACHE_FOUND ccache)
+    if(CCACHE_FOUND)
+        set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
+    endif(CCACHE_FOUND)
+endif()
+
 project(glslang)
 # make testing optional
 include(CTest)
@@ -52,7 +61,7 @@ if(ENABLE_HLSL)
 endif(ENABLE_HLSL)
 
 if(WIN32)
-    set(CMAKE_DEBUG_POSTFIX "d")
+    set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Adds a postfix for debug-built libraries.")
     if(MSVC)
         include(ChooseMSVCCRT.cmake)
     endif(MSVC)

+ 19 - 6
3rdparty/glslang/SPIRV/CMakeLists.txt

@@ -45,13 +45,17 @@ set_property(TARGET SPIRV PROPERTY FOLDER glslang)
 set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON)
 target_include_directories(SPIRV PUBLIC ..)
 
-add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
-set_property(TARGET SPVRemapper PROPERTY FOLDER glslang)
-set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON)
+if (ENABLE_SPVREMAPPER)
+    add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
+    set_property(TARGET SPVRemapper PROPERTY FOLDER glslang)
+    set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON)
+endif()
 
 if(WIN32 AND BUILD_SHARED_LIBS)
     set_target_properties(SPIRV PROPERTIES PREFIX "")
-    set_target_properties(SPVRemapper PROPERTIES PREFIX "")
+    if (ENABLE_SPVREMAPPER)
+        set_target_properties(SPVRemapper PROPERTIES PREFIX "")
+    endif()
 endif()
 
 if(ENABLE_OPT)
@@ -72,11 +76,20 @@ endif(WIN32)
 
 if(ENABLE_GLSLANG_INSTALL)
     if(BUILD_SHARED_LIBS)
-        install(TARGETS SPIRV SPVRemapper
+        if (ENABLE_SPVREMAPPER)
+            install(TARGETS SPVRemapper
+                    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
+        endif()
+        install(TARGETS SPIRV
                 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
                 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
     else()
-        install(TARGETS SPIRV SPVRemapper
+        if (ENABLE_SPVREMAPPER)
+            install(TARGETS SPVRemapper
+                    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+        endif()
+        install(TARGETS SPIRV
                 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
     endif()
 

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

@@ -911,6 +911,7 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp
 {
     if (indexType.getQualifier().isNonUniform()) {
         // deal with an asserted non-uniform index
+        // SPV_EXT_descriptor_indexing already added in TranslateNonUniformDecoration
         if (baseType.getBasicType() == glslang::EbtSampler) {
             if (baseType.getQualifier().hasAttachment())
                 builder.addCapability(spv::CapabilityInputAttachmentArrayNonUniformIndexingEXT);
@@ -931,12 +932,16 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp
     } else {
         // assume a dynamically uniform index
         if (baseType.getBasicType() == glslang::EbtSampler) {
-            if (baseType.getQualifier().hasAttachment())
+            if (baseType.getQualifier().hasAttachment()) {
+                builder.addExtension("SPV_EXT_descriptor_indexing");
                 builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT);
-            else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer)
+            } else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) {
+                builder.addExtension("SPV_EXT_descriptor_indexing");
                 builder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT);
-            else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer)
+            } else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer) {
+                builder.addExtension("SPV_EXT_descriptor_indexing");
                 builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT);
+            }
         }
     }
 }

+ 31 - 1
3rdparty/glslang/SPIRV/SpvBuilder.cpp

@@ -2031,7 +2031,37 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
     Instruction* instr = module.getInstruction(componentTypeId);
     Id bitCount = instr->getIdOperand(0);
 
-    // Will use a two step process
+    // Optimize matrix constructed from a bigger matrix
+    if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
+        // To truncate the matrix to a smaller number of rows/columns, we need to:
+        // 1. For each column, extract the column and truncate it to the required size using shuffle
+        // 2. Assemble the resulting matrix from all columns
+        Id matrix = sources[0];
+        Id columnTypeId = getContainedTypeId(resultTypeId);
+        Id sourceColumnTypeId = getContainedTypeId(getTypeId(matrix));
+
+        std::vector<unsigned> channels;
+        for (int row = 0; row < numRows; ++row)
+            channels.push_back(row);
+
+        std::vector<Id> matrixColumns;
+        for (int col = 0; col < numCols; ++col) {
+            std::vector<unsigned> indexes;
+            indexes.push_back(col);
+            Id colv = createCompositeExtract(matrix, sourceColumnTypeId, indexes);
+            setPrecision(colv, precision);
+
+            if (numRows != getNumRows(matrix)) {
+                matrixColumns.push_back(createRvalueSwizzle(precision, columnTypeId, colv, channels));
+            } else {
+                matrixColumns.push_back(colv);
+            }
+        }
+
+        return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision);
+    }
+
+    // Otherwise, will use a two step process
     // 1. make a compile-time 2D array of values
     // 2. construct a matrix from that array
 

+ 56 - 69
3rdparty/glslang/Test/baseResults/hlsl.cbuffer-identifier.vert.out

@@ -251,12 +251,12 @@ Shader version: 500
 
 // Module Version 10000
 // Generated by (magic number): 80007
-// Id's are bound by 106
+// Id's are bound by 93
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Vertex 4  "main" 87 91 99 103
+                              EntryPoint Vertex 4  "main" 74 78 86 90
                               Source HLSL 500
                               Name 4  "main"
                               Name 9  "VS_INPUT"
@@ -274,13 +274,13 @@ Shader version: 500
                               MemberName 28(C) 1  "View"
                               MemberName 28(C) 2  "Projection"
                               Name 30  ""
-                              Name 85  "input"
-                              Name 87  "input.Pos"
-                              Name 91  "input.Norm"
-                              Name 94  "flattenTemp"
-                              Name 95  "param"
-                              Name 99  "@entryPointOutput.Pos"
-                              Name 103  "@entryPointOutput.Norm"
+                              Name 72  "input"
+                              Name 74  "input.Pos"
+                              Name 78  "input.Norm"
+                              Name 81  "flattenTemp"
+                              Name 82  "param"
+                              Name 86  "@entryPointOutput.Pos"
+                              Name 90  "@entryPointOutput.Norm"
                               MemberDecorate 28(C) 0 RowMajor
                               MemberDecorate 28(C) 0 Offset 0
                               MemberDecorate 28(C) 0 MatrixStride 16
@@ -293,10 +293,10 @@ Shader version: 500
                               Decorate 28(C) Block
                               Decorate 30 DescriptorSet 0
                               Decorate 30 Binding 0
-                              Decorate 87(input.Pos) Location 0
-                              Decorate 91(input.Norm) Location 1
-                              Decorate 99(@entryPointOutput.Pos) BuiltIn Position
-                              Decorate 103(@entryPointOutput.Norm) Location 0
+                              Decorate 74(input.Pos) Location 0
+                              Decorate 78(input.Norm) Location 1
+                              Decorate 86(@entryPointOutput.Pos) BuiltIn Position
+                              Decorate 90(@entryPointOutput.Norm) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -324,37 +324,36 @@ Shader version: 500
               39:     16(int) Constant 1
               46:     16(int) Constant 2
               55:             TypeMatrix 7(fvec4) 3
-              56:    6(float) Constant 1065353216
-              73:             TypePointer Function 8(fvec3)
-              86:             TypePointer Input 7(fvec4)
-   87(input.Pos):     86(ptr) Variable Input
-              90:             TypePointer Input 8(fvec3)
-  91(input.Norm):     90(ptr) Variable Input
-              98:             TypePointer Output 7(fvec4)
-99(@entryPointOutput.Pos):     98(ptr) Variable Output
-             102:             TypePointer Output 8(fvec3)
-103(@entryPointOutput.Norm):    102(ptr) Variable Output
+              60:             TypePointer Function 8(fvec3)
+              73:             TypePointer Input 7(fvec4)
+   74(input.Pos):     73(ptr) Variable Input
+              77:             TypePointer Input 8(fvec3)
+  78(input.Norm):     77(ptr) Variable Input
+              85:             TypePointer Output 7(fvec4)
+86(@entryPointOutput.Pos):     85(ptr) Variable Output
+              89:             TypePointer Output 8(fvec3)
+90(@entryPointOutput.Norm):     89(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
-       85(input):     10(ptr) Variable Function
- 94(flattenTemp):     20(ptr) Variable Function
-       95(param):     10(ptr) Variable Function
-              88:    7(fvec4) Load 87(input.Pos)
-              89:     34(ptr) AccessChain 85(input) 26
-                              Store 89 88
-              92:    8(fvec3) Load 91(input.Norm)
-              93:     73(ptr) AccessChain 85(input) 39
-                              Store 93 92
-              96: 9(VS_INPUT) Load 85(input)
-                              Store 95(param) 96
-              97:11(PS_INPUT) FunctionCall 14(@main(struct-VS_INPUT-vf4-vf31;) 95(param)
-                              Store 94(flattenTemp) 97
-             100:     34(ptr) AccessChain 94(flattenTemp) 26
-             101:    7(fvec4) Load 100
-                              Store 99(@entryPointOutput.Pos) 101
-             104:     73(ptr) AccessChain 94(flattenTemp) 39
-             105:    8(fvec3) Load 104
-                              Store 103(@entryPointOutput.Norm) 105
+       72(input):     10(ptr) Variable Function
+ 81(flattenTemp):     20(ptr) Variable Function
+       82(param):     10(ptr) Variable Function
+              75:    7(fvec4) Load 74(input.Pos)
+              76:     34(ptr) AccessChain 72(input) 26
+                              Store 76 75
+              79:    8(fvec3) Load 78(input.Norm)
+              80:     60(ptr) AccessChain 72(input) 39
+                              Store 80 79
+              83: 9(VS_INPUT) Load 72(input)
+                              Store 82(param) 83
+              84:11(PS_INPUT) FunctionCall 14(@main(struct-VS_INPUT-vf4-vf31;) 82(param)
+                              Store 81(flattenTemp) 84
+              87:     34(ptr) AccessChain 81(flattenTemp) 26
+              88:    7(fvec4) Load 87
+                              Store 86(@entryPointOutput.Pos) 88
+              91:     60(ptr) AccessChain 81(flattenTemp) 39
+              92:    8(fvec3) Load 91
+                              Store 90(@entryPointOutput.Norm) 92
                               Return
                               FunctionEnd
 14(@main(struct-VS_INPUT-vf4-vf31;):11(PS_INPUT) Function None 12
@@ -387,31 +386,19 @@ Shader version: 500
                               Store 52 51
               53:     31(ptr) AccessChain 30 26
               54:          27 Load 53
-              57:    6(float) CompositeExtract 54 0 0
-              58:    6(float) CompositeExtract 54 0 1
-              59:    6(float) CompositeExtract 54 0 2
-              60:    6(float) CompositeExtract 54 0 3
-              61:    6(float) CompositeExtract 54 1 0
-              62:    6(float) CompositeExtract 54 1 1
-              63:    6(float) CompositeExtract 54 1 2
-              64:    6(float) CompositeExtract 54 1 3
-              65:    6(float) CompositeExtract 54 2 0
-              66:    6(float) CompositeExtract 54 2 1
-              67:    6(float) CompositeExtract 54 2 2
-              68:    6(float) CompositeExtract 54 2 3
-              69:    7(fvec4) CompositeConstruct 57 58 59 60
-              70:    7(fvec4) CompositeConstruct 61 62 63 64
-              71:    7(fvec4) CompositeConstruct 65 66 67 68
-              72:          55 CompositeConstruct 69 70 71
-              74:     73(ptr) AccessChain 13(input) 39
-              75:    8(fvec3) Load 74
-              76:    7(fvec4) MatrixTimesVector 72 75
-              77:    6(float) CompositeExtract 76 0
-              78:    6(float) CompositeExtract 76 1
-              79:    6(float) CompositeExtract 76 2
-              80:    8(fvec3) CompositeConstruct 77 78 79
-              81:     73(ptr) AccessChain 21(output) 39
-                              Store 81 80
-              82:11(PS_INPUT) Load 21(output)
-                              ReturnValue 82
+              56:    7(fvec4) CompositeExtract 54 0
+              57:    7(fvec4) CompositeExtract 54 1
+              58:    7(fvec4) CompositeExtract 54 2
+              59:          55 CompositeConstruct 56 57 58
+              61:     60(ptr) AccessChain 13(input) 39
+              62:    8(fvec3) Load 61
+              63:    7(fvec4) MatrixTimesVector 59 62
+              64:    6(float) CompositeExtract 63 0
+              65:    6(float) CompositeExtract 63 1
+              66:    6(float) CompositeExtract 63 2
+              67:    8(fvec3) CompositeConstruct 64 65 66
+              68:     60(ptr) AccessChain 21(output) 39
+                              Store 68 67
+              69:11(PS_INPUT) Load 21(output)
+                              ReturnValue 69
                               FunctionEnd

+ 154 - 195
3rdparty/glslang/Test/baseResults/hlsl.mul-truncate.frag.out

@@ -384,12 +384,12 @@ gl_FragCoord origin is upper left
 
 // Module Version 10000
 // Generated by (magic number): 80007
-// Id's are bound by 231
+// Id's are bound by 190
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 229
+                              EntryPoint Fragment 4  "main" 188
                               ExecutionMode 4 OriginUpperLeft
                               Source HLSL 500
                               Name 4  "main"
@@ -408,14 +408,14 @@ gl_FragCoord origin is upper left
                               Name 23  ""
                               Name 37  "r01"
                               Name 49  "r10"
-                              Name 75  "r11"
-                              Name 87  "r20"
-                              Name 110  "r21"
-                              Name 124  "r30"
-                              Name 144  "r31"
-                              Name 162  "r32"
-                              Name 181  "r33"
-                              Name 229  "@entryPointOutput"
+                              Name 61  "r11"
+                              Name 73  "r20"
+                              Name 88  "r21"
+                              Name 102  "r30"
+                              Name 118  "r31"
+                              Name 133  "r32"
+                              Name 146  "r33"
+                              Name 188  "@entryPointOutput"
                               MemberDecorate 21(Matrix) 0 RowMajor
                               MemberDecorate 21(Matrix) 0 Offset 0
                               MemberDecorate 21(Matrix) 0 MatrixStride 16
@@ -439,7 +439,7 @@ gl_FragCoord origin is upper left
                               MemberDecorate 21(Matrix) 8 Offset 352
                               Decorate 21(Matrix) Block
                               Decorate 23 DescriptorSet 0
-                              Decorate 229(@entryPointOutput) Location 0
+                              Decorate 188(@entryPointOutput) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -467,32 +467,30 @@ gl_FragCoord origin is upper left
               48:             TypePointer Function 7(fvec4)
               50:     24(int) Constant 0
               51:             TypePointer Uniform 13
-              54:    6(float) Constant 1065353216
-              55:    6(float) Constant 0
-              76:     24(int) Constant 2
-              77:             TypePointer Uniform 16
-             117:     24(int) Constant 1
-             118:             TypePointer Uniform 15
-             122:             TypeMatrix 14(fvec3) 2
-             123:             TypePointer Function 122
-             125:     24(int) Constant 3
-             126:             TypePointer Uniform 17
-             129:     24(int) Constant 4
-             130:             TypePointer Uniform 18
-             143:             TypePointer Function 16
-             149:             TypeMatrix 19(fvec2) 3
-             161:             TypePointer Function 149
-             163:     24(int) Constant 5
-             164:             TypePointer Uniform 20
-             180:             TypePointer Function 15
-             209:             TypeInt 32 0
-             210:    209(int) Constant 0
-             228:             TypePointer Output 7(fvec4)
-229(@entryPointOutput):    228(ptr) Variable Output
+              62:     24(int) Constant 2
+              63:             TypePointer Uniform 16
+              95:     24(int) Constant 1
+              96:             TypePointer Uniform 15
+             100:             TypeMatrix 14(fvec3) 2
+             101:             TypePointer Function 100
+             103:     24(int) Constant 3
+             104:             TypePointer Uniform 17
+             107:     24(int) Constant 4
+             108:             TypePointer Uniform 18
+             117:             TypePointer Function 16
+             123:             TypeMatrix 19(fvec2) 3
+             132:             TypePointer Function 123
+             134:     24(int) Constant 5
+             135:             TypePointer Uniform 20
+             145:             TypePointer Function 15
+             168:             TypeInt 32 0
+             169:    168(int) Constant 0
+             187:             TypePointer Output 7(fvec4)
+188(@entryPointOutput):    187(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
-             230:    7(fvec4) FunctionCall 9(@main()
-                              Store 229(@entryPointOutput) 230
+             189:    7(fvec4) FunctionCall 9(@main()
+                              Store 188(@entryPointOutput) 189
                               Return
                               FunctionEnd
        9(@main():    7(fvec4) Function None 8
@@ -500,13 +498,13 @@ gl_FragCoord origin is upper left
          12(r00):     11(ptr) Variable Function
          37(r01):     11(ptr) Variable Function
          49(r10):     48(ptr) Variable Function
-         75(r11):     48(ptr) Variable Function
-         87(r20):     48(ptr) Variable Function
-        110(r21):     48(ptr) Variable Function
-        124(r30):    123(ptr) Variable Function
-        144(r31):    143(ptr) Variable Function
-        162(r32):    161(ptr) Variable Function
-        181(r33):    180(ptr) Variable Function
+         61(r11):     48(ptr) Variable Function
+         73(r20):     48(ptr) Variable Function
+         88(r21):     48(ptr) Variable Function
+        102(r30):    101(ptr) Variable Function
+        118(r31):    117(ptr) Variable Function
+        133(r32):    132(ptr) Variable Function
+        146(r33):    145(ptr) Variable Function
               27:     26(ptr) AccessChain 23 25
               28:   19(fvec2) Load 27
               31:     30(ptr) AccessChain 23 29
@@ -527,158 +525,119 @@ gl_FragCoord origin is upper left
                               Store 37(r01) 47
               52:     51(ptr) AccessChain 23 50
               53:          13 Load 52
-              56:    6(float) CompositeExtract 53 0 0
-              57:    6(float) CompositeExtract 53 0 1
-              58:    6(float) CompositeExtract 53 0 2
-              59:    6(float) CompositeExtract 53 0 3
-              60:    6(float) CompositeExtract 53 1 0
-              61:    6(float) CompositeExtract 53 1 1
-              62:    6(float) CompositeExtract 53 1 2
-              63:    6(float) CompositeExtract 53 1 3
-              64:    6(float) CompositeExtract 53 2 0
-              65:    6(float) CompositeExtract 53 2 1
-              66:    6(float) CompositeExtract 53 2 2
-              67:    6(float) CompositeExtract 53 2 3
-              68:    7(fvec4) CompositeConstruct 56 57 58 59
-              69:    7(fvec4) CompositeConstruct 60 61 62 63
-              70:    7(fvec4) CompositeConstruct 64 65 66 67
-              71:          16 CompositeConstruct 68 69 70
-              72:     30(ptr) AccessChain 23 29
-              73:   14(fvec3) Load 72
-              74:    7(fvec4) MatrixTimesVector 71 73
-                              Store 49(r10) 74
-              78:     77(ptr) AccessChain 23 76
-              79:          16 Load 78
-              80:     39(ptr) AccessChain 23 38
-              81:    7(fvec4) Load 80
-              82:    6(float) CompositeExtract 81 0
-              83:    6(float) CompositeExtract 81 1
-              84:    6(float) CompositeExtract 81 2
-              85:   14(fvec3) CompositeConstruct 82 83 84
-              86:    7(fvec4) MatrixTimesVector 79 85
-                              Store 75(r11) 86
-              88:     30(ptr) AccessChain 23 29
-              89:   14(fvec3) Load 88
-              90:     51(ptr) AccessChain 23 50
-              91:          13 Load 90
-              92:    6(float) CompositeExtract 91 0 0
-              93:    6(float) CompositeExtract 91 0 1
-              94:    6(float) CompositeExtract 91 0 2
-              95:    6(float) CompositeExtract 91 1 0
-              96:    6(float) CompositeExtract 91 1 1
-              97:    6(float) CompositeExtract 91 1 2
-              98:    6(float) CompositeExtract 91 2 0
-              99:    6(float) CompositeExtract 91 2 1
-             100:    6(float) CompositeExtract 91 2 2
-             101:    6(float) CompositeExtract 91 3 0
-             102:    6(float) CompositeExtract 91 3 1
-             103:    6(float) CompositeExtract 91 3 2
-             104:   14(fvec3) CompositeConstruct 92 93 94
-             105:   14(fvec3) CompositeConstruct 95 96 97
-             106:   14(fvec3) CompositeConstruct 98 99 100
-             107:   14(fvec3) CompositeConstruct 101 102 103
-             108:          15 CompositeConstruct 104 105 106 107
-             109:    7(fvec4) VectorTimesMatrix 89 108
-                              Store 87(r20) 109
-             111:     39(ptr) AccessChain 23 38
-             112:    7(fvec4) Load 111
-             113:    6(float) CompositeExtract 112 0
-             114:    6(float) CompositeExtract 112 1
-             115:    6(float) CompositeExtract 112 2
-             116:   14(fvec3) CompositeConstruct 113 114 115
-             119:    118(ptr) AccessChain 23 117
-             120:          15 Load 119
-             121:    7(fvec4) VectorTimesMatrix 116 120
-                              Store 110(r21) 121
-             127:    126(ptr) AccessChain 23 125
-             128:          17 Load 127
-             131:    130(ptr) AccessChain 23 129
-             132:          18 Load 131
-             133:    6(float) CompositeExtract 132 0 0
-             134:    6(float) CompositeExtract 132 0 1
-             135:    6(float) CompositeExtract 132 0 2
-             136:    6(float) CompositeExtract 132 1 0
-             137:    6(float) CompositeExtract 132 1 1
-             138:    6(float) CompositeExtract 132 1 2
-             139:   14(fvec3) CompositeConstruct 133 134 135
-             140:   14(fvec3) CompositeConstruct 136 137 138
-             141:         122 CompositeConstruct 139 140
-             142:         122 MatrixTimesMatrix 128 141
-                              Store 124(r30) 142
-             145:    130(ptr) AccessChain 23 129
-             146:          18 Load 145
-             147:    126(ptr) AccessChain 23 125
+              54:    7(fvec4) CompositeExtract 53 0
+              55:    7(fvec4) CompositeExtract 53 1
+              56:    7(fvec4) CompositeExtract 53 2
+              57:          16 CompositeConstruct 54 55 56
+              58:     30(ptr) AccessChain 23 29
+              59:   14(fvec3) Load 58
+              60:    7(fvec4) MatrixTimesVector 57 59
+                              Store 49(r10) 60
+              64:     63(ptr) AccessChain 23 62
+              65:          16 Load 64
+              66:     39(ptr) AccessChain 23 38
+              67:    7(fvec4) Load 66
+              68:    6(float) CompositeExtract 67 0
+              69:    6(float) CompositeExtract 67 1
+              70:    6(float) CompositeExtract 67 2
+              71:   14(fvec3) CompositeConstruct 68 69 70
+              72:    7(fvec4) MatrixTimesVector 65 71
+                              Store 61(r11) 72
+              74:     30(ptr) AccessChain 23 29
+              75:   14(fvec3) Load 74
+              76:     51(ptr) AccessChain 23 50
+              77:          13 Load 76
+              78:    7(fvec4) CompositeExtract 77 0
+              79:   14(fvec3) VectorShuffle 78 78 0 1 2
+              80:    7(fvec4) CompositeExtract 77 1
+              81:   14(fvec3) VectorShuffle 80 80 0 1 2
+              82:    7(fvec4) CompositeExtract 77 2
+              83:   14(fvec3) VectorShuffle 82 82 0 1 2
+              84:    7(fvec4) CompositeExtract 77 3
+              85:   14(fvec3) VectorShuffle 84 84 0 1 2
+              86:          15 CompositeConstruct 79 81 83 85
+              87:    7(fvec4) VectorTimesMatrix 75 86
+                              Store 73(r20) 87
+              89:     39(ptr) AccessChain 23 38
+              90:    7(fvec4) Load 89
+              91:    6(float) CompositeExtract 90 0
+              92:    6(float) CompositeExtract 90 1
+              93:    6(float) CompositeExtract 90 2
+              94:   14(fvec3) CompositeConstruct 91 92 93
+              97:     96(ptr) AccessChain 23 95
+              98:          15 Load 97
+              99:    7(fvec4) VectorTimesMatrix 94 98
+                              Store 88(r21) 99
+             105:    104(ptr) AccessChain 23 103
+             106:          17 Load 105
+             109:    108(ptr) AccessChain 23 107
+             110:          18 Load 109
+             111:    7(fvec4) CompositeExtract 110 0
+             112:   14(fvec3) VectorShuffle 111 111 0 1 2
+             113:    7(fvec4) CompositeExtract 110 1
+             114:   14(fvec3) VectorShuffle 113 113 0 1 2
+             115:         100 CompositeConstruct 112 114
+             116:         100 MatrixTimesMatrix 106 115
+                              Store 102(r30) 116
+             119:    108(ptr) AccessChain 23 107
+             120:          18 Load 119
+             121:    104(ptr) AccessChain 23 103
+             122:          17 Load 121
+             124:   14(fvec3) CompositeExtract 122 0
+             125:   19(fvec2) VectorShuffle 124 124 0 1
+             126:   14(fvec3) CompositeExtract 122 1
+             127:   19(fvec2) VectorShuffle 126 126 0 1
+             128:   14(fvec3) CompositeExtract 122 2
+             129:   19(fvec2) VectorShuffle 128 128 0 1
+             130:         123 CompositeConstruct 125 127 129
+             131:          16 MatrixTimesMatrix 120 130
+                              Store 118(r31) 131
+             136:    135(ptr) AccessChain 23 134
+             137:          20 Load 136
+             138:   19(fvec2) CompositeExtract 137 0
+             139:   19(fvec2) CompositeExtract 137 1
+             140:   19(fvec2) CompositeExtract 137 2
+             141:         123 CompositeConstruct 138 139 140
+             142:    104(ptr) AccessChain 23 103
+             143:          17 Load 142
+             144:         123 MatrixTimesMatrix 141 143
+                              Store 133(r32) 144
+             147:    104(ptr) AccessChain 23 103
              148:          17 Load 147
-             150:    6(float) CompositeExtract 148 0 0
-             151:    6(float) CompositeExtract 148 0 1
-             152:    6(float) CompositeExtract 148 1 0
-             153:    6(float) CompositeExtract 148 1 1
-             154:    6(float) CompositeExtract 148 2 0
-             155:    6(float) CompositeExtract 148 2 1
-             156:   19(fvec2) CompositeConstruct 150 151
-             157:   19(fvec2) CompositeConstruct 152 153
-             158:   19(fvec2) CompositeConstruct 154 155
-             159:         149 CompositeConstruct 156 157 158
-             160:          16 MatrixTimesMatrix 146 159
-                              Store 144(r31) 160
-             165:    164(ptr) AccessChain 23 163
-             166:          20 Load 165
-             167:    6(float) CompositeExtract 166 0 0
-             168:    6(float) CompositeExtract 166 0 1
-             169:    6(float) CompositeExtract 166 1 0
-             170:    6(float) CompositeExtract 166 1 1
-             171:    6(float) CompositeExtract 166 2 0
-             172:    6(float) CompositeExtract 166 2 1
-             173:   19(fvec2) CompositeConstruct 167 168
-             174:   19(fvec2) CompositeConstruct 169 170
-             175:   19(fvec2) CompositeConstruct 171 172
-             176:         149 CompositeConstruct 173 174 175
-             177:    126(ptr) AccessChain 23 125
-             178:          17 Load 177
-             179:         149 MatrixTimesMatrix 176 178
-                              Store 162(r32) 179
-             182:    126(ptr) AccessChain 23 125
-             183:          17 Load 182
-             184:    6(float) CompositeExtract 183 0 0
-             185:    6(float) CompositeExtract 183 0 1
-             186:    6(float) CompositeExtract 183 0 2
-             187:    6(float) CompositeExtract 183 1 0
-             188:    6(float) CompositeExtract 183 1 1
-             189:    6(float) CompositeExtract 183 1 2
-             190:   14(fvec3) CompositeConstruct 184 185 186
-             191:   14(fvec3) CompositeConstruct 187 188 189
-             192:         122 CompositeConstruct 190 191
-             193:    164(ptr) AccessChain 23 163
-             194:          20 Load 193
-             195:          15 MatrixTimesMatrix 192 194
-                              Store 181(r33) 195
-             196:    7(fvec4) Load 49(r10)
-             197:    7(fvec4) Load 75(r11)
-             198:    7(fvec4) FAdd 196 197
-             199:    7(fvec4) Load 87(r20)
-             200:    7(fvec4) FAdd 198 199
-             201:    7(fvec4) Load 110(r21)
-             202:    7(fvec4) FAdd 200 201
-             203:    6(float) Load 12(r00)
-             204:    7(fvec4) CompositeConstruct 203 203 203 203
-             205:    7(fvec4) FAdd 202 204
-             206:    6(float) Load 37(r01)
-             207:    7(fvec4) CompositeConstruct 206 206 206 206
-             208:    7(fvec4) FAdd 205 207
-             211:     11(ptr) AccessChain 124(r30) 50 210
-             212:    6(float) Load 211
-             213:    7(fvec4) CompositeConstruct 212 212 212 212
-             214:    7(fvec4) FAdd 208 213
-             215:     48(ptr) AccessChain 144(r31) 50
-             216:    7(fvec4) Load 215
-             217:    7(fvec4) FAdd 214 216
-             218:     11(ptr) AccessChain 162(r32) 50 210
-             219:    6(float) Load 218
-             220:    7(fvec4) CompositeConstruct 219 219 219 219
-             221:    7(fvec4) FAdd 217 220
-             222:          15 Load 181(r33)
-             223:          16 Transpose 222
-             224:    7(fvec4) CompositeExtract 223 0
-             225:    7(fvec4) FAdd 221 224
-                              ReturnValue 225
+             149:   14(fvec3) CompositeExtract 148 0
+             150:   14(fvec3) CompositeExtract 148 1
+             151:         100 CompositeConstruct 149 150
+             152:    135(ptr) AccessChain 23 134
+             153:          20 Load 152
+             154:          15 MatrixTimesMatrix 151 153
+                              Store 146(r33) 154
+             155:    7(fvec4) Load 49(r10)
+             156:    7(fvec4) Load 61(r11)
+             157:    7(fvec4) FAdd 155 156
+             158:    7(fvec4) Load 73(r20)
+             159:    7(fvec4) FAdd 157 158
+             160:    7(fvec4) Load 88(r21)
+             161:    7(fvec4) FAdd 159 160
+             162:    6(float) Load 12(r00)
+             163:    7(fvec4) CompositeConstruct 162 162 162 162
+             164:    7(fvec4) FAdd 161 163
+             165:    6(float) Load 37(r01)
+             166:    7(fvec4) CompositeConstruct 165 165 165 165
+             167:    7(fvec4) FAdd 164 166
+             170:     11(ptr) AccessChain 102(r30) 50 169
+             171:    6(float) Load 170
+             172:    7(fvec4) CompositeConstruct 171 171 171 171
+             173:    7(fvec4) FAdd 167 172
+             174:     48(ptr) AccessChain 118(r31) 50
+             175:    7(fvec4) Load 174
+             176:    7(fvec4) FAdd 173 175
+             177:     11(ptr) AccessChain 133(r32) 50 169
+             178:    6(float) Load 177
+             179:    7(fvec4) CompositeConstruct 178 178 178 178
+             180:    7(fvec4) FAdd 176 179
+             181:          15 Load 146(r33)
+             182:          16 Transpose 181
+             183:    7(fvec4) CompositeExtract 182 0
+             184:    7(fvec4) FAdd 180 183
+                              ReturnValue 184
                               FunctionEnd

+ 47 - 48
3rdparty/glslang/Test/baseResults/link1.vk.frag.out

@@ -198,7 +198,7 @@ gl_FragCoord origin is upper left
 
 // Module Version 10000
 // Generated by (magic number): 80007
-// Id's are bound by 71
+// Id's are bound by 70
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
@@ -214,24 +214,24 @@ gl_FragCoord origin is upper left
                               Name 32  "b"
                               Name 33  "i"
                               Name 39  "c"
-                              Name 54  "s2D"
-                              Name 63  "bnameRuntime"
-                              MemberName 63(bnameRuntime) 0  "r"
-                              Name 65  ""
-                              Name 68  "bnameImplicit"
-                              MemberName 68(bnameImplicit) 0  "m"
-                              Name 70  ""
+                              Name 53  "s2D"
+                              Name 62  "bnameRuntime"
+                              MemberName 62(bnameRuntime) 0  "r"
+                              Name 64  ""
+                              Name 67  "bnameImplicit"
+                              MemberName 67(bnameImplicit) 0  "m"
+                              Name 69  ""
                               Decorate 12(color) Location 0
-                              Decorate 54(s2D) DescriptorSet 0
-                              Decorate 54(s2D) Binding 1
-                              Decorate 62 ArrayStride 4
-                              MemberDecorate 63(bnameRuntime) 0 Offset 0
-                              Decorate 63(bnameRuntime) BufferBlock
-                              Decorate 65 DescriptorSet 0
-                              Decorate 67 ArrayStride 4
-                              MemberDecorate 68(bnameImplicit) 0 Offset 0
-                              Decorate 68(bnameImplicit) BufferBlock
-                              Decorate 70 DescriptorSet 0
+                              Decorate 53(s2D) DescriptorSet 0
+                              Decorate 53(s2D) Binding 1
+                              Decorate 61 ArrayStride 4
+                              MemberDecorate 62(bnameRuntime) 0 Offset 0
+                              Decorate 62(bnameRuntime) BufferBlock
+                              Decorate 64 DescriptorSet 0
+                              Decorate 66 ArrayStride 4
+                              MemberDecorate 67(bnameImplicit) 0 Offset 0
+                              Decorate 67(bnameImplicit) BufferBlock
+                              Decorate 69 DescriptorSet 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -263,24 +263,23 @@ gl_FragCoord origin is upper left
            39(c):     38(ptr) Variable Private
               40:     14(int) Constant 3
               42:     14(int) Constant 2
-              43:             TypePointer Output 6(float)
-              45:     14(int) Constant 9
-              51:             TypeImage 6(float) 2D sampled format:Unknown
-              52:             TypeSampledImage 51
-              53:             TypePointer UniformConstant 52
-         54(s2D):     53(ptr) Variable UniformConstant
-              56:             TypeVector 6(float) 2
-              57:    6(float) Constant 1056964608
-              58:   56(fvec2) ConstantComposite 57 57
-              62:             TypeRuntimeArray 6(float)
-63(bnameRuntime):             TypeStruct 62
-              64:             TypePointer Uniform 63(bnameRuntime)
-              65:     64(ptr) Variable Uniform
-              66:     15(int) Constant 4
-              67:             TypeArray 6(float) 66
-68(bnameImplicit):             TypeStruct 67
-              69:             TypePointer Uniform 68(bnameImplicit)
-              70:     69(ptr) Variable Uniform
+              44:     14(int) Constant 9
+              50:             TypeImage 6(float) 2D sampled format:Unknown
+              51:             TypeSampledImage 50
+              52:             TypePointer UniformConstant 51
+         53(s2D):     52(ptr) Variable UniformConstant
+              55:             TypeVector 6(float) 2
+              56:    6(float) Constant 1056964608
+              57:   55(fvec2) ConstantComposite 56 56
+              61:             TypeRuntimeArray 6(float)
+62(bnameRuntime):             TypeStruct 61
+              63:             TypePointer Uniform 62(bnameRuntime)
+              64:     63(ptr) Variable Uniform
+              65:     15(int) Constant 4
+              66:             TypeArray 6(float) 65
+67(bnameImplicit):             TypeStruct 66
+              68:             TypePointer Uniform 67(bnameImplicit)
+              69:     68(ptr) Variable Uniform
          4(main):           2 Function None 3
                5:             Label
               13:    7(fvec4) FunctionCall 9(getColor()
@@ -298,18 +297,18 @@ gl_FragCoord origin is upper left
                               FunctionEnd
     9(getColor():    7(fvec4) Function None 8
               10:             Label
-              44:     43(ptr) AccessChain 12(color) 42
-                              Store 44 21
-              46:     22(ptr) AccessChain 19(a1) 45
+              43:     22(ptr) AccessChain 19(a1) 42
+                              Store 43 21
+              45:     22(ptr) AccessChain 27(a2) 44
+                              Store 45 21
+              46:     22(ptr) AccessChain 32(b) 42
                               Store 46 21
-              47:     22(ptr) AccessChain 27(a2) 42
+              47:     22(ptr) AccessChain 39(c) 40
                               Store 47 21
-              48:     22(ptr) AccessChain 32(b) 40
-                              Store 48 21
-              49:          37 Load 39(c)
-              50:     22(ptr) AccessChain 32(b) 49
-                              Store 50 21
-              55:          52 Load 54(s2D)
-              59:    7(fvec4) ImageSampleImplicitLod 55 58
-                              ReturnValue 59
+              48:     14(int) Load 33(i)
+              49:     22(ptr) AccessChain 39(c) 48
+                              Store 49 21
+              54:          51 Load 53(s2D)
+              58:    7(fvec4) ImageSampleImplicitLod 54 57
+                              ReturnValue 58
                               FunctionEnd

+ 298 - 0
3rdparty/glslang/Test/baseResults/spv.unit1.frag.out

@@ -0,0 +1,298 @@
+spv.unit1.frag
+Shader version: 460
+gl_FragCoord origin is upper left
+0:? Sequence
+0:10  Function Definition: main( ( global void)
+0:10    Function Parameters: 
+0:12    Sequence
+0:12      move second child to first child ( temp highp float)
+0:12        'f' ( global highp float)
+0:12        Constant:
+0:12          10.000000
+0:13      Sequence
+0:13        move second child to first child ( temp highp float)
+0:13          'g' ( temp highp float)
+0:13          Function Call: foo( ( global highp float)
+0:14      add second child into first child ( temp highp float)
+0:14        'f' ( global highp float)
+0:14        'g' ( temp highp float)
+0:15      add second child into first child ( temp highp float)
+0:15        'f' ( global highp float)
+0:15        direct index ( temp highp float)
+0:15          'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
+0:15          Constant:
+0:15            1 (const int)
+0:?   Linker Objects
+0:?     'f' ( global highp float)
+0:?     'a1' ( global highp float)
+0:?     'cout' ( out highp float)
+
+spv.unit2.frag
+Shader version: 410
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12  Function Definition: foo( ( global highp float)
+0:12    Function Parameters: 
+0:14    Sequence
+0:14      Sequence
+0:14        move second child to first child ( temp highp float)
+0:14          'h2' ( temp highp float)
+0:14          add ( temp highp float)
+0:14            component-wise multiply ( temp highp float)
+0:14              Constant:
+0:14                2.000000
+0:14              'f' ( global highp float)
+0:14            'cin' ( smooth in highp float)
+0:15      Sequence
+0:15        move second child to first child ( temp highp float)
+0:15          'g2' ( temp highp float)
+0:15          Function Call: bar( ( global highp float)
+0:16      Branch: Return with expression
+0:16        add ( temp highp float)
+0:16          add ( temp highp float)
+0:16            'h2' ( temp highp float)
+0:16            'g2' ( temp highp float)
+0:16          direct index ( temp highp float)
+0:16            'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
+0:16            Constant:
+0:16              1 (const int)
+0:?   Linker Objects
+0:?     'a2' ( global highp float)
+0:?     'f' ( global highp float)
+0:?     'cout' ( out highp float)
+0:?     'cin' ( smooth in highp float)
+
+spv.unit3.frag
+Shader version: 460
+gl_FragCoord origin is upper left
+0:? Sequence
+0:4  Sequence
+0:4    move second child to first child ( temp highp float)
+0:4      'h3' ( global highp float)
+0:4      Constant:
+0:4        3.000000
+0:9  Function Definition: bar( ( global highp float)
+0:9    Function Parameters: 
+0:11    Sequence
+0:11      multiply second child into first child ( temp highp float)
+0:11        'h3' ( global highp float)
+0:11        'f' ( global highp float)
+0:12      Sequence
+0:12        move second child to first child ( temp highp float)
+0:12          'g3' ( temp highp float)
+0:12          component-wise multiply ( temp highp float)
+0:12            Constant:
+0:12              2.000000
+0:12            'h3' ( global highp float)
+0:13      move second child to first child ( temp highp float)
+0:13        'cout' ( out highp float)
+0:13        'g3' ( temp highp float)
+0:14      Branch: Return with expression
+0:14        add ( temp highp float)
+0:14          add ( temp highp float)
+0:14            'h3' ( global highp float)
+0:14            'g3' ( temp highp float)
+0:14          direct index ( temp highp float)
+0:14            'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
+0:14            Constant:
+0:14              1 (const int)
+0:?   Linker Objects
+0:?     'f' ( global highp float)
+0:?     'h3' ( global highp float)
+0:?     'cout' ( out highp float)
+0:?     'cin' ( smooth in highp float)
+
+
+Linked fragment stage:
+
+
+Shader version: 460
+gl_FragCoord origin is upper left
+0:? Sequence
+0:10  Function Definition: main( ( global void)
+0:10    Function Parameters: 
+0:12    Sequence
+0:12      move second child to first child ( temp highp float)
+0:12        'f' ( global highp float)
+0:12        Constant:
+0:12          10.000000
+0:13      Sequence
+0:13        move second child to first child ( temp highp float)
+0:13          'g' ( temp highp float)
+0:13          Function Call: foo( ( global highp float)
+0:14      add second child into first child ( temp highp float)
+0:14        'f' ( global highp float)
+0:14        'g' ( temp highp float)
+0:15      add second child into first child ( temp highp float)
+0:15        'f' ( global highp float)
+0:15        direct index ( temp highp float)
+0:15          'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
+0:15          Constant:
+0:15            1 (const int)
+0:12  Function Definition: foo( ( global highp float)
+0:12    Function Parameters: 
+0:14    Sequence
+0:14      Sequence
+0:14        move second child to first child ( temp highp float)
+0:14          'h2' ( temp highp float)
+0:14          add ( temp highp float)
+0:14            component-wise multiply ( temp highp float)
+0:14              Constant:
+0:14                2.000000
+0:14              'f' ( global highp float)
+0:14            'cin' ( smooth in highp float)
+0:15      Sequence
+0:15        move second child to first child ( temp highp float)
+0:15          'g2' ( temp highp float)
+0:15          Function Call: bar( ( global highp float)
+0:16      Branch: Return with expression
+0:16        add ( temp highp float)
+0:16          add ( temp highp float)
+0:16            'h2' ( temp highp float)
+0:16            'g2' ( temp highp float)
+0:16          direct index ( temp highp float)
+0:16            'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
+0:16            Constant:
+0:16              1 (const int)
+0:4  Sequence
+0:4    move second child to first child ( temp highp float)
+0:4      'h3' ( global highp float)
+0:4      Constant:
+0:4        3.000000
+0:9  Function Definition: bar( ( global highp float)
+0:9    Function Parameters: 
+0:11    Sequence
+0:11      multiply second child into first child ( temp highp float)
+0:11        'h3' ( global highp float)
+0:11        'f' ( global highp float)
+0:12      Sequence
+0:12        move second child to first child ( temp highp float)
+0:12          'g3' ( temp highp float)
+0:12          component-wise multiply ( temp highp float)
+0:12            Constant:
+0:12              2.000000
+0:12            'h3' ( global highp float)
+0:13      move second child to first child ( temp highp float)
+0:13        'cout' ( out highp float)
+0:13        'g3' ( temp highp float)
+0:14      Branch: Return with expression
+0:14        add ( temp highp float)
+0:14          add ( temp highp float)
+0:14            'h3' ( global highp float)
+0:14            'g3' ( temp highp float)
+0:14          direct index ( temp highp float)
+0:14            'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
+0:14            Constant:
+0:14              1 (const int)
+0:?   Linker Objects
+0:?     'f' ( global highp float)
+0:?     'a1' ( global highp float)
+0:?     'cout' ( out highp float)
+0:?     'a2' ( global highp float)
+0:?     'cin' ( smooth in highp float)
+0:?     'h3' ( global highp float)
+
+// Module Version 10000
+// Generated by (magic number): 80007
+// Id's are bound by 69
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 25 37 57
+                              ExecutionMode 4 OriginUpperLeft
+                              Source GLSL 460
+                              Name 4  "main"
+                              Name 8  "foo("
+                              Name 10  "bar("
+                              Name 13  "h3"
+                              Name 15  "f"
+                              Name 18  "g"
+                              Name 25  "gl_FragCoord"
+                              Name 33  "h2"
+                              Name 37  "cin"
+                              Name 40  "g2"
+                              Name 53  "g3"
+                              Name 57  "cout"
+                              Name 67  "a1"
+                              Name 68  "a2"
+                              Decorate 25(gl_FragCoord) BuiltIn FragCoord
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeFunction 6(float)
+              12:             TypePointer Private 6(float)
+          13(h3):     12(ptr) Variable Private
+              14:    6(float) Constant 1077936128
+           15(f):     12(ptr) Variable Private
+              16:    6(float) Constant 1092616192
+              17:             TypePointer Function 6(float)
+              23:             TypeVector 6(float) 4
+              24:             TypePointer Input 23(fvec4)
+25(gl_FragCoord):     24(ptr) Variable Input
+              26:             TypeInt 32 0
+              27:     26(int) Constant 1
+              28:             TypePointer Input 6(float)
+              34:    6(float) Constant 1073741824
+         37(cin):     28(ptr) Variable Input
+              56:             TypePointer Output 6(float)
+        57(cout):     56(ptr) Variable Output
+          67(a1):     12(ptr) Variable Private
+          68(a2):     12(ptr) Variable Private
+         4(main):           2 Function None 3
+               5:             Label
+           18(g):     17(ptr) Variable Function
+                              Store 13(h3) 14
+                              Store 15(f) 16
+              19:    6(float) FunctionCall 8(foo()
+                              Store 18(g) 19
+              20:    6(float) Load 18(g)
+              21:    6(float) Load 15(f)
+              22:    6(float) FAdd 21 20
+                              Store 15(f) 22
+              29:     28(ptr) AccessChain 25(gl_FragCoord) 27
+              30:    6(float) Load 29
+              31:    6(float) Load 15(f)
+              32:    6(float) FAdd 31 30
+                              Store 15(f) 32
+                              Return
+                              FunctionEnd
+         8(foo():    6(float) Function None 7
+               9:             Label
+          33(h2):     17(ptr) Variable Function
+          40(g2):     17(ptr) Variable Function
+              35:    6(float) Load 15(f)
+              36:    6(float) FMul 34 35
+              38:    6(float) Load 37(cin)
+              39:    6(float) FAdd 36 38
+                              Store 33(h2) 39
+              41:    6(float) FunctionCall 10(bar()
+                              Store 40(g2) 41
+              42:    6(float) Load 33(h2)
+              43:    6(float) Load 40(g2)
+              44:    6(float) FAdd 42 43
+              45:     28(ptr) AccessChain 25(gl_FragCoord) 27
+              46:    6(float) Load 45
+              47:    6(float) FAdd 44 46
+                              ReturnValue 47
+                              FunctionEnd
+        10(bar():    6(float) Function None 7
+              11:             Label
+          53(g3):     17(ptr) Variable Function
+              50:    6(float) Load 15(f)
+              51:    6(float) Load 13(h3)
+              52:    6(float) FMul 51 50
+                              Store 13(h3) 52
+              54:    6(float) Load 13(h3)
+              55:    6(float) FMul 34 54
+                              Store 53(g3) 55
+              58:    6(float) Load 53(g3)
+                              Store 57(cout) 58
+              59:    6(float) Load 13(h3)
+              60:    6(float) Load 53(g3)
+              61:    6(float) FAdd 59 60
+              62:     28(ptr) AccessChain 25(gl_FragCoord) 27
+              63:    6(float) Load 62
+              64:    6(float) FAdd 61 63
+                              ReturnValue 64
+                              FunctionEnd

+ 16 - 0
3rdparty/glslang/Test/spv.unit1.frag

@@ -0,0 +1,16 @@
+#version 460
+
+float f;
+float a1;
+
+float foo();
+
+out float cout;
+
+void main()
+{
+    f = 10;
+    float g = foo();
+    f += g;
+    f += gl_FragCoord.y;
+}

+ 17 - 0
3rdparty/glslang/Test/spv.unit2.frag

@@ -0,0 +1,17 @@
+#version 410
+// a different version number makes different id's for the same shared symbol
+
+float a2;
+float f;
+
+float bar();
+
+out float cout;
+in float cin;
+
+float foo()
+{
+    float h2 = 2 * f + cin;
+    float g2 = bar();
+    return h2 + g2 + gl_FragCoord.y;
+}

+ 15 - 0
3rdparty/glslang/Test/spv.unit3.frag

@@ -0,0 +1,15 @@
+#version 460
+
+float f;
+float h3 = 3.0;
+
+out float cout;
+in float cin;
+
+float bar()
+{
+    h3 *= f;
+    float g3 = 2 * h3;
+    cout = g3;
+    return h3 + g3 + gl_FragCoord.y;
+}

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

@@ -616,6 +616,22 @@ public:
         }
     }
 
+    // non-built-in symbols that might link between compilation units
+    bool isLinkable() const
+    {
+        switch (storage) {
+        case EvqGlobal:
+        case EvqVaryingIn:
+        case EvqVaryingOut:
+        case EvqUniform:
+        case EvqBuffer:
+        case EvqShared:
+            return true;
+        default:
+            return false;
+        }
+    }
+
     // True if this type of IO is supposed to be arrayed with extra level for per-vertex data
     bool isArrayedIo(EShLanguage language) const
     {

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

@@ -1164,6 +1164,7 @@ public:
         constSubtree(nullptr)
           { name = n; }
     virtual int getId() const { return id; }
+    virtual void changeId(int i) { id = i; }
     virtual const TString& getName() const { return name; }
     virtual void traverse(TIntermTraverser*);
     virtual       TIntermSymbol* getAsSymbolNode()       { return this; }

+ 224 - 44
3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp

@@ -77,12 +77,13 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message)
 //
 void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
 {
-    if (source == EShSourceNone)
-        source = unit.source;
-
-    if (source != unit.source)
-        error(infoSink, "can't link compilation units from different source languages");
+    mergeCallGraphs(infoSink, unit);
+    mergeModes(infoSink, unit);
+    mergeTrees(infoSink, unit);
+}
 
+void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
+{
     if (unit.getNumEntryPoints() > 0) {
         if (getNumEntryPoints() > 0)
             error(infoSink, "can't handle multiple entry points per stage");
@@ -92,35 +93,50 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
         }
     }
     numEntryPoints += unit.getNumEntryPoints();
-    numErrors += unit.getNumErrors();
-    numPushConstants += unit.numPushConstants;
+
     callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
+}
 
-    if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
-        error(infoSink, "gl_FragCoord redeclarations must match across shaders");
+#define MERGE_MAX(member) member = std::max(member, unit.member)
+#define MERGE_TRUE(member) if (unit.member) member = unit.member;
 
-    if (! earlyFragmentTests)
-        earlyFragmentTests = unit.earlyFragmentTests;
+void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
+{
+    if (language != unit.language)
+        error(infoSink, "stages must match when linking into a single stage");
 
-    if (!postDepthCoverage)
-        postDepthCoverage = unit.postDepthCoverage;
+    if (source == EShSourceNone)
+        source = unit.source;
+    if (source != unit.source)
+        error(infoSink, "can't link compilation units from different source languages");
 
-    if (depthLayout == EldNone)
-        depthLayout = unit.depthLayout;
-    else if (depthLayout != unit.depthLayout)
-        error(infoSink, "Contradictory depth layouts");
+    if (treeRoot == nullptr) {
+        profile = unit.profile;
+        version = unit.version;
+        requestedExtensions = unit.requestedExtensions;
+    } else {
+        if ((profile == EEsProfile) != (unit.profile == EEsProfile))
+            error(infoSink, "Cannot cross link ES and desktop profiles");
+        else if (unit.profile == ECompatibilityProfile)
+            profile = ECompatibilityProfile;
+        version = std::max(version, unit.version);
+        requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
+    }
 
-    blendEquations |= unit.blendEquations;
+    MERGE_MAX(spvVersion.spv);
+    MERGE_MAX(spvVersion.vulkanGlsl);
+    MERGE_MAX(spvVersion.vulkan);
+    MERGE_MAX(spvVersion.openGl);
 
-    if (inputPrimitive == ElgNone)
-        inputPrimitive = unit.inputPrimitive;
-    else if (inputPrimitive != unit.inputPrimitive)
-        error(infoSink, "Contradictory input layout primitives");
+    numErrors += unit.getNumErrors();
+    numPushConstants += unit.numPushConstants;
 
-    if (outputPrimitive == ElgNone)
-        outputPrimitive = unit.outputPrimitive;
-    else if (outputPrimitive != unit.outputPrimitive)
-        error(infoSink, "Contradictory output layout primitives");
+    if (unit.invocations != TQualifier::layoutNotSet) {
+        if (invocations == TQualifier::layoutNotSet)
+            invocations = unit.invocations;
+        else if (invocations != unit.invocations)
+            error(infoSink, "number of invocations must match between compilation units");
+    }
 
     if (vertices == TQualifier::layoutNotSet)
         vertices = unit.vertices;
@@ -133,6 +149,19 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
             assert(0);
     }
 
+    if (inputPrimitive == ElgNone)
+        inputPrimitive = unit.inputPrimitive;
+    else if (inputPrimitive != unit.inputPrimitive)
+        error(infoSink, "Contradictory input layout primitives");
+
+    if (outputPrimitive == ElgNone)
+        outputPrimitive = unit.outputPrimitive;
+    else if (outputPrimitive != unit.outputPrimitive)
+        error(infoSink, "Contradictory output layout primitives");
+
+    if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
+        error(infoSink, "gl_FragCoord redeclarations must match across shaders");
+
     if (vertexSpacing == EvsNone)
         vertexSpacing = unit.vertexSpacing;
     else if (vertexSpacing != unit.vertexSpacing)
@@ -143,8 +172,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
     else if (vertexOrder != unit.vertexOrder)
         error(infoSink, "Contradictory triangle ordering");
 
-    if (unit.pointMode)
-        pointMode = true;
+    MERGE_TRUE(pointMode);
 
     for (int i = 0; i < 3; ++i) {
         if (localSize[i] > 1)
@@ -158,8 +186,21 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
             error(infoSink, "Contradictory local size specialization ids");
     }
 
-    if (unit.xfbMode)
-        xfbMode = true;
+    MERGE_TRUE(earlyFragmentTests);
+    MERGE_TRUE(postDepthCoverage);
+
+    if (depthLayout == EldNone)
+        depthLayout = unit.depthLayout;
+    else if (depthLayout != unit.depthLayout)
+        error(infoSink, "Contradictory depth layouts");
+
+    MERGE_TRUE(depthReplacing);
+    MERGE_TRUE(hlslFunctionality1);
+
+    blendEquations |= unit.blendEquations;
+
+    MERGE_TRUE(xfbMode);
+
     for (size_t b = 0; b < xfbBuffers.size(); ++b) {
         if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
             xfbBuffers[b].stride = unit.xfbBuffers[b].stride;
@@ -171,35 +212,174 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
         // TODO: 4.4 link: enhanced layouts: compare ranges
     }
 
-    if (unit.treeRoot == 0)
+    MERGE_TRUE(multiStream);
+
+#ifdef NV_EXTENSIONS
+    MERGE_TRUE(layoutOverrideCoverage);
+    MERGE_TRUE(geoPassthroughEXT);
+#endif
+
+    for (unsigned int i = 0; i < unit.shiftBinding.size(); ++i) {
+        if (unit.shiftBinding[i] > 0)
+            setShiftBinding((TResourceType)i, unit.shiftBinding[i]);
+    }
+
+    for (unsigned int i = 0; i < unit.shiftBindingForSet.size(); ++i) {
+        for (auto it = unit.shiftBindingForSet[i].begin(); it != unit.shiftBindingForSet[i].end(); ++it)
+            setShiftBindingForSet((TResourceType)i, it->second, it->first);
+    }
+
+    resourceSetBinding.insert(resourceSetBinding.end(), unit.resourceSetBinding.begin(), unit.resourceSetBinding.end());
+
+    MERGE_TRUE(autoMapBindings);
+    MERGE_TRUE(autoMapLocations);
+    MERGE_TRUE(invertY);
+    MERGE_TRUE(flattenUniformArrays);
+    MERGE_TRUE(useUnknownFormat);
+    MERGE_TRUE(hlslOffsets);
+    MERGE_TRUE(useStorageBuffer);
+    MERGE_TRUE(hlslIoMapping);
+
+    // TODO: sourceFile
+    // TODO: sourceText
+    // TODO: processes
+
+    MERGE_TRUE(needToLegalize);
+    MERGE_TRUE(binaryDoubleOutput);
+}
+
+//
+// Merge the 'unit' AST into 'this' AST.
+// That includes rationalizing the unique IDs, which were set up independently,
+// and might have overlaps that are not the same symbol, or might have different
+// IDs for what should be the same shared symbol.
+//
+void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
+{
+    if (unit.treeRoot == nullptr)
         return;
 
-    if (treeRoot == 0) {
+    if (treeRoot == nullptr) {
         treeRoot = unit.treeRoot;
-        version = unit.version;
-        requestedExtensions = unit.requestedExtensions;
         return;
     }
 
     // Getting this far means we have two existing trees to merge...
 
-    version = std::max(version, unit.version);
-    requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
-
     // Get the top-level globals of each unit
     TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
     TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence();
 
     // Get the linker-object lists
-    TIntermSequence& linkerObjects = findLinkerObjects();
-    TIntermSequence& unitLinkerObjects = unit.findLinkerObjects();
+    TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
+    const TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence();
+
+    // Map by global name to unique ID to rationalize the same object having
+    // differing IDs in different trees.
+    TMap<TString, int> idMap;
+    int maxId;
+    seedIdMap(idMap, maxId);
+    remapIds(idMap, maxId + 1, unit);
 
     mergeBodies(infoSink, globals, unitGlobals);
     mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
-
     ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
 }
 
+// Traverser that seeds an ID map with all built-ins, and tracks the
+// maximum ID used.
+// (It would be nice to put this in a function, but that causes warnings
+// on having no bodies for the copy-constructor/operator=.)
+class TBuiltInIdTraverser : public TIntermTraverser {
+public:
+    TBuiltInIdTraverser(TMap<TString, int>& idMap) : idMap(idMap), maxId(0) { }
+    // If it's a built in, add it to the map.
+    // Track the max ID.
+    virtual void visitSymbol(TIntermSymbol* symbol)
+    {
+        const TQualifier& qualifier = symbol->getType().getQualifier();
+        if (qualifier.builtIn != EbvNone)
+            idMap[symbol->getName()] = symbol->getId();
+        maxId = std::max(maxId, symbol->getId());
+    }
+    int getMaxId() const { return maxId; }
+protected:
+    TBuiltInIdTraverser(TBuiltInIdTraverser&);
+    TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
+    TMap<TString, int>& idMap;
+    int maxId;
+};
+
+// Traverser that seeds an ID map with non-builtins.
+// (It would be nice to put this in a function, but that causes warnings
+// on having no bodies for the copy-constructor/operator=.)
+class TUserIdTraverser : public TIntermTraverser {
+public:
+    TUserIdTraverser(TMap<TString, int>& idMap) : idMap(idMap) { }
+    // If its a non-built-in global, add it to the map.
+    virtual void visitSymbol(TIntermSymbol* symbol)
+    {
+        const TQualifier& qualifier = symbol->getType().getQualifier();
+        if (qualifier.builtIn == EbvNone)
+            idMap[symbol->getName()] = symbol->getId();
+    }
+
+protected:
+    TUserIdTraverser(TUserIdTraverser&);
+    TUserIdTraverser& operator=(TUserIdTraverser&);
+    TMap<TString, int>& idMap; // over biggest id
+};
+
+// Initialize the the ID map with what we know of 'this' AST.
+void TIntermediate::seedIdMap(TMap<TString, int>& idMap, int& maxId)
+{
+    // all built-ins everywhere need to align on IDs and contribute to the max ID
+    TBuiltInIdTraverser builtInIdTraverser(idMap);
+    treeRoot->traverse(&builtInIdTraverser);
+    maxId = builtInIdTraverser.getMaxId();
+
+    // user variables in the linker object list need to align on ids
+    TUserIdTraverser userIdTraverser(idMap);
+    findLinkerObjects()->traverse(&userIdTraverser);
+}
+
+// Traverser to map an AST ID to what was known from the seeding AST.
+// (It would be nice to put this in a function, but that causes warnings
+// on having no bodies for the copy-constructor/operator=.)
+class TRemapIdTraverser : public TIntermTraverser {
+public:
+    TRemapIdTraverser(const TMap<TString, int>& idMap, int idShift) : idMap(idMap), idShift(idShift) { }
+    // Do the mapping:
+    //  - if the same symbol, adopt the 'this' ID
+    //  - otherwise, ensure a unique ID by shifting to a new space
+    virtual void visitSymbol(TIntermSymbol* symbol)
+    {
+        const TQualifier& qualifier = symbol->getType().getQualifier();
+        bool remapped = false;
+        if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) {
+            auto it = idMap.find(symbol->getName());
+            if (it != idMap.end()) {
+                symbol->changeId(it->second);
+                remapped = true;
+            }
+        }
+        if (!remapped)
+            symbol->changeId(symbol->getId() + idShift);
+    }
+protected:
+    TRemapIdTraverser(TRemapIdTraverser&);
+    TRemapIdTraverser& operator=(TRemapIdTraverser&);
+    const TMap<TString, int>& idMap;
+    int idShift;
+};
+
+void TIntermediate::remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate& unit)
+{
+    // Remap all IDs to either share or be unique, as dictated by the idMap and idShift.
+    TRemapIdTraverser idTraverser(idMap, idShift);
+    unit.getTreeRoot()->traverse(&idTraverser);
+}
+
 //
 // Merge the function bodies and global-level initializers from unitGlobals into globals.
 // Will error check duplication of function bodies for the same signature.
@@ -699,7 +879,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink)
 
     // TODO: linker functionality: location collision checking
 
-    TIntermSequence& linkObjects = findLinkerObjects();
+    TIntermSequence& linkObjects = findLinkerObjects()->getSequence();
     for (size_t i = 0; i < linkObjects.size(); ++i) {
         const TType& type = linkObjects[i]->getAsTyped()->getType();
         const TQualifier& qualifier = type.getQualifier();
@@ -718,7 +898,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink)
     }
 }
 
-TIntermSequence& TIntermediate::findLinkerObjects() const
+TIntermAggregate* TIntermediate::findLinkerObjects() const
 {
     // Get the top-level globals
     TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
@@ -726,7 +906,7 @@ TIntermSequence& TIntermediate::findLinkerObjects() const
     // Get the last member of the sequences, expected to be the linker-object lists
     assert(globals.back()->getAsAggregate()->getOp() == EOpLinkerObjects);
 
-    return globals.back()->getAsAggregate()->getSequence();
+    return globals.back()->getAsAggregate();
 }
 
 // See if a variable was both a user-declared output and used.
@@ -734,7 +914,7 @@ TIntermSequence& TIntermediate::findLinkerObjects() const
 // is more useful, and perhaps the spec should be changed to reflect that.
 bool TIntermediate::userOutputUsed() const
 {
-    const TIntermSequence& linkerObjects = findLinkerObjects();
+    const TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
 
     bool found = false;
     for (size_t i = 0; i < linkerObjects.size(); ++i) {

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

@@ -645,6 +645,11 @@ protected:
     TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
     void error(TInfoSink& infoSink, const char*);
     void warn(TInfoSink& infoSink, const char*);
+    void mergeCallGraphs(TInfoSink&, TIntermediate&);
+    void mergeModes(TInfoSink&, TIntermediate&);
+    void mergeTrees(TInfoSink&, TIntermediate&);
+    void seedIdMap(TMap<TString, int>& idMap, int& maxId);
+    void remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate&);
     void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
     void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
     void mergeImplicitArraySizes(TType&, const TType&);
@@ -652,7 +657,7 @@ protected:
     void checkCallGraphCycles(TInfoSink&);
     void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
     void inOutLocationCheck(TInfoSink&);
-    TIntermSequence& findLinkerObjects() const;
+    TIntermAggregate* findLinkerObjects() const;
     bool userOutputUsed() const;
     bool isSpecializationOperation(const TIntermOperator&) const;
     bool isNonuniformPropagating(TOperator) const;
@@ -674,6 +679,8 @@ protected:
     EShSource source;            // source language, known a bit later
     std::string entryPointName;
     std::string entryPointMangledName;
+    typedef std::list<TCall> TGraph;
+    TGraph callGraph;
 
     EProfile profile;                           // source profile
     int version;                                // source version
@@ -703,6 +710,7 @@ protected:
     bool hlslFunctionality1;
     int blendEquations;        // an 'or'ing of masks of shifts of TBlendEquationShift
     bool xfbMode;
+    std::vector<TXfbBuffer> xfbBuffers;     // all the data we need to track per xfb buffer
     bool multiStream;
 
 #ifdef NV_EXTENSIONS
@@ -714,7 +722,7 @@ protected:
     std::array<unsigned int, EResCount> shiftBinding;
 
     // Per-descriptor-set shift values
-    std::array<std::map<int, int>, EResCount>  shiftBindingForSet;
+    std::array<std::map<int, int>, EResCount> shiftBindingForSet;
 
     std::vector<std::string> resourceSetBinding;
     bool autoMapBindings;
@@ -726,13 +734,9 @@ protected:
     bool useStorageBuffer;
     bool hlslIoMapping;
 
-    typedef std::list<TCall> TGraph;
-    TGraph callGraph;
-
     std::set<TString> ioAccessed;           // set of names of statically read/written I/O that might need extra checking
     std::vector<TIoRange> usedIo[4];        // sets of used locations, one for each of in, out, uniform, and buffers
     std::vector<TOffsetRange> usedAtomics;  // sets of bindings used by atomic counters
-    std::vector<TXfbBuffer> xfbBuffers;     // all the data we need to track per xfb buffer
     std::unordered_set<int> usedConstantId; // specialization constant ids used
     std::set<TString> semanticNameSet;
 

+ 1 - 0
3rdparty/glslang/gtests/Link.FromFile.Vk.cpp

@@ -106,6 +106,7 @@ INSTANTIATE_TEST_CASE_P(
     Glsl, LinkTestVulkan,
     ::testing::ValuesIn(std::vector<std::vector<std::string>>({
         {"link1.vk.frag", "link2.vk.frag"},
+        {"spv.unit1.frag", "spv.unit2.frag", "spv.unit3.frag"},
     })),
 );
 // clang-format on