Clean up/resolve a bunch of TODO, which included implementing pixel_center_integer and origin_upper_left and adjusting what versions see legacy texturing names.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23874 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-11-05 18:07:25 +00:00
parent c36e1d8e51
commit 8ec55cdcd2
28 changed files with 374 additions and 160 deletions

Binary file not shown.

View File

@ -31,3 +31,9 @@ void bar()
{ {
vec4 s = textureGather(sampC, vec3(0.2)); vec4 s = textureGather(sampC, vec3(0.2));
} }
flat in vec3 gl_Color; // ERROR, type
in vec4 gl_Color;
flat in vec4 gl_Color;
flat in vec4 gl_Color[2]; // ERROR, array
vec4 gl_Color; // ERROR, storage

14
Test/150.frag Normal file
View File

@ -0,0 +1,14 @@
#version 150 core
in vec4 gl_FragCoord;
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR
layout(pixel_center_integer) in vec4 gl_FragCoord; // ERROR
layout(origin_upper_left) in vec4 foo; // ERROR
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;
void main()
{
vec4 c = gl_FragCoord;
}
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;

View File

@ -103,5 +103,13 @@ uniform multi {
int c[2][3]; // ERROR int c[2][3]; // ERROR
} multiInst[2][3]; // ERROR } multiInst[2][3]; // ERROR
out vec4 colors[4];
void foo()
{
colors[2] = c4D;
colors[ic1D] = c4D;
}
float imageBuffer; // ERROR, reserved float imageBuffer; // ERROR, reserved
float uimage2DRect; // ERROR, reserved float uimage2DRect; // ERROR, reserved

View File

@ -21,6 +21,8 @@ void main()
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), 4); // ERROR, last argument out of range iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), 4); // ERROR, last argument out of range
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), 1+2); iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), 1+2);
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(i)); iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(i));
vec4 c = gl_FragCoord;
} }
layout(location = 4) in vec4 vl; // ERROR, not supported layout(location = 4) in vec4 vl; // ERROR, not supported
@ -32,3 +34,8 @@ layout(location = 4) in vec4 vl; // ERROR, not supported
layout(location = 4) in vec4 vl2; layout(location = 4) in vec4 vl2;
layout(location = 3) uniform vec3 uv3; layout(location = 3) uniform vec3 uv3;
layout(location = 5) in vec4 gl_Color; // ERROR, layout
noperspective in float gl_ClipDistance[4]; // ERROR, can't change qualifier
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;

View File

@ -1,6 +1,9 @@
Warning, version 130 is not yet complete; most features are present, but a few are missing. Warning, version 130 is not yet complete; most features are present, but a few are missing.
ERROR: 0:25: 'texture gather function' : not supported for this version or the enabled extensions ERROR: 0:25: 'texture gather function' : not supported for this version or the enabled extensions
ERROR: 1 compilation errors. No code generated. ERROR: 0:35: 'redeclaration' : cannot change the type of gl_Color
ERROR: 0:38: 'gl_Color' : redeclaring non-array as array
ERROR: 0:39: 'redeclaration' : cannot change storage, memory, or auxiliary qualification of gl_Color
ERROR: 4 compilation errors. No code generated.
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:16 Function Definition: main( (void) 0:16 Function Definition: main( (void)
@ -48,4 +51,6 @@ ERROR: node is still EOpNull!
0:? 'fnop' (noperspective in float) 0:? 'fnop' (noperspective in float)
0:? 'gl_ClipDistance' (smooth in unsized array of float) 0:? 'gl_ClipDistance' (smooth in unsized array of float)
0:? 'sampC' (uniform samplerCube) 0:? 'sampC' (uniform samplerCube)
0:? 'gl_Color' (smooth in 4-component vector of float)
0:? 'gl_Color' (flat in 4-component vector of float)

View File

@ -0,0 +1,21 @@
Warning, version 150 is not yet complete; some version-specific features are present, but many are missing.
ERROR: 0:4: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord
ERROR: 0:5: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord
ERROR: 0:6: 'layout qualifier' : can only apply origin_upper_left and pixel_center_origin to gl_FragCoord
ERROR: 3 compilation errors. No code generated.
gl_FragCoord pixel center is integer
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:9 Function Definition: main( (void)
0:9 Function Parameters:
0:11 Sequence
0:11 Sequence
0:11 move second child to first child (4-component vector of float)
0:11 'c' (4-component vector of float)
0:11 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
0:? Linker Objects
0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
0:? 'foo' (smooth in 4-component vector of float)

View File

@ -71,7 +71,7 @@ ERROR: node is still EOpNull!
0:33 Constant: 0:33 Constant:
0:33 2 (const int) 0:33 2 (const int)
0:34 move second child to first child (4-component vector of float) 0:34 move second child to first child (4-component vector of float)
0:34 gl_Position: direct index for structure (layout(stream=0 ) 4-component vector of float) 0:34 gl_Position: direct index for structure (layout(stream=0 ) gl_Position 4-component vector of float)
0:34 '__anon__1' (layout(stream=0 ) out block{gl_Position,gl_PointSize,gl_ClipDistance}) 0:34 '__anon__1' (layout(stream=0 ) out block{gl_Position,gl_PointSize,gl_ClipDistance})
0:34 Constant: 0:34 Constant:
0:34 0 (const uint) 0:34 0 (const uint)
@ -83,7 +83,7 @@ ERROR: node is still EOpNull!
0:34 Constant: 0:34 Constant:
0:34 0 (const int) 0:34 0 (const int)
0:35 move second child to first child (float) 0:35 move second child to first child (float)
0:35 gl_PointSize: direct index for structure (layout(stream=0 ) float) 0:35 gl_PointSize: direct index for structure (layout(stream=0 ) gl_PointSize float)
0:35 '__anon__1' (layout(stream=0 ) out block{gl_Position,gl_PointSize,gl_ClipDistance}) 0:35 '__anon__1' (layout(stream=0 ) out block{gl_Position,gl_PointSize,gl_ClipDistance})
0:35 Constant: 0:35 Constant:
0:35 1 (const uint) 0:35 1 (const uint)

View File

@ -17,9 +17,10 @@ ERROR: 0:102: 'arrays of arrays' : not supported with this profile: es
ERROR: 0:102: 'arrays of arrays' : not supported with this profile: es ERROR: 0:102: 'arrays of arrays' : not supported with this profile: es
ERROR: 0:103: 'arrays of arrays' : not supported with this profile: es ERROR: 0:103: 'arrays of arrays' : not supported with this profile: es
ERROR: 0:100: 'arrays of arrays' : not supported with this profile: es ERROR: 0:100: 'arrays of arrays' : not supported with this profile: es
ERROR: 0:106: 'imageBuffer' : Reserved word. ERROR: 0:111: 'variable indexing fragment shader ouput array' : not supported with this profile: es
ERROR: 0:106: '' : syntax error ERROR: 0:114: 'imageBuffer' : Reserved word.
ERROR: 21 compilation errors. No code generated. ERROR: 0:114: '' : syntax error
ERROR: 22 compilation errors. No code generated.
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:53 Function Definition: main( (void) 0:53 Function Definition: main( (void)
@ -208,6 +209,20 @@ ERROR: node is still EOpNull!
0:96 'c4D' (smooth lowp 4-component vector of float) 0:96 'c4D' (smooth lowp 4-component vector of float)
0:97 arc hyp. tangent (lowp 3-component vector of float) 0:97 arc hyp. tangent (lowp 3-component vector of float)
0:97 'c3D' (smooth in lowp 3-component vector of float) 0:97 'c3D' (smooth in lowp 3-component vector of float)
0:108 Function Definition: foo( (void)
0:108 Function Parameters:
0:110 Sequence
0:110 move second child to first child (lowp 4-component vector of float)
0:110 direct index (lowp 4-component vector of float)
0:110 'colors' (out 4-element array of lowp 4-component vector of float)
0:110 Constant:
0:110 2 (const int)
0:110 'c4D' (smooth lowp 4-component vector of float)
0:111 move second child to first child (lowp 4-component vector of float)
0:111 indirect index (lowp 4-component vector of float)
0:111 'colors' (out 4-element array of lowp 4-component vector of float)
0:111 'ic1D' (flat in mediump int)
0:111 'c4D' (smooth lowp 4-component vector of float)
0:? Linker Objects 0:? Linker Objects
0:? 's2D' (uniform lowp sampler2D) 0:? 's2D' (uniform lowp sampler2D)
0:? 's3D' (uniform lowp sampler3D) 0:? 's3D' (uniform lowp sampler3D)
@ -240,4 +255,5 @@ ERROR: node is still EOpNull!
0:? 'sf' (out lowp float) 0:? 'sf' (out lowp float)
0:? 'arrayedSampler' (uniform 5-element array of lowp sampler2D) 0:? 'arrayedSampler' (uniform 5-element array of lowp sampler2D)
0:? 'multiInst' (layout(column_major shared ) uniform 2-element array of block{a,b,c}) 0:? 'multiInst' (layout(column_major shared ) uniform 2-element array of block{a,b,c})
0:? 'colors' (out 4-element array of lowp 4-component vector of float)

View File

@ -1,10 +1,15 @@
Warning, version 400 is not yet complete; some version-specific features are present, but many are missing. Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.
ERROR: 0:20: 'texture gather component' : must be a constant ERROR: 0:20: 'texture gather component' : must be a constant
ERROR: 0:21: 'texture gather component' : must be 0, 1, 2, or 3 ERROR: 0:21: 'texture gather component' : must be 0, 1, 2, or 3
ERROR: 0:26: 'location qualifier on input' : not supported for this version or the enabled extensions ERROR: 0:28: 'location qualifier on input' : not supported for this version or the enabled extensions
ERROR: 0:34: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions ERROR: 0:36: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions
ERROR: 4 compilation errors. No code generated. ERROR: 0:38: 'redeclaration' : cannot apply layout qualifier to gl_Color
ERROR: 0:39: 'redeclaration' : cannot change qualification of gl_ClipDistance
ERROR: 0:41: 'gl_FragCoord' : cannot redeclare after use
ERROR: 7 compilation errors. No code generated.
gl_FragCoord pixel center is integer
gl_FragCoord origin is upper left
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:10 Function Definition: main( (void) 0:10 Function Definition: main( (void)
0:10 Function Parameters: 0:10 Function Parameters:
@ -105,6 +110,10 @@ ERROR: node is still EOpNull!
0:23 0.100000 0:23 0.100000
0:23 Construct ivec2 (2-component vector of int) 0:23 Construct ivec2 (2-component vector of int)
0:23 'i' (flat in int) 0:23 'i' (flat in int)
0:25 Sequence
0:25 move second child to first child (4-component vector of float)
0:25 'c' (4-component vector of float)
0:25 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
0:? Linker Objects 0:? Linker Objects
0:? 'c2D' (smooth in 2-component vector of float) 0:? 'c2D' (smooth in 2-component vector of float)
0:? 'i' (flat in int) 0:? 'i' (flat in int)
@ -112,8 +121,12 @@ ERROR: node is still EOpNull!
0:? 'arrayedSampler' (uniform 5-element array of sampler2D) 0:? 'arrayedSampler' (uniform 5-element array of sampler2D)
0:? 'samp2dr' (uniform usampler2DRect) 0:? 'samp2dr' (uniform usampler2DRect)
0:? 'isamp2DA' (uniform isampler2DArray) 0:? 'isamp2DA' (uniform isampler2DArray)
0:? 'gl_ClipDistance' (smooth in unsized array of float) 0:? 'gl_ClipDistance' (smooth in 4-element array of float)
0:? 'vl' (layout(location=4 ) smooth in 4-component vector of float) 0:? 'vl' (layout(location=4 ) smooth in 4-component vector of float)
0:? 'vl2' (layout(location=4 ) smooth in 4-component vector of float) 0:? 'vl2' (layout(location=4 ) smooth in 4-component vector of float)
0:? 'uv3' (layout(location=3 ) uniform 3-component vector of float) 0:? 'uv3' (layout(location=3 ) uniform 3-component vector of float)
0:? '__anon__0' (in block{gl_FogFragCoord,gl_TexCoord,gl_Color,gl_SecondaryColor})
0:? '__anon__0' (in block{gl_FogFragCoord,gl_TexCoord,gl_Color,gl_SecondaryColor})
0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float)

View File

@ -32,7 +32,7 @@ ERROR: node is still EOpNull!
0:30 Constant: 0:30 Constant:
0:30 0 (const int) 0:30 0 (const int)
0:31 move second child to first child (float) 0:31 move second child to first child (float)
0:31 gl_PointSize: direct index for structure (layout(stream=0 ) float) 0:31 gl_PointSize: direct index for structure (layout(stream=0 ) gl_PointSize float)
0:31 '__anon__0' (layout(stream=0 ) out block{gl_PointSize}) 0:31 '__anon__0' (layout(stream=0 ) out block{gl_PointSize})
0:31 Constant: 0:31 Constant:
0:31 0 (const uint) 0:31 0 (const uint)

View File

@ -6,10 +6,8 @@ ERROR: 0:37: 'view' : redefinition
ERROR: 0:68: 'lightPosition' : redefinition ERROR: 0:68: 'lightPosition' : redefinition
ERROR: 0:75: 'Atten' : member storage qualifier cannot contradict block storage qualifier ERROR: 0:75: 'Atten' : member storage qualifier cannot contradict block storage qualifier
ERROR: 0:87: 'Color' : redefinition ERROR: 0:87: 'Color' : redefinition
ERROR: 0:92: 'origin_upper_left' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) ERROR: 0:92: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord
ERROR: 0:93: 'pixel_center_integer' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) ERROR: 0:93: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord
ERROR: 0:94: 'origin_upper_left' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
ERROR: 0:94: 'pixel_center_integer' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
ERROR: 0:96: 'early_fragment_tests' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4) ERROR: 0:96: 'early_fragment_tests' : unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)
ERROR: 0:99: 'local_size_x' : there is no such layout identifier for this stage taking an assigned value ERROR: 0:99: 'local_size_x' : there is no such layout identifier for this stage taking an assigned value
ERROR: 0:99: 'local_size_y' : there is no such layout identifier for this stage taking an assigned value ERROR: 0:99: 'local_size_y' : there is no such layout identifier for this stage taking an assigned value
@ -48,8 +46,10 @@ ERROR: 0:226: 'in' : not allowed in nested scope
ERROR: 0:227: 'in' : not allowed in nested scope ERROR: 0:227: 'in' : not allowed in nested scope
ERROR: 0:228: 'in' : not allowed in nested scope ERROR: 0:228: 'in' : not allowed in nested scope
ERROR: 0:232: 'out' : not allowed in nested scope ERROR: 0:232: 'out' : not allowed in nested scope
ERROR: 49 compilation errors. No code generated. ERROR: 47 compilation errors. No code generated.
gl_FragCoord pixel center is integer
gl_FragCoord origin is upper left
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:5 Sequence 0:5 Sequence
0:5 move second child to first child (int) 0:5 move second child to first child (int)

View File

@ -30,6 +30,8 @@ ERROR: 0:95: 'binding' : requires block, or sampler/image, or atomic-counter typ
ERROR: 0:96: 'binding' : requires block, or sampler/image, or atomic-counter type ERROR: 0:96: 'binding' : requires block, or sampler/image, or atomic-counter type
ERROR: 0:97: 'binding' : requires block, or sampler/image, or atomic-counter type ERROR: 0:97: 'binding' : requires block, or sampler/image, or atomic-counter type
ERROR: 0:106: '' : vertex input cannot be further qualified ERROR: 0:106: '' : vertex input cannot be further qualified
ERROR: 0:106: 'redeclaration' : cannot change storage, memory, or auxiliary qualification of gl_FrontColor
ERROR: 0:107: 'redeclaration' : cannot change storage, memory, or auxiliary qualification of gl_FrontColor
ERROR: 0:112: 'ColorIvn' : identifier not previously declared ERROR: 0:112: 'ColorIvn' : identifier not previously declared
ERROR: 0:132: 'shared' : not supported in this stage: vertex ERROR: 0:132: 'shared' : not supported in this stage: vertex
ERROR: 0:134: '' : function does not return a value: funcA ERROR: 0:134: '' : function does not return a value: funcA
@ -40,7 +42,7 @@ ERROR: 0:153: '' : function does not return a value: func3
ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array
ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array
ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array
ERROR: 40 compilation errors. No code generated. ERROR: 42 compilation errors. No code generated.
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:134 Function Definition: funcA(I21; (4-component vector of float) 0:134 Function Definition: funcA(I21; (4-component vector of float)

View File

@ -14,6 +14,7 @@ versionsErrors.vert
140.frag 140.frag
150.vert 150.vert
150.geom 150.geom
150.frag
precision.frag precision.frag
precision.vert precision.vert
nonSquare.vert nonSquare.vert

View File

@ -12,40 +12,49 @@ Link Validation
- statically consumed input not produced by previous stage - statically consumed input not produced by previous stage
- give error for sharing a packed block - give error for sharing a packed block
- 1.2: matching initializers for uniforms - 1.2: matching initializers for uniforms
- 1.3: only statically used built-ins have to be redeclared as flat
- 1.5: matching between gl_PerVertex blocks and gl_PerFragment blocks - 1.5: matching between gl_PerVertex blocks and gl_PerFragment blocks
- 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: compute shader not combined with any other stages - 4.3: compute shader not combined with any other stages
- 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, single shader
- ES 3.0: location aliasing/overlap (except desktop vertex shader inputs) - limits checking:
+ ES 3.0: fragment outputs all have locations, if more than one - number of texture image units
- texel offsets (or compile-time?)
- number of input/output compononents
- tessellation limits
- ...
+ exactly one main + exactly one main
+ Non ES: type consistency check of uniforms, globals, ins, and outs + ES 3.0: fragment outputs all have locations, if more than one
+ Non ES: value checking of global const initializers - ES 3.0: location aliasing/overlap (except desktop vertex shader inputs)
+ Non ES: value checking of uniform initializers - Non ES: binding overlap?
+ Non ES: location match
- Non ES: gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords - Non ES: gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords
+ recursion for functions + Non ES: geometry shader input array sizes and input layout qualifier declaration
- Non ES: block matching
- Non ES: component/binding/index/offset match check
- Non ES: geometry shader input array sizes and input layout qualifier declaration
- Non ES: compute shader layout(local_size_*) matching
+ mixed es/non-es profiles are an error
- Non ES: Even the potential for recursion through subroutine uniforms is an error.
- Non ES: matching redeclarations of interface blocks
- Non ES: read or write to both gl_ClipVertex and gl_ClipDistance - Non ES: read or write to both gl_ClipVertex and gl_ClipDistance
- Non ES: write to only one of gl_FragColor, gl_FragData, or user-declared - Non ES: write to only one of gl_FragColor, gl_FragData, or user-declared
- 1.50: at least one geometry shader says input primitive and at least one says output primitive... - 1.50: at least one geometry shader says input primitive and at least one says output primitive...
- 1.50: at least one geometry shader says max_vertices... - 1.50: at least one geometry shader says max_vertices...
- 1.50: match between all explicit input array sizes and input primitive
- 4.3: Be clear that early_fragment_tests is only needed in one fragment-stage compilation unit.
- 4.3: Be clear that implicit array sizing is only within a stage, not cross stage.
- 4.4: overlapping transform/feedback offsets, offset/stride overflow checks, and stride matching
- 4.4: If gl_FragCoord is redeclared in any fragment shader in a program, it must be redeclared in all the fragment shaders in that program that have a static use gl_FragCoord
- 4.4: An interface contains two different blocks, each with no instance name, where the blocks contain a member with the same name. - 4.4: An interface contains two different blocks, each with no instance name, where the blocks contain a member with the same name.
- 4.4: component aliasing (except desktop vertex shader inputs) - 4.4: component aliasing (except desktop vertex shader inputs)
Intra-stage linking, multiple shader
+ Non ES: type consistency check of uniforms, globals, ins, and outs
+ Non ES: value checking of global const initializers
+ Non ES: value checking of uniform initializers
+ Non ES: location match
+ recursion for functions
- Non ES: block matching
- Non ES: component/binding/index/offset match check
- Non ES: compute shader layout(local_size_*) matching
+ mixed es/non-es profiles are an error
- Non ES: Even the potential for recursion through subroutine uniforms is an error.
- Non ES: matching redeclarations of interface blocks
- 1.50: match between all explicit input array sizes and input primitive
- 4.3: early_fragment_tests contradictions
- 4.3: implicit array sizing is cross shader within a stage
- 4.4: overlapping transform/feedback offsets, offset/stride overflow checks, and stride matching
- 4.4: If gl_FragCoord is redeclared in any fragment shader in a program, it must be redeclared in all the fragment shaders in that program that have a static use gl_FragCoord
Shader Functionality to Implement/Finish Shader Functionality to Implement/Finish
ESSL 2.0 (#version 100) ESSL 2.0 (#version 100)
@ -53,19 +62,16 @@ Shader Functionality to Implement/Finish
+ implement non-inductive array accesses limitation detection + implement non-inductive array accesses limitation detection
ESSL 3.0 ESSL 3.0
- "const" compile-time constant propagation in the front-end has to be complete, for all built-in functions - "const" compile-time constant propagation in the front-end has to be complete, for all built-in functions
- add limitation around #define GL_FRAGMENT_PRECISION_HIGH 1 ?
GLSL 1.2 GLSL 1.2
+ Handle multiple compilation units per stage + Handle multiple compilation units per stage
+ Allow initializers on uniform declarations + Allow initializers on uniform declarations
+ signature matching takes type conversions into account, ambiguity is an error + signature matching takes type conversions into account, ambiguity is an error
- allow constructors to contain non-dereferenced arrays? - bug: allow constructors to contain non-dereferenced arrays?
GLSL 1.3 GLSL 1.3
. flat is for both user and predeclared built-in in/out variables + flat redeclaration of built-in variables
GLSL 1.3 (Non-ES)
- Preprocessor token pasting (##), ## does macro expansion after pasting not before - Preprocessor token pasting (##), ## does macro expansion after pasting not before
- non-perspective (linear) interpolation (noperspective) + non-perspective (linear) interpolation (noperspective)
+ add gl_ClipDistance[] to both vertex and fragment shaders + add gl_ClipDistance[] to both vertex and fragment shaders
- only statically used built-ins have to be redeclared as flat
+ Deprecated gl_ClipVertex + Deprecated gl_ClipVertex
+ deprecate almost all built-in state + deprecate almost all built-in state
+ ftransform() is deprecated + ftransform() is deprecated
@ -163,7 +169,7 @@ Shader Functionality to Implement/Finish
- Add built-in functions to pack/unpack 16 bit floating-point numbers (ARB_shading_language_pack2f). - Add built-in functions to pack/unpack 16 bit floating-point numbers (ARB_shading_language_pack2f).
- packHalf2x16 and unpackHalf2x16 - packHalf2x16 and unpackHalf2x16
- packSnorm2x16and unpackSnorm2x16 - packSnorm2x16and unpackSnorm2x16
- Add gl_FragDepthlayout qualifiers to communicate what kind of changes will be made to gl_FragDepth(GL_AMD_conservative depth). - Add gl_FragDepth layout qualifiers to communicate what kind of changes will be made to gl_FragDepth (GL_AMD_conservative depth).
+ Add C-style curly brace initializer lists syntax for initializers. Full initialization of aggregates is required when these are used. + Add C-style curly brace initializer lists syntax for initializers. Full initialization of aggregates is required when these are used.
- Allow .length() to be applied to vectors and matrices, returning the number of components or columns. - Allow .length() to be applied to vectors and matrices, returning the number of components or columns.
+ Clarify that .length() returns an int type and can be used as a constant integer expression. + Clarify that .length() returns an int type and can be used as a constant integer expression.
@ -188,7 +194,7 @@ Shader Functionality to Implement/Finish
member, so that must a have valid index. member, so that must a have valid index.
- Arrays of other objects (uniform blocks) containing implicitly sized arrays will have the same implicit size for all - Arrays of other objects (uniform blocks) containing implicitly sized arrays will have the same implicit size for all
elements of the array. elements of the array.
- Arrays of arrays are now supported, as per the GL_ARB_arrays_of_arraysextension. - Arrays of arrays are now supported, as per the GL_ARB_arrays_of_arrays extension.
- Compute shaders are now supported, as per the GL_ARB_compute_shader extension. - Compute shaders are now supported, as per the GL_ARB_compute_shader extension.
- Added imageSize() built-ins to query the dimensions of an image. - Added imageSize() built-ins to query the dimensions of an image.
- Define robust out-of-bounds access behavior when enabled, as per the GL_ARB_robust_buffer_access_behavior extension. - Define robust out-of-bounds access behavior when enabled, as per the GL_ARB_robust_buffer_access_behavior extension.
@ -232,3 +238,4 @@ Shader Functionality to Implement/Finish
transform feedback buffering. transform feedback buffering.
+ Bug 10530: To be consistent with ES, include sample types as valid in a precision statement. + Bug 10530: To be consistent with ES, include sample types as valid in a precision statement.
Note the defaults are irrelevant, as precision qualifiers are not required or have any meaning. Note the defaults are irrelevant, as precision qualifiers are not required or have any meaning.

View File

@ -386,6 +386,25 @@ public:
} }
}; };
// Qualifiers that don't need to be keep per object. They have shader scope, not object scope.
// So, they will not be part of TType, TQualifier, etc.
struct TShaderQualifiers {
TLayoutGeometry geometry; // geometry shader in/out primitives
bool pixelCenterInteger; // fragment shader
bool originUpperLeft; // fragment shader
int invocations; // 0 means no declaration
int maxVertices;
void init()
{
geometry = ElgNone;
originUpperLeft = false;
pixelCenterInteger = false;
invocations = 0; // 0 means no declaration
maxVertices = 0;
}
};
// //
// TPublicType is just temporarily used while parsing and not quite the same // TPublicType is just temporarily used while parsing and not quite the same
// information kept per node in TType. Due to the bison stack, it can't have // information kept per node in TType. Due to the bison stack, it can't have
@ -399,9 +418,7 @@ public:
TBasicType basicType; TBasicType basicType;
TSampler sampler; TSampler sampler;
TQualifier qualifier; TQualifier qualifier;
TLayoutGeometry geometry; // don't keep this in the qualifier; it's more a per shader than per type TShaderQualifiers shaderQualifiers;
int invocations; // 0 means no declaration
int maxVertices;
int vectorSize : 4; int vectorSize : 4;
int matrixCols : 4; int matrixCols : 4;
int matrixRows : 4; int matrixRows : 4;
@ -432,9 +449,7 @@ public:
initType(loc); initType(loc);
sampler.clear(); sampler.clear();
initQualifiers(global); initQualifiers(global);
geometry = ElgNone; shaderQualifiers.init();
invocations = 0; // 0 means no declaration
maxVertices = 0;
} }
void setVector(int s) void setVector(int s)
@ -793,10 +808,11 @@ public:
else else
totalSize = vectorSize; totalSize = vectorSize;
if (isArray()) if (isArray()) {
totalSize *= Max(getArraySize(), getMaxArraySize()); // this function can only be used in paths that don't allow unsized arrays
assert(getArraySize() > 0);
// TODO: desktop arrays: it should be ill-defined to get object size if the array is not sized, so the max() above maybe should be an assert totalSize *= getArraySize();
}
return totalSize; return totalSize;
} }

View File

@ -297,7 +297,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
// but not always. // but not always.
int resultSize; int resultSize;
switch (op) { switch (op) {
// TODO: functionality: constant folding: finish listing exceptions to size here // TODO: 3.0 functionality: constant folding: finish listing exceptions to size here
case EOpDeterminant: case EOpDeterminant:
case EOpAny: case EOpAny:
case EOpAll: case EOpAll:
@ -481,7 +481,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
break; break;
} }
// TODO: Functionality: constant folding: the rest of the ops have to be fleshed out // TODO: 3.0 Functionality: constant folding: the rest of the ops have to be fleshed out
case EOpSinh: case EOpSinh:
case EOpCosh: case EOpCosh:
@ -665,7 +665,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
switch (aggrNode->getOp()) { switch (aggrNode->getOp()) {
// TODO: Functionality: constant folding: the rest of the ops have to be fleshed out // TODO: 3.0 Functionality: constant folding: the rest of the ops have to be fleshed out
case EOpModf: case EOpModf:
case EOpDistance: case EOpDistance:

View File

@ -621,8 +621,9 @@ void TBuiltIns::initialize(int version, EProfile profile)
// (Per-stage functions below.) // (Per-stage functions below.)
// //
if ((profile == EEsProfile && version == 100) || if ((profile == EEsProfile && version == 100) ||
profile == ECompatibilityProfile || profile == ECompatibilityProfile ||
version < 150) { (profile == ECoreProfile && version < 420) ||
profile == ENoProfile) {
commonBuiltins.append( commonBuiltins.append(
"vec4 texture2D(sampler2D, vec2);" "vec4 texture2D(sampler2D, vec2);"
@ -634,8 +635,9 @@ void TBuiltIns::initialize(int version, EProfile profile)
"\n"); "\n");
} }
if (profile != EEsProfile && if ( profile == ECompatibilityProfile ||
(profile == ECompatibilityProfile || version < 150)) { (profile == ECoreProfile && version < 420) ||
profile == ENoProfile) {
commonBuiltins.append( commonBuiltins.append(
"vec4 texture1D(sampler1D, float);" "vec4 texture1D(sampler1D, float);"
@ -651,8 +653,6 @@ void TBuiltIns::initialize(int version, EProfile profile)
"vec4 shadow2DProj(sampler2DShadow, vec4);" "vec4 shadow2DProj(sampler2DShadow, vec4);"
"\n"); "\n");
// TODO: functionality: non-ES legacy texturing for Lod, others?
} }
// //
@ -686,6 +686,8 @@ void TBuiltIns::initialize(int version, EProfile profile)
//============================================================================ //============================================================================
// //
// Prototypes for built-in functions seen by vertex shaders only. // Prototypes for built-in functions seen by vertex shaders only.
// (Except legacy lod functions, where it depends which release they are
// vertex only.)
// //
//============================================================================ //============================================================================
@ -698,8 +700,16 @@ void TBuiltIns::initialize(int version, EProfile profile)
// //
// Original-style texture Functions with lod. // Original-style texture Functions with lod.
// //
if (profile != EEsProfile || version == 100) { TString* s;
stageBuiltins[EShLangVertex].append( if (version < 130)
s = &stageBuiltins[EShLangVertex];
else
s = &commonBuiltins;
if ((profile == EEsProfile && version == 100) ||
profile == ECompatibilityProfile ||
(profile == ECoreProfile && version < 420) ||
profile == ENoProfile) {
s->append(
"vec4 texture2DLod(sampler2D, vec2, float);" "vec4 texture2DLod(sampler2D, vec2, float);"
"vec4 texture2DProjLod(sampler2D, vec3, float);" "vec4 texture2DProjLod(sampler2D, vec3, float);"
"vec4 texture2DProjLod(sampler2D, vec4, float);" "vec4 texture2DProjLod(sampler2D, vec4, float);"
@ -707,8 +717,10 @@ void TBuiltIns::initialize(int version, EProfile profile)
"\n"); "\n");
} }
if (profile != EEsProfile && version > 100) { if ( profile == ECompatibilityProfile ||
stageBuiltins[EShLangVertex].append( (profile == ECoreProfile && version < 420) ||
profile == ENoProfile) {
s->append(
"vec4 texture1DLod(sampler1D, float, float);" "vec4 texture1DLod(sampler1D, float, float);"
"vec4 texture1DProjLod(sampler1D, vec2, float);" "vec4 texture1DProjLod(sampler1D, vec2, float);"
"vec4 texture1DProjLod(sampler1D, vec4, float);" "vec4 texture1DProjLod(sampler1D, vec4, float);"
@ -982,7 +994,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
if (version >= 430) { if (version >= 430) {
stageBuiltins[EShLangCompute].append( stageBuiltins[EShLangCompute].append(
"in uvec3 gl_NumWorkGroups;" "in uvec3 gl_NumWorkGroups;"
// TODO: compute shader: constant with no initializer "const uvec3 gl_WorkGroupSize;" // TODO: 4.3 functionality: compute shader: constant with no initializer "const uvec3 gl_WorkGroupSize;"
"in uvec3 gl_WorkGroupID;" "in uvec3 gl_WorkGroupID;"
"in uvec3 gl_LocalInvocationID;" "in uvec3 gl_LocalInvocationID;"
@ -1184,7 +1196,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
//============================================================================ //============================================================================
if (version >= 400) { if (version >= 400) {
// TODO: tessellation: gl_MaxPatchVertices below needs to move to resources mechanism // TODO: 4.0 tessellation: gl_MaxPatchVertices below needs to move to resources mechanism
stageBuiltins[EShLangTessControl].append( stageBuiltins[EShLangTessControl].append(
"const int gl_MaxPatchVertices = 32;" "const int gl_MaxPatchVertices = 32;"
); );
@ -1242,7 +1254,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
//============================================================================ //============================================================================
if (version >= 400) { if (version >= 400) {
// TODO: tessellation: gl_MaxPatchVertices below needs to move to resources mechanism // TODO: 4.0 tessellation: gl_MaxPatchVertices below needs to move to resources mechanism
stageBuiltins[EShLangTessEvaluation].append( stageBuiltins[EShLangTessEvaluation].append(
"const int gl_MaxPatchVertices = 32;" "const int gl_MaxPatchVertices = 32;"
); );
@ -2084,6 +2096,9 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
// //
switch(language) { switch(language) {
case EShLangVertex: case EShLangVertex:
case EShLangTessControl:
case EShLangTessEvaluation:
case EShLangGeometry:
SpecialQualifier("gl_Position", EvqPosition, symbolTable); SpecialQualifier("gl_Position", EvqPosition, symbolTable);
SpecialQualifier("gl_PointSize", EvqPointSize, symbolTable); SpecialQualifier("gl_PointSize", EvqPointSize, symbolTable);
SpecialQualifier("gl_ClipVertex", EvqClipVertex, symbolTable); SpecialQualifier("gl_ClipVertex", EvqClipVertex, symbolTable);
@ -2091,12 +2106,6 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
SpecialQualifier("gl_InstanceID", EvqInstanceId, symbolTable); SpecialQualifier("gl_InstanceID", EvqInstanceId, symbolTable);
break; break;
case EShLangTessControl:
case EShLangTessEvaluation:
case EShLangGeometry:
// TODO: desktop functionality: support new stages: note it is probably best to stop adding/using special qualifiers, given the passthrough nature of these stages
break;
case EShLangFragment: case EShLangFragment:
SpecialQualifier("gl_FrontFacing", EvqFace, symbolTable); SpecialQualifier("gl_FrontFacing", EvqFace, symbolTable);
SpecialQualifier("gl_FragCoord", EvqFragCoord, symbolTable); SpecialQualifier("gl_FragCoord", EvqFragCoord, symbolTable);
@ -2106,7 +2115,7 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
break; break;
case EShLangCompute: case EShLangCompute:
// TODO: desktop functionality: support new stages // TODO: 4.3 desktop functionality: compute special variables
break; break;
default: default:

View File

@ -867,7 +867,7 @@ void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguag
// //
//if (ftransformUsed) { //if (ftransformUsed) {
// TODO: desktop: track ftransform() usage // TODO: 1.1 lowering functionality: track ftransform() usage
// addSymbolLinkageNode(root, symbolTable, "gl_Vertex"); // addSymbolLinkageNode(root, symbolTable, "gl_Vertex");
// addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix"); // addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix");
//} //}

View File

@ -54,7 +54,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0),
tokensBeforeEOF(false), currentScanner(0), tokensBeforeEOF(false), currentScanner(0),
numErrors(0), parsingBuiltins(pb), afterEOF(false), numErrors(0), parsingBuiltins(pb), afterEOF(false),
anyIndexLimits(false) anyIndexLimits(false), fragCoordUsedBeforeRedeclaration(false)
{ {
// ensure we always have a linkage node, even if empty, to simplify tree topology algorithms // ensure we always have a linkage node, even if empty, to simplify tree topology algorithms
linkage = new TIntermAggregate; linkage = new TIntermAggregate;
@ -412,11 +412,15 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
if (variable->getType().getQualifier().storage == EvqConst) if (variable->getType().getQualifier().storage == EvqConst)
node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc); node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc);
else { else {
// break sharing with built-ins
TType* type; TType* type;
if (variable->isReadOnly()) { if (variable->isReadOnly()) {
type = new TType; type = new TType;
// break sharing with built-ins
type->deepCopy(variable->getType()); type->deepCopy(variable->getType());
// track use of unredeclared gl_FragCoord
if (variable->getName() == "gl_FragCoord")
fragCoordUsedBeforeRedeclaration = true;
} else } else
type = &variable->getWritableType(); type = &variable->getWritableType();
node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), *type, loc); node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), *type, loc);
@ -473,6 +477,8 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable"); error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
if (base->getBasicType() == EbtBlock) if (base->getBasicType() == EbtBlock)
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing block array"); requireProfile(base->getLoc(), ~EEsProfile, "variable indexing block array");
else if (language == EShLangFragment && base->getQualifier().storage == EvqVaryingOut)
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader ouput array");
else if (base->getBasicType() == EbtSampler && version >= 130) { else if (base->getBasicType() == EbtSampler && version >= 130) {
const char* explanation = "variable indexing sampler array"; const char* explanation = "variable indexing sampler array";
requireProfile(base->getLoc(), ECoreProfile | ECompatibilityProfile, explanation); requireProfile(base->getLoc(), ECoreProfile | ECompatibilityProfile, explanation);
@ -923,7 +929,7 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
} }
// generic error recovery // generic error recovery
// TODO: coding: localize all the error recoveries that look like this // TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades
if (result == 0) { if (result == 0) {
TConstUnionArray unionArray(1); TConstUnionArray unionArray(1);
unionArray[0].setDConst(0.0); unionArray[0].setDConst(0.0);
@ -1895,19 +1901,18 @@ void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TTyp
void TParseContext::updateMaxArraySize(TSourceLoc loc, TIntermNode *node, int index) void TParseContext::updateMaxArraySize(TSourceLoc loc, TIntermNode *node, int index)
{ {
TIntermSymbol* symbolNode = node->getAsSymbolNode();
if (! symbolNode) {
// TODO: functionality: unsized arrays: handle members of blocks
return;
}
// maybe there is nothing to do... // maybe there is nothing to do...
// TODO: functionality: unsized arrays: is the node sharing the array type with the symbol table? TIntermTyped* typedNode = node->getAsTyped();
if (symbolNode->getType().getMaxArraySize() > index) if (typedNode->getType().getMaxArraySize() > index)
return; return;
// something to do... // something to do...
// TODO: 1.50 linker: unsized block member array: 'node' could be an expression for a dereference
TIntermSymbol* symbolNode = node->getAsSymbolNode();
if (! symbolNode)
return;
TSymbol* symbol = symbolTable.find(symbolNode->getName()); TSymbol* symbol = symbolTable.find(symbolNode->getName());
assert(symbol); assert(symbol);
if (symbol == 0) if (symbol == 0)
@ -1919,7 +1924,7 @@ void TParseContext::updateMaxArraySize(TSourceLoc loc, TIntermNode *node, int in
} }
// For read-only built-ins, add a new variable for holding the maximum array size of an implicitly-sized shared array. // For read-only built-ins, add a new variable for holding the maximum array size of an implicitly-sized shared array.
// TODO: functionality: unsized arrays: is this new array type shared with the node? // TODO: desktop linker: unsized arrays: is this new array type shared with the node?
if (symbol->isReadOnly()) { if (symbol->isReadOnly()) {
symbol = symbolTable.copyUp(symbol); symbol = symbolTable.copyUp(symbol);
@ -1959,7 +1964,7 @@ void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType
// //
// Returns a redeclared and type-modified variable if a redeclarated occurred. // Returns a redeclared and type-modified variable if a redeclarated occurred.
// //
TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, bool& newDeclaration) TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration)
{ {
if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel()) if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel())
return 0; return 0;
@ -2003,7 +2008,53 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
} }
// Now, modify the type of the copy, as per the type of the current redeclaration. // Now, modify the type of the copy, as per the type of the current redeclaration.
// TODO: functionality: verify type change is allowed and make the change in type
TQualifier& symbolQualifier = symbol->getWritableType().getQualifier();
if (identifier == "gl_FrontColor" ||
identifier == "gl_BackColor" ||
identifier == "gl_FrontSecondaryColor" ||
identifier == "gl_BackSecondaryColor" ||
identifier == "gl_SecondaryColor" ||
identifier == "gl_Color") {
symbolQualifier.flat = qualifier.flat;
symbolQualifier.smooth = qualifier.smooth;
symbolQualifier.nopersp = qualifier.nopersp;
if (qualifier.hasLayout())
error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
if (qualifier.isMemory() || qualifier.isAuxiliary() || symbol->getType().getQualifier().storage != qualifier.storage)
error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
} else if (identifier == "gl_TexCoord" ||
identifier == "gl_ClipDistance") {
if (qualifier.hasLayout() || qualifier.isMemory() || qualifier.isAuxiliary() ||
qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
symbolQualifier.storage != qualifier.storage)
error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
} else if (identifier == "gl_FragCoord") {
if (fragCoordUsedBeforeRedeclaration)
error(loc, "cannot redeclare after use", "gl_FragCoord", "");
// Note: this did not catch the case of 1) declare, 2) use, 3) declare again, because the "use" was of a redeclaration, and so didn't set fragCoordUsedBeforeRedeclaration.
// (and that's what the rules are too, as long as #3 matches #1)
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
qualifier.isMemory() || qualifier.isAuxiliary())
error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
if (identifier == "gl_FragCoord" && qualifier.storage != EvqVaryingIn)
error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str());
if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
if (publicType.pixelCenterInteger)
intermediate.setPixelCenterInteger();
if (publicType.originUpperLeft)
intermediate.setOriginUpperLeft();
} else if (identifier == "gl_FragDepth") {
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
qualifier.isMemory() || qualifier.isAuxiliary())
error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
if (qualifier.storage != EvqVaryingOut)
error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
// TODO 4.2: gl_FragDepth redeclaration
}
// TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
return symbol; return symbol;
} }
@ -2062,7 +2113,7 @@ bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, c
if (language == EShLangGeometry && block->getType().isArray() && block->getType().getQualifier().storage == EvqVaryingIn) if (language == EShLangGeometry && block->getType().isArray() && block->getType().getQualifier().storage == EvqVaryingIn)
inputArraySymbolResizeList.push_back(block); inputArraySymbolResizeList.push_back(block);
// TODO: semantics: block redeclaration: instance array size matching? // TODO: SSO/4.10 semantics: block redeclaration: instance array size matching
// Edit and error check the container against the redeclaration // Edit and error check the container against the redeclaration
// - remove unused members // - remove unused members
@ -2085,7 +2136,7 @@ bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, c
else else
member = type.getStruct()->erase(member); member = type.getStruct()->erase(member);
// TODO: semantics: block redeclaration: member type/qualifier matching // TODO: SSO/4.10 semantics: block redeclaration: member type/qualifier matching
} }
symbolTable.insert(*block); symbolTable.insert(*block);
@ -2306,36 +2357,48 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
} }
if (language == EShLangGeometry || language == EShLangTessEvaluation) { if (language == EShLangGeometry || language == EShLangTessEvaluation) {
if (id == TQualifier::getGeometryString(ElgTriangles)) { if (id == TQualifier::getGeometryString(ElgTriangles)) {
publicType.geometry = ElgTriangles; publicType.shaderQualifiers.geometry = ElgTriangles;
return; return;
} }
if (language == EShLangGeometry) { if (language == EShLangGeometry) {
if (id == TQualifier::getGeometryString(ElgPoints)) { if (id == TQualifier::getGeometryString(ElgPoints)) {
publicType.geometry = ElgPoints; publicType.shaderQualifiers.geometry = ElgPoints;
return; return;
} }
if (id == TQualifier::getGeometryString(ElgLineStrip)) { if (id == TQualifier::getGeometryString(ElgLineStrip)) {
publicType.geometry = ElgLineStrip; publicType.shaderQualifiers.geometry = ElgLineStrip;
return; return;
} }
if (id == TQualifier::getGeometryString(ElgLines)) { if (id == TQualifier::getGeometryString(ElgLines)) {
publicType.geometry = ElgLines; publicType.shaderQualifiers.geometry = ElgLines;
return; return;
} }
if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) { if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
publicType.geometry = ElgLinesAdjacency; publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
return; return;
} }
if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) { if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
publicType.geometry = ElgTrianglesAdjacency; publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
return; return;
} }
if (id == TQualifier::getGeometryString(ElgTriangleStrip)) { if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
publicType.geometry = ElgTriangleStrip; publicType.shaderQualifiers.geometry = ElgTriangleStrip;
return; return;
} }
} else { } else {
// TODO: tessellation evaluation // TODO: 4.0 tessellation evaluation
}
}
if (language == EShLangFragment) {
if (id == "origin_upper_left") {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left");
publicType.shaderQualifiers.originUpperLeft = true;
return;
}
if (id == "pixel_center_integer") {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer");
publicType.shaderQualifiers.pixelCenterInteger = true;
return;
} }
} }
error(loc, "unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)", id.c_str(), ""); error(loc, "unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)", id.c_str(), "");
@ -2345,6 +2408,12 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
// type information for error checking. // type information for error checking.
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, int value) void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, int value)
{ {
if (value < 0) {
error(loc, "cannot be negative", "layout qualifier value", "");
return;
// TODO: 4.4: test the above, once expressions are allowed; until then, can't even express a negative location
}
std::transform(id.begin(), id.end(), id.begin(), ::tolower); std::transform(id.begin(), id.end(), id.begin(), ::tolower);
if (id == "location") { if (id == "location") {
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "location"); requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "location");
@ -2367,11 +2436,11 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
if (language == EShLangGeometry) { if (language == EShLangGeometry) {
if (id == "invocations") { if (id == "invocations") {
profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, 0, "invocations"); profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, 0, "invocations");
publicType.invocations = value; publicType.shaderQualifiers.invocations = value;
return; return;
} }
if (id == "max_vertices") { if (id == "max_vertices") {
publicType.maxVertices = value; publicType.shaderQualifiers.maxVertices = value;
return; return;
} }
if (id == "stream") { if (id == "stream") {
@ -2380,16 +2449,13 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
} }
} }
error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), ""); error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
// TODO: semantics: error check: make sure locations are non-overlapping across the whole stage
// TODO: semantics: error check: output arrays can only be indexed with a constant (es 300)
} }
// //
// Merge characteristics of the 'src' qualifier into the 'dst', at the TPublicType level, // Merge characteristics of the 'src' qualifier into the 'dst', at the TPublicType level,
// which means for layout-qualifier information not kept per qualifier. // which means for layout-qualifier information not kept per qualifier.
// //
void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TPublicType& dst, const TPublicType& src) void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TShaderQualifiers& dst, const TShaderQualifiers& src)
{ {
if (src.geometry != ElgNone) if (src.geometry != ElgNone)
dst.geometry = src.geometry; dst.geometry = src.geometry;
@ -2397,6 +2463,10 @@ void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TPublicType& dst
dst.invocations = src.invocations; dst.invocations = src.invocations;
if (src.maxVertices != 0) if (src.maxVertices != 0)
dst.maxVertices = src.maxVertices; dst.maxVertices = src.maxVertices;
if (src.pixelCenterInteger)
dst.pixelCenterInteger = src.pixelCenterInteger;
if (src.originUpperLeft)
dst.originUpperLeft = src.originUpperLeft;
} }
// Merge any layout qualifier information from src into dst, leaving everything else in dst alone // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
@ -2464,11 +2534,11 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol)
// an array of size N, all elements of the array from binding through binding + N 1 must be within this // an array of size N, all elements of the array from binding through binding + N 1 must be within this
// range." // range."
// //
// TODO: binding error checking against limits, arrays // TODO: 4.2 binding limits: binding error checking against limits, arrays
// //
if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock) if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock)
error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", ""); error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
// TODO: atomic counter functionality: include in test above // TODO: 4.2 functionality: atomic counter: include in test above
} }
} }
@ -2527,15 +2597,15 @@ void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& quali
} }
// For places that can't have shader-level layout qualifiers // For places that can't have shader-level layout qualifiers
void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TPublicType& publicType) void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TShaderQualifiers& shaderQualifiers)
{ {
const char* message = "can only apply to a standalone qualifier"; const char* message = "can only apply to a standalone qualifier";
if (publicType.geometry != ElgNone) if (shaderQualifiers.geometry != ElgNone)
error(loc, message, TQualifier::getGeometryString(publicType.geometry), ""); error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
if (publicType.invocations > 0) if (shaderQualifiers.invocations > 0)
error(loc, message, "invocations", ""); error(loc, message, "invocations", "");
if (publicType.maxVertices > 0) if (shaderQualifiers.maxVertices > 0)
error(loc, message, "max_vertices", ""); error(loc, message, "max_vertices", "");
} }
@ -2658,7 +2728,7 @@ const TFunction* TParseContext::findFunction400(TSourceLoc loc, const TFunction&
// Returns a subtree node that computes an initializer, if needed. // Returns a subtree node that computes an initializer, if needed.
// Returns 0 if there is no code to execute for initialization. // Returns 0 if there is no code to execute for initialization.
// //
TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer) TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
{ {
TType type(publicType); TType type(publicType);
@ -2672,9 +2742,12 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
if (! type.getQualifier().hasStream() && language == EShLangGeometry && type.getQualifier().storage == EvqVaryingOut) if (! type.getQualifier().hasStream() && language == EShLangGeometry && type.getQualifier().storage == EvqVaryingOut)
type.getQualifier().layoutStream = globalOutputDefaults.layoutStream; type.getQualifier().layoutStream = globalOutputDefaults.layoutStream;
if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
// Check for redeclaration of built-ins and/or attempting to declare a reserved name // Check for redeclaration of built-ins and/or attempting to declare a reserved name
bool newDeclaration = false; // true if a new entry gets added to the symbol table bool newDeclaration = false; // true if a new entry gets added to the symbol table
TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, newDeclaration); TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers, newDeclaration);
if (! symbol) if (! symbol)
reservedErrorCheck(loc, identifier); reservedErrorCheck(loc, identifier);
@ -2698,6 +2771,8 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
// non-array case // non-array case
if (! symbol) if (! symbol)
symbol = declareNonArray(loc, identifier, type, newDeclaration); symbol = declareNonArray(loc, identifier, type, newDeclaration);
else if (type != symbol->getType())
error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
} }
// Deal with initializer // Deal with initializer
@ -2859,7 +2934,7 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
arrayType.setArraySizes(type); arrayType.setArraySizes(type);
arrayType.changeArraySize(initList->getSequence().size()); arrayType.changeArraySize(initList->getSequence().size());
TType elementType; TType elementType;
elementType.shallowCopy(arrayType); // TODO: arrays of arrays: combine this with deref. elementType.shallowCopy(arrayType); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
elementType.dereference(); elementType.dereference();
for (size_t i = 0; i < initList->getSequence().size(); ++i) { for (size_t i = 0; i < initList->getSequence().size(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped()); initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
@ -2884,7 +2959,7 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
return 0; return 0;
} }
TType vectorType; TType vectorType;
vectorType.shallowCopy(type); // TODO: arrays of arrays: combine this with deref. vectorType.shallowCopy(type); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
vectorType.dereference(); vectorType.dereference();
for (int i = 0; i < type.getMatrixCols(); ++i) { for (int i = 0; i < type.getMatrixCols(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped()); initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
@ -2925,7 +3000,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
TType elementType; TType elementType;
elementType.shallowCopy(type); elementType.shallowCopy(type);
if (type.isArray()) if (type.isArray())
elementType.dereference(); // TODO: arrays of arrays: combine this with shallowCopy elementType.dereference(); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
bool singleArg; bool singleArg;
if (aggrNode) { if (aggrNode) {
@ -3280,43 +3355,43 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
// //
void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPublicType& publicType) void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPublicType& publicType)
{ {
if (publicType.maxVertices) { if (publicType.shaderQualifiers.maxVertices) {
if (! intermediate.setMaxVertices(publicType.maxVertices)) if (! intermediate.setMaxVertices(publicType.shaderQualifiers.maxVertices))
error(loc, "cannot change previously set layout value", "max_vertices", ""); error(loc, "cannot change previously set layout value", "max_vertices", "");
} }
if (publicType.invocations) { if (publicType.shaderQualifiers.invocations) {
if (! intermediate.setInvocations(publicType.invocations)) if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations))
error(loc, "cannot change previously set layout value", "invocations", ""); error(loc, "cannot change previously set layout value", "invocations", "");
} }
if (publicType.geometry != ElgNone) { if (publicType.shaderQualifiers.geometry != ElgNone) {
if (publicType.qualifier.storage == EvqVaryingIn) { if (publicType.qualifier.storage == EvqVaryingIn) {
switch (publicType.geometry) { switch (publicType.shaderQualifiers.geometry) {
case ElgPoints: case ElgPoints:
case ElgLines: case ElgLines:
case ElgLinesAdjacency: case ElgLinesAdjacency:
case ElgTriangles: case ElgTriangles:
case ElgTrianglesAdjacency: case ElgTrianglesAdjacency:
if (intermediate.setInputPrimitive(publicType.geometry)) if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry))
checkInputArrayConsistency(loc); checkInputArrayConsistency(loc);
else else
error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.geometry), ""); error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
break; break;
default: default:
error(loc, "does not apply to input", TQualifier::getGeometryString(publicType.geometry), ""); error(loc, "does not apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
} }
} else if (publicType.qualifier.storage == EvqVaryingOut) { } else if (publicType.qualifier.storage == EvqVaryingOut) {
switch (publicType.geometry) { switch (publicType.shaderQualifiers.geometry) {
case ElgPoints: case ElgPoints:
case ElgLineStrip: case ElgLineStrip:
case ElgTriangleStrip: case ElgTriangleStrip:
if (! intermediate.setOutputPrimitive(publicType.geometry)) if (! intermediate.setOutputPrimitive(publicType.shaderQualifiers.geometry))
error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.geometry), ""); error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
break; break;
default: default:
error(loc, "does not only apply to output", TQualifier::getGeometryString(publicType.geometry), ""); error(loc, "does not only apply to output", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
} }
} else } else
error(loc, "cannot be used here", TQualifier::getGeometryString(publicType.geometry), ""); error(loc, "cannot be used here", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
} }
const TQualifier& qualifier = publicType.qualifier; const TQualifier& qualifier = publicType.qualifier;
@ -3472,7 +3547,7 @@ TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression,
return switchNode; return switchNode;
} }
// TODO: constant folding: these should use a follow a fully folded model now, and probably move to Constant.cpp scheme. // TODO: simplification: constant folding: these should use a follow a fully folded model now, and probably move to Constant.cpp scheme.
// //
// This function returns the tree representation for the vector field(s) being accessed from a constant vector. // This function returns the tree representation for the vector field(s) being accessed from a constant vector.
@ -3552,7 +3627,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
TIntermTyped* typedNode; TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
TType arrayElementType; TType arrayElementType;
arrayElementType.shallowCopy(node->getType()); // TODO: arrays of arrays: combine this with deref. arrayElementType.shallowCopy(node->getType()); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
arrayElementType.dereference(); arrayElementType.dereference();
if (index >= node->getType().getArraySize() || index < 0) { if (index >= node->getType().getArraySize() || index < 0) {

View File

@ -122,7 +122,7 @@ public:
void precisionQualifierCheck(TSourceLoc, TPublicType&); void precisionQualifierCheck(TSourceLoc, TPublicType&);
void parameterSamplerCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type); void parameterSamplerCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type);
bool containsSampler(const TType& type); bool containsSampler(const TType& type);
TSymbol* redeclareBuiltinVariable(TSourceLoc, const TString&, bool& newDeclaration); TSymbol* redeclareBuiltinVariable(TSourceLoc, const TString&, const TQualifier&, const TShaderQualifiers&, bool& newDeclaration);
bool redeclareBuiltinBlock(TSourceLoc, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes); bool redeclareBuiltinBlock(TSourceLoc, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
void paramCheck(TSourceLoc, const TStorageQualifier&, TType* type); void paramCheck(TSourceLoc, const TStorageQualifier&, TType* type);
void nestedBlockCheck(TSourceLoc); void nestedBlockCheck(TSourceLoc);
@ -134,17 +134,17 @@ public:
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&); void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int); void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
void mergeShaderLayoutQualifiers(TSourceLoc, TPublicType& dst, const TPublicType& src); void mergeShaderLayoutQualifiers(TSourceLoc, TShaderQualifiers& dst, const TShaderQualifiers& src);
void mergeObjectLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src); void mergeObjectLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
void layoutTypeCheck(TSourceLoc, const TSymbol&); void layoutTypeCheck(TSourceLoc, const TSymbol&);
void layoutQualifierCheck(TSourceLoc, const TQualifier&); void layoutQualifierCheck(TSourceLoc, const TQualifier&);
void checkNoShaderLayouts(TSourceLoc, const TPublicType&); void checkNoShaderLayouts(TSourceLoc, const TShaderQualifiers&);
const TFunction* findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn); const TFunction* findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn);
const TFunction* findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn); const TFunction* findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn);
const TFunction* findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn); const TFunction* findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn);
const TFunction* findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn); const TFunction* findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn);
TIntermNode* declareVariable(TSourceLoc, TString& identifier, TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0); TIntermNode* declareVariable(TSourceLoc, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
TIntermTyped* addConstructor(TSourceLoc, TIntermNode*, const TType&, TOperator); TIntermTyped* addConstructor(TSourceLoc, TIntermNode*, const TType&, TOperator);
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc); TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
@ -241,7 +241,7 @@ protected:
TIdSetType inductiveLoopIds; TIdSetType inductiveLoopIds;
bool anyIndexLimits; bool anyIndexLimits;
TVector<TIntermTyped*> needsIndexLimitationChecking; TVector<TIntermTyped*> needsIndexLimitationChecking;
// TODO: desktop functionality: track use of gl_FragDepth before redeclaration bool fragCoordUsedBeforeRedeclaration;
// //
// Geometry shader input arrays: // Geometry shader input arrays:

View File

@ -779,13 +779,13 @@ declaration
} }
| type_qualifier IDENTIFIER SEMICOLON { | type_qualifier IDENTIFIER SEMICOLON {
parseContext.pipeInOutFix($1.loc, $1.qualifier); parseContext.pipeInOutFix($1.loc, $1.qualifier);
parseContext.checkNoShaderLayouts($1.loc, $1); parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string); parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string);
$$ = 0; $$ = 0;
} }
| type_qualifier IDENTIFIER identifier_list SEMICOLON { | type_qualifier IDENTIFIER identifier_list SEMICOLON {
parseContext.pipeInOutFix($1.loc, $1.qualifier); parseContext.pipeInOutFix($1.loc, $1.qualifier);
parseContext.checkNoShaderLayouts($1.loc, $1); parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
$3->push_back($2.string); $3->push_back($2.string);
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3); parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3);
$$ = 0; $$ = 0;
@ -797,7 +797,7 @@ block_structure
--parseContext.structNestingLevel; --parseContext.structNestingLevel;
parseContext.blockName = $2.string; parseContext.blockName = $2.string;
parseContext.pipeInOutFix($1.loc, $1.qualifier); parseContext.pipeInOutFix($1.loc, $1.qualifier);
parseContext.checkNoShaderLayouts($1.loc, $1); parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
parseContext.currentBlockQualifier = $1.qualifier; parseContext.currentBlockQualifier = $1.qualifier;
$$.loc = $1.loc; $$.loc = $1.loc;
$$.typeList = $5; $$.typeList = $5;
@ -919,7 +919,7 @@ parameter_declaration
if ($1.qualifier.precision != EpqNone) if ($1.qualifier.precision != EpqNone)
$$.param.type->getQualifier().precision = $1.qualifier.precision; $$.param.type->getQualifier().precision = $1.qualifier.precision;
parseContext.checkNoShaderLayouts($1.loc, $1); parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type); parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);
parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type); parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type);
} }
@ -937,7 +937,7 @@ parameter_declaration
if ($1.qualifier.precision != EpqNone) if ($1.qualifier.precision != EpqNone)
$$.param.type->getQualifier().precision = $1.qualifier.precision; $$.param.type->getQualifier().precision = $1.qualifier.precision;
parseContext.checkNoShaderLayouts($1.loc, $1); parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type); parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);
parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type); parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type);
} }
@ -1038,7 +1038,8 @@ fully_specified_type
if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1.qualifier)) if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1.qualifier))
$2.arraySizes = 0; $2.arraySizes = 0;
parseContext.checkNoShaderLayouts($2.loc, $1); parseContext.checkNoShaderLayouts($2.loc, $1.shaderQualifiers);
parseContext.mergeShaderLayoutQualifiers($2.loc, $2.shaderQualifiers, $1.shaderQualifiers);
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true); parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
parseContext.precisionQualifierCheck($2.loc, $2); parseContext.precisionQualifierCheck($2.loc, $2);
@ -1095,7 +1096,7 @@ layout_qualifier_id_list
} }
| layout_qualifier_id_list COMMA layout_qualifier_id { | layout_qualifier_id_list COMMA layout_qualifier_id {
$$ = $1; $$ = $1;
parseContext.mergeShaderLayoutQualifiers($2.loc, $$, $3); parseContext.mergeShaderLayoutQualifiers($2.loc, $$.shaderQualifiers, $3.shaderQualifiers);
parseContext.mergeObjectLayoutQualifiers($2.loc, $$.qualifier, $3.qualifier); parseContext.mergeObjectLayoutQualifiers($2.loc, $$.qualifier, $3.qualifier);
} }
@ -1134,7 +1135,7 @@ type_qualifier
if ($$.basicType == EbtVoid) if ($$.basicType == EbtVoid)
$$.basicType = $2.basicType; $$.basicType = $2.basicType;
parseContext.mergeShaderLayoutQualifiers($$.loc, $$, $2); parseContext.mergeShaderLayoutQualifiers($$.loc, $$.shaderQualifiers, $2.shaderQualifiers);
parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false); parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false);
} }
; ;
@ -1569,7 +1570,7 @@ type_specifier_nonarray
$$.setMatrix(4, 4); $$.setMatrix(4, 4);
} }
| ATOMIC_UINT { | ATOMIC_UINT {
// TODO: 4.2 functionality: add type // TODO: 4.2 functionality: add atomic_uint type
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt; $$.basicType = EbtInt;
} }
@ -2051,7 +2052,7 @@ struct_declaration
$$ = $3; $$ = $3;
parseContext.checkNoShaderLayouts($1.loc, $1); parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType); parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType);
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true); parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
parseContext.precisionQualifierCheck($2.loc, $2); parseContext.precisionQualifierCheck($2.loc, $2);

View File

@ -585,6 +585,12 @@ void TIntermediate::outputTree(TInfoSink& infoSink)
infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n"; infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n"; infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
} }
if (language == EShLangFragment) {
if (pixelCenterInteger)
infoSink.debug << "gl_FragCoord pixel center is integer\n";
if (originUpperLeft)
infoSink.debug << "gl_FragCoord origin is upper left\n";
}
if (treeRoot == 0) if (treeRoot == 0)
return; return;

View File

@ -73,6 +73,9 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
(profile == EEsProfile && unit.profile != EEsProfile)) (profile == EEsProfile && unit.profile != EEsProfile))
error(infoSink, "Cannot mix ES profile with non-ES profile shaders\n"); error(infoSink, "Cannot mix ES profile with non-ES profile shaders\n");
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
error(infoSink, "gl_FragCoord redeclarations must match across shaders\n");
if (unit.treeRoot == 0) if (unit.treeRoot == 0)
return; return;
@ -101,7 +104,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
// //
void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, const TIntermSequence& unitGlobals) void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, const TIntermSequence& unitGlobals)
{ {
// TODO: Performance: Processing in alphabetical order will be faster // TODO: link-time performance: Processing in alphabetical order will be faster
// Error check the global objects, not including the linker objects // Error check the global objects, not including the linker objects
for (unsigned int child = 0; child < globals.size() - 1; ++child) { for (unsigned int child = 0; child < globals.size() - 1; ++child) {
@ -157,8 +160,6 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
// //
// This function only does one of intra- or cross-stage matching per call. // This function only does one of intra- or cross-stage matching per call.
// //
// TODO: Linker Functionality: this function is under active development
//
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage) void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
{ {
bool writeTypeComparison = false; bool writeTypeComparison = false;
@ -340,7 +341,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink)
bool fragOutWithNoLocation = false; bool fragOutWithNoLocation = false;
int numFragOut = 0; int numFragOut = 0;
// TODO: maps for location collision checking // TODO: linker functionality: location collision checking
TIntermSequence& linkObjects = findLinkerObjects(); TIntermSequence& linkObjects = findLinkerObjects();
for (size_t i = 0; i < linkObjects.size(); ++i) { for (size_t i = 0; i < linkObjects.size(); ++i) {

View File

@ -57,7 +57,7 @@ class TSymbol;
class TIntermediate { class TIntermediate {
public: public:
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), 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),
invocations(0), maxVertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone) { } invocations(0), maxVertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false) { }
void setVersion(int v) { version = v; } void setVersion(int v) { version = v; }
int getVersion() const { return version; } int getVersion() const { return version; }
@ -129,6 +129,10 @@ public:
outputPrimitive = p; outputPrimitive = p;
return true; return true;
} }
void setOriginUpperLeft() { originUpperLeft = true; }
bool getOriginUpperLeft() const { return originUpperLeft; }
void setPixelCenterInteger() { pixelCenterInteger = true; }
bool getPixelCenterInteger() const { return pixelCenterInteger; }
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
void merge(TInfoSink&, TIntermediate&); void merge(TInfoSink&, TIntermediate&);
@ -157,6 +161,8 @@ protected:
int maxVertices; int maxVertices;
TLayoutGeometry inputPrimitive; TLayoutGeometry inputPrimitive;
TLayoutGeometry outputPrimitive; TLayoutGeometry outputPrimitive;
bool pixelCenterInteger;
bool originUpperLeft;
// for detecting recursion: pair is <caller, callee> // for detecting recursion: pair is <caller, callee>
struct TCall { struct TCall {

View File

@ -627,7 +627,7 @@ int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * ppToken)
return '.'; return '.';
} }
case '/': case '/':
// TODO: preprocessor: use the Scan.cpp comment scanner // TODO: preprocessor simplification: use the Scan.cpp comment scanner
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken); ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '/') { if (ch == '/') {
do { do {

View File

@ -299,7 +299,7 @@ void TPpContext::RewindTokenStream(TokenStream *pTok)
int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken) int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
{ {
//TODO: PP: why is this different than byte_scan //TODO: preprocessor simplification: why is this different than byte_scan
char tokenText[TPpToken::maxTokenLength + 1]; char tokenText[TPpToken::maxTokenLength + 1];
int ltoken, len; int ltoken, len;

View File

@ -137,7 +137,7 @@ bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
return false; return false;
} }
// TODO: if we need these on linux, flesh them out // TODO: non-windows: if we need these on linux, flesh them out
void InitGlobalLock() { } void InitGlobalLock() { }
void GetGlobalLock() { } void GetGlobalLock() { }
void ReleaseGlobalLock() { } void ReleaseGlobalLock() { }