Add limit checking for constant texture texel offsets and max_vertices.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24158 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-11-20 23:46:57 +00:00
parent 1e91f5ee8d
commit 1d1132d9eb
11 changed files with 193 additions and 46 deletions

View File

@ -85,7 +85,7 @@ layout(lines_adjancency) in;
layout(triangles) in; // ERROR, can't change it layout(triangles) in; // ERROR, can't change it
layout(triangles_adjacency) in; // ERROR, can't change it layout(triangles_adjacency) in; // ERROR, can't change it
layout(invocations = 4, max_vertices = 127) out; layout(invocations = 4, max_vertices = 300) out;
in inbn { in inbn {
layout(stream = 2) int a; // ERROR, stream on input layout(stream = 2) int a; // ERROR, stream on input

View File

@ -57,7 +57,7 @@ void main()
v = texture(s2D, c2D); v = texture(s2D, c2D);
v = textureProj(s3D, c4D); v = textureProj(s3D, c4D);
v = textureLod(s2DArray, c3D, 1.2); v = textureLod(s2DArray, c3D, 1.2);
f = textureOffset(s2DShadow, c3D, ic2D, c1D); f = textureOffset(s2DShadow, c3D, ic2D, c1D); // ERROR, offset argument not constant
v = texelFetch(s3D, ic3D, ic1D); v = texelFetch(s3D, ic3D, ic1D);
v = texelFetchOffset(arrayedSampler[2], ic2D, 4, ic2D); v = texelFetchOffset(arrayedSampler[2], ic2D, 4, ic2D);
f = textureLodOffset(s2DShadow, c3D, c1D, ic2D); f = textureLodOffset(s2DShadow, c3D, c1D, ic2D);
@ -123,5 +123,11 @@ void foo13(s inSt2)
inSt2 == st1; // ERROR inSt2 == st1; // ERROR
} }
void foo23()
{
textureOffset(s2DShadow, c3D, ivec2(-8, 7), c1D);
textureOffset(s2DShadow, c3D, ivec2(-9, 8), c1D);
}
float imageBuffer; // ERROR, reserved float imageBuffer; // ERROR, reserved
float uimage2DRect; // ERROR, reserved float uimage2DRect; // ERROR, reserved

View File

@ -39,3 +39,15 @@ layout(location = 5) in vec4 gl_Color; // ERROR, layout
noperspective in float gl_ClipDistance[4]; // ERROR, can't change qualifier noperspective in float gl_ClipDistance[4]; // ERROR, can't change qualifier
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR, declared after use layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR, declared after use
uniform sampler2DRectShadow u2drs;
void foo23()
{
const ivec2[3] offsets = ivec2[3](ivec2(1,2), ivec2(3,4), ivec2(15,16));
textureProjGradOffset(u2drs, outp, vec2(0.0), vec2(0.0), ivec2(c2D)); // ERROR, offset not constant
textureProjGradOffset(u2drs, outp, vec2(0.0), vec2(0.0), offsets[1]);
textureProjGradOffset(u2drs, outp, vec2(0.0), vec2(0.0), offsets[2]);
textureProjGradOffset(u2drs, outp, vec2(0.0), vec2(0.0), ivec2(-10, 20)); // ERROR, offset out of range
}

View File

@ -4,7 +4,13 @@ ERROR: 0:30: 'noperspective' : not supported with this profile: es
ERROR: 0:31: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: bads ERROR: 0:31: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: bads
ERROR: 0:32: 'uint' : cannot apply precision statement to this type; use 'float', 'int' or a sampler type ERROR: 0:32: 'uint' : cannot apply precision statement to this type; use 'float', 'int' or a sampler type
ERROR: 0:39: 'structure' : non-uniform struct contains a sampler or image: badout ERROR: 0:39: 'structure' : non-uniform struct contains a sampler or image: badout
ERROR: 0:60: 'texel offset' : argument must be compile-time constant
ERROR: 0:63: 'texel offset' : argument must be compile-time constant
ERROR: 0:64: 'texel offset' : argument must be compile-time constant
ERROR: 0:66: 'texel offset' : argument must be compile-time constant
ERROR: 0:68: 'texel offset' : argument must be compile-time constant
ERROR: 0:69: 'variable indexing sampler array' : not supported with this profile: es ERROR: 0:69: 'variable indexing sampler array' : not supported with this profile: es
ERROR: 0:73: 'texel offset' : argument must be compile-time constant
ERROR: 0:83: 'double' : Reserved word. ERROR: 0:83: 'double' : Reserved word.
ERROR: 0:83: 'double' : not supported with this profile: es ERROR: 0:83: 'double' : not supported with this profile: es
ERROR: 0:84: 'dvec2' : Reserved word. ERROR: 0:84: 'dvec2' : Reserved word.
@ -25,9 +31,11 @@ ERROR: 0:121: '==' : can't use with samplers or structs containing samplers
ERROR: 0:121: '==' : wrong operand types: no operation '==' exists that takes a left-hand operand of type 'lowp sampler2D' and a right operand of type 'lowp sampler2D' (or there is no acceptable conversion) ERROR: 0:121: '==' : wrong operand types: no operation '==' exists that takes a left-hand operand of type 'lowp sampler2D' and a right operand of type 'lowp sampler2D' (or there is no acceptable conversion)
ERROR: 0:122: '=' : can't use with samplers or structs containing samplers ERROR: 0:122: '=' : can't use with samplers or structs containing samplers
ERROR: 0:123: '==' : can't use with samplers or structs containing samplers ERROR: 0:123: '==' : can't use with samplers or structs containing samplers
ERROR: 0:126: 'imageBuffer' : Reserved word. ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
ERROR: 0:126: '' : syntax error ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
ERROR: 28 compilation errors. No code generated. ERROR: 0:132: 'imageBuffer' : Reserved word.
ERROR: 0:132: '' : syntax error
ERROR: 36 compilation errors. No code generated.
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
@ -255,6 +263,23 @@ ERROR: node is still EOpNull!
0:123 Compare Equal (bool) 0:123 Compare Equal (bool)
0:123 'inSt2' (in structure{i,s}) 0:123 'inSt2' (in structure{i,s})
0:123 'st1' (uniform structure{i,s}) 0:123 'st1' (uniform structure{i,s})
0:126 Function Definition: foo23( (void)
0:126 Function Parameters:
0:128 Sequence
0:128 Function Call: textureOffset(sS21;vf3;vi2;f1; (lowp float)
0:128 's2DShadow' (uniform lowp sampler2DShadow)
0:128 'c3D' (smooth in lowp 3-component vector of float)
0:128 Constant:
0:128 -8 (const int)
0:128 7 (const int)
0:128 'c1D' (smooth in lowp float)
0:129 Function Call: textureOffset(sS21;vf3;vi2;f1; (lowp float)
0:129 's2DShadow' (uniform lowp sampler2DShadow)
0:129 'c3D' (smooth in lowp 3-component vector of float)
0:129 Constant:
0:129 -9 (const int)
0:129 8 (const int)
0:129 'c1D' (smooth in lowp 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)

View File

@ -7,7 +7,12 @@ ERROR: 0:36: 'location qualifier on uniform or buffer' : not supported for this
ERROR: 0:38: 'redeclaration' : cannot apply layout qualifier to gl_Color ERROR: 0:38: 'redeclaration' : cannot apply layout qualifier to gl_Color
ERROR: 0:39: 'redeclaration' : cannot change qualification of gl_ClipDistance ERROR: 0:39: 'redeclaration' : cannot change qualification of gl_ClipDistance
ERROR: 0:41: 'gl_FragCoord' : cannot redeclare after use ERROR: 0:41: 'gl_FragCoord' : cannot redeclare after use
ERROR: 7 compilation errors. No code generated. ERROR: 0:49: 'texel offset' : argument must be compile-time constant
ERROR: 0:51: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
ERROR: 0:51: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
ERROR: 0:52: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
ERROR: 0:52: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
ERROR: 12 compilation errors. No code generated.
gl_FragCoord pixel center is integer gl_FragCoord pixel center is integer
@ -116,6 +121,56 @@ ERROR: node is still EOpNull!
0:25 move second child to first child (4-component vector of float) 0:25 move second child to first child (4-component vector of float)
0:25 'c' (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:25 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
0:45 Function Definition: foo23( (void)
0:45 Function Parameters:
0:? Sequence
0:49 Function Call: textureProjGradOffset(sSR21;vf4;vf2;vf2;vi2; (float)
0:49 'u2drs' (uniform sampler2DRectShadow)
0:49 'outp' (out 4-component vector of float)
0:49 Constant:
0:49 0.000000
0:49 0.000000
0:49 Constant:
0:49 0.000000
0:49 0.000000
0:49 Convert float to int (2-component vector of int)
0:49 'c2D' (smooth in 2-component vector of float)
0:50 Function Call: textureProjGradOffset(sSR21;vf4;vf2;vf2;vi2; (float)
0:50 'u2drs' (uniform sampler2DRectShadow)
0:50 'outp' (out 4-component vector of float)
0:50 Constant:
0:50 0.000000
0:50 0.000000
0:50 Constant:
0:50 0.000000
0:50 0.000000
0:50 Constant:
0:50 3 (const int)
0:50 4 (const int)
0:51 Function Call: textureProjGradOffset(sSR21;vf4;vf2;vf2;vi2; (float)
0:51 'u2drs' (uniform sampler2DRectShadow)
0:51 'outp' (out 4-component vector of float)
0:51 Constant:
0:51 0.000000
0:51 0.000000
0:51 Constant:
0:51 0.000000
0:51 0.000000
0:51 Constant:
0:51 15 (const int)
0:51 16 (const int)
0:52 Function Call: textureProjGradOffset(sSR21;vf4;vf2;vf2;vi2; (float)
0:52 'u2drs' (uniform sampler2DRectShadow)
0:52 'outp' (out 4-component vector of float)
0:52 Constant:
0:52 0.000000
0:52 0.000000
0:52 Constant:
0:52 0.000000
0:52 0.000000
0:52 Constant:
0:52 -10 (const int)
0:52 20 (const int)
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)
@ -131,6 +186,7 @@ ERROR: node is still EOpNull!
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)
0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float) 0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float)
0:? 'u2drs' (uniform sampler2DRectShadow)
Linked fragment stage: Linked fragment stage:

View File

@ -31,7 +31,9 @@ Warning, version 430 is not yet complete; some version-specific features are pre
0:39 Function Call: textureOffset(sS21;vf3;vi2;f1; (float) 0:39 Function Call: textureOffset(sS21;vf3;vi2;f1; (float)
0:39 's2DShadow' (uniform sampler2DShadow) 0:39 's2DShadow' (uniform sampler2DShadow)
0:39 'c3D' (smooth in 3-component vector of float) 0:39 'c3D' (smooth in 3-component vector of float)
0:39 'ic2D' (flat in 2-component vector of int) 0:39 Constant:
0:39 3 (const int)
0:39 3 (const int)
0:39 'c1D' (smooth in float) 0:39 'c1D' (smooth in float)
0:40 add second child into first child (4-component vector of float) 0:40 add second child into first child (4-component vector of float)
0:40 'v' (4-component vector of float) 0:40 'v' (4-component vector of float)
@ -56,14 +58,18 @@ Warning, version 430 is not yet complete; some version-specific features are pre
0:42 's2DShadow' (uniform sampler2DShadow) 0:42 's2DShadow' (uniform sampler2DShadow)
0:42 'c3D' (smooth in 3-component vector of float) 0:42 'c3D' (smooth in 3-component vector of float)
0:42 'c1D' (smooth in float) 0:42 'c1D' (smooth in float)
0:42 'ic2D' (flat in 2-component vector of int) 0:42 Constant:
0:42 3 (const int)
0:42 3 (const int)
0:43 add second child into first child (4-component vector of float) 0:43 add second child into first child (4-component vector of float)
0:43 'v' (4-component vector of float) 0:43 'v' (4-component vector of float)
0:43 Function Call: textureProjLodOffset(s21;vf3;f1;vi2; (4-component vector of float) 0:43 Function Call: textureProjLodOffset(s21;vf3;f1;vi2; (4-component vector of float)
0:43 's2D' (uniform sampler2D) 0:43 's2D' (uniform sampler2D)
0:43 'c3D' (smooth in 3-component vector of float) 0:43 'c3D' (smooth in 3-component vector of float)
0:43 'c1D' (smooth in float) 0:43 'c1D' (smooth in float)
0:43 'ic2D' (flat in 2-component vector of int) 0:43 Constant:
0:43 3 (const int)
0:43 3 (const int)
0:44 add second child into first child (4-component vector of float) 0:44 add second child into first child (4-component vector of float)
0:44 'v' (4-component vector of float) 0:44 'v' (4-component vector of float)
0:44 Function Call: textureGrad(sC1;vf3;vf3;vf3; (4-component vector of float) 0:44 Function Call: textureGrad(sC1;vf3;vf3;vf3; (4-component vector of float)
@ -81,7 +87,9 @@ Warning, version 430 is not yet complete; some version-specific features are pre
0:45 'c4D' (smooth in 4-component vector of float) 0:45 'c4D' (smooth in 4-component vector of float)
0:45 'c2D' (smooth in 2-component vector of float) 0:45 'c2D' (smooth in 2-component vector of float)
0:45 'c2D' (smooth in 2-component vector of float) 0:45 'c2D' (smooth in 2-component vector of float)
0:45 'ic2D' (flat in 2-component vector of int) 0:45 Constant:
0:45 3 (const int)
0:45 3 (const int)
0:46 add second child into first child (4-component vector of float) 0:46 add second child into first child (4-component vector of float)
0:46 'v' (4-component vector of float) 0:46 'v' (4-component vector of float)
0:46 Function Call: textureProjGrad(s31;vf4;vf3;vf3; (4-component vector of float) 0:46 Function Call: textureProjGrad(s31;vf4;vf3;vf3; (4-component vector of float)
@ -96,7 +104,9 @@ Warning, version 430 is not yet complete; some version-specific features are pre
0:47 'c3D' (smooth in 3-component vector of float) 0:47 'c3D' (smooth in 3-component vector of float)
0:47 'c2D' (smooth in 2-component vector of float) 0:47 'c2D' (smooth in 2-component vector of float)
0:47 'c2D' (smooth in 2-component vector of float) 0:47 'c2D' (smooth in 2-component vector of float)
0:47 'ic2D' (flat in 2-component vector of int) 0:47 Constant:
0:47 3 (const int)
0:47 3 (const int)
0:49 Sequence 0:49 Sequence
0:49 move second child to first child (4-component vector of int) 0:49 move second child to first child (4-component vector of int)
0:49 'iv' (4-component vector of int) 0:49 'iv' (4-component vector of int)
@ -112,7 +122,9 @@ Warning, version 430 is not yet complete; some version-specific features are pre
0:51 Function Call: textureProjOffset(is21;vf4;vi2; (4-component vector of int) 0:51 Function Call: textureProjOffset(is21;vf4;vi2; (4-component vector of int)
0:51 'is2D' (uniform isampler2D) 0:51 'is2D' (uniform isampler2D)
0:51 'c4D' (smooth in 4-component vector of float) 0:51 'c4D' (smooth in 4-component vector of float)
0:51 'ic2D' (flat in 2-component vector of int) 0:51 Constant:
0:51 3 (const int)
0:51 3 (const int)
0:52 add second child into first child (4-component vector of float) 0:52 add second child into first child (4-component vector of float)
0:52 'v' (4-component vector of float) 0:52 'v' (4-component vector of float)
0:52 Convert int to float (4-component vector of float) 0:52 Convert int to float (4-component vector of float)

View File

@ -214,12 +214,6 @@ WARNING: 0:15: varying deprecated in version 130; may be removed in future relea
0:63 'gradY' (2-component vector of float) 0:63 'gradY' (2-component vector of float)
0:63 dPdy (2-component vector of float) 0:63 dPdy (2-component vector of float)
0:63 'coords2D' (smooth in 2-component vector of float) 0:63 'coords2D' (smooth in 2-component vector of float)
0:64 Sequence
0:64 move second child to first child (2-component vector of int)
0:64 'offset' (2-component vector of int)
0:64 Constant:
0:64 3 (const int)
0:64 -7 (const int)
0:66 add second child into first child (4-component vector of float) 0:66 add second child into first child (4-component vector of float)
0:66 'color' (4-component vector of float) 0:66 'color' (4-component vector of float)
0:66 Function Call: textureGrad(s21;vf2;vf2;vf2; (4-component vector of float) 0:66 Function Call: textureGrad(s21;vf2;vf2;vf2; (4-component vector of float)
@ -243,7 +237,9 @@ WARNING: 0:15: varying deprecated in version 130; may be removed in future relea
0:68 'coords2D' (smooth in 2-component vector of float) 0:68 'coords2D' (smooth in 2-component vector of float)
0:68 'gradX' (2-component vector of float) 0:68 'gradX' (2-component vector of float)
0:68 'gradY' (2-component vector of float) 0:68 'gradY' (2-component vector of float)
0:68 'offset' (2-component vector of int) 0:68 Constant:
0:68 3 (const int)
0:68 -7 (const int)
0:69 add second child into first child (4-component vector of float) 0:69 add second child into first child (4-component vector of float)
0:69 'color' (4-component vector of float) 0:69 'color' (4-component vector of float)
0:69 Function Call: textureProjGradOffset(s21;vf3;vf2;vf2;vi2; (4-component vector of float) 0:69 Function Call: textureProjGradOffset(s21;vf3;vf2;vf2;vi2; (4-component vector of float)
@ -251,7 +247,9 @@ WARNING: 0:15: varying deprecated in version 130; may be removed in future relea
0:69 'coords3D' (3-component vector of float) 0:69 'coords3D' (3-component vector of float)
0:69 'gradX' (2-component vector of float) 0:69 'gradX' (2-component vector of float)
0:69 'gradY' (2-component vector of float) 0:69 'gradY' (2-component vector of float)
0:69 'offset' (2-component vector of int) 0:69 Constant:
0:69 3 (const int)
0:69 -7 (const int)
0:70 add second child into first child (4-component vector of float) 0:70 add second child into first child (4-component vector of float)
0:70 'color' (4-component vector of float) 0:70 'color' (4-component vector of float)
0:70 Function Call: textureGrad(sS21;vf3;vf2;vf2; (float) 0:70 Function Call: textureGrad(sS21;vf3;vf2;vf2; (float)

View File

@ -22,11 +22,8 @@ Link Validation
Intra-stage linking, single shader Intra-stage linking, single shader
+ recursion for functions + recursion for functions
- limits checking: - limits checking:
- number of texture image units
- texel offsets (or compile-time?)
- number of input/output compononents - number of input/output compononents
- 4.x tessellation limits - 4.x tessellation limits
- 1.50: geometry shaders: max_vertices must be checked against gl_MaxGeometryOutputVertices (maybe at compile time)
- 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
- ... - ...
+ exactly one main + exactly one main
@ -101,6 +98,8 @@ Shader Functionality to Implement/Finish
+ geometry shader layouts: they must be declared, telling the system the primitive input and output types and maximum number of vertices. + geometry shader layouts: they must be declared, telling the system the primitive input and output types and maximum number of vertices.
+ Added geometry shader constants. + Added geometry shader constants.
+ Broaden structure usage to include geometry inputs and geometry outputs. + Broaden structure usage to include geometry inputs and geometry outputs.
+ texel offset limit checking
+ 1.50: geometry shaders: max_vertices must be checked against gl_MaxGeometryOutputVertices (maybe at compile time)
GLSL 4.0 GLSL 4.0
- tessellation control stage and tessellation evaluation stage. Includes barrier() built-in for synchronization. - tessellation control stage and tessellation evaluation stage. Includes barrier() built-in for synchronization.
- Polymorphic functions: Run-time selection of what function gets called, through the new keyword subroutine. - Polymorphic functions: Run-time selection of what function gets called, through the new keyword subroutine.

View File

@ -52,7 +52,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
intermediate(interm), symbolTable(symt), infoSink(is), language(L), intermediate(interm), symbolTable(symt), infoSink(is), language(L),
version(v), profile(p), forwardCompatible(fc), messages(m), version(v), profile(p), forwardCompatible(fc), messages(m),
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0),
tokensBeforeEOF(false), currentScanner(0), tokensBeforeEOF(false), limits(resources.limits), currentScanner(0),
numErrors(0), parsingBuiltins(pb), afterEOF(false), numErrors(0), parsingBuiltins(pb), afterEOF(false),
anyIndexLimits(false) anyIndexLimits(false)
{ {
@ -108,9 +108,9 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
globalOutputDefaults.layoutStream = 0; globalOutputDefaults.layoutStream = 0;
} }
void TParseContext::setLimits(const TLimits& L) void TParseContext::setLimits(const TBuiltInResource& r)
{ {
limits = L; resources = r;
anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing || anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing ||
! limits.generalConstantMatrixVectorIndexing || ! limits.generalConstantMatrixVectorIndexing ||
@ -951,7 +951,7 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
} }
if (builtIn) if (builtIn)
nonOpBuiltInCheck(loc, *fnCandidate, result->getAsAggregate()); nonOpBuiltInCheck(loc, *fnCandidate, *result->getAsAggregate());
} }
} }
} }
@ -973,26 +973,62 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
// //
// Assumes there has been a semantically correct match to a built-in function. // Assumes there has been a semantically correct match to a built-in function.
// //
void TParseContext::nonOpBuiltInCheck(TSourceLoc loc, const TFunction& fnCandidate, TIntermAggregate* callNode) void TParseContext::nonOpBuiltInCheck(TSourceLoc loc, const TFunction& fnCandidate, TIntermAggregate& callNode)
{ {
// built-in texturing functions get their return value precision from the precision of the sampler // built-in texturing functions get their return value precision from the precision of the sampler
if (fnCandidate.getType().getQualifier().precision == EpqNone && if (fnCandidate.getType().getQualifier().precision == EpqNone &&
fnCandidate.getParamCount() > 0 && fnCandidate[0].type->getBasicType() == EbtSampler) fnCandidate.getParamCount() > 0 && fnCandidate[0].type->getBasicType() == EbtSampler)
callNode->getQualifier().precision = callNode->getAsAggregate()->getSequence()[0]->getAsTyped()->getQualifier().precision; callNode.getQualifier().precision = callNode.getAsAggregate()->getSequence()[0]->getAsTyped()->getQualifier().precision;
if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) { if (fnCandidate.getName().compare(0, 7, "texture") == 0) {
const char* feature = "texture gather function"; if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) {
requireProfile(loc, ~EEsProfile, feature); const char* feature = "texture gather function";
profileRequires(loc, ~EEsProfile, 400, GL_ARB_texture_gather, feature); // TODO: GL_ARB_gpu_shader5 requireProfile(loc, ~EEsProfile, feature);
int lastArgIndex = fnCandidate.getParamCount() - 1; profileRequires(loc, ~EEsProfile, 400, GL_ARB_texture_gather, feature); // TODO: GL_ARB_gpu_shader5
if (fnCandidate[lastArgIndex].type->getBasicType() == EbtInt && fnCandidate[lastArgIndex].type->isScalar()) { int lastArgIndex = fnCandidate.getParamCount() - 1;
// the last integral argument to a texture gather must be a constant int between 0 and 3 if (fnCandidate[lastArgIndex].type->getBasicType() == EbtInt && fnCandidate[lastArgIndex].type->isScalar()) {
if (callNode->getSequence()[lastArgIndex]->getAsConstantUnion()) { // the last integral argument to a texture gather must be a constant int between 0 and 3
int value = callNode->getSequence()[lastArgIndex]->getAsConstantUnion()->getConstArray()[0].getIConst(); if (callNode.getSequence()[lastArgIndex]->getAsConstantUnion()) {
if (value < 0 || value > 3) int value = callNode.getSequence()[lastArgIndex]->getAsConstantUnion()->getConstArray()[0].getIConst();
error(loc, "must be 0, 1, 2, or 3", "texture gather component", ""); if (value < 0 || value > 3)
} else error(loc, "must be 0, 1, 2, or 3", "texture gather component", "");
error(loc, "must be a constant", "texture gather component", ""); } else
error(loc, "must be a constant", "texture gather component", "");
}
} else {
// this is only for functions not starting "textureGather"...
if (fnCandidate.getName().find("Offset") != TString::npos) {
// Handle texture-offset limits checking
int arg = -1;
if (fnCandidate.getName().compare("textureOffset") == 0)
arg = 2;
else if (fnCandidate.getName().compare("texelFetchOffset") == 0)
arg = 3;
else if (fnCandidate.getName().compare("textureProjOffset") == 0)
arg = 2;
else if (fnCandidate.getName().compare("textureLodOffset") == 0)
arg = 3;
else if (fnCandidate.getName().compare("textureProjLodOffset") == 0)
arg = 3;
else if (fnCandidate.getName().compare("textureGradOffset") == 0)
arg = 4;
else if (fnCandidate.getName().compare("textureProjGradOffset") == 0)
arg = 4;
if (arg > 0) {
if (! callNode.getSequence()[arg]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "texel offset", "");
else {
const TType& type = callNode.getSequence()[arg]->getAsTyped()->getType();
for (int c = 0; c < type.getVectorSize(); ++c) {
int offset = callNode.getSequence()[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
}
}
}
}
} }
} }
} }
@ -2524,6 +2560,8 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
} }
if (id == "max_vertices") { if (id == "max_vertices") {
publicType.shaderQualifiers.maxVertices = value; publicType.shaderQualifiers.maxVertices = value;
if (value > resources.maxGeometryOutputVertices)
error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
return; return;
} }
if (id == "stream") { if (id == "stream") {

View File

@ -65,7 +65,7 @@ public:
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&, TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&,
bool forwardCompatible = false, EShMessages messages = EShMsgDefault); bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
void setLimits(const TLimits&); void setLimits(const TBuiltInResource&);
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false); bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
void parserError(const char *s); // for bison's yyerror void parserError(const char *s); // for bison's yyerror
const char* getPreamble(); const char* getPreamble();
@ -91,7 +91,7 @@ public:
TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function); TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function);
TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&); TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&);
TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*, TIntermAggregate*); TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*, TIntermAggregate*);
void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate*); void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate&);
TFunction* handleConstructorCall(TSourceLoc, TPublicType&); TFunction* handleConstructorCall(TSourceLoc, TPublicType&);
bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&); bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&);
@ -231,7 +231,8 @@ public:
TIntermAggregate *linkage; // aggregate node of objects the linker may need, if not referenced by the rest of the AST TIntermAggregate *linkage; // aggregate node of objects the linker may need, if not referenced by the rest of the AST
TPrecisionQualifier defaultPrecision[EbtNumTypes]; TPrecisionQualifier defaultPrecision[EbtNumTypes];
bool tokensBeforeEOF; bool tokensBeforeEOF;
TLimits limits; TBuiltInResource resources;
TLimits& limits;
protected: protected:
TScanContext* scanContext; TScanContext* scanContext;

View File

@ -486,7 +486,7 @@ bool CompileDeferred(
TPpContext ppContext(parseContext); TPpContext ppContext(parseContext);
parseContext.setScanContext(&scanContext); parseContext.setScanContext(&scanContext);
parseContext.setPpContext(&ppContext); parseContext.setPpContext(&ppContext);
parseContext.setLimits(resources->limits); parseContext.setLimits(*resources);
if (! goodVersion) if (! goodVersion)
parseContext.addError(); parseContext.addError();