Linker: Fix #1329: correctly merge unsized arrays, and fix link tests.
authorJohn Kessenich <cepheus@frii.com>
Mon, 2 Apr 2018 03:22:34 +0000 (21:22 -0600)
committerJohn Kessenich <cepheus@frii.com>
Mon, 2 Apr 2018 03:22:34 +0000 (21:22 -0600)
Test/baseResults/150.tesc.out
Test/baseResults/link1.vk.frag.out
Test/link1.vk.frag
Test/link2.vk.frag
glslang/MachineIndependent/linkValidate.cpp
gtests/Link.FromFile.Vk.cpp

index 0abe12d..d237ee4 100644 (file)
@@ -943,8 +943,6 @@ ERROR: Linking tessellation control stage: Multiple function bodies in multiple
 ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
     main(
 ERROR: Linking tessellation control stage: Types must match:
-    gl_out: " out 4-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 2-element array of float ClipDistance gl_ClipDistance}" versus " out unsized 1-element array of block{ out 4-component vector of float Position gl_Position,  out float PointSize gl_PointSize,  out unsized 1-element array of float ClipDistance gl_ClipDistance}"
-ERROR: Linking tessellation control stage: Types must match:
     outa: " global 4-element array of int" versus " global 1-element array of int"
 ERROR: Linking tessellation control stage: can't handle multiple entry points per stage
 ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
index 5768687..e113a36 100644 (file)
@@ -2,30 +2,105 @@ link1.vk.frag
 Shader version: 450
 gl_FragCoord origin is upper left
 0:? Sequence
-0:7  Function Definition: main( ( global void)
-0:7    Function Parameters: 
-0:9    Sequence
-0:9      move second child to first child ( temp highp 4-component vector of float)
-0:9        'color' ( out highp 4-component vector of float)
-0:9        Function Call: getColor( ( global highp 4-component vector of float)
+0:16  Function Definition: main( ( global void)
+0:16    Function Parameters: 
+0:18    Sequence
+0:18      move second child to first child ( temp highp 4-component vector of float)
+0:18        'color' (layout( location=0) out highp 4-component vector of float)
+0:18        Function Call: getColor( ( global highp 4-component vector of float)
+0:20      move second child to first child ( temp highp int)
+0:20        direct index ( temp highp int)
+0:20          'a1' ( global unsized 9-element array of highp int)
+0:20          Constant:
+0:20            8 (const int)
+0:20        Constant:
+0:20          1 (const int)
+0:21      move second child to first child ( temp highp int)
+0:21        direct index ( temp highp int)
+0:21          'a2' ( global unsized 2-element array of highp int)
+0:21          Constant:
+0:21            1 (const int)
+0:21        Constant:
+0:21          1 (const int)
+0:22      move second child to first child ( temp highp int)
+0:22        indirect index ( temp highp int)
+0:22          'b' ( global 5-element array of highp int)
+0:22          'i' ( global highp int)
+0:22        Constant:
+0:22          1 (const int)
+0:23      move second child to first child ( temp highp int)
+0:23        direct index ( temp highp int)
+0:23          'c' ( global unsized 4-element array of highp int)
+0:23          Constant:
+0:23            3 (const int)
+0:23        Constant:
+0:23          1 (const int)
 0:?   Linker Objects
-0:?     'color' ( out highp 4-component vector of float)
+0:?     'color' (layout( location=0) out highp 4-component vector of float)
+0:?     'a1' ( global unsized 9-element array of highp int)
+0:?     'a2' ( global unsized 2-element array of highp int)
+0:?     'b' ( global 5-element array of highp int)
+0:?     'c' ( global unsized 4-element array of highp int)
+0:?     'i' ( global highp int)
+0:?     'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r})
+0:?     'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float m})
 
 link2.vk.frag
 Shader version: 450
 gl_FragCoord origin is upper left
 0:? Sequence
-0:5  Function Definition: getColor( ( global highp 4-component vector of float)
-0:5    Function Parameters: 
-0:7    Sequence
-0:7      Branch: Return with expression
-0:7        texture ( global highp 4-component vector of float)
-0:7          's2D' (layout( binding=1) uniform highp sampler2D)
-0:7          Constant:
-0:7            0.500000
-0:7            0.500000
+0:14  Function Definition: getColor( ( global highp 4-component vector of float)
+0:14    Function Parameters: 
+0:16    Sequence
+0:16      move second child to first child ( temp highp int)
+0:16        direct index ( temp highp int)
+0:16          'a1' ( global unsized 3-element array of highp int)
+0:16          Constant:
+0:16            2 (const int)
+0:16        Constant:
+0:16          1 (const int)
+0:17      move second child to first child ( temp highp int)
+0:17        direct index ( temp highp int)
+0:17          'a2' ( global unsized 10-element array of highp int)
+0:17          Constant:
+0:17            9 (const int)
+0:17        Constant:
+0:17          1 (const int)
+0:18      move second child to first child ( temp highp int)
+0:18        direct index ( temp highp int)
+0:18          'b' ( global unsized 3-element array of highp int)
+0:18          Constant:
+0:18            2 (const int)
+0:18        Constant:
+0:18          1 (const int)
+0:19      move second child to first child ( temp highp int)
+0:19        direct index ( temp highp int)
+0:19          'c' ( global 7-element array of highp int)
+0:19          Constant:
+0:19            3 (const int)
+0:19        Constant:
+0:19          1 (const int)
+0:20      move second child to first child ( temp highp int)
+0:20        indirect index ( temp highp int)
+0:20          'c' ( global 7-element array of highp int)
+0:20          'i' ( global highp int)
+0:20        Constant:
+0:20          1 (const int)
+0:22      Branch: Return with expression
+0:22        texture ( global highp 4-component vector of float)
+0:22          's2D' (layout( binding=1) uniform highp sampler2D)
+0:22          Constant:
+0:22            0.500000
+0:22            0.500000
 0:?   Linker Objects
 0:?     's2D' (layout( binding=1) uniform highp sampler2D)
+0:?     'a1' ( global unsized 3-element array of highp int)
+0:?     'a2' ( global unsized 10-element array of highp int)
+0:?     'b' ( global unsized 3-element array of highp int)
+0:?     'c' ( global 7-element array of highp int)
+0:?     'i' ( global highp int)
+0:?     'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r})
+0:?     'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer 4-element array of highp float m})
 
 
 Linked fragment stage:
@@ -34,23 +109,207 @@ Linked fragment stage:
 Shader version: 450
 gl_FragCoord origin is upper left
 0:? Sequence
-0:7  Function Definition: main( ( global void)
-0:7    Function Parameters: 
-0:9    Sequence
-0:9      move second child to first child ( temp highp 4-component vector of float)
-0:9        'color' ( out highp 4-component vector of float)
-0:9        Function Call: getColor( ( global highp 4-component vector of float)
-0:5  Function Definition: getColor( ( global highp 4-component vector of float)
-0:5    Function Parameters: 
-0:7    Sequence
-0:7      Branch: Return with expression
-0:7        texture ( global highp 4-component vector of float)
-0:7          's2D' (layout( binding=1) uniform highp sampler2D)
-0:7          Constant:
-0:7            0.500000
-0:7            0.500000
+0:16  Function Definition: main( ( global void)
+0:16    Function Parameters: 
+0:18    Sequence
+0:18      move second child to first child ( temp highp 4-component vector of float)
+0:18        'color' (layout( location=0) out highp 4-component vector of float)
+0:18        Function Call: getColor( ( global highp 4-component vector of float)
+0:20      move second child to first child ( temp highp int)
+0:20        direct index ( temp highp int)
+0:20          'a1' ( global 9-element array of highp int)
+0:20          Constant:
+0:20            8 (const int)
+0:20        Constant:
+0:20          1 (const int)
+0:21      move second child to first child ( temp highp int)
+0:21        direct index ( temp highp int)
+0:21          'a2' ( global 10-element array of highp int)
+0:21          Constant:
+0:21            1 (const int)
+0:21        Constant:
+0:21          1 (const int)
+0:22      move second child to first child ( temp highp int)
+0:22        indirect index ( temp highp int)
+0:22          'b' ( global 5-element array of highp int)
+0:22          'i' ( global highp int)
+0:22        Constant:
+0:22          1 (const int)
+0:23      move second child to first child ( temp highp int)
+0:23        direct index ( temp highp int)
+0:23          'c' ( global 7-element array of highp int)
+0:23          Constant:
+0:23            3 (const int)
+0:23        Constant:
+0:23          1 (const int)
+0:14  Function Definition: getColor( ( global highp 4-component vector of float)
+0:14    Function Parameters: 
+0:16    Sequence
+0:16      move second child to first child ( temp highp int)
+0:16        direct index ( temp highp int)
+0:16          'a1' ( global 3-element array of highp int)
+0:16          Constant:
+0:16            2 (const int)
+0:16        Constant:
+0:16          1 (const int)
+0:17      move second child to first child ( temp highp int)
+0:17        direct index ( temp highp int)
+0:17          'a2' ( global 10-element array of highp int)
+0:17          Constant:
+0:17            9 (const int)
+0:17        Constant:
+0:17          1 (const int)
+0:18      move second child to first child ( temp highp int)
+0:18        direct index ( temp highp int)
+0:18          'b' ( global 3-element array of highp int)
+0:18          Constant:
+0:18            2 (const int)
+0:18        Constant:
+0:18          1 (const int)
+0:19      move second child to first child ( temp highp int)
+0:19        direct index ( temp highp int)
+0:19          'c' ( global 7-element array of highp int)
+0:19          Constant:
+0:19            3 (const int)
+0:19        Constant:
+0:19          1 (const int)
+0:20      move second child to first child ( temp highp int)
+0:20        indirect index ( temp highp int)
+0:20          'c' ( global 7-element array of highp int)
+0:20          'i' ( global highp int)
+0:20        Constant:
+0:20          1 (const int)
+0:22      Branch: Return with expression
+0:22        texture ( global highp 4-component vector of float)
+0:22          's2D' (layout( binding=1) uniform highp sampler2D)
+0:22          Constant:
+0:22            0.500000
+0:22            0.500000
 0:?   Linker Objects
-0:?     'color' ( out highp 4-component vector of float)
+0:?     'color' (layout( location=0) out highp 4-component vector of float)
+0:?     'a1' ( global 9-element array of highp int)
+0:?     'a2' ( global 10-element array of highp int)
+0:?     'b' ( global 5-element array of highp int)
+0:?     'c' ( global 7-element array of highp int)
+0:?     'i' ( global highp int)
+0:?     'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r})
+0:?     'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer 4-element array of highp float m})
 0:?     's2D' (layout( binding=1) uniform highp sampler2D)
 
-SPIR-V is not generated for failed compile or link
+// Module Version 10000
+// Generated by (magic number): 80006
+// Id's are bound by 71
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 12
+                              ExecutionMode 4 OriginUpperLeft
+                              Source GLSL 450
+                              Name 4  "main"
+                              Name 9  "getColor("
+                              Name 12  "color"
+                              Name 19  "a1"
+                              Name 27  "a2"
+                              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  ""
+                              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
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeFunction 7(fvec4)
+              11:             TypePointer Output 7(fvec4)
+       12(color):     11(ptr) Variable Output
+              14:             TypeInt 32 1
+              15:             TypeInt 32 0
+              16:     15(int) Constant 9
+              17:             TypeArray 14(int) 16
+              18:             TypePointer Private 17
+          19(a1):     18(ptr) Variable Private
+              20:     14(int) Constant 8
+              21:     14(int) Constant 1
+              22:             TypePointer Private 14(int)
+              24:     15(int) Constant 10
+              25:             TypeArray 14(int) 24
+              26:             TypePointer Private 25
+          27(a2):     26(ptr) Variable Private
+              29:     15(int) Constant 5
+              30:             TypeArray 14(int) 29
+              31:             TypePointer Private 30
+           32(b):     31(ptr) Variable Private
+           33(i):     22(ptr) Variable Private
+              36:     15(int) Constant 7
+              37:             TypeArray 14(int) 36
+              38:             TypePointer Private 37
+           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
+         4(main):           2 Function None 3
+               5:             Label
+              13:    7(fvec4) FunctionCall 9(getColor()
+                              Store 12(color) 13
+              23:     22(ptr) AccessChain 19(a1) 20
+                              Store 23 21
+              28:     22(ptr) AccessChain 27(a2) 21
+                              Store 28 21
+              34:     14(int) Load 33(i)
+              35:     22(ptr) AccessChain 32(b) 34
+                              Store 35 21
+              41:     22(ptr) AccessChain 39(c) 40
+                              Store 41 21
+                              Return
+                              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
+                              Store 46 21
+              47:     22(ptr) AccessChain 27(a2) 42
+                              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
+                              FunctionEnd
index 443a320..167e78e 100644 (file)
@@ -2,9 +2,23 @@
 \r
 vec4 getColor();\r
 \r
-out vec4 color;\r
+layout(location=0) out vec4 color;\r
+\r
+int a1[];  // max size from link1\r
+int a2[];  // max size from link2\r
+int b[5];\r
+int c[];\r
+int i;\r
+\r
+buffer bnameRuntime  { float r[]; };\r
+buffer bnameImplicit { float m[]; };\r
 \r
 void main()\r
 {\r
     color = getColor();\r
+\r
+    a1[8] = 1;\r
+    a2[1] = 1;\r
+    b[i] = 1;\r
+    c[3] = 1;\r
 }\r
index febbe7c..b80402c 100644 (file)
@@ -2,7 +2,22 @@
 \r
 layout(binding=1) uniform sampler2D s2D;\r
 \r
+int a1[];  // max size from link1\r
+int a2[];  // max size from link2\r
+int b[];\r
+int c[7];\r
+int i;\r
+\r
+buffer bnameRuntime  { float r[]; };\r
+buffer bnameImplicit { float m[4]; };\r
+\r
 vec4 getColor()\r
 {\r
-  return texture(s2D, vec2(0.5));\r
+    a1[2] = 1;\r
+    a2[9] = 1;\r
+    b[2] = 1;\r
+    c[3] = 1;\r
+    c[i] = 1;\r
+\r
+    return texture(s2D, vec2(0.5));\r
 }\r
index 5efd7fb..c80fdb3 100644 (file)
@@ -268,12 +268,13 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
 // Recursively merge the implicit array sizes through the objects' respective type trees.
 void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
 {
-    if (type.isUnsizedArray() && unitType.isArray()) {
-        int newImplicitArraySize = unitType.isSizedArray() ? unitType.getOuterArraySize() : 
-                                                             unitType.getImplicitArraySize();
-        type.updateImplicitArraySize(type.getImplicitArraySize());
-        if (unitType.isArrayVariablyIndexed())
-            type.setArrayVariablyIndexed();
+    if (type.isUnsizedArray()) {
+        if (unitType.isUnsizedArray()) {
+            type.updateImplicitArraySize(unitType.getImplicitArraySize());
+            if (unitType.isArrayVariablyIndexed())
+                type.setArrayVariablyIndexed();
+        } else if (unitType.isSizedArray())
+            type.changeOuterArraySize(unitType.getOuterArraySize());
     }
 
     // Type mismatches are caught and reported after this, just be careful for now.
@@ -296,8 +297,13 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
 
     // Types have to match
     if (symbol.getType() != unitSymbol.getType()) {
-        error(infoSink, "Types must match:");
-        writeTypeComparison = true;
+        // but, we make an exception if one is an implicit array and the other is sized
+        if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() &&
+                symbol.getType().sameElementType(unitSymbol.getType()) &&
+                (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) {
+            error(infoSink, "Types must match:");
+            writeTypeComparison = true;
+        }
     }
 
     // Qualifiers have to (almost) match
index 6e1969a..0a616d8 100644 (file)
@@ -52,6 +52,7 @@ TEST_P(LinkTestVulkan, FromFile)
     GlslangResult result;
 
     // Compile each input shader file.
+    bool success = true;
     std::vector<std::unique_ptr<glslang::TShader>> shaders;
     for (size_t i = 0; i < fileCount; ++i) {
         std::string contents;
@@ -61,7 +62,7 @@ TEST_P(LinkTestVulkan, FromFile)
                 new glslang::TShader(GetShaderStage(GetSuffix(fileNames[i]))));
         auto* shader = shaders.back().get();
         shader->setAutoMapLocations(true);
-        compile(shader, contents, "", controls);
+        success &= compile(shader, contents, "", controls);
         result.shaderResults.push_back(
             {fileNames[i], shader->getInfoLog(), shader->getInfoDebugLog()});
     }
@@ -69,10 +70,25 @@ TEST_P(LinkTestVulkan, FromFile)
     // Link all of them.
     glslang::TProgram program;
     for (const auto& shader : shaders) program.addShader(shader.get());
-    program.link(controls);
+    success &= program.link(controls);
     result.linkingOutput = program.getInfoLog();
     result.linkingError = program.getInfoDebugLog();
 
+    if (success && (controls & EShMsgSpvRules)) {
+        spv::SpvBuildLogger logger;
+        std::vector<uint32_t> spirv_binary;
+        glslang::SpvOptions options;
+        options.disableOptimizer = true;
+        glslang::GlslangToSpv(*program.getIntermediate(shaders.front()->getStage()),
+                                spirv_binary, &logger, &options);
+
+        std::ostringstream disassembly_stream;
+        spv::Parameterize();
+        spv::Disassemble(disassembly_stream, spirv_binary);
+        result.spirvWarningsErrors = logger.getAllMessages();
+        result.spirv = disassembly_stream.str();
+    }
+
     std::ostringstream stream;
     outputResultToStream(&stream, result, controls);