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:
John Kessenich 2013-09-24 21:18:46 +00:00
parent f5ebfb5f27
commit 337dbc7d8c
37 changed files with 657 additions and 196 deletions

View File

@ -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 'gl_TexCoord' (smooth in unsized array of 4-component vector of float)
0:121 3 (const int) 0:121 3 (const int)
0:? Linker Objects 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:? 'i' (smooth in 4-component vector of float)
0:? 'o' (out 4-component vector of float) 0:? 'o' (out 4-component vector of float)
0:? 's2D' (uniform sampler2D) 0:? 's2D' (uniform sampler2D)
0:? 'centTexCoord' (centroid smooth in 2-component vector of float) 0:? 'centTexCoord' (centroid smooth in 2-component vector of float)
0:? 'm' (uniform 4X2 matrix of float) 0:? 'm' (uniform 4X2 matrix of float)
0:? 'imageBuffer' (float)
0:? 'uimage2DRect' (float)

View File

@ -134,6 +134,7 @@ ERROR: node is still EOpNull!
0:? 'rep2' (centroid smooth sample out highp 4-component vector of float) 0:? 'rep2' (centroid smooth sample out highp 4-component vector of float)
0:? 'rep3' (in highp 4-component vector of float) 0:? 'rep3' (in highp 4-component vector of float)
0:? 's' (smooth out structure) 0:? 's' (smooth out structure)
0:? 'badsize2' (unsized array of highp float)
0:? 'ubInst' (layout(shared ) uniform unsized array of block) 0:? 'ubInst' (layout(shared ) uniform unsized array of block)
0:? 'gl_VertexID' (gl_VertexId highp int) 0:? 'gl_VertexID' (gl_VertexId highp int)
0:? 'gl_InstanceID' (gl_InstanceId highp int) 0:? 'gl_InstanceID' (gl_InstanceId highp int)

View File

@ -181,4 +181,25 @@ ERROR: node is still EOpNull!
0:67 unpackHalf2x16 (mediump 2-component vector of float) 0:67 unpackHalf2x16 (mediump 2-component vector of float)
0:67 'uy' (mediump uint) 0:67 'uy' (mediump uint)
0:70 0.000000 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)

View File

@ -199,4 +199,5 @@ ERROR: node is still EOpNull!
0:127 'iv3' (mediump 3-component vector of int) 0:127 'iv3' (mediump 3-component vector of int)
0:? Linker Objects 0:? Linker Objects
0:? 'instanceName' (layout(shared ) uniform block) 0:? 'instanceName' (layout(shared ) uniform block)
0:? 's' (structure)

View File

@ -90,6 +90,7 @@ ERROR: node is still EOpNull!
0:62 'S' (structure) 0:62 'S' (structure)
0:62 0 (const int) 0:62 0 (const int)
0:? Linker Objects 0:? Linker Objects
0:? 'b' (bool)
0:? 'gl_VertexID' (gl_VertexId highp int) 0:? 'gl_VertexID' (gl_VertexId highp int)
0:? 'gl_InstanceID' (gl_InstanceId highp int) 0:? 'gl_InstanceID' (gl_InstanceId highp int)

View File

@ -1,4 +1,5 @@
0:3Function Definition: main( (void) 0:? Sequence
0:3 Function Definition: main( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:5 Sequence 0:5 Sequence
0:5 EmitStreamVertex (void) 0:5 EmitStreamVertex (void)
@ -7,4 +8,5 @@
0:6 0 (const int) 0:6 0 (const int)
0:7 EmitVertex (void) 0:7 EmitVertex (void)
0:8 EndPrimitive (void) 0:8 EndPrimitive (void)
0:? Linker Objects

View File

@ -1,5 +1,7 @@
0:3Function Definition: main( (void) 0:? Sequence
0:3 Function Definition: main( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:5 Sequence 0:5 Sequence
0:5 Barrier (void) 0:5 Barrier (void)
0:? Linker Objects

View File

@ -1,8 +1,10 @@
ERROR: 0:5: 'barrier' : no matching overloaded function found ERROR: 0:5: 'barrier' : no matching overloaded function found
ERROR: 1 compilation errors. No code generated. 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:3 Function Parameters:
0:5 Sequence 0:5 Sequence
0:5 0.000000 0:5 0.000000
0:? Linker Objects

View File

@ -1,5 +1,7 @@
0:3Function Definition: main( (void) 0:? Sequence
0:3 Function Definition: main( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:5 Sequence 0:5 Sequence
0:5 MemoryBarrier (void) 0:5 MemoryBarrier (void)
0:? Linker Objects

View File

@ -1,4 +1,5 @@
0:3Function Definition: main( (void) 0:? Sequence
0:3 Function Definition: main( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:5 Sequence 0:5 Sequence
0:5 MemoryBarrierAtomicCounter (void) 0:5 MemoryBarrierAtomicCounter (void)
@ -6,4 +7,5 @@
0:7 MemoryBarrierShared (void) 0:7 MemoryBarrierShared (void)
0:8 MemoryBarrierImage (void) 0:8 MemoryBarrierImage (void)
0:9 GroupMemoryBarrier (void) 0:9 GroupMemoryBarrier (void)
0:? Linker Objects

View File

@ -86,6 +86,8 @@ ERROR: node is still EOpNull!
0:62 'S' (structure) 0:62 'S' (structure)
0:62 0 (const int) 0:62 0 (const int)
0:? Linker Objects 0:? Linker Objects
0:? 'b' (bool)
0:? 'tan' (float)
0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_VertexID' (gl_VertexId int)
0:? 'gl_InstanceID' (gl_InstanceId int) 0:? 'gl_InstanceID' (gl_InstanceId int)

View File

@ -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 'gl_Position' (gl_Position highp 4-component vector of float)
0:39 Construct vec4 (highp 4-component vector of float) 0:39 Construct vec4 (highp 4-component vector of float)
0:39 'sum' (highp float) 0:39 'sum' (highp float)
0:? Linker Objects

View File

@ -25,4 +25,5 @@
0:56 'gl_Position' (gl_Position 4-component vector of float) 0:56 'gl_Position' (gl_Position 4-component vector of float)
0:56 Construct vec4 (4-component vector of float) 0:56 Construct vec4 (4-component vector of float)
0:56 'sum' (float) 0:56 'sum' (float)
0:? Linker Objects

View File

@ -28,4 +28,5 @@
0:86 'gl_Position' (gl_Position 4-component vector of float) 0:86 'gl_Position' (gl_Position 4-component vector of float)
0:86 Construct vec4 (4-component vector of float) 0:86 Construct vec4 (4-component vector of float)
0:86 'sum' (float) 0:86 'sum' (float)
0:? Linker Objects

View File

@ -70,4 +70,6 @@ ERROR: node is still EOpNull!
0:130 move second child to first child (float) 0:130 move second child to first child (float)
0:130 'twoPi' (float) 0:130 'twoPi' (float)
0:130 6.280000 0:130 6.280000
0:? Linker Objects
0:? 'tod' (float)

View File

@ -113,4 +113,5 @@
0:53 5 (const int) 0:53 5 (const int)
0:55 Pre-Increment (int) 0:55 Pre-Increment (int)
0:55 'c' (int) 0:55 'c' (int)
0:? Linker Objects

View File

@ -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: 0:1: 'int' : main function cannot return a value
ERROR: 2 compilation errors. No code generated. 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 Function Parameters:
0:1 'foo' (in mediump int) 0:1 'foo' (in mediump int)
0:3 Sequence 0:3 Sequence
0:3 Branch: Return with expression 0:3 Branch: Return with expression
0:3 1 (const int) 0:3 1 (const int)
0:? Linker Objects

View File

@ -97,4 +97,5 @@
0:35 Construct vec4 (mediump 4-component vector of float) 0:35 Construct vec4 (mediump 4-component vector of float)
0:35 Convert int to float (mediump float) 0:35 Convert int to float (mediump float)
0:35 'color' (mediump int) 0:35 'color' (mediump int)
0:? Linker Objects

View File

@ -18,4 +18,5 @@
0:17 30.000000 0:17 30.000000
0:17 30.000000 0:17 30.000000
0:17 30.000000 0:17 30.000000
0:? Linker Objects

View File

@ -12,6 +12,7 @@ ERROR: node is still EOpNull!
0:20 Construct vec4 (highp 4-component vector of float) 0:20 Construct vec4 (highp 4-component vector of float)
0:20 'foo' (highp float) 0:20 'foo' (highp float)
0:? Linker Objects 0:? Linker Objects
0:? 'foo' (highp float)
0:? 'gl_VertexID' (gl_VertexId highp int) 0:? 'gl_VertexID' (gl_VertexId highp int)
0:? 'gl_InstanceID' (gl_InstanceId highp int) 0:? 'gl_InstanceID' (gl_InstanceId highp int)

View 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)

View File

@ -1,33 +1,54 @@
mains1.frag mains1.frag
0:3Function Definition: main( (void) 0:? Sequence
0:3 Function Definition: main( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:? Linker Objects
mains2.frag mains2.frag
0:3Function Definition: main( (void) 0:? Sequence
0:3 Function Definition: main( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:? Linker Objects
noMain1.geom noMain1.geom
ERROR: #version: geometry shaders require non-es profile and version 150 or above ERROR: #version: geometry shaders require non-es profile and version 150 or above
ERROR: 1 compilation errors. No code generated. 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:3 Function Parameters:
0:? Linker Objects
noMain2.geom noMain2.geom
0:3Function Definition: bar( (void) 0:? Sequence
0:3 Function Definition: bar( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:? Linker Objects
Linked geometry stage: 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: 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

View File

@ -1,7 +1,11 @@
noMain.vert noMain.vert
0:3Function Definition: foo( (void) 0:? Sequence
0:3 Function Definition: foo( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:? Linker Objects
0:? 'gl_VertexID' (gl_VertexId highp int)
0:? 'gl_InstanceID' (gl_InstanceId highp int)
mains.frag mains.frag
ERROR: 0:7: 'main' : function already has a body ERROR: 0:7: 'main' : function already has a body
@ -13,14 +17,14 @@ ERROR: node is still EOpNull!
0:3 Function Parameters: 0:3 Function Parameters:
0:7 Function Definition: main( (void) 0:7 Function Definition: main( (void)
0:7 Function Parameters: 0:7 Function Parameters:
0:? Linker Objects
Linked vertex stage: 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: Linked fragment stage:
ERROR: Too many entry points: Each stage can have at most one "void main()" entry point.

View File

@ -103,7 +103,10 @@ ERROR: node is still EOpNull!
0:69 0.200000 0:69 0.200000
0:? Linker Objects 0:? Linker Objects
0:? 'color' (smooth in mediump 3-component vector of float) 0:? 'color' (smooth in mediump 3-component vector of float)
0:? 'global_medium' (mediump int)
0:? 'samplerLow' (uniform lowp sampler2D) 0:? 'samplerLow' (uniform lowp sampler2D)
0:? 'samplerMed' (uniform mediump sampler2D) 0:? 'samplerMed' (uniform mediump sampler2D)
0:? 'samplerHigh' (uniform highp sampler2D) 0:? 'samplerHigh' (uniform highp sampler2D)
0:? 'uint' (mediump 4-component vector of float)
0:? 'global_high' (highp int)

View File

@ -1,4 +1,5 @@
0:3Function Definition: main( (void) 0:? Sequence
0:3 Function Definition: main( (void)
0:3 Function Parameters: 0:3 Function Parameters:
0:? Sequence 0:? Sequence
0:10 Sequence 0:10 Sequence
@ -109,4 +110,5 @@
0:37 vector-scale (4-component vector of float) 0:37 vector-scale (4-component vector of float)
0:37 'z' (float) 0:37 'z' (float)
0:37 'v' (4-component vector of float) 0:37 'v' (4-component vector of float)
0:? Linker Objects

View File

@ -196,6 +196,22 @@ ERROR: node is still EOpNull!
0:218 'c' (5-element array of float) 0:218 'c' (5-element array of float)
0:218 'a' (5-element array of float) 0:218 'a' (5-element array of float)
0:? Linker Objects 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:? 'normal' (smooth in 3-component vector of float)
0:? 'TexCoord' (centroid smooth in 2-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) 0:? 'Color' (invariant centroid smooth in 4-component vector of float)

View File

@ -2,4 +2,9 @@ ERROR: 0:9: 'vec5' : undeclared identifier
ERROR: 0:9: '' : syntax error ERROR: 0:9: '' : syntax error
ERROR: 2 compilation errors. No code generated. 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)

View File

@ -77,6 +77,7 @@ ERROR: node is still EOpNull!
0:? Linker Objects 0:? Linker Objects
0:? 'BCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789' (in highp float) 0:? 'BCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789' (in highp float)
0:? 'ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789' (in highp float) 0:? 'ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789' (in highp float)
0:? 'BCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789B' (highp float)
0:? 'gl_VertexID' (gl_VertexId highp int) 0:? 'gl_VertexID' (gl_VertexId highp int)
0:? 'gl_InstanceID' (gl_InstanceId highp int) 0:? 'gl_InstanceID' (gl_InstanceId highp int)

24
Test/link1.frag Normal file
View 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
View 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
View File

@ -0,0 +1,5 @@
#version 300 es
precision highp float;
in vec2 iv3;

View File

@ -34,6 +34,7 @@ function runLinkTest {
runLinkTest mains1.frag mains2.frag noMain1.geom noMain2.geom runLinkTest mains1.frag mains2.frag noMain1.geom noMain2.geom
runLinkTest noMain.vert mains.frag runLinkTest noMain.vert mains.frag
runLinkTest link1.frag link2.frag link3.frag
# #
# multi-threaded test # 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 > singleThread.out
$EXE -i *.vert *.geom *.frag *.tes* *.comp -t > multiThread.out $EXE -i *.vert *.geom *.frag *.tes* *.comp -t > multiThread.out
diff singleThread.out multiThread.out diff singleThread.out multiThread.out

View File

@ -11,25 +11,28 @@ Link Validation
- mixed es/non-es profiles - mixed es/non-es profiles
- statically consumed input not produced by previous stage - statically consumed input not produced by previous stage
- matching between gl_PerVertex blocks and gl_PerFragment blocks - 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. - 1.3: deprecated mixing fixed vertex/fragment stage with programmable fragment/vertex stage.
- 4.3: remove cross-version linking restrictions. - 4.3: remove cross-version linking restrictions.
- 4.3: Allow mismatches in interpolation and auxiliary qualification across stages. - 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. - 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 Intra-stage linking
- exactly one main + exactly one main
- type consistency check of uniforms, globals, ins, and outs, both variables and blocks + 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 global const initializers
- value checking of uniform 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/component aliasing (except desktop vertex shader inputs)
- location layout range/overlap semantics - location layout range/overlap semantics
- geometry shader input array sizes and input layout qualifier declaration - geometry shader input array sizes and input layout qualifier declaration
- compute shader layout(local_size_*) matching - compute shader layout(local_size_*) matching
- mixed es/non-es profiles + mixed es/non-es profiles
- matching initializers for globals
- recursion for both functions and subroutines - recursion for both functions and subroutines
- Even the potential for recursion through subroutine uniforms is an error. - Even the potential for recursion through subroutine uniforms is an error.
- block matching
- matching redeclarations of interface blocks - matching redeclarations of interface blocks
- read or write to both gl_ClipVertex and gl_ClipDistance - read or write to both gl_ClipVertex and gl_ClipDistance
- write to only one of gl_FragColor, gl_FragData, or user-declared - write to only one of gl_FragColor, gl_FragData, or user-declared

View File

@ -850,7 +850,7 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
return true; 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 // Add top-level nodes for declarations that must be checked cross
// compilation unit by a linker, yet might not have been referenced // 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"); 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 // 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) 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; 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) void TIntermediate::errorCheck(TInfoSink& infoSink)
{ {
if (numMains < 1) if (numMains < 1)
error(infoSink, "Missing entry point: Each stage requires one \"void main()\" entry point"); 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) void TIntermediate::error(TInfoSink& infoSink, const char* message)
{ {
infoSink.info.prefix(EPrefixError); infoSink.info.prefix(EPrefixError);
infoSink.info << message << "\n"; infoSink.info << "Linking " << StageName[language] << " stage: " << message << "\n";
++numErrors; ++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. // This deletes the tree.
// //

View File

@ -51,12 +51,15 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
intermediate(interm), symbolTable(symt), infoSink(is), language(L), intermediate(interm), symbolTable(symt), infoSink(is), language(L),
version(v), profile(p), forwardCompatible(fc), messages(m), version(v), profile(p), forwardCompatible(fc), messages(m),
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0),
linkage(0), tokensBeforeEOF(false), tokensBeforeEOF(false),
parsingBuiltins(pb), numErrors(0), afterEOF(false) parsingBuiltins(pb), numErrors(0), afterEOF(false)
{ {
currentLoc.line = 1; currentLoc.line = 1;
currentLoc.string = 0; 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 // 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) // and for ES types that don't have defaults (thus getting an error on use)
for (int type = 0; type < EbtNumTypes; ++type) 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) void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicType& publicType)
{ {
TType type(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); TVariable* variable = redeclare(loc, identifier, type, newDeclaration);
if (! variable) { if (! variable) {
reservedErrorCheck(loc, identifier); reservedErrorCheck(loc, identifier);
variable = new TVariable(&identifier, type); variable = new TVariable(&identifier, type);
@ -1823,7 +1828,7 @@ void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicTyp
voidErrorCheck(loc, identifier, publicType); voidErrorCheck(loc, identifier, publicType);
// see if it's a linker-level object to track // 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); 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, // 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 // 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) 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()) if (profile == EEsProfile || identifier.substr(0, 3) != TString("gl_") || symbolTable.atBuiltInLevel())
return 0; return 0;

View File

@ -106,7 +106,7 @@ TPoolAllocator* PerProcessGPA = 0;
bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink, bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink,
TSymbolTable& symbolTable) TSymbolTable& symbolTable)
{ {
TIntermediate intermediate(version, profile); TIntermediate intermediate(language, version, profile);
TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink); TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink);
TPpContext ppContext(parseContext); TPpContext ppContext(parseContext);
@ -452,7 +452,7 @@ bool CompileDeferred(
bool ret = parseContext.parseShaderStrings(ppContext, const_cast<char**>(shaderStrings), lengths, numStrings); bool ret = parseContext.parseShaderStrings(ppContext, const_cast<char**>(shaderStrings), lengths, numStrings);
if (! ret) if (! ret)
success = false; 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. // Clean up the symbol table. The AST is self-sufficient now.
delete symbolTableMemory; delete symbolTableMemory;
@ -595,7 +595,7 @@ int ShCompile(
compiler->infoSink.info.erase(); compiler->infoSink.info.erase();
compiler->infoSink.debug.erase(); compiler->infoSink.debug.erase();
TIntermediate intermediate; TIntermediate intermediate(compiler->getLanguage());
bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, optLevel, resources, defaultVersion, forwardCompatible, messages, intermediate); bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, optLevel, resources, defaultVersion, forwardCompatible, messages, intermediate);
// //
@ -866,7 +866,7 @@ TShader::TShader(EShLanguage s)
{ {
infoSink = new TInfoSink; infoSink = new TInfoSink;
compiler = new TDeferredCompiler(stage, *infoSink); compiler = new TDeferredCompiler(stage, *infoSink);
intermediate = new TIntermediate; intermediate = new TIntermediate(s);
} }
TShader::~TShader() TShader::~TShader()
@ -941,7 +941,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
if (stages[stage].size() == 1) if (stages[stage].size() == 1)
merged = stages[stage].front()->intermediate; merged = stages[stage].front()->intermediate;
else { else {
intermediate[stage] = new TIntermediate(); intermediate[stage] = new TIntermediate(stage);
merged = intermediate[stage]; merged = intermediate[stage];
} }
@ -950,7 +950,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
if (stages[stage].size() > 1) { if (stages[stage].size() > 1) {
std::list<TShader*>::const_iterator it; std::list<TShader*>::const_iterator it;
for (it = stages[stage].begin(); it != stages[stage].end(); ++it) for (it = stages[stage].begin(); it != stages[stage].end(); ++it)
merged->merge(*(*it)->intermediate); merged->merge(*infoSink, *(*it)->intermediate);
if (messages & EShMsgAST) if (messages & EShMsgAST)
merged->outputTree(*infoSink); merged->outputTree(*infoSink);

View File

@ -56,7 +56,7 @@ class TVariable;
// //
class TIntermediate { class TIntermediate {
public: 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; } void setVersion(int v) { version = v; }
int getVersion() const { return version; } int getVersion() const { return version; }
@ -95,20 +95,24 @@ public:
TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc); TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc); TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
bool postProcess(TIntermNode*, EShLanguage); 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, TSymbolTable&, const TString&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable&);
void merge(TIntermediate&); void merge(TInfoSink&, TIntermediate&);
void errorCheck(TInfoSink& infoSink); void errorCheck(TInfoSink&);
void outputTree(TInfoSink& infoSink); void outputTree(TInfoSink&);
void removeTree(); void removeTree();
protected: protected:
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
void error(TInfoSink& infoSink, const char*); void error(TInfoSink& infoSink, const char*);
void linkErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage);
protected: protected:
EShLanguage language;
TIntermNode* treeRoot; TIntermNode* treeRoot;
EProfile profile; EProfile profile;
int version; int version;