Add geometry shader input array sizing/checking WRT declared input primitive layout.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23698 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
ab41fe5df6
commit
9497485e14
@ -12,3 +12,40 @@ void main()
|
|||||||
|
|
||||||
layout(invocations = 3) out outbn { int a; }; // ERROR, not on a block
|
layout(invocations = 3) out outbn { int a; }; // ERROR, not on a block
|
||||||
layout(max_vertices = 127, invocations = 4) out;
|
layout(max_vertices = 127, invocations = 4) out;
|
||||||
|
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
in gl_PerVertex { // testing input arrays with a block redeclaration, see 420.geom for without
|
||||||
|
vec4 gl_Position;
|
||||||
|
} gl_in[];
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
gl_in.length(); // ERROR
|
||||||
|
gl_in[1].gl_Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
in vec4 color[];
|
||||||
|
in vec4 color2[];
|
||||||
|
in vec4 colorS[3];
|
||||||
|
in vec4 colorBad[4];
|
||||||
|
|
||||||
|
void foo2()
|
||||||
|
{
|
||||||
|
color.length(); // ERROR
|
||||||
|
colorS.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(triangles) in; // give ERROR just for colorBad
|
||||||
|
|
||||||
|
in vec4 color[3];
|
||||||
|
in vec4 color2[3];
|
||||||
|
in vec4 colorbad2[2]; // ERROR
|
||||||
|
|
||||||
|
void foo3()
|
||||||
|
{
|
||||||
|
gl_in.length();
|
||||||
|
color.length();
|
||||||
|
color2.length();
|
||||||
|
colorS.length();
|
||||||
|
}
|
||||||
|
23
Test/420.geom
Normal file
23
Test/420.geom
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#version 150 core
|
||||||
|
|
||||||
|
// testing input arrays without a gl_in[] block redeclaration, see 400.geom for with
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
gl_in.length(); // ERROR
|
||||||
|
gl_in[1].gl_Position;
|
||||||
|
gl_in[i].gl_Position; // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(triangles) in;
|
||||||
|
|
||||||
|
in vec4 color3[3];
|
||||||
|
|
||||||
|
void foo3()
|
||||||
|
{
|
||||||
|
gl_in.length();
|
||||||
|
gl_in[i].gl_Position;
|
||||||
|
color3.length();
|
||||||
|
}
|
@ -300,7 +300,7 @@ ERROR: node is still EOpNull!
|
|||||||
0:121 add second child into first child (4-component vector of float)
|
0:121 add second child into first child (4-component vector of float)
|
||||||
0:121 'v' (4-component vector of float)
|
0:121 'v' (4-component vector of float)
|
||||||
0:121 direct index (smooth in 4-component vector of float)
|
0:121 direct index (smooth in 4-component vector of float)
|
||||||
0:121 'gl_TexCoord' (smooth in unsized array of 4-component vector of float)
|
0:121 'gl_TexCoord' (smooth in 6-element array of 4-component vector of float)
|
||||||
0:121 Constant:
|
0:121 Constant:
|
||||||
0:121 3 (const int)
|
0:121 3 (const int)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
|
@ -46,5 +46,6 @@ ERROR: node is still EOpNull!
|
|||||||
0:? 'fflat' (flat in float)
|
0:? 'fflat' (flat in float)
|
||||||
0:? 'fsmooth' (smooth in float)
|
0:? 'fsmooth' (smooth in float)
|
||||||
0:? 'fnop' (noperspective in float)
|
0:? 'fnop' (noperspective in float)
|
||||||
|
0:? 'gl_ClipDistance' (smooth in unsized array of float)
|
||||||
0:? 'sampC' (uniform samplerCube)
|
0:? 'sampC' (uniform samplerCube)
|
||||||
|
|
||||||
|
@ -19,4 +19,5 @@ ERROR: node is still EOpNull!
|
|||||||
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:? 'gl_ClipDistance' (smooth in 5-element array of float)
|
0:? 'gl_ClipDistance' (smooth in 5-element array of float)
|
||||||
|
0:? 'gl_ClipDistance' (smooth in 5-element array of float)
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ ERROR: node is still EOpNull!
|
|||||||
0:33 direct index (float)
|
0:33 direct index (float)
|
||||||
0:33 gl_ClipDistance: direct index for structure (unsized array of float)
|
0:33 gl_ClipDistance: direct index for structure (unsized array of float)
|
||||||
0:33 direct index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
0:33 direct index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
0:33 'gl_in' (in unsized array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
0:33 'gl_in' (in 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
0:33 Constant:
|
0:33 Constant:
|
||||||
0:33 1 (const int)
|
0:33 1 (const int)
|
||||||
0:33 Constant:
|
0:33 Constant:
|
||||||
@ -77,7 +77,7 @@ ERROR: node is still EOpNull!
|
|||||||
0:34 0 (const uint)
|
0:34 0 (const uint)
|
||||||
0:34 gl_Position: direct index for structure (4-component vector of float)
|
0:34 gl_Position: direct index for structure (4-component vector of float)
|
||||||
0:34 direct index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
0:34 direct index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
0:34 'gl_in' (in unsized array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
0:34 'gl_in' (in 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
0:34 Constant:
|
0:34 Constant:
|
||||||
0:34 0 (const int)
|
0:34 0 (const int)
|
||||||
0:34 Constant:
|
0:34 Constant:
|
||||||
@ -89,7 +89,7 @@ ERROR: node is still EOpNull!
|
|||||||
0:35 1 (const uint)
|
0:35 1 (const uint)
|
||||||
0:35 gl_PointSize: direct index for structure (float)
|
0:35 gl_PointSize: direct index for structure (float)
|
||||||
0:35 direct index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
0:35 direct index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
0:35 'gl_in' (in unsized array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
0:35 'gl_in' (in 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
0:35 Constant:
|
0:35 Constant:
|
||||||
0:35 3 (const int)
|
0:35 3 (const int)
|
||||||
0:35 Constant:
|
0:35 Constant:
|
||||||
@ -119,6 +119,7 @@ ERROR: node is still EOpNull!
|
|||||||
0:? 'fromV' (in block{color})
|
0:? 'fromV' (in block{color})
|
||||||
0:? 'toF' (layout(stream=0 ) out block{color})
|
0:? 'toF' (layout(stream=0 ) out block{color})
|
||||||
0:? '__anon__0' (layout(stream=0 ) out block{color})
|
0:? '__anon__0' (layout(stream=0 ) out block{color})
|
||||||
|
0:? 'gl_in' (in 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
0:? 'ov0' (layout(stream=0 ) out 4-component vector of float)
|
0:? 'ov0' (layout(stream=0 ) out 4-component vector of float)
|
||||||
0:? 'ov4' (layout(stream=4 ) out 4-component vector of float)
|
0:? 'ov4' (layout(stream=4 ) out 4-component vector of float)
|
||||||
0:? 'o1v0' (layout(stream=0 ) out 4-component vector of float)
|
0:? 'o1v0' (layout(stream=0 ) out 4-component vector of float)
|
||||||
|
@ -112,6 +112,7 @@ 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:? '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)
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
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:13: 'invocations' : can only apply to a standalone qualifier
|
ERROR: 0:13: 'invocations' : can only apply to a standalone qualifier
|
||||||
ERROR: 1 compilation errors. No code generated.
|
ERROR: 0:24: 'length' : array must be declared with a size before using this method
|
||||||
|
ERROR: 0:35: 'length' : array must be declared with a size before using this method
|
||||||
|
ERROR: 0:39: 'triangles' : inconsistent input primitive for array size colorBad
|
||||||
|
ERROR: 0:43: 'triangles' : inconsistent input primitive for array size colorbad2
|
||||||
|
ERROR: 5 compilation errors. No code generated.
|
||||||
|
|
||||||
invocations = 4
|
invocations = 4
|
||||||
max_vertices = 127
|
max_vertices = 127
|
||||||
input primitive = none
|
input primitive = triangles
|
||||||
output primitive = none
|
output primitive = none
|
||||||
ERROR: node is still EOpNull!
|
ERROR: node is still EOpNull!
|
||||||
0:3 Function Definition: main( (void)
|
0:3 Function Definition: main( (void)
|
||||||
@ -22,6 +26,42 @@ ERROR: node is still EOpNull!
|
|||||||
0:10 move second child to first child (int)
|
0:10 move second child to first child (int)
|
||||||
0:10 'id' (int)
|
0:10 'id' (int)
|
||||||
0:10 'gl_InvocationID' (in int)
|
0:10 'gl_InvocationID' (in int)
|
||||||
|
0:22 Function Definition: foo( (void)
|
||||||
|
0:22 Function Parameters:
|
||||||
|
0:24 Sequence
|
||||||
|
0:24 Constant:
|
||||||
|
0:24 1 (const int)
|
||||||
|
0:25 gl_Position: direct index for structure (4-component vector of float)
|
||||||
|
0:25 direct index (in block{gl_Position})
|
||||||
|
0:25 'gl_in' (in 3-element array of block{gl_Position})
|
||||||
|
0:25 Constant:
|
||||||
|
0:25 1 (const int)
|
||||||
|
0:25 Constant:
|
||||||
|
0:25 0 (const int)
|
||||||
|
0:33 Function Definition: foo2( (void)
|
||||||
|
0:33 Function Parameters:
|
||||||
|
0:35 Sequence
|
||||||
|
0:35 Constant:
|
||||||
|
0:35 1 (const int)
|
||||||
|
0:36 Constant:
|
||||||
|
0:36 3 (const int)
|
||||||
|
0:45 Function Definition: foo3( (void)
|
||||||
|
0:45 Function Parameters:
|
||||||
|
0:47 Sequence
|
||||||
|
0:47 Constant:
|
||||||
|
0:47 3 (const int)
|
||||||
|
0:48 Constant:
|
||||||
|
0:48 3 (const int)
|
||||||
|
0:49 Constant:
|
||||||
|
0:49 3 (const int)
|
||||||
|
0:50 Constant:
|
||||||
|
0:50 3 (const int)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? '__anon__0' (layout(stream=0 ) out block{a})
|
0:? '__anon__0' (layout(stream=0 ) out block{a})
|
||||||
|
0:? 'gl_in' (in 3-element array of block{gl_Position})
|
||||||
|
0:? 'color' (in 3-element array of 4-component vector of float)
|
||||||
|
0:? 'color2' (in 3-element array of 4-component vector of float)
|
||||||
|
0:? 'colorS' (in 3-element array of 4-component vector of float)
|
||||||
|
0:? 'colorBad' (in 4-element array of 4-component vector of float)
|
||||||
|
0:? 'colorbad2' (in 2-element array of 4-component vector of float)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ Warning, version 410 is not yet complete; some version-specific features are pre
|
|||||||
ERROR: 0:8: 'myIn' : cannot redeclare a built-in block with a user name
|
ERROR: 0:8: 'myIn' : cannot redeclare a built-in block with a user name
|
||||||
ERROR: 0:8: 'gl_' : reserved built-in name
|
ERROR: 0:8: 'gl_' : reserved built-in name
|
||||||
ERROR: 0:12: 'gl_' : reserved built-in name
|
ERROR: 0:12: 'gl_' : reserved built-in name
|
||||||
ERROR: 0:20: 'gl_PerVertex' : can only redeclare a built-in block once
|
ERROR: 0:20: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use
|
||||||
ERROR: 0:20: 'gl_' : reserved built-in name
|
ERROR: 0:20: 'gl_' : reserved built-in name
|
||||||
ERROR: 5 compilation errors. No code generated.
|
ERROR: 5 compilation errors. No code generated.
|
||||||
|
|
||||||
|
46
Test/baseResults/420.geom.out
Normal file
46
Test/baseResults/420.geom.out
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
Warning, version 150 is not yet complete; some version-specific features are present, but many are missing.
|
||||||
|
ERROR: 0:9: 'length' : array must be declared with a size before using this method
|
||||||
|
ERROR: 0:11: '[' : array must be redeclared with a size before being indexed with a variable
|
||||||
|
ERROR: 2 compilation errors. No code generated.
|
||||||
|
|
||||||
|
invocations = 0
|
||||||
|
max_vertices = 0
|
||||||
|
input primitive = triangles
|
||||||
|
output primitive = none
|
||||||
|
ERROR: node is still EOpNull!
|
||||||
|
0:7 Function Definition: foo( (void)
|
||||||
|
0:7 Function Parameters:
|
||||||
|
0:9 Sequence
|
||||||
|
0:9 Constant:
|
||||||
|
0:9 1 (const int)
|
||||||
|
0:10 gl_Position: direct index for structure (4-component vector of float)
|
||||||
|
0:10 direct index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
|
0:10 'gl_in' (in 3-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
|
0:10 Constant:
|
||||||
|
0:10 1 (const int)
|
||||||
|
0:10 Constant:
|
||||||
|
0:10 0 (const int)
|
||||||
|
0:11 gl_Position: direct index for structure (4-component vector of float)
|
||||||
|
0:11 indirect index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
|
0:11 'gl_in' (in 3-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
|
0:11 'i' (int)
|
||||||
|
0:11 Constant:
|
||||||
|
0:11 0 (const int)
|
||||||
|
0:18 Function Definition: foo3( (void)
|
||||||
|
0:18 Function Parameters:
|
||||||
|
0:20 Sequence
|
||||||
|
0:20 Constant:
|
||||||
|
0:20 3 (const int)
|
||||||
|
0:21 gl_Position: direct index for structure (4-component vector of float)
|
||||||
|
0:21 indirect index (in block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
|
0:21 'gl_in' (in 3-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
|
0:21 'i' (int)
|
||||||
|
0:21 Constant:
|
||||||
|
0:21 0 (const int)
|
||||||
|
0:22 Constant:
|
||||||
|
0:22 3 (const int)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'i' (int)
|
||||||
|
0:? 'gl_in' (in 3-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
|
||||||
|
0:? 'color3' (in 3-element array of 4-component vector of float)
|
||||||
|
|
@ -286,8 +286,11 @@ ERROR: node is still EOpNull!
|
|||||||
0:? '__anon__1' (in block{LightPos,LightColor})
|
0:? '__anon__1' (in block{LightPos,LightColor})
|
||||||
0:? 'Materiala' (in block{Color,TexCoord})
|
0:? 'Materiala' (in block{Color,TexCoord})
|
||||||
0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
|
0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
|
||||||
|
0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
|
||||||
0:? 'factor' (layout(location=3 ) out 4-component vector of float)
|
0:? 'factor' (layout(location=3 ) out 4-component vector of float)
|
||||||
0:? 'colors' (layout(location=2 ) out 3-element array of 4-component vector of float)
|
0:? 'colors' (layout(location=2 ) out 3-element array of 4-component vector of float)
|
||||||
0:? 'gl_FragDepth' (gl_FragDepth float)
|
0:? 'gl_FragDepth' (gl_FragDepth float)
|
||||||
|
0:? 'gl_FragDepth' (gl_FragDepth float)
|
||||||
|
0:? '__anon__2' (in block{gl_FogFragCoord,gl_TexCoord,gl_Color,gl_SecondaryColor})
|
||||||
0:? '__anon__2' (in block{gl_FogFragCoord,gl_TexCoord,gl_Color,gl_SecondaryColor})
|
0:? '__anon__2' (in block{gl_FogFragCoord,gl_TexCoord,gl_Color,gl_SecondaryColor})
|
||||||
|
|
||||||
|
@ -294,6 +294,7 @@ ERROR: node is still EOpNull!
|
|||||||
0:? 'c2' (layout(binding=3 ) uniform int)
|
0:? 'c2' (layout(binding=3 ) uniform int)
|
||||||
0:? 'd2' (layout(binding=2 ) uniform int)
|
0:? 'd2' (layout(binding=2 ) uniform int)
|
||||||
0:? '__anon__5' (out block{gl_Position,gl_PointSize,gl_ClipDistance,gl_ClipVertex,gl_FrontColor,gl_BackColor,gl_FrontSecondaryColor,gl_BackSecondaryColor,gl_TexCoord,gl_FogFragCoord})
|
0:? '__anon__5' (out block{gl_Position,gl_PointSize,gl_ClipDistance,gl_ClipVertex,gl_FrontColor,gl_BackColor,gl_FrontSecondaryColor,gl_BackSecondaryColor,gl_TexCoord,gl_FogFragCoord})
|
||||||
|
0:? '__anon__5' (out block{gl_Position,gl_PointSize,gl_ClipDistance,gl_ClipVertex,gl_FrontColor,gl_BackColor,gl_FrontSecondaryColor,gl_BackSecondaryColor,gl_TexCoord,gl_FogFragCoord})
|
||||||
0:? 'ColorInv' (smooth out 3-component vector of float)
|
0:? 'ColorInv' (smooth out 3-component vector of float)
|
||||||
0:? 'Color4' (invariant centroid smooth out 3-component vector of float)
|
0:? 'Color4' (invariant centroid smooth out 3-component vector of float)
|
||||||
0:? 'position' (smooth out 4-component vector of float)
|
0:? 'position' (smooth out 4-component vector of float)
|
||||||
|
@ -54,5 +54,6 @@ WARNING: 0:8: varying deprecated in version 130; may be removed in future releas
|
|||||||
0:? 'color' (smooth in 4-component vector of float)
|
0:? 'color' (smooth in 4-component vector of float)
|
||||||
0:? 'alpha' (smooth in float)
|
0:? 'alpha' (smooth in float)
|
||||||
0:? 'gl_TexCoord' (smooth in 6-element array of 4-component vector of float)
|
0:? 'gl_TexCoord' (smooth in 6-element array of 4-component vector of float)
|
||||||
|
0:? 'gl_TexCoord' (smooth in 6-element array of 4-component vector of float)
|
||||||
0:? 'foo' (smooth in 3-element array of 4-component vector of float)
|
0:? 'foo' (smooth in 3-element array of 4-component vector of float)
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ WARNING: 0:8: varying deprecated in version 130; may be removed in future releas
|
|||||||
0:? 'color' (smooth in 4-component vector of float)
|
0:? 'color' (smooth in 4-component vector of float)
|
||||||
0:? 'alpha' (smooth in float)
|
0:? 'alpha' (smooth in float)
|
||||||
0:? 'gl_TexCoord' (smooth in 6-element array of 4-component vector of float)
|
0:? 'gl_TexCoord' (smooth in 6-element array of 4-component vector of float)
|
||||||
|
0:? 'gl_TexCoord' (smooth in 6-element array of 4-component vector of float)
|
||||||
0:? 'userIn' (smooth in 2-element array of 4-component vector of float)
|
0:? 'userIn' (smooth in 2-element array of 4-component vector of float)
|
||||||
0:? 'a' (uniform int)
|
0:? 'a' (uniform int)
|
||||||
0:? 'b' (uniform int)
|
0:? 'b' (uniform int)
|
||||||
|
@ -47,6 +47,7 @@ tokenLength.vert
|
|||||||
300scope.vert
|
300scope.vert
|
||||||
400.frag
|
400.frag
|
||||||
420.vert
|
420.vert
|
||||||
|
420.geom
|
||||||
430scope.vert
|
430scope.vert
|
||||||
lineContinuation.vert
|
lineContinuation.vert
|
||||||
numeral.frag
|
numeral.frag
|
||||||
|
@ -423,7 +423,7 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
|
|||||||
} else {
|
} else {
|
||||||
// The symbol table search was done in the lexical phase, but
|
// The symbol table search was done in the lexical phase, but
|
||||||
// if this is a new symbol, it wouldn't have found it.
|
// if this is a new symbol, it wouldn't have found it.
|
||||||
const TVariable* variable = symbol ? symbol->getAsVariable() : 0;
|
TVariable* variable = symbol ? symbol->getAsVariable() : 0;
|
||||||
if (symbol && ! variable)
|
if (symbol && ! variable)
|
||||||
error(loc, "variable name expected", string->c_str(), "");
|
error(loc, "variable name expected", string->c_str(), "");
|
||||||
|
|
||||||
@ -435,8 +435,16 @@ 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 {
|
||||||
node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
|
// break sharing with built-ins
|
||||||
|
TType* type;
|
||||||
|
if (variable->isReadOnly()) {
|
||||||
|
type = new TType;
|
||||||
|
type->deepCopy(variable->getType());
|
||||||
|
} else
|
||||||
|
type = &variable->getWritableType();
|
||||||
|
node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), *type, loc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
@ -470,6 +478,7 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
|
|||||||
result = addConstMatrixNode(index->getAsConstantUnion()->getConstArray()[0].getIConst(), base, loc);
|
result = addConstMatrixNode(index->getAsConstantUnion()->getConstArray()[0].getIConst(), base, loc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// at least one of base and index is variable...
|
||||||
if (index->getQualifier().storage == EvqConst) {
|
if (index->getQualifier().storage == EvqConst) {
|
||||||
int indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
|
int indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
if (! base->isArray() && ((base->isVector() && base->getType().getVectorSize() <= indexValue) ||
|
if (! base->isArray() && ((base->isVector() && base->getType().getVectorSize() <= indexValue) ||
|
||||||
@ -488,7 +497,7 @@ 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");
|
||||||
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);
|
||||||
profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, 0, explanation);
|
profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, 0, explanation);
|
||||||
@ -510,8 +519,19 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
|
|||||||
newType.dereference();
|
newType.dereference();
|
||||||
result->setType(newType);
|
result->setType(newType);
|
||||||
|
|
||||||
if (anyIndexLimits) {
|
if (anyIndexLimits)
|
||||||
// for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
|
handleIndexLimits(loc, base, index);
|
||||||
|
|
||||||
|
if (language == EShLangGeometry && base->isArray())
|
||||||
|
handleInputArrayAccess(loc, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
|
||||||
|
void TParseContext::handleIndexLimits(TSourceLoc loc, TIntermTyped* base, TIntermTyped* index)
|
||||||
|
{
|
||||||
if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) ||
|
if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) ||
|
||||||
(! limits.generalUniformIndexing && base->getQualifier().isUniform() && language != EShLangVertex) ||
|
(! limits.generalUniformIndexing && base->getQualifier().isUniform() && language != EShLangVertex) ||
|
||||||
(! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) ||
|
(! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) ||
|
||||||
@ -525,10 +545,64 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
|
|||||||
// it's too early to know what the inductive variables are, save it for post processing
|
// it's too early to know what the inductive variables are, save it for post processing
|
||||||
needsIndexLimitationChecking.push_back(index);
|
needsIndexLimitationChecking.push_back(index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle a dereference of a geometry shader input arrays.
|
||||||
|
// See inputArrayNodeResizeList comment in ParseHelper.h.
|
||||||
|
//
|
||||||
|
void TParseContext::handleInputArrayAccess(TSourceLoc loc, TIntermTyped* base)
|
||||||
|
{
|
||||||
|
if (base->getType().getQualifier().storage == EvqVaryingIn) {
|
||||||
|
TIntermSymbol* symbol = base->getAsSymbolNode();
|
||||||
|
assert(symbol);
|
||||||
|
inputArrayNodeResizeList.push_back(symbol);
|
||||||
|
if (symbol && builtInName(symbol->getName())) {
|
||||||
|
// make sure we have a user-modifiable copy of this built-in input array
|
||||||
|
TSymbol* input = symbolTable.find(symbol->getName());
|
||||||
|
if (input->isReadOnly()) {
|
||||||
|
input = symbolTable.copyUp(input);
|
||||||
|
inputArraySymbolResizeList.push_back(input);
|
||||||
|
|
||||||
|
// Save it in the AST for linker use.
|
||||||
|
intermediate.addSymbolLinkageNode(linkage, *input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there has been an input primitive declaration, make sure all input array types
|
||||||
|
// match it in size. Types come either from nodes in the AST or symbols in the
|
||||||
|
// symbol table.
|
||||||
|
//
|
||||||
|
// Types without an array size will be given one.
|
||||||
|
// Types already having a size that is wrong will get an error.
|
||||||
|
//
|
||||||
|
void TParseContext::checkInputArrayConsistency(TSourceLoc loc, bool tailOnly)
|
||||||
|
{
|
||||||
|
TLayoutGeometry primitive = intermediate.getInputPrimitive();
|
||||||
|
if (primitive == ElgNone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tailOnly) {
|
||||||
|
checkInputArrayConsistency(loc, primitive, inputArraySymbolResizeList.back()->getWritableType(), inputArraySymbolResizeList.back()->getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
for (size_t i = 0; i < inputArrayNodeResizeList.size(); ++i)
|
||||||
|
checkInputArrayConsistency(loc, primitive, inputArrayNodeResizeList[i]->getWritableType(), inputArrayNodeResizeList[i]->getName());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < inputArraySymbolResizeList.size(); ++i)
|
||||||
|
checkInputArrayConsistency(loc, primitive, inputArraySymbolResizeList[i]->getWritableType(), inputArraySymbolResizeList[i]->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TParseContext::checkInputArrayConsistency(TSourceLoc loc, TLayoutGeometry primitive, TType& type, const TString& name)
|
||||||
|
{
|
||||||
|
int requiredSize = TQualifier::mapGeometryToSize(primitive);
|
||||||
|
|
||||||
|
if (type.getArraySize() == 0)
|
||||||
|
type.changeArraySize(requiredSize);
|
||||||
|
else if (type.getArraySize() != requiredSize)
|
||||||
|
error(loc, "inconsistent input primitive for array size", TQualifier::getGeometryString(primitive), name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1268,7 +1342,7 @@ void TParseContext::globalCheck(TSourceLoc loc, const char* token)
|
|||||||
bool TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier)
|
bool TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier)
|
||||||
{
|
{
|
||||||
if (! symbolTable.atBuiltInLevel()) {
|
if (! symbolTable.atBuiltInLevel()) {
|
||||||
if (identifier.compare(0, 3, "gl_") == 0) {
|
if (builtInName(identifier)) {
|
||||||
error(loc, "reserved built-in name", "gl_", "");
|
error(loc, "reserved built-in name", "gl_", "");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1283,6 +1357,11 @@ bool TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TParseContext::builtInName(const TString& identifier)
|
||||||
|
{
|
||||||
|
return identifier.compare(0, 3, "gl_") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Make sure there is enough data provided to the constructor to build
|
// Make sure there is enough data provided to the constructor to build
|
||||||
// something of the type of the constructor. Also returns the type of
|
// something of the type of the constructor. Also returns the type of
|
||||||
@ -1787,6 +1866,13 @@ void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TTyp
|
|||||||
symbol = new TVariable(&identifier, type);
|
symbol = new TVariable(&identifier, type);
|
||||||
symbolTable.insert(*symbol);
|
symbolTable.insert(*symbol);
|
||||||
newDeclaration = true;
|
newDeclaration = true;
|
||||||
|
|
||||||
|
// Handle user geometry shader input arrays: see inputArrayNodeResizeList comment in ParseHelper.h
|
||||||
|
if (language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn && ! symbolTable.atBuiltInLevel()) {
|
||||||
|
inputArraySymbolResizeList.push_back(symbol);
|
||||||
|
checkInputArrayConsistency(loc, true);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (symbol->getAsAnonMember()) {
|
if (symbol->getAsAnonMember()) {
|
||||||
@ -1811,16 +1897,21 @@ void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TTyp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (newType.getArraySize() > 0) {
|
if (newType.getArraySize() > 0) {
|
||||||
|
// be more leniant for input arrays to geometry shaders, where the redeclaration is the same size
|
||||||
|
if (! (language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn && newType.getArraySize() == type.getArraySize()))
|
||||||
error(loc, "redeclaration of array with size", identifier.c_str(), "");
|
error(loc, "redeclaration of array with size", identifier.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! newType.sameElementType(type)) {
|
if (! newType.sameElementType(type)) {
|
||||||
error(loc, "redeclaration of array with a different newType", identifier.c_str(), "");
|
error(loc, "redeclaration of array with a different type", identifier.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
newType.shareArraySizes(type);
|
newType.shareArraySizes(type);
|
||||||
|
|
||||||
|
if (language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn)
|
||||||
|
checkInputArrayConsistency(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseContext::updateMaxArraySize(TSourceLoc loc, TIntermNode *node, int index)
|
void TParseContext::updateMaxArraySize(TSourceLoc loc, TIntermNode *node, int index)
|
||||||
@ -1850,9 +1941,17 @@ 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: functionality: 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);
|
||||||
|
|
||||||
|
// Handle geometry shader input arrays: see inputArrayNodeResizeList comment in ParseHelper.h
|
||||||
|
if (language == EShLangGeometry && symbol->getType().getQualifier().storage == EvqVaryingIn)
|
||||||
|
inputArraySymbolResizeList.push_back(symbol);
|
||||||
|
|
||||||
|
// Save it in the AST for linker use.
|
||||||
|
intermediate.addSymbolLinkageNode(linkage, *symbol);
|
||||||
|
}
|
||||||
|
|
||||||
symbol->getWritableType().setMaxArraySize(index + 1);
|
symbol->getWritableType().setMaxArraySize(index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1883,7 +1982,7 @@ void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType
|
|||||||
//
|
//
|
||||||
TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, bool& newDeclaration)
|
TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, bool& newDeclaration)
|
||||||
{
|
{
|
||||||
if (profile == EEsProfile || identifier.compare(0, 3, "gl_") != 0 || symbolTable.atBuiltInLevel())
|
if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Potentially redeclaring a built-in variable...
|
// Potentially redeclaring a built-in variable...
|
||||||
@ -1915,6 +2014,13 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
|
|||||||
// Copy the symbol up to make a writable version
|
// Copy the symbol up to make a writable version
|
||||||
newDeclaration = true;
|
newDeclaration = true;
|
||||||
symbol = symbolTable.copyUp(symbol);
|
symbol = symbolTable.copyUp(symbol);
|
||||||
|
|
||||||
|
// Handle geometry shader input arrays: see inputArrayNodeResizeList comment in ParseHelper.h
|
||||||
|
if (language == EShLangGeometry && symbol->getType().getQualifier().storage == EvqVaryingIn && symbol->getType().isArray())
|
||||||
|
inputArraySymbolResizeList.push_back(symbol);
|
||||||
|
|
||||||
|
// Save it in the AST for linker use.
|
||||||
|
intermediate.addSymbolLinkageNode(linkage, *symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
@ -1929,10 +2035,10 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
|
|||||||
bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes)
|
bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes)
|
||||||
{
|
{
|
||||||
// just a quick out, not everything that must be checked:
|
// just a quick out, not everything that must be checked:
|
||||||
if (symbolTable.atBuiltInLevel() || profile == EEsProfile || blockName.compare(0, 3, "gl_") != 0)
|
if (symbolTable.atBuiltInLevel() || profile == EEsProfile || ! builtInName(blockName))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (instanceName && instanceName->compare(0, 3, "gl_") != 0) {
|
if (instanceName && ! builtInName(*instanceName)) {
|
||||||
error(loc, "cannot redeclare a built-in block with a user name", instanceName->c_str(), "");
|
error(loc, "cannot redeclare a built-in block with a user name", instanceName->c_str(), "");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1944,11 +2050,8 @@ bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, c
|
|||||||
if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment")
|
if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
// Blocks with instance names are easy to find, lookup the instance name,
|
// Blocks with instance names are easy to find, lookup the instance name,
|
||||||
// Anonymous blocks need to be found via a member. copyUp()?? will work
|
// Anonymous blocks need to be found via a member.
|
||||||
// just fine for either find.
|
|
||||||
|
|
||||||
bool builtIn;
|
bool builtIn;
|
||||||
TSymbol* block;
|
TSymbol* block;
|
||||||
if (instanceName)
|
if (instanceName)
|
||||||
@ -1964,7 +2067,7 @@ bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, c
|
|||||||
// Built-in blocks cannot be redeclared more than once, which if happened,
|
// Built-in blocks cannot be redeclared more than once, which if happened,
|
||||||
// we'd be finding the already redeclared one here, rather than the built in.
|
// we'd be finding the already redeclared one here, rather than the built in.
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
error(loc, "can only redeclare a built-in block once", blockName.c_str(), "");
|
error(loc, "can only redeclare a built-in block once, and before any use", blockName.c_str(), "");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1976,6 +2079,10 @@ bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, c
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle geometry shader input arrays: see inputArrayNodeResizeList comment in ParseHelper.h
|
||||||
|
if (language == EShLangGeometry && block->getType().isArray() && block->getType().getQualifier().storage == EvqVaryingIn)
|
||||||
|
inputArraySymbolResizeList.push_back(block);
|
||||||
|
|
||||||
// TODO: semantics: block redeclaration: instance array size matching?
|
// TODO: 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
|
||||||
@ -3124,7 +3231,9 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
|
|||||||
case ElgLinesAdjacency:
|
case ElgLinesAdjacency:
|
||||||
case ElgTriangles:
|
case ElgTriangles:
|
||||||
case ElgTrianglesAdjacency:
|
case ElgTrianglesAdjacency:
|
||||||
if (! intermediate.setInputPrimitive(publicType.geometry))
|
if (intermediate.setInputPrimitive(publicType.geometry))
|
||||||
|
checkInputArrayConsistency(loc);
|
||||||
|
else
|
||||||
error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.geometry), "");
|
error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.geometry), "");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -72,12 +72,17 @@ public:
|
|||||||
const char *szExtraInfoFormat, ...);
|
const char *szExtraInfoFormat, ...);
|
||||||
void C_DECL warn(TSourceLoc, const char *szReason, const char *szToken,
|
void C_DECL warn(TSourceLoc, const char *szReason, const char *szToken,
|
||||||
const char *szExtraInfoFormat, ...);
|
const char *szExtraInfoFormat, ...);
|
||||||
bool reservedErrorCheck(TSourceLoc, const TString& identifier);
|
bool reservedErrorCheck(TSourceLoc, const TString&);
|
||||||
|
bool builtInName(const TString&);
|
||||||
|
|
||||||
void updateExtensionBehavior(const char* extName, const char* behavior);
|
void updateExtensionBehavior(const char* extName, const char* behavior);
|
||||||
void handlePragma(const char **tokens, int numTokens);
|
void handlePragma(const char **tokens, int numTokens);
|
||||||
TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
|
TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
|
||||||
TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
|
TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
|
||||||
|
void handleIndexLimits(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
|
||||||
|
void handleInputArrayAccess(TSourceLoc, TIntermTyped* base);
|
||||||
|
void checkInputArrayConsistency(TSourceLoc, bool tailOnly = false);
|
||||||
|
void checkInputArrayConsistency(TSourceLoc, TLayoutGeometry, TType&, const TString&);
|
||||||
TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
|
TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
|
||||||
TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function);
|
TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function);
|
||||||
TIntermAggregate* handleFunctionPrototype(TSourceLoc, TFunction&);
|
TIntermAggregate* handleFunctionPrototype(TSourceLoc, TFunction&);
|
||||||
@ -230,6 +235,40 @@ protected:
|
|||||||
bool anyIndexLimits;
|
bool anyIndexLimits;
|
||||||
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
||||||
// TODO: desktop functionality: track use of gl_FragDepth before redeclaration
|
// TODO: desktop functionality: track use of gl_FragDepth before redeclaration
|
||||||
|
|
||||||
|
//
|
||||||
|
// Geometry shader input arrays:
|
||||||
|
// - array sizing is based on input primitive and/or explicit size
|
||||||
|
// - array sizing is retroactive
|
||||||
|
// - built-in block redeclarations interact with this
|
||||||
|
//
|
||||||
|
// Design:
|
||||||
|
// - use a per-context "resize-list", a list of entities whose array sizes
|
||||||
|
// can be fixed; this is logically one list, but physically two:
|
||||||
|
// * a list for nodes in the AST
|
||||||
|
// * a list for symbols in the symbol table
|
||||||
|
// this could be done a bit more simply, but this allows better error messages.
|
||||||
|
//
|
||||||
|
// - the resize-list starts empty at beginning of user-shader compilation, it does
|
||||||
|
// not have built-ins in it
|
||||||
|
//
|
||||||
|
// - on built-in input array use: copy-up symbol and add both the symbol and
|
||||||
|
// its use to resize-list
|
||||||
|
//
|
||||||
|
// - on user-input array declaration: add it to the resize-list
|
||||||
|
//
|
||||||
|
// - on block redeclaration: copy-up symbol and add it to the resize-list
|
||||||
|
// * note, that appropriately gives an error if redeclaring a block that
|
||||||
|
// was already used and hence already copied-up
|
||||||
|
//
|
||||||
|
// - on seeing an input primitive-layout declaration, fix everything in the resize-list,
|
||||||
|
// giving errors for mismatch
|
||||||
|
//
|
||||||
|
// - on seeing an array size declaration, give errors on mismatch between it and previous
|
||||||
|
// input primitive declarations
|
||||||
|
//
|
||||||
|
TVector<TIntermSymbol*> inputArrayNodeResizeList;
|
||||||
|
TVector<TSymbol*> inputArraySymbolResizeList;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
@ -99,7 +99,7 @@ public:
|
|||||||
virtual int getUniqueId() const { return uniqueId; }
|
virtual int getUniqueId() const { return uniqueId; }
|
||||||
virtual void dump(TInfoSink &infoSink) const = 0;
|
virtual void dump(TInfoSink &infoSink) const = 0;
|
||||||
|
|
||||||
virtual bool isReadOnly() { return ! writable; }
|
virtual bool isReadOnly() const { return ! writable; }
|
||||||
virtual void makeReadOnly() { writable = false; }
|
virtual void makeReadOnly() { writable = false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -417,9 +417,10 @@ public:
|
|||||||
// 3: user-shader globals
|
// 3: user-shader globals
|
||||||
//
|
//
|
||||||
protected:
|
protected:
|
||||||
|
static const int globalLevel = 3;
|
||||||
bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
|
bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
|
||||||
bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
|
bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
|
||||||
bool isGlobalLevel(int level) { return level <= 3; } // include user globals
|
bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals
|
||||||
public:
|
public:
|
||||||
bool isEmpty() { return table.size() == 0; }
|
bool isEmpty() { return table.size() == 0; }
|
||||||
bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
|
bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
|
||||||
@ -482,7 +483,7 @@ public:
|
|||||||
TSymbol* copyUp(TSymbol* shared)
|
TSymbol* copyUp(TSymbol* shared)
|
||||||
{
|
{
|
||||||
TSymbol* copy = copyUpDeferredInsert(shared);
|
TSymbol* copy = copyUpDeferredInsert(shared);
|
||||||
table[currentLevel()]->insert(*copy);
|
table[globalLevel]->insert(*copy);
|
||||||
if (shared->getAsVariable())
|
if (shared->getAsVariable())
|
||||||
return copy;
|
return copy;
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user