Add basic intra-stage linking validation for matching types and qualification of uniforms/ins/outs/globals, function body duplication, and mixing ES/non-ES shaders.
Still need to handle arrays and built-in redeclarations, and many more rules, but this puts the basics in place. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23225 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
		
							parent
							
								
									f5ebfb5f27
								
							
						
					
					
						commit
						337dbc7d8c
					
				@ -281,9 +281,15 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:121          'gl_TexCoord' (smooth in unsized array of 4-component vector of float)
 | 
			
		||||
0:121          3 (const int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'lowp' (float)
 | 
			
		||||
0:?     'mediump' (float)
 | 
			
		||||
0:?     'highp' (float)
 | 
			
		||||
0:?     'precision' (float)
 | 
			
		||||
0:?     'i' (smooth in 4-component vector of float)
 | 
			
		||||
0:?     'o' (out 4-component vector of float)
 | 
			
		||||
0:?     's2D' (uniform sampler2D)
 | 
			
		||||
0:?     'centTexCoord' (centroid smooth in 2-component vector of float)
 | 
			
		||||
0:?     'm' (uniform 4X2 matrix of float)
 | 
			
		||||
0:?     'imageBuffer' (float)
 | 
			
		||||
0:?     'uimage2DRect' (float)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -134,6 +134,7 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:?     'rep2' (centroid smooth sample out highp 4-component vector of float)
 | 
			
		||||
0:?     'rep3' (in highp 4-component vector of float)
 | 
			
		||||
0:?     's' (smooth out structure)
 | 
			
		||||
0:?     'badsize2' (unsized array of highp float)
 | 
			
		||||
0:?     'ubInst' (layout(shared ) uniform unsized array of block)
 | 
			
		||||
0:?     'gl_VertexID' (gl_VertexId highp int)
 | 
			
		||||
0:?     'gl_InstanceID' (gl_InstanceId highp int)
 | 
			
		||||
 | 
			
		||||
@ -181,4 +181,25 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:67          unpackHalf2x16 (mediump 2-component vector of float)
 | 
			
		||||
0:67            'uy' (mediump uint)
 | 
			
		||||
0:70      0.000000
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'imax' (mediump int)
 | 
			
		||||
0:?     'imin' (mediump int)
 | 
			
		||||
0:?     'umax' (mediump uint)
 | 
			
		||||
0:?     'umin' (mediump uint)
 | 
			
		||||
0:?     'x' (mediump 3-component vector of float)
 | 
			
		||||
0:?     'y' (mediump 3-component vector of float)
 | 
			
		||||
0:?     'bv' (3-component vector of bool)
 | 
			
		||||
0:?     'uy' (mediump uint)
 | 
			
		||||
0:?     'uv2c' (mediump 2-component vector of uint)
 | 
			
		||||
0:?     'uv2y' (mediump 2-component vector of uint)
 | 
			
		||||
0:?     'uv2x' (mediump 2-component vector of uint)
 | 
			
		||||
0:?     'uv4y' (mediump 4-component vector of uint)
 | 
			
		||||
0:?     'iv3a' (mediump 3-component vector of int)
 | 
			
		||||
0:?     'iv3b' (mediump 3-component vector of int)
 | 
			
		||||
0:?     'iv4a' (mediump 4-component vector of int)
 | 
			
		||||
0:?     'iv4b' (mediump 4-component vector of int)
 | 
			
		||||
0:?     'f' (mediump float)
 | 
			
		||||
0:?     'v2a' (mediump 2-component vector of float)
 | 
			
		||||
0:?     'v2b' (mediump 2-component vector of float)
 | 
			
		||||
0:?     'v4' (mediump 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -199,4 +199,5 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:127        'iv3' (mediump 3-component vector of int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'instanceName' (layout(shared ) uniform block)
 | 
			
		||||
0:?     's' (structure)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -90,6 +90,7 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:62          'S' (structure)
 | 
			
		||||
0:62          0 (const int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'b' (bool)
 | 
			
		||||
0:?     'gl_VertexID' (gl_VertexId highp int)
 | 
			
		||||
0:?     'gl_InstanceID' (gl_InstanceId highp int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
0:3Function Definition: main( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:5    Sequence
 | 
			
		||||
0:5      EmitStreamVertex (void)
 | 
			
		||||
@ -7,4 +8,5 @@
 | 
			
		||||
0:6        0 (const int)
 | 
			
		||||
0:7      EmitVertex (void)
 | 
			
		||||
0:8      EndPrimitive (void)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
0:3Function Definition: main( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:5    Sequence
 | 
			
		||||
0:5      Barrier (void)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,10 @@
 | 
			
		||||
ERROR: 0:5: 'barrier' : no matching overloaded function found 
 | 
			
		||||
ERROR: 1 compilation errors.  No code generated.
 | 
			
		||||
 | 
			
		||||
0:3Function Definition: main( (void)
 | 
			
		||||
ERROR: node is still EOpNull!
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:5    Sequence
 | 
			
		||||
0:5      0.000000
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
0:3Function Definition: main( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:5    Sequence
 | 
			
		||||
0:5      MemoryBarrier (void)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
0:3Function Definition: main( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:5    Sequence
 | 
			
		||||
0:5      MemoryBarrierAtomicCounter (void)
 | 
			
		||||
@ -6,4 +7,5 @@
 | 
			
		||||
0:7      MemoryBarrierShared (void)
 | 
			
		||||
0:8      MemoryBarrierImage (void)
 | 
			
		||||
0:9      GroupMemoryBarrier (void)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -86,6 +86,8 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:62          'S' (structure)
 | 
			
		||||
0:62          0 (const int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'b' (bool)
 | 
			
		||||
0:?     'tan' (float)
 | 
			
		||||
0:?     'gl_VertexID' (gl_VertexId int)
 | 
			
		||||
0:?     'gl_InstanceID' (gl_InstanceId int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -20,4 +20,5 @@ WARNING: #version: statement missing; use #version on first line of shader
 | 
			
		||||
0:39        'gl_Position' (gl_Position highp 4-component vector of float)
 | 
			
		||||
0:39        Construct vec4 (highp 4-component vector of float)
 | 
			
		||||
0:39          'sum' (highp float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,4 +25,5 @@
 | 
			
		||||
0:56        'gl_Position' (gl_Position 4-component vector of float)
 | 
			
		||||
0:56        Construct vec4 (4-component vector of float)
 | 
			
		||||
0:56          'sum' (float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -28,4 +28,5 @@
 | 
			
		||||
0:86        'gl_Position' (gl_Position 4-component vector of float)
 | 
			
		||||
0:86        Construct vec4 (4-component vector of float)
 | 
			
		||||
0:86          'sum' (float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -70,4 +70,6 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:130    move second child to first child (float)
 | 
			
		||||
0:130      'twoPi' (float)
 | 
			
		||||
0:130      6.280000
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'tod' (float)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -113,4 +113,5 @@
 | 
			
		||||
0:53        5 (const int)
 | 
			
		||||
0:55      Pre-Increment (int)
 | 
			
		||||
0:55        'c' (int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,10 +3,12 @@ ERROR: 0:1: 'main' : function cannot take any parameter(s)
 | 
			
		||||
ERROR: 0:1: 'int' :  main function cannot return a value
 | 
			
		||||
ERROR: 2 compilation errors.  No code generated.
 | 
			
		||||
 | 
			
		||||
0:1Function Definition: main(i1; (mediump int)
 | 
			
		||||
ERROR: node is still EOpNull!
 | 
			
		||||
0:1  Function Definition: main(i1; (mediump int)
 | 
			
		||||
0:1    Function Parameters: 
 | 
			
		||||
0:1      'foo' (in mediump int)
 | 
			
		||||
0:3    Sequence
 | 
			
		||||
0:3      Branch: Return with expression
 | 
			
		||||
0:3        1 (const int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -97,4 +97,5 @@
 | 
			
		||||
0:35        Construct vec4 (mediump 4-component vector of float)
 | 
			
		||||
0:35          Convert int to float (mediump float)
 | 
			
		||||
0:35            'color' (mediump int)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,4 +18,5 @@
 | 
			
		||||
0:17        30.000000
 | 
			
		||||
0:17        30.000000
 | 
			
		||||
0:17        30.000000
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:20        Construct vec4 (highp 4-component vector of float)
 | 
			
		||||
0:20          'foo' (highp float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'foo' (highp float)
 | 
			
		||||
0:?     'gl_VertexID' (gl_VertexId highp int)
 | 
			
		||||
0:?     'gl_InstanceID' (gl_InstanceId highp int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										150
									
								
								Test/baseResults/link1.frag.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								Test/baseResults/link1.frag.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,150 @@
 | 
			
		||||
link1.frag
 | 
			
		||||
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:8  Sequence
 | 
			
		||||
0:8    move second child to first child (4-component vector of float)
 | 
			
		||||
0:8      'a' (4-component vector of float)
 | 
			
		||||
0:8      vector-scale (4-component vector of float)
 | 
			
		||||
0:8        8.000000
 | 
			
		||||
0:8        'uv4' (uniform 4-component vector of float)
 | 
			
		||||
0:13  Function Definition: main( (void)
 | 
			
		||||
0:13    Function Parameters: 
 | 
			
		||||
0:17  Sequence
 | 
			
		||||
0:17    move second child to first child (4-component vector of float)
 | 
			
		||||
0:17      'b' (4-component vector of float)
 | 
			
		||||
0:17      vector-scale (4-component vector of float)
 | 
			
		||||
0:17        8.000000
 | 
			
		||||
0:17        'a' (4-component vector of float)
 | 
			
		||||
0:19  Function Definition: foo(mf22; (2-component vector of int)
 | 
			
		||||
0:19    Function Parameters: 
 | 
			
		||||
0:19      'm' (in 2X2 matrix of float)
 | 
			
		||||
0:21    Sequence
 | 
			
		||||
0:21      Branch: Return with expression
 | 
			
		||||
0:21        Convert float to int (2-component vector of int)
 | 
			
		||||
0:21          direct index (in 2-component vector of float)
 | 
			
		||||
0:21            'm' (in 2X2 matrix of float)
 | 
			
		||||
0:21            0 (const int)
 | 
			
		||||
0:24  Sequence
 | 
			
		||||
0:24    move second child to first child (4-component vector of float)
 | 
			
		||||
0:24      'c' (4-component vector of float)
 | 
			
		||||
0:24      component-wise multiply (4-component vector of float)
 | 
			
		||||
0:24        'b' (4-component vector of float)
 | 
			
		||||
0:24        'b' (4-component vector of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'uv4' (uniform 4-component vector of float)
 | 
			
		||||
0:?     'glass' (uniform 3-component vector of float)
 | 
			
		||||
0:?     'iv3' (smooth in 3-component vector of float)
 | 
			
		||||
0:?     'cup' (smooth in 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
link2.frag
 | 
			
		||||
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:8  Sequence
 | 
			
		||||
0:8    move second child to first child (4-component vector of float)
 | 
			
		||||
0:8      'd' (4-component vector of float)
 | 
			
		||||
0:8      vector-scale (4-component vector of float)
 | 
			
		||||
0:8        8.000000
 | 
			
		||||
0:8        'uv4' (uniform 4-component vector of float)
 | 
			
		||||
0:13  Sequence
 | 
			
		||||
0:13    move second child to first child (4-component vector of float)
 | 
			
		||||
0:13      'e' (4-component vector of float)
 | 
			
		||||
0:13      vector-scale (4-component vector of float)
 | 
			
		||||
0:13        8.000000
 | 
			
		||||
0:13        'd' (4-component vector of float)
 | 
			
		||||
0:15  Function Definition: foo( (2-component vector of int)
 | 
			
		||||
0:15    Function Parameters: 
 | 
			
		||||
0:17    Sequence
 | 
			
		||||
0:17      Branch: Return with expression
 | 
			
		||||
0:17        2 (const int)
 | 
			
		||||
0:17        2 (const int)
 | 
			
		||||
0:20  Sequence
 | 
			
		||||
0:20    move second child to first child (4-component vector of float)
 | 
			
		||||
0:20      'f' (4-component vector of float)
 | 
			
		||||
0:20      component-wise multiply (4-component vector of float)
 | 
			
		||||
0:20        'e' (4-component vector of float)
 | 
			
		||||
0:20        'e' (4-component vector of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'uv4' (uniform 4-component vector of float)
 | 
			
		||||
0:?     'glass' (uniform 2-component vector of float)
 | 
			
		||||
0:?     'iv3' (smooth in 3-component vector of float)
 | 
			
		||||
0:?     'cup' (flat in 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
link3.frag
 | 
			
		||||
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'iv3' (smooth in highp 2-component vector of float)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Linked fragment stage:
 | 
			
		||||
 | 
			
		||||
ERROR: Linking fragment stage: Types must match:
 | 
			
		||||
    glass: "uniform 3-component vector of float" versus "uniform 2-component vector of float"
 | 
			
		||||
ERROR: Linking fragment stage: Interpolation and auxiliary storage qualifiers must match:
 | 
			
		||||
    cup: "smooth in 4-component vector of float" versus "flat in 4-component vector of float"
 | 
			
		||||
ERROR: Linking fragment stage: Cannot mix ES profile with non-ES profile shaders
 | 
			
		||||
 | 
			
		||||
ERROR: Linking fragment stage: Types must match:
 | 
			
		||||
ERROR: Linking fragment stage: Precision qualifiers must match:
 | 
			
		||||
    iv3: "smooth in 3-component vector of float" versus "smooth in highp 2-component vector of float"
 | 
			
		||||
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:8  Sequence
 | 
			
		||||
0:8    move second child to first child (4-component vector of float)
 | 
			
		||||
0:8      'a' (4-component vector of float)
 | 
			
		||||
0:8      vector-scale (4-component vector of float)
 | 
			
		||||
0:8        8.000000
 | 
			
		||||
0:8        'uv4' (uniform 4-component vector of float)
 | 
			
		||||
0:13  Function Definition: main( (void)
 | 
			
		||||
0:13    Function Parameters: 
 | 
			
		||||
0:17  Sequence
 | 
			
		||||
0:17    move second child to first child (4-component vector of float)
 | 
			
		||||
0:17      'b' (4-component vector of float)
 | 
			
		||||
0:17      vector-scale (4-component vector of float)
 | 
			
		||||
0:17        8.000000
 | 
			
		||||
0:17        'a' (4-component vector of float)
 | 
			
		||||
0:19  Function Definition: foo(mf22; (2-component vector of int)
 | 
			
		||||
0:19    Function Parameters: 
 | 
			
		||||
0:19      'm' (in 2X2 matrix of float)
 | 
			
		||||
0:21    Sequence
 | 
			
		||||
0:21      Branch: Return with expression
 | 
			
		||||
0:21        Convert float to int (2-component vector of int)
 | 
			
		||||
0:21          direct index (in 2-component vector of float)
 | 
			
		||||
0:21            'm' (in 2X2 matrix of float)
 | 
			
		||||
0:21            0 (const int)
 | 
			
		||||
0:24  Sequence
 | 
			
		||||
0:24    move second child to first child (4-component vector of float)
 | 
			
		||||
0:24      'c' (4-component vector of float)
 | 
			
		||||
0:24      component-wise multiply (4-component vector of float)
 | 
			
		||||
0:24        'b' (4-component vector of float)
 | 
			
		||||
0:24        'b' (4-component vector of float)
 | 
			
		||||
0:8  Sequence
 | 
			
		||||
0:8    move second child to first child (4-component vector of float)
 | 
			
		||||
0:8      'd' (4-component vector of float)
 | 
			
		||||
0:8      vector-scale (4-component vector of float)
 | 
			
		||||
0:8        8.000000
 | 
			
		||||
0:8        'uv4' (uniform 4-component vector of float)
 | 
			
		||||
0:13  Sequence
 | 
			
		||||
0:13    move second child to first child (4-component vector of float)
 | 
			
		||||
0:13      'e' (4-component vector of float)
 | 
			
		||||
0:13      vector-scale (4-component vector of float)
 | 
			
		||||
0:13        8.000000
 | 
			
		||||
0:13        'd' (4-component vector of float)
 | 
			
		||||
0:15  Function Definition: foo( (2-component vector of int)
 | 
			
		||||
0:15    Function Parameters: 
 | 
			
		||||
0:17    Sequence
 | 
			
		||||
0:17      Branch: Return with expression
 | 
			
		||||
0:17        2 (const int)
 | 
			
		||||
0:17        2 (const int)
 | 
			
		||||
0:20  Sequence
 | 
			
		||||
0:20    move second child to first child (4-component vector of float)
 | 
			
		||||
0:20      'f' (4-component vector of float)
 | 
			
		||||
0:20      component-wise multiply (4-component vector of float)
 | 
			
		||||
0:20        'e' (4-component vector of float)
 | 
			
		||||
0:20        'e' (4-component vector of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'uv4' (uniform 4-component vector of float)
 | 
			
		||||
0:?     'glass' (uniform 3-component vector of float)
 | 
			
		||||
0:?     'iv3' (smooth in 3-component vector of float)
 | 
			
		||||
0:?     'cup' (smooth in 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
@ -1,33 +1,54 @@
 | 
			
		||||
mains1.frag
 | 
			
		||||
 | 
			
		||||
0:3Function Definition: main( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
mains2.frag
 | 
			
		||||
 | 
			
		||||
0:3Function Definition: main( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
noMain1.geom
 | 
			
		||||
ERROR: #version: geometry shaders require non-es profile and version 150 or above
 | 
			
		||||
ERROR: 1 compilation errors.  No code generated.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
0:3Function Definition: foo( (void)
 | 
			
		||||
ERROR: node is still EOpNull!
 | 
			
		||||
0:3  Function Definition: foo( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
noMain2.geom
 | 
			
		||||
 | 
			
		||||
0:3Function Definition: bar( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: bar( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Linked geometry stage:
 | 
			
		||||
 | 
			
		||||
ERROR: Missing entry point: Each stage requires one "void main()" entry point
 | 
			
		||||
ERROR: Linking geometry stage: Missing entry point: Each stage requires one "void main()" entry point
 | 
			
		||||
 | 
			
		||||
Linked fragment stage:
 | 
			
		||||
 | 
			
		||||
ERROR: Too many entry points: Each stage can have at most one "void main()" entry point.
 | 
			
		||||
ERROR: Linking fragment stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
 | 
			
		||||
    main(
 | 
			
		||||
 | 
			
		||||
ERROR: node is still EOpNull!
 | 
			
		||||
0:3  Function Definition: foo( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:3  Function Definition: bar( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,11 @@
 | 
			
		||||
noMain.vert
 | 
			
		||||
 | 
			
		||||
0:3Function Definition: foo( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: foo( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'gl_VertexID' (gl_VertexId highp int)
 | 
			
		||||
0:?     'gl_InstanceID' (gl_InstanceId highp int)
 | 
			
		||||
 | 
			
		||||
mains.frag
 | 
			
		||||
ERROR: 0:7: 'main' : function already has a body 
 | 
			
		||||
@ -13,14 +17,14 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:7  Function Definition: main( (void)
 | 
			
		||||
0:7    Function Parameters: 
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Linked vertex stage:
 | 
			
		||||
 | 
			
		||||
ERROR: Missing entry point: Each stage requires one "void main()" entry point
 | 
			
		||||
ERROR: Linking vertex stage: Missing entry point: Each stage requires one "void main()" entry point
 | 
			
		||||
 | 
			
		||||
Linked fragment stage:
 | 
			
		||||
 | 
			
		||||
ERROR: Too many entry points: Each stage can have at most one "void main()" entry point.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -103,7 +103,10 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:69        0.200000
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'color' (smooth in mediump 3-component vector of float)
 | 
			
		||||
0:?     'global_medium' (mediump int)
 | 
			
		||||
0:?     'samplerLow' (uniform lowp sampler2D)
 | 
			
		||||
0:?     'samplerMed' (uniform mediump sampler2D)
 | 
			
		||||
0:?     'samplerHigh' (uniform highp sampler2D)
 | 
			
		||||
0:?     'uint' (mediump 4-component vector of float)
 | 
			
		||||
0:?     'global_high' (highp int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
0:3Function Definition: main( (void)
 | 
			
		||||
0:? Sequence
 | 
			
		||||
0:3  Function Definition: main( (void)
 | 
			
		||||
0:3    Function Parameters: 
 | 
			
		||||
0:?     Sequence
 | 
			
		||||
0:10      Sequence
 | 
			
		||||
@ -109,4 +110,5 @@
 | 
			
		||||
0:37        vector-scale (4-component vector of float)
 | 
			
		||||
0:37          'z' (float)
 | 
			
		||||
0:37          'v' (4-component vector of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -196,6 +196,22 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:218            'c' (5-element array of float)
 | 
			
		||||
0:218            'a' (5-element array of float)
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'fa' (float)
 | 
			
		||||
0:?     'fc' (double)
 | 
			
		||||
0:?     'texcoord1' (2-component vector of float)
 | 
			
		||||
0:?     'texcoord2' (2-component vector of float)
 | 
			
		||||
0:?     'position' (3-component vector of float)
 | 
			
		||||
0:?     'myRGBA' (4-component vector of float)
 | 
			
		||||
0:?     'textureLookup' (2-component vector of int)
 | 
			
		||||
0:?     'less' (3-component vector of bool)
 | 
			
		||||
0:?     'mat2D' (2X2 matrix of float)
 | 
			
		||||
0:?     'optMatrix' (3X3 matrix of float)
 | 
			
		||||
0:?     'view' (4X4 matrix of float)
 | 
			
		||||
0:?     'projection' (4X4 matrix of float)
 | 
			
		||||
0:?     'm' (3X2 matrix of float)
 | 
			
		||||
0:?     'highPrecisionMVP' (4X4 matrix of double)
 | 
			
		||||
0:?     'dm' (2X4 matrix of double)
 | 
			
		||||
0:?     'lightVar' (structure)
 | 
			
		||||
0:?     'normal' (smooth in 3-component vector of float)
 | 
			
		||||
0:?     'TexCoord' (centroid smooth in 2-component vector of float)
 | 
			
		||||
0:?     'Color' (invariant centroid smooth in 4-component vector of float)
 | 
			
		||||
 | 
			
		||||
@ -2,4 +2,9 @@ ERROR: 0:9: 'vec5' : undeclared identifier
 | 
			
		||||
ERROR: 0:9: '' :  syntax error
 | 
			
		||||
ERROR: 2 compilation errors.  No code generated.
 | 
			
		||||
 | 
			
		||||
ERROR: node is still EOpNull!
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'bigColor' (uniform 4-component vector of float)
 | 
			
		||||
0:?     'BaseColor' (smooth in 4-component vector of float)
 | 
			
		||||
0:?     'd' (uniform float)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -77,6 +77,7 @@ ERROR: node is still EOpNull!
 | 
			
		||||
0:?   Linker Objects
 | 
			
		||||
0:?     'BCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789' (in highp float)
 | 
			
		||||
0:?     'ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789' (in highp float)
 | 
			
		||||
0:?     'BCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789B' (highp float)
 | 
			
		||||
0:?     'gl_VertexID' (gl_VertexId highp int)
 | 
			
		||||
0:?     'gl_InstanceID' (gl_InstanceId highp int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								Test/link1.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Test/link1.frag
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
#version 130
 | 
			
		||||
 | 
			
		||||
uniform vec4 uv4;
 | 
			
		||||
uniform vec3 glass;
 | 
			
		||||
 | 
			
		||||
const int ci = 8;
 | 
			
		||||
 | 
			
		||||
vec4 a = ci * uv4;
 | 
			
		||||
 | 
			
		||||
in vec3 iv3;
 | 
			
		||||
in vec4 cup;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec4 b = ci * a;
 | 
			
		||||
 | 
			
		||||
ivec2 foo(mat2 m)
 | 
			
		||||
{
 | 
			
		||||
    return ivec2(m[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec4 c = b * b;
 | 
			
		||||
							
								
								
									
										20
									
								
								Test/link2.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Test/link2.frag
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
#version 130
 | 
			
		||||
 | 
			
		||||
uniform vec4 uv4;
 | 
			
		||||
uniform vec2 glass;
 | 
			
		||||
 | 
			
		||||
const int ci = 8;
 | 
			
		||||
 | 
			
		||||
vec4 d = ci * uv4;
 | 
			
		||||
 | 
			
		||||
in vec3 iv3;
 | 
			
		||||
flat in vec4 cup;
 | 
			
		||||
 | 
			
		||||
vec4 e = ci * d;
 | 
			
		||||
 | 
			
		||||
ivec2 foo()
 | 
			
		||||
{
 | 
			
		||||
    return ivec2(2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec4 f = e * e;
 | 
			
		||||
							
								
								
									
										5
									
								
								Test/link3.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Test/link3.frag
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
#version 300 es
 | 
			
		||||
 | 
			
		||||
precision highp float;
 | 
			
		||||
 | 
			
		||||
in vec2 iv3;
 | 
			
		||||
@ -34,6 +34,7 @@ function runLinkTest {
 | 
			
		||||
 | 
			
		||||
runLinkTest mains1.frag mains2.frag noMain1.geom noMain2.geom
 | 
			
		||||
runLinkTest noMain.vert mains.frag
 | 
			
		||||
runLinkTest link1.frag link2.frag link3.frag
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# multi-threaded test
 | 
			
		||||
@ -42,4 +43,3 @@ echo Comparing single thread to multithread for all tests in current directory..
 | 
			
		||||
$EXE -i *.vert *.geom *.frag *.tes* *.comp > singleThread.out
 | 
			
		||||
$EXE -i *.vert *.geom *.frag *.tes* *.comp -t > multiThread.out
 | 
			
		||||
diff singleThread.out multiThread.out
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								Todo.txt
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Todo.txt
									
									
									
									
									
								
							@ -11,25 +11,28 @@ Link Validation
 | 
			
		||||
      - mixed es/non-es profiles
 | 
			
		||||
      - statically consumed input not produced by previous stage
 | 
			
		||||
      - matching between gl_PerVertex blocks and gl_PerFragment blocks
 | 
			
		||||
      - compute shader not with other stages
 | 
			
		||||
      - compute shader not combined with any other stages
 | 
			
		||||
      - give error for sharing a packed block
 | 
			
		||||
      - 1.3: deprecated mixing fixed vertex/fragment stage with programmable fragment/vertex stage.
 | 
			
		||||
      - 4.3: remove cross-version linking restrictions.
 | 
			
		||||
      - 4.3: Allow mismatches in interpolation and auxiliary qualification across stages.
 | 
			
		||||
	  - 4.4: A stage contains two different blocks, each with no instance name, where the blocks contain a member with the same name.
 | 
			
		||||
    Intra-stage linking
 | 
			
		||||
      - exactly one main
 | 
			
		||||
      - type consistency check of uniforms, globals, ins, and outs, both variables and blocks
 | 
			
		||||
      + exactly one main
 | 
			
		||||
      + type consistency check of uniforms, globals, ins, and outs
 | 
			
		||||
        - still need to cover arrays and the combinations of this rule with redeclarations of built-ins
 | 
			
		||||
      - value checking of global const initializers
 | 
			
		||||
      - value checking of uniform initializers
 | 
			
		||||
      - location/component/binding/index/offset match check
 | 
			
		||||
      + location match
 | 
			
		||||
      - component/binding/index/offset match check
 | 
			
		||||
      - location/component aliasing (except desktop vertex shader inputs)
 | 
			
		||||
      - location layout range/overlap semantics
 | 
			
		||||
      - geometry shader input array sizes and input layout qualifier declaration
 | 
			
		||||
      - compute shader layout(local_size_*) matching
 | 
			
		||||
      - mixed es/non-es profiles
 | 
			
		||||
      - matching initializers for globals
 | 
			
		||||
      + mixed es/non-es profiles
 | 
			
		||||
      - recursion for both functions and subroutines
 | 
			
		||||
        - Even the potential for recursion through subroutine uniforms is an error.
 | 
			
		||||
      - block matching
 | 
			
		||||
        - matching redeclarations of interface blocks
 | 
			
		||||
      - read or write to both gl_ClipVertex and gl_ClipDistance
 | 
			
		||||
      - write to only one of gl_FragColor, gl_FragData, or user-declared
 | 
			
		||||
 | 
			
		||||
@ -850,7 +850,7 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TIntermediate::addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable)
 | 
			
		||||
void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable)
 | 
			
		||||
{
 | 
			
		||||
    // Add top-level nodes for declarations that must be checked cross
 | 
			
		||||
    // compilation unit by a linker, yet might not have been referenced
 | 
			
		||||
@ -880,13 +880,9 @@ void TIntermediate::addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*&
 | 
			
		||||
        addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (linkage) {
 | 
			
		||||
        // Finish off linkage sequence
 | 
			
		||||
        linkage->setOperator(EOpLinkerObjects);
 | 
			
		||||
 | 
			
		||||
    // Add a child to the root node for the linker objects    
 | 
			
		||||
        growAggregate(root, linkage);
 | 
			
		||||
    }
 | 
			
		||||
    linkage->setOperator(EOpLinkerObjects);
 | 
			
		||||
    treeRoot = growAggregate(treeRoot, linkage);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name)
 | 
			
		||||
@ -903,29 +899,178 @@ void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TVari
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Merge the information in 'unit' into 'this'
 | 
			
		||||
// Merge the information from 'unit' into 'this'
 | 
			
		||||
//
 | 
			
		||||
void TIntermediate::merge(TIntermediate& unit)
 | 
			
		||||
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
 | 
			
		||||
{
 | 
			
		||||
    numMains += unit.numMains;
 | 
			
		||||
 | 
			
		||||
    if (profile != EEsProfile && unit.profile == EEsProfile ||
 | 
			
		||||
        profile == EEsProfile && unit.profile != EEsProfile)
 | 
			
		||||
        error(infoSink, "Cannot mix ES profile with non-ES profile shaders\n");
 | 
			
		||||
 | 
			
		||||
    if (unit.treeRoot == 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (treeRoot == 0) {
 | 
			
		||||
        version = unit.version;
 | 
			
		||||
        treeRoot = unit.treeRoot;
 | 
			
		||||
        return;
 | 
			
		||||
    } else
 | 
			
		||||
        version = std::max(version, unit.version);
 | 
			
		||||
 | 
			
		||||
    // Get the top-level globals of each level
 | 
			
		||||
    TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
 | 
			
		||||
    TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence();
 | 
			
		||||
 | 
			
		||||
    // Get the last members of the sequences, expected to be the linker-object lists
 | 
			
		||||
    assert(globals.back()->getAsAggregate()->getOp() == EOpLinkerObjects);
 | 
			
		||||
    assert(unitGlobals.back()->getAsAggregate()->getOp() == EOpLinkerObjects);
 | 
			
		||||
    TIntermSequence& linkerObjects = globals.back()->getAsAggregate()->getSequence();
 | 
			
		||||
    TIntermSequence& unitLinkerObjects = unitGlobals.back()->getAsAggregate()->getSequence();
 | 
			
		||||
 | 
			
		||||
    mergeBodies(infoSink, globals, unitGlobals);
 | 
			
		||||
    mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Merge the function bodies and global-level initalizers from unitGlobals into globals.
 | 
			
		||||
// Will error check duplication of function bodies for the same signature.
 | 
			
		||||
//
 | 
			
		||||
void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, const TIntermSequence& unitGlobals)
 | 
			
		||||
{
 | 
			
		||||
    // TODO: Performance: Processing in alphabetical order will be faster
 | 
			
		||||
 | 
			
		||||
    // Error check the global objects, not including the linker objects
 | 
			
		||||
    for (unsigned int child = 0; child < globals.size() - 1; ++child) {
 | 
			
		||||
        for (unsigned int unitChild = 0; unitChild < unitGlobals.size() - 1; ++unitChild) {
 | 
			
		||||
            TIntermAggregate* body = globals[child]->getAsAggregate();
 | 
			
		||||
            TIntermAggregate* unitBody = unitGlobals[unitChild]->getAsAggregate();
 | 
			
		||||
            if (body && unitBody && body->getOp() == EOpFunction && unitBody->getOp() == EOpFunction && body->getName() == unitBody->getName()) {
 | 
			
		||||
                error(infoSink, "Multiple function bodies in multiple compilation units for the same signature in the same stage:");
 | 
			
		||||
                infoSink.info << "    " << globals[child]->getAsAggregate()->getName() << "\n";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Merge the global objects, just in front of the linker objects
 | 
			
		||||
    globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Merge the linker objects from unitLinkerObjects into linkerObjects.
 | 
			
		||||
// Duplication is expected and filtered out, but contradictions are an error.
 | 
			
		||||
//
 | 
			
		||||
void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects)
 | 
			
		||||
{
 | 
			
		||||
    // Error check and merge the linker objects (duplicates should not be merged)
 | 
			
		||||
    unsigned int initialNumLinkerObjects = linkerObjects.size();
 | 
			
		||||
    for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) {
 | 
			
		||||
        bool merge = true;
 | 
			
		||||
        for (unsigned int linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
 | 
			
		||||
            TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
 | 
			
		||||
            TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
 | 
			
		||||
            assert(symbol && unitSymbol);
 | 
			
		||||
            if (symbol->getName() == unitSymbol->getName()) {
 | 
			
		||||
                // filter out copy
 | 
			
		||||
                merge = false;
 | 
			
		||||
                
 | 
			
		||||
                // Check for consistent types/qualification/etc.
 | 
			
		||||
                linkErrorCheck(infoSink, *symbol, *unitSymbol, false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (merge)
 | 
			
		||||
            linkerObjects.push_back(unitLinkerObjects[unitLinkObj]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TIntermediate::errorCheck(TInfoSink& infoSink)
 | 
			
		||||
{   
 | 
			
		||||
    if (numMains < 1)
 | 
			
		||||
        error(infoSink, "Missing entry point: Each stage requires one \"void main()\" entry point");
 | 
			
		||||
    if (numMains > 1)
 | 
			
		||||
        error(infoSink, "Too many entry points: Each stage can have at most one \"void main()\" entry point.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TIntermediate::error(TInfoSink& infoSink, const char* message)
 | 
			
		||||
{
 | 
			
		||||
    infoSink.info.prefix(EPrefixError);
 | 
			
		||||
    infoSink.info << message << "\n";
 | 
			
		||||
    infoSink.info << "Linking " << StageName[language] << " stage: " << message << "\n";
 | 
			
		||||
 | 
			
		||||
    ++numErrors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Compare two global objects from two compilation units and see if they match
 | 
			
		||||
// well enough.  Rules can be different for intra- vs. cross-stage matching.
 | 
			
		||||
//
 | 
			
		||||
// This function only does one of intra- or cross-stage matching per call.
 | 
			
		||||
//
 | 
			
		||||
// TODO: Linker Functionality: this function is under active development
 | 
			
		||||
//
 | 
			
		||||
void TIntermediate::linkErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
 | 
			
		||||
{
 | 
			
		||||
    bool writeTypeComparison = false;
 | 
			
		||||
 | 
			
		||||
    // Types have to match
 | 
			
		||||
    if (symbol.getType() != unitSymbol.getType()) {
 | 
			
		||||
        error(infoSink, "Types must match:");
 | 
			
		||||
        writeTypeComparison = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Qualifiers have to (almost) match
 | 
			
		||||
 | 
			
		||||
    // Storage...
 | 
			
		||||
    if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
 | 
			
		||||
        error(infoSink, "Storage qualifiers must match:");
 | 
			
		||||
        writeTypeComparison = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Precision...
 | 
			
		||||
    if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
 | 
			
		||||
        error(infoSink, "Precision qualifiers must match:");
 | 
			
		||||
        writeTypeComparison = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Invariance...
 | 
			
		||||
    if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) {
 | 
			
		||||
        error(infoSink, "Presence of invariant qualifier must match:");
 | 
			
		||||
        writeTypeComparison = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Auxiliary and interpolation...
 | 
			
		||||
    if (symbol.getQualifier().centroid  != unitSymbol.getQualifier().centroid ||
 | 
			
		||||
        symbol.getQualifier().smooth    != unitSymbol.getQualifier().smooth ||
 | 
			
		||||
        symbol.getQualifier().flat      != unitSymbol.getQualifier().flat ||
 | 
			
		||||
        symbol.getQualifier().sample    != unitSymbol.getQualifier().sample ||
 | 
			
		||||
        symbol.getQualifier().patch     != unitSymbol.getQualifier().patch ||
 | 
			
		||||
        symbol.getQualifier().nopersp   != unitSymbol.getQualifier().nopersp) {
 | 
			
		||||
        error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
 | 
			
		||||
        writeTypeComparison = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Memory...
 | 
			
		||||
    if (symbol.getQualifier().shared    != unitSymbol.getQualifier().shared ||
 | 
			
		||||
        symbol.getQualifier().coherent  != unitSymbol.getQualifier().coherent ||
 | 
			
		||||
        symbol.getQualifier().volatil   != unitSymbol.getQualifier().volatil ||
 | 
			
		||||
        symbol.getQualifier().restrict  != unitSymbol.getQualifier().restrict ||
 | 
			
		||||
        symbol.getQualifier().readonly  != unitSymbol.getQualifier().readonly ||
 | 
			
		||||
        symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
 | 
			
		||||
        error(infoSink, "Memory qualifiers must match:");
 | 
			
		||||
        writeTypeComparison = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Layouts...
 | 
			
		||||
    if (symbol.getQualifier().layoutMatrix       != unitSymbol.getQualifier().layoutMatrix ||
 | 
			
		||||
        symbol.getQualifier().layoutPacking      != unitSymbol.getQualifier().layoutPacking ||
 | 
			
		||||
        symbol.getQualifier().layoutSlotLocation != unitSymbol.getQualifier().layoutSlotLocation) {
 | 
			
		||||
        error(infoSink, "Layout qualification must match:");
 | 
			
		||||
        writeTypeComparison = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (writeTypeComparison)
 | 
			
		||||
        infoSink.info << "    " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" <<
 | 
			
		||||
                                                             unitSymbol.getType().getCompleteString() << "\"\n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// This deletes the tree.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@ -51,12 +51,15 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
 | 
			
		||||
            intermediate(interm), symbolTable(symt), infoSink(is), language(L),
 | 
			
		||||
            version(v), profile(p), forwardCompatible(fc), messages(m),    
 | 
			
		||||
            contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0),
 | 
			
		||||
            linkage(0), tokensBeforeEOF(false),
 | 
			
		||||
            tokensBeforeEOF(false),
 | 
			
		||||
            parsingBuiltins(pb), numErrors(0), afterEOF(false)
 | 
			
		||||
{
 | 
			
		||||
    currentLoc.line = 1;
 | 
			
		||||
    currentLoc.string = 0;
 | 
			
		||||
 | 
			
		||||
    // ensure we always have a linkage node, even if empty, to simplify tree topology algorithms
 | 
			
		||||
    linkage = new TIntermAggregate;
 | 
			
		||||
 | 
			
		||||
    // set all precision defaults to EpqNone, which is correct for all desktop types
 | 
			
		||||
    // and for ES types that don't have defaults (thus getting an error on use)
 | 
			
		||||
    for (int type = 0; type < EbtNumTypes; ++type)
 | 
			
		||||
@ -1808,8 +1811,10 @@ void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TPubl
 | 
			
		||||
void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicType& publicType)
 | 
			
		||||
{
 | 
			
		||||
    TType type(publicType);
 | 
			
		||||
    bool newDeclaration;
 | 
			
		||||
 | 
			
		||||
    bool newDeclaration;    // true if a new entry gets added to the symbol table
 | 
			
		||||
    TVariable* variable = redeclare(loc, identifier, type, newDeclaration);
 | 
			
		||||
    
 | 
			
		||||
    if (! variable) {
 | 
			
		||||
        reservedErrorCheck(loc, identifier);
 | 
			
		||||
        variable = new TVariable(&identifier, type);
 | 
			
		||||
@ -1823,7 +1828,7 @@ void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicTyp
 | 
			
		||||
        voidErrorCheck(loc, identifier, publicType);
 | 
			
		||||
 | 
			
		||||
        // see if it's a linker-level object to track
 | 
			
		||||
        if (type.getQualifier().isUniform() || type.getQualifier().isPipeInput() || type.getQualifier().isPipeOutput())
 | 
			
		||||
        if (type.getQualifier().isUniform() || type.getQualifier().isPipeInput() || type.getQualifier().isPipeOutput() || type.getQualifier().storage == EvqGlobal)
 | 
			
		||||
            intermediate.addSymbolLinkageNode(linkage, *variable);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1831,11 +1836,11 @@ void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicTyp
 | 
			
		||||
//
 | 
			
		||||
// See if the identifier is a built-in symbol that can be redeclared,
 | 
			
		||||
// and if so, copy of the symbol table's read-only built-in to the current
 | 
			
		||||
// globol level, so it can be modified.
 | 
			
		||||
// global level, so it can be modified.
 | 
			
		||||
//
 | 
			
		||||
TVariable* TParseContext::redeclare(TSourceLoc loc, const TString& identifier, const TType& type, bool& newDeclaration)
 | 
			
		||||
{
 | 
			
		||||
    newDeclaration = false;
 | 
			
		||||
    newDeclaration = false;  // true if a new entry gets added to the symbol table
 | 
			
		||||
 | 
			
		||||
    if (profile == EEsProfile || identifier.substr(0, 3) != TString("gl_") || symbolTable.atBuiltInLevel())
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
@ -106,7 +106,7 @@ TPoolAllocator* PerProcessGPA = 0;
 | 
			
		||||
bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink, 
 | 
			
		||||
                           TSymbolTable& symbolTable)
 | 
			
		||||
{
 | 
			
		||||
    TIntermediate intermediate(version, profile);
 | 
			
		||||
    TIntermediate intermediate(language, version, profile);
 | 
			
		||||
	
 | 
			
		||||
    TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink);
 | 
			
		||||
    TPpContext ppContext(parseContext);
 | 
			
		||||
@ -452,7 +452,7 @@ bool CompileDeferred(
 | 
			
		||||
    bool ret = parseContext.parseShaderStrings(ppContext, const_cast<char**>(shaderStrings), lengths, numStrings);
 | 
			
		||||
    if (! ret)
 | 
			
		||||
        success = false;
 | 
			
		||||
    intermediate.addSymbolLinkageNodes(intermediate.getTreeRoot(), parseContext.linkage, parseContext.language, symbolTable);
 | 
			
		||||
    intermediate.addSymbolLinkageNodes(parseContext.linkage, parseContext.language, symbolTable);
 | 
			
		||||
 | 
			
		||||
    // Clean up the symbol table. The AST is self-sufficient now.
 | 
			
		||||
    delete symbolTableMemory;
 | 
			
		||||
@ -595,7 +595,7 @@ int ShCompile(
 | 
			
		||||
    compiler->infoSink.info.erase();
 | 
			
		||||
    compiler->infoSink.debug.erase();
 | 
			
		||||
 | 
			
		||||
    TIntermediate intermediate;
 | 
			
		||||
    TIntermediate intermediate(compiler->getLanguage());
 | 
			
		||||
    bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, optLevel, resources, defaultVersion, forwardCompatible, messages, intermediate);
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
@ -866,7 +866,7 @@ TShader::TShader(EShLanguage s)
 | 
			
		||||
{
 | 
			
		||||
    infoSink = new TInfoSink;
 | 
			
		||||
    compiler = new TDeferredCompiler(stage, *infoSink);
 | 
			
		||||
    intermediate = new TIntermediate;
 | 
			
		||||
    intermediate = new TIntermediate(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TShader::~TShader()
 | 
			
		||||
@ -941,7 +941,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
 | 
			
		||||
    if (stages[stage].size() == 1)
 | 
			
		||||
        merged = stages[stage].front()->intermediate;    
 | 
			
		||||
    else {
 | 
			
		||||
        intermediate[stage] = new TIntermediate();
 | 
			
		||||
        intermediate[stage] = new TIntermediate(stage);
 | 
			
		||||
        merged = intermediate[stage];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -950,7 +950,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
 | 
			
		||||
    if (stages[stage].size() > 1) {
 | 
			
		||||
        std::list<TShader*>::const_iterator it;
 | 
			
		||||
        for (it = stages[stage].begin(); it != stages[stage].end(); ++it)
 | 
			
		||||
            merged->merge(*(*it)->intermediate);
 | 
			
		||||
            merged->merge(*infoSink, *(*it)->intermediate);
 | 
			
		||||
 | 
			
		||||
        if (messages & EShMsgAST)
 | 
			
		||||
            merged->outputTree(*infoSink);
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ class TVariable;
 | 
			
		||||
//
 | 
			
		||||
class TIntermediate {
 | 
			
		||||
public:
 | 
			
		||||
    explicit TIntermediate(int v = 0, EProfile p = ENoProfile) : treeRoot(0), profile(p), version(v), numMains(0), numErrors(0) { }
 | 
			
		||||
    explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), numMains(0), numErrors(0) { }
 | 
			
		||||
 | 
			
		||||
    void setVersion(int v) { version = v; }
 | 
			
		||||
    int getVersion() const { return version; }
 | 
			
		||||
@ -95,20 +95,24 @@ public:
 | 
			
		||||
    TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
 | 
			
		||||
    TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
 | 
			
		||||
    bool postProcess(TIntermNode*, EShLanguage);
 | 
			
		||||
    void addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
 | 
			
		||||
    void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
 | 
			
		||||
    void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
 | 
			
		||||
    void addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable&);
 | 
			
		||||
 | 
			
		||||
    void merge(TIntermediate&);
 | 
			
		||||
    void errorCheck(TInfoSink& infoSink);
 | 
			
		||||
    void merge(TInfoSink&, TIntermediate&);
 | 
			
		||||
    void errorCheck(TInfoSink&);
 | 
			
		||||
 | 
			
		||||
    void outputTree(TInfoSink& infoSink);
 | 
			
		||||
    void outputTree(TInfoSink&);
 | 
			
		||||
	void removeTree();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
 | 
			
		||||
    void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
 | 
			
		||||
    void error(TInfoSink& infoSink, const char*);
 | 
			
		||||
    void linkErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    EShLanguage language;
 | 
			
		||||
    TIntermNode* treeRoot;
 | 
			
		||||
    EProfile profile;
 | 
			
		||||
    int version;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user