Link/SPV: Correct symbol IDs on merging ASTs to a single coherent space
This is one step in providing full linker functionality for creating correct SPIR-V from multiple compilation units for the same stage. (This was the only remaining "hard" part. The rest should be simple.)
This commit is contained in:
		
							parent
							
								
									e7f9caeac4
								
							
						
					
					
						commit
						41436ad204
					
				@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										272
									
								
								Test/baseResults/spv.unit1.frag.out
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										272
									
								
								Test/baseResults/spv.unit1.frag.out
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,272 @@
 | 
			
		||||
spv.unit1.frag
 | 
			
		||||
Shader version: 460
 | 
			
		||||
gl_FragCoord origin is upper left
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:8  Function Definition: main( ( global void)
 | 
			
		||||
0:8    Function Parameters: 
 | 
			
		||||
0:10    Sequence
 | 
			
		||||
0:10      move second child to first child ( temp highp float)
 | 
			
		||||
0:10        'f' ( global highp float)
 | 
			
		||||
0:10        Constant:
 | 
			
		||||
0:10          10.000000
 | 
			
		||||
0:11      Sequence
 | 
			
		||||
0:11        move second child to first child ( temp highp float)
 | 
			
		||||
0:11          'g' ( temp highp float)
 | 
			
		||||
0:11          Function Call: foo( ( global highp float)
 | 
			
		||||
0:12      add second child into first child ( temp highp float)
 | 
			
		||||
0:12        'f' ( global highp float)
 | 
			
		||||
0:12        'g' ( temp highp float)
 | 
			
		||||
0:13      add second child into first child ( temp highp float)
 | 
			
		||||
0:13        'f' ( global highp float)
 | 
			
		||||
0:13        direct index ( temp highp float)
 | 
			
		||||
0:13          'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
 | 
			
		||||
0:13          Constant:
 | 
			
		||||
0:13            1 (const int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'f' ( global highp float)
 | 
			
		||||
0:?     'a1' ( global highp float)
 | 
			
		||||
 | 
			
		||||
spv.unit2.frag
 | 
			
		||||
Shader version: 410
 | 
			
		||||
gl_FragCoord origin is upper left
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:9  Function Definition: foo( ( global highp float)
 | 
			
		||||
0:9    Function Parameters: 
 | 
			
		||||
0:11    Sequence
 | 
			
		||||
0:11      Sequence
 | 
			
		||||
0:11        move second child to first child ( temp highp float)
 | 
			
		||||
0:11          'h2' ( temp highp float)
 | 
			
		||||
0:11          component-wise multiply ( temp highp float)
 | 
			
		||||
0:11            Constant:
 | 
			
		||||
0:11              2.000000
 | 
			
		||||
0:11            'f' ( global highp float)
 | 
			
		||||
0:12      Sequence
 | 
			
		||||
0:12        move second child to first child ( temp highp float)
 | 
			
		||||
0:12          'g2' ( temp highp float)
 | 
			
		||||
0:12          Function Call: bar( ( global highp float)
 | 
			
		||||
0:13      Branch: Return with expression
 | 
			
		||||
0:13        add ( temp highp float)
 | 
			
		||||
0:13          add ( temp highp float)
 | 
			
		||||
0:13            'h2' ( temp highp float)
 | 
			
		||||
0:13            'g2' ( temp highp float)
 | 
			
		||||
0:13          direct index ( temp highp float)
 | 
			
		||||
0:13            'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
 | 
			
		||||
0:13            Constant:
 | 
			
		||||
0:13              1 (const int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'a2' ( global highp float)
 | 
			
		||||
0:?     'f' ( global 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:6  Function Definition: bar( ( global highp float)
 | 
			
		||||
0:6    Function Parameters: 
 | 
			
		||||
0:8    Sequence
 | 
			
		||||
0:8      multiply second child into first child ( temp highp float)
 | 
			
		||||
0:8        'h3' ( global highp float)
 | 
			
		||||
0:8        'f' ( global highp float)
 | 
			
		||||
0:9      Sequence
 | 
			
		||||
0:9        move second child to first child ( temp highp float)
 | 
			
		||||
0:9          'g3' ( temp highp float)
 | 
			
		||||
0:9          component-wise multiply ( temp highp float)
 | 
			
		||||
0:9            Constant:
 | 
			
		||||
0:9              2.000000
 | 
			
		||||
0:9            'h3' ( global highp float)
 | 
			
		||||
0:10      Branch: Return with expression
 | 
			
		||||
0:10        add ( temp highp float)
 | 
			
		||||
0:10          add ( temp highp float)
 | 
			
		||||
0:10            'h3' ( global highp float)
 | 
			
		||||
0:10            'g3' ( temp highp float)
 | 
			
		||||
0:10          direct index ( temp highp float)
 | 
			
		||||
0:10            'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
 | 
			
		||||
0:10            Constant:
 | 
			
		||||
0:10              1 (const int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'f' ( global highp float)
 | 
			
		||||
0:?     'h3' ( global highp float)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Linked fragment stage:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Shader version: 460
 | 
			
		||||
gl_FragCoord origin is upper left
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:8  Function Definition: main( ( global void)
 | 
			
		||||
0:8    Function Parameters: 
 | 
			
		||||
0:10    Sequence
 | 
			
		||||
0:10      move second child to first child ( temp highp float)
 | 
			
		||||
0:10        'f' ( global highp float)
 | 
			
		||||
0:10        Constant:
 | 
			
		||||
0:10          10.000000
 | 
			
		||||
0:11      Sequence
 | 
			
		||||
0:11        move second child to first child ( temp highp float)
 | 
			
		||||
0:11          'g' ( temp highp float)
 | 
			
		||||
0:11          Function Call: foo( ( global highp float)
 | 
			
		||||
0:12      add second child into first child ( temp highp float)
 | 
			
		||||
0:12        'f' ( global highp float)
 | 
			
		||||
0:12        'g' ( temp highp float)
 | 
			
		||||
0:13      add second child into first child ( temp highp float)
 | 
			
		||||
0:13        'f' ( global highp float)
 | 
			
		||||
0:13        direct index ( temp highp float)
 | 
			
		||||
0:13          'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
 | 
			
		||||
0:13          Constant:
 | 
			
		||||
0:13            1 (const int)
 | 
			
		||||
0:9  Function Definition: foo( ( global highp float)
 | 
			
		||||
0:9    Function Parameters: 
 | 
			
		||||
0:11    Sequence
 | 
			
		||||
0:11      Sequence
 | 
			
		||||
0:11        move second child to first child ( temp highp float)
 | 
			
		||||
0:11          'h2' ( temp highp float)
 | 
			
		||||
0:11          component-wise multiply ( temp highp float)
 | 
			
		||||
0:11            Constant:
 | 
			
		||||
0:11              2.000000
 | 
			
		||||
0:11            'f' ( global highp float)
 | 
			
		||||
0:12      Sequence
 | 
			
		||||
0:12        move second child to first child ( temp highp float)
 | 
			
		||||
0:12          'g2' ( temp highp float)
 | 
			
		||||
0:12          Function Call: bar( ( global highp float)
 | 
			
		||||
0:13      Branch: Return with expression
 | 
			
		||||
0:13        add ( temp highp float)
 | 
			
		||||
0:13          add ( temp highp float)
 | 
			
		||||
0:13            'h2' ( temp highp float)
 | 
			
		||||
0:13            'g2' ( temp highp float)
 | 
			
		||||
0:13          direct index ( temp highp float)
 | 
			
		||||
0:13            'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
 | 
			
		||||
0:13            Constant:
 | 
			
		||||
0:13              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:6  Function Definition: bar( ( global highp float)
 | 
			
		||||
0:6    Function Parameters: 
 | 
			
		||||
0:8    Sequence
 | 
			
		||||
0:8      multiply second child into first child ( temp highp float)
 | 
			
		||||
0:8        'h3' ( global highp float)
 | 
			
		||||
0:8        'f' ( global highp float)
 | 
			
		||||
0:9      Sequence
 | 
			
		||||
0:9        move second child to first child ( temp highp float)
 | 
			
		||||
0:9          'g3' ( temp highp float)
 | 
			
		||||
0:9          component-wise multiply ( temp highp float)
 | 
			
		||||
0:9            Constant:
 | 
			
		||||
0:9              2.000000
 | 
			
		||||
0:9            'h3' ( global highp float)
 | 
			
		||||
0:10      Branch: Return with expression
 | 
			
		||||
0:10        add ( temp highp float)
 | 
			
		||||
0:10          add ( temp highp float)
 | 
			
		||||
0:10            'h3' ( global highp float)
 | 
			
		||||
0:10            'g3' ( temp highp float)
 | 
			
		||||
0:10          direct index ( temp highp float)
 | 
			
		||||
0:10            'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
 | 
			
		||||
0:10            Constant:
 | 
			
		||||
0:10              1 (const int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'f' ( global highp float)
 | 
			
		||||
0:?     'a1' ( global highp float)
 | 
			
		||||
0:?     'a2' ( global highp float)
 | 
			
		||||
0:?     'h3' ( global highp float)
 | 
			
		||||
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 80007
 | 
			
		||||
// Id's are bound by 63
 | 
			
		||||
 | 
			
		||||
                              Capability Shader
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint Fragment 4  "main" 25
 | 
			
		||||
                              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  "g2"
 | 
			
		||||
                              Name 50  "g3"
 | 
			
		||||
                              Name 61  "a1"
 | 
			
		||||
                              Name 62  "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
 | 
			
		||||
          61(a1):     12(ptr) Variable Private
 | 
			
		||||
          62(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
 | 
			
		||||
          37(g2):     17(ptr) Variable Function
 | 
			
		||||
              35:    6(float) Load 15(f)
 | 
			
		||||
              36:    6(float) FMul 34 35
 | 
			
		||||
                              Store 33(h2) 36
 | 
			
		||||
              38:    6(float) FunctionCall 10(bar()
 | 
			
		||||
                              Store 37(g2) 38
 | 
			
		||||
              39:    6(float) Load 33(h2)
 | 
			
		||||
              40:    6(float) Load 37(g2)
 | 
			
		||||
              41:    6(float) FAdd 39 40
 | 
			
		||||
              42:     28(ptr) AccessChain 25(gl_FragCoord) 27
 | 
			
		||||
              43:    6(float) Load 42
 | 
			
		||||
              44:    6(float) FAdd 41 43
 | 
			
		||||
                              ReturnValue 44
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
        10(bar():    6(float) Function None 7
 | 
			
		||||
              11:             Label
 | 
			
		||||
          50(g3):     17(ptr) Variable Function
 | 
			
		||||
              47:    6(float) Load 15(f)
 | 
			
		||||
              48:    6(float) Load 13(h3)
 | 
			
		||||
              49:    6(float) FMul 48 47
 | 
			
		||||
                              Store 13(h3) 49
 | 
			
		||||
              51:    6(float) Load 13(h3)
 | 
			
		||||
              52:    6(float) FMul 34 51
 | 
			
		||||
                              Store 50(g3) 52
 | 
			
		||||
              53:    6(float) Load 13(h3)
 | 
			
		||||
              54:    6(float) Load 50(g3)
 | 
			
		||||
              55:    6(float) FAdd 53 54
 | 
			
		||||
              56:     28(ptr) AccessChain 25(gl_FragCoord) 27
 | 
			
		||||
              57:    6(float) Load 56
 | 
			
		||||
              58:    6(float) FAdd 55 57
 | 
			
		||||
                              ReturnValue 58
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										14
									
								
								Test/spv.unit1.frag
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								Test/spv.unit1.frag
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
#version 460
 | 
			
		||||
 | 
			
		||||
float f;
 | 
			
		||||
float a1;
 | 
			
		||||
 | 
			
		||||
float foo();
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    f = 10;
 | 
			
		||||
    float g = foo();
 | 
			
		||||
    f += g;
 | 
			
		||||
    f += gl_FragCoord.y;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								Test/spv.unit2.frag
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								Test/spv.unit2.frag
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
#version 410
 | 
			
		||||
// a different version number makes different id's for the same shared symbol
 | 
			
		||||
 | 
			
		||||
float a2;
 | 
			
		||||
float f;
 | 
			
		||||
 | 
			
		||||
float bar();
 | 
			
		||||
 | 
			
		||||
float foo()
 | 
			
		||||
{
 | 
			
		||||
    float h2 = 2 * f;
 | 
			
		||||
    float g2 = bar();
 | 
			
		||||
    return h2 + g2 + gl_FragCoord.y;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Test/spv.unit3.frag
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								Test/spv.unit3.frag
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
#version 460
 | 
			
		||||
 | 
			
		||||
float f;
 | 
			
		||||
float h3 = 3.0;
 | 
			
		||||
 | 
			
		||||
float bar()
 | 
			
		||||
{
 | 
			
		||||
    h3 *= f;
 | 
			
		||||
    float g3 = 2 * h3;
 | 
			
		||||
    return h3 + g3 + gl_FragCoord.y;
 | 
			
		||||
}
 | 
			
		||||
@ -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; }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										124
									
								
								glslang/MachineIndependent/linkValidate.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										124
									
								
								glslang/MachineIndependent/linkValidate.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -182,22 +182,132 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Getting this far means we have two existing trees to merge...
 | 
			
		||||
    mergeTree(infoSink, unit);
 | 
			
		||||
 | 
			
		||||
    version = std::max(version, unit.version);
 | 
			
		||||
    requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
 | 
			
		||||
    ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// 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::mergeTree(TInfoSink& infoSink, TIntermediate& unit)
 | 
			
		||||
{
 | 
			
		||||
    // 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-builtin globals.
 | 
			
		||||
// (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.storage == EvqGlobal && 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.storage == EvqGlobal || 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
@ -699,7 +809,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 +828,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 +836,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 +844,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) {
 | 
			
		||||
 | 
			
		||||
@ -645,6 +645,9 @@ 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 mergeTree(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 +655,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;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								gtests/Link.FromFile.Vk.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										1
									
								
								gtests/Link.FromFile.Vk.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user