Turn on ESSL 3.1 for most features:

- images: load/store, memory qualifiers
 - buffer blocks
 - compute shaders
 - atomic counters
 - texture gather
 - SSO
 - uniform locations
 - all the numeric-based version # comparisons


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27710 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2014-08-12 22:07:22 +00:00
parent bedb1bc2db
commit 4d57090da5
20 changed files with 500 additions and 195 deletions

View File

@ -168,3 +168,7 @@ int Bfoo;
layout(std140) Binst; // ERROR layout(std140) Binst; // ERROR
layout(std140) Bblock; // ERROR layout(std140) Bblock; // ERROR
layout(std140) Bfoo; // ERROR layout(std140) Bfoo; // ERROR
struct SNA {
int a[]; // ERROR
};

141
Test/310.comp Normal file
View File

@ -0,0 +1,141 @@
#version 310 es
layout(local_size_x = 2) in;
layout(local_size_x = 16) in; // ERROR, changing
layout(local_size_z = 4096) in; // ERROR, too large
layout(local_size_x = 2) in;
const int total = gl_MaxComputeWorkGroupCount.y
+ gl_MaxComputeUniformComponents
+ gl_MaxComputeTextureImageUnits
+ gl_MaxComputeImageUniforms
+ gl_MaxComputeAtomicCounters
+ gl_MaxComputeAtomicCounterBuffers;
buffer ShaderStorageBlock
{
int value;
float values[];
};
buffer InvalidShaderStorageBlock
{
float values[]; // ERROR
int value;
} invalid;
void main()
{
barrier();
memoryBarrier();
memoryBarrierAtomicCounter();
memoryBarrierBuffer();
memoryBarrierShared();
memoryBarrierImage();
groupMemoryBarrier();
value = int(values[gl_LocalInvocationIndex]);
}
layout(location = 2) in vec3 v3; // ERROR
in float f; // ERROR
out float fo; // ERROR
shared vec4 s;
layout(location = 2) shared vec4 sl; // ERROR
shared float fs = 4.2; // ERROR
layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) out; // ERROR
int arrX[gl_WorkGroupSize.x];
int arrY[gl_WorkGroupSize.y];
int arrZ[gl_WorkGroupSize.z];
readonly buffer roblock
{
int value;
float values[];
} ro;
void foo()
{
ro.values[2] = 4.7; // ERROR, readonly
ro.values.length();
++s;
}
buffer vec4 v; // ERROR
uniform usampler2D us2dbad; // ERROR, default precision
precision highp usampler2D;
precision highp iimage2DArray;
precision highp iimage2D;
uniform usampler2D us2d;
uniform iimage2DArray ii2dabad; // ERROR, not writeonly
uniform writeonly iimage2DArray ii2da;
layout(r32i) uniform iimage2D iimg2D;
layout(rgba32i) uniform iimage2D iimg2Drgba;
layout(rgba32f) uniform image2D img2Drgba;
layout(r32ui) uniform uimage2D uimg2D;
void qux()
{
int i = 4;
imageAtomicCompSwap(iimg2D, ivec2(i,i), i, i);// ERROR no longer in 310
imageAtomicAdd(uimg2D, ivec2(i,i), uint(i)); // ERROR no longer in 310
imageAtomicMin(iimg2Drgba, ivec2(i,i), i); // ERROR no longer in 310 // ERROR iimg2Drgba does not have r32i layout
imageAtomicMax(img2Drgba, ivec2(i,i), i); // ERROR no longer in 310 // ERROR img2Drgba is not integer image
ivec4 pos = imageLoad(iimg2D, ivec2(i,i));
imageStore(ii2da, ivec3(i,i,i), ivec4(0));
imageLoad(img2Drgba, ivec2(i,i));
imageLoad(ii2da, ivec3(i,i,i)); // ERROR, drops writeonly
}
volatile float vol; // ERROR, not an image
readonly int vol2; // ERROR, not an image
void passr(coherent readonly iimage2D image)
{
}
layout(r32i) coherent readonly uniform iimage2D qualim1;
layout(r32i) coherent restrict readonly uniform iimage2D qualim2;
void passrc()
{
passr(qualim1);
passr(qualim2); // ERROR, drops restrict
passr(iimg2D);
}
layout(rg8i) uniform uimage2D i1bad; // ERROR, type mismatch
layout(rgba32i) uniform image2D i2bad; // ERROR, type mismatch
layout(rgba32f) uniform uimage2D i3bad; // ERROR, type mismatch
layout(r8_snorm) uniform iimage2D i4bad; // ERROR, type mismatch
layout(rgba32ui) uniform iimage2D i5bad; // ERROR, type mismatch
layout(r8ui) uniform iimage2D i6bad; // ERROR, type mismatch
layout(binding = 0) uniform atomic_uint counter;
uint func(atomic_uint c)
{
return atomicCounterIncrement(c);
}
uint func2(out atomic_uint c) // ERROR, output
{
return counter; // ERROR, type mismatch
return atomicCounter(counter);
}
void mainAC()
{
atomic_uint non_uniform_counter; // ERROR
uint val = atomicCounter(counter);
atomicCounterDecrement(counter);
}
layout(binding = 1) uniform mediump atomic_uint counterBad; // ERROR, not highp

46
Test/310.frag Normal file
View File

@ -0,0 +1,46 @@
#version 310 es
precision mediump float;
precision highp usampler2D;
precision highp sampler2D;
precision highp isampler2DArray;
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR, not supported
layout(location = 2) in vec3 v3;
layout(location = 2) in mat4 yi; // ERROR, locations conflict with xi
uniform sampler2D arrayedSampler[5];
uniform usampler2D usamp2d;
uniform usampler2DRect samp2dr; // ERROR, reserved
uniform isampler2DArray isamp2DA;
in vec2 c2D;
uniform int i;
void main()
{
vec4 v = texture(arrayedSampler[i], c2D); // ERROR
ivec2 offsets[4];
const ivec2 constOffsets[4] = ivec2[4](ivec2(1,2), ivec2(3,4), ivec2(15,16), ivec2(-2,0));
uvec4 uv4 = textureGatherOffsets(samp2dr, c2D, offsets, 2); // ERROR, not supported
vec4 v4 = textureGather(arrayedSampler[0], c2D);
ivec4 iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), 3);
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), i); // ERROR, last argument not const
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(i));
}
out vec4 outp;
void foo23()
{
const ivec2[3] offsets = ivec2[3](ivec2(1,2), ivec2(3,4), ivec2(15,16));
textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), ivec2(c2D)); // ERROR, offset not constant
textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[1]);
textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[2]); // ERROR, offset out of range
textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), ivec2(-10, 20)); // ERROR, offset out of range
}

10
Test/310.vert Normal file
View File

@ -0,0 +1,10 @@
#version 310 es
shared vec4 s; // ERROR
layout(local_size_x = 2) out; // ERROR
buffer vec4 v; // ERROR
layout(location = 2) uniform mat4 x;
layout(location = 3) uniform mat4 y;
layout(location = 2) out mat4 xi;
layout(location = 3) out mat4 yi; // ERROR, locations conflict with xi

View File

@ -143,7 +143,7 @@ out bblck5 {
layout(xfb_stride=80, xfb_buffer=1, xfb_offset=64) vec4 bbv2; layout(xfb_stride=80, xfb_buffer=1, xfb_offset=64) vec4 bbv2;
} bbinst5; } bbinst5;
shared vec4 sharedv; shared vec4 sharedv; // ERROR
void fooBarrier() void fooBarrier()
{ {

View File

@ -9,7 +9,8 @@ uint func(atomic_uint c)
uint func2(out atomic_uint c) // ERROR uint func2(out atomic_uint c) // ERROR
{ {
return counter; return counter; // ERROR, type mismatch
return atomicCounter(counter);
} }
void main() void main()

View File

@ -19,11 +19,11 @@ ERROR: 0:85: 'dvec3' : Reserved word.
ERROR: 0:85: 'double vector' : not supported with this profile: es ERROR: 0:85: 'double vector' : not supported with this profile: es
ERROR: 0:86: 'dvec4' : Reserved word. ERROR: 0:86: 'dvec4' : Reserved word.
ERROR: 0:86: 'double vector' : not supported with this profile: es ERROR: 0:86: 'double vector' : not supported with this profile: es
ERROR: 0:101: 'arrays of arrays' : not supported with this profile: es ERROR: 0:101: 'arrays of arrays' : not supported for this version or the enabled extensions
ERROR: 0:102: 'arrays of arrays' : not supported with this profile: es ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled extensions
ERROR: 0:102: 'arrays of arrays' : not supported with this profile: es ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled extensions
ERROR: 0:103: 'arrays of arrays' : not supported with this profile: es ERROR: 0:103: 'arrays of arrays' : not supported for this version or the enabled extensions
ERROR: 0:100: 'arrays of arrays' : not supported with this profile: es ERROR: 0:100: 'arrays of arrays' : not supported for this version or the enabled extensions
ERROR: 0:111: 'variable indexing fragment shader ouput array' : not supported with this profile: es ERROR: 0:111: 'variable indexing fragment shader ouput array' : not supported with this profile: es
ERROR: 0:119: '==' : can't use with samplers or structs containing samplers ERROR: 0:119: '==' : can't use with samplers or structs containing samplers
ERROR: 0:120: '!=' : can't use with samplers or structs containing samplers ERROR: 0:120: '!=' : can't use with samplers or structs containing samplers

View File

@ -16,8 +16,8 @@ ERROR: 0:18: 'uniform' : too many storage qualifiers
ERROR: 0:56: '#error' : GL_ES is set ERROR: 0:56: '#error' : GL_ES is set
ERROR: 0:62: '' : array size required ERROR: 0:62: '' : array size required
ERROR: 0:63: '' : array size required ERROR: 0:63: '' : array size required
ERROR: 0:65: '' : array size required
ERROR: 0:64: '' : array size required ERROR: 0:64: '' : array size required
ERROR: 0:65: 'implicitly-sized array in a block' : not supported with this profile: es
ERROR: 0:67: '' : array size required ERROR: 0:67: '' : array size required
ERROR: 0:76: 'invariant' : cannot change qualification after use ERROR: 0:76: 'invariant' : cannot change qualification after use
ERROR: 0:78: 'invariant' : can only apply to an output: invIn ERROR: 0:78: 'invariant' : can only apply to an output: invIn
@ -38,7 +38,8 @@ ERROR: 0:149: 'float' : cannot apply precision statement to this type; use 'floa
ERROR: 0:168: 'Binst' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable ERROR: 0:168: 'Binst' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable
ERROR: 0:169: 'Bblock' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable ERROR: 0:169: 'Bblock' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable
ERROR: 0:170: 'Bfoo' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable ERROR: 0:170: 'Bfoo' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable
ERROR: 39 compilation errors. No code generated. ERROR: 0:173: '' : array size required
ERROR: 40 compilation errors. No code generated.
Shader version: 300 Shader version: 300

View File

@ -1,8 +1,9 @@
300layout.frag 300layout.frag
ERROR: 0:4: 'location qualifier on input' : not supported in this stage: fragment ERROR: 0:4: 'location qualifier on input' : not supported in this stage: fragment
ERROR: 0:4: 'location qualifier on input' : not supported for this version or the enabled extensions
ERROR: 0:18: 'location' : overlapping use of location 41 ERROR: 0:18: 'location' : overlapping use of location 41
ERROR: 0:19: 'location' : overlapping use of location 40 ERROR: 0:19: 'location' : overlapping use of location 40
ERROR: 3 compilation errors. No code generated. ERROR: 4 compilation errors. No code generated.
Shader version: 300 Shader version: 300

View File

@ -13,11 +13,12 @@ ERROR: 0:23: 'bad3' : member of block cannot have a packing layout qualifier
ERROR: 0:31: 'T3' : nameless block contains a member that already has a name at global scope ERROR: 0:31: 'T3' : nameless block contains a member that already has a name at global scope
ERROR: 0:38: 'output block' : not supported with this profile: es ERROR: 0:38: 'output block' : not supported with this profile: es
ERROR: 0:42: 'location qualifier on output' : not supported in this stage: vertex ERROR: 0:42: 'location qualifier on output' : not supported in this stage: vertex
ERROR: 0:50: 'shared' : not supported with this profile: es ERROR: 0:42: 'location qualifier on output' : not supported for this version or the enabled extensions
ERROR: 0:50: 'shared' : not supported for this version or the enabled extensions
ERROR: 0:50: 'shared' : not supported in this stage: vertex ERROR: 0:50: 'shared' : not supported in this stage: vertex
ERROR: 0:54: 'layout' : cannot specify packing on a variable declaration ERROR: 0:54: 'layout' : cannot specify packing on a variable declaration
ERROR: 0:57: 'location' : overlapping use of location 40 ERROR: 0:57: 'location' : overlapping use of location 40
ERROR: 18 compilation errors. No code generated. ERROR: 19 compilation errors. No code generated.
Shader version: 300 Shader version: 300

View File

@ -2,7 +2,7 @@ atomic_uint.frag
Warning, version 420 is not yet complete; most version-specific features are present, but some are missing. Warning, version 420 is not yet complete; most version-specific features are present, but some are missing.
ERROR: 0:10: 'atomic_uint' : samplers and atomic_uints cannot be output parameters ERROR: 0:10: 'atomic_uint' : samplers and atomic_uints cannot be output parameters
ERROR: 0:12: 'return' : type does not match, or is not convertible to, the function's return type ERROR: 0:12: 'return' : type does not match, or is not convertible to, the function's return type
ERROR: 0:17: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: non_uniform_counter ERROR: 0:18: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: non_uniform_counter
ERROR: 3 compilation errors. No code generated. ERROR: 3 compilation errors. No code generated.
@ -21,16 +21,19 @@ ERROR: node is still EOpNull!
0:12 Sequence 0:12 Sequence
0:12 Branch: Return with expression 0:12 Branch: Return with expression
0:12 'counter' (layout(binding=0 ) uniform atomic_uint) 0:12 'counter' (layout(binding=0 ) uniform atomic_uint)
0:15 Function Definition: main( (void) 0:13 Branch: Return with expression
0:15 Function Parameters: 0:13 Function Call: atomicCounter(au1; (uint)
0:13 'counter' (layout(binding=0 ) uniform atomic_uint)
0:16 Function Definition: main( (void)
0:16 Function Parameters:
0:? Sequence 0:? Sequence
0:18 Sequence 0:19 Sequence
0:18 move second child to first child (uint) 0:19 move second child to first child (uint)
0:18 'val' (uint) 0:19 'val' (uint)
0:18 Function Call: atomicCounter(au1; (uint) 0:19 Function Call: atomicCounter(au1; (uint)
0:18 'counter' (layout(binding=0 ) uniform atomic_uint)
0:19 Function Call: atomicCounterDecrement(au1; (uint)
0:19 'counter' (layout(binding=0 ) uniform atomic_uint) 0:19 'counter' (layout(binding=0 ) uniform atomic_uint)
0:20 Function Call: atomicCounterDecrement(au1; (uint)
0:20 'counter' (layout(binding=0 ) uniform atomic_uint)
0:? Linker Objects 0:? Linker Objects
0:? 'counter' (layout(binding=0 ) uniform atomic_uint) 0:? 'counter' (layout(binding=0 ) uniform atomic_uint)
@ -53,16 +56,19 @@ ERROR: node is still EOpNull!
0:12 Sequence 0:12 Sequence
0:12 Branch: Return with expression 0:12 Branch: Return with expression
0:12 'counter' (layout(binding=0 ) uniform atomic_uint) 0:12 'counter' (layout(binding=0 ) uniform atomic_uint)
0:15 Function Definition: main( (void) 0:13 Branch: Return with expression
0:15 Function Parameters: 0:13 Function Call: atomicCounter(au1; (uint)
0:13 'counter' (layout(binding=0 ) uniform atomic_uint)
0:16 Function Definition: main( (void)
0:16 Function Parameters:
0:? Sequence 0:? Sequence
0:18 Sequence 0:19 Sequence
0:18 move second child to first child (uint) 0:19 move second child to first child (uint)
0:18 'val' (uint) 0:19 'val' (uint)
0:18 Function Call: atomicCounter(au1; (uint) 0:19 Function Call: atomicCounter(au1; (uint)
0:18 'counter' (layout(binding=0 ) uniform atomic_uint)
0:19 Function Call: atomicCounterDecrement(au1; (uint)
0:19 'counter' (layout(binding=0 ) uniform atomic_uint) 0:19 'counter' (layout(binding=0 ) uniform atomic_uint)
0:20 Function Call: atomicCounterDecrement(au1; (uint)
0:20 'counter' (layout(binding=0 ) uniform atomic_uint)
0:? Linker Objects 0:? Linker Objects
0:? 'counter' (layout(binding=0 ) uniform atomic_uint) 0:? 'counter' (layout(binding=0 ) uniform atomic_uint)

View File

@ -36,6 +36,9 @@ comment.frag
300layout.frag 300layout.frag
300operations.frag 300operations.frag
300block.frag 300block.frag
310.comp
310.vert
310.frag
330.frag 330.frag
330comp.frag 330comp.frag
constErrors.frag constErrors.frag

View File

@ -248,20 +248,23 @@ enum TLayoutFormat {
// Float image // Float image
ElfRgba32f, ElfRgba32f,
ElfRgba16f, ElfRgba16f,
ElfR32f,
ElfRgba8,
ElfRgba8Snorm,
ElfEsFloatGuard, // to help with comparisons
ElfRg32f, ElfRg32f,
ElfRg16f, ElfRg16f,
ElfR11fG11fB10f, ElfR11fG11fB10f,
ElfR32f,
ElfR16f, ElfR16f,
ElfRgba16, ElfRgba16,
ElfRgb10A2, ElfRgb10A2,
ElfRgba8,
ElfRg16, ElfRg16,
ElfRg8, ElfRg8,
ElfR16, ElfR16,
ElfR8, ElfR8,
ElfRgba16Snorm, ElfRgba16Snorm,
ElfRgba8Snorm,
ElfRg16Snorm, ElfRg16Snorm,
ElfRg8Snorm, ElfRg8Snorm,
ElfR16Snorm, ElfR16Snorm,
@ -273,10 +276,13 @@ enum TLayoutFormat {
ElfRgba32i, ElfRgba32i,
ElfRgba16i, ElfRgba16i,
ElfRgba8i, ElfRgba8i,
ElfR32i,
ElfEsIntGuard, // to help with comparisons
ElfRg32i, ElfRg32i,
ElfRg16i, ElfRg16i,
ElfRg8i, ElfRg8i,
ElfR32i,
ElfR16i, ElfR16i,
ElfR8i, ElfR8i,
@ -286,10 +292,13 @@ enum TLayoutFormat {
ElfRgba32ui, ElfRgba32ui,
ElfRgba16ui, ElfRgba16ui,
ElfRgba8ui, ElfRgba8ui,
ElfR32ui,
ElfEsUintGuard, // to help with comparisons
ElfRg32ui, ElfRg32ui,
ElfRg16ui, ElfRg16ui,
ElfRg8ui, ElfRg8ui,
ElfR32ui,
ElfR16ui, ElfR16ui,
ElfR8ui, ElfR8ui,

View File

@ -743,7 +743,8 @@ void TBuiltIns::initialize(int version, EProfile profile)
// //
// Atomic counter functions. // Atomic counter functions.
// //
if (profile != EEsProfile && version >= 420) { if ((profile != EEsProfile && version >= 420) ||
(profile == EEsProfile && version >= 310)) {
commonBuiltins.append( commonBuiltins.append(
"uint atomicCounterIncrement(atomic_uint x);" "uint atomicCounterIncrement(atomic_uint x);"
"uint atomicCounterDecrement(atomic_uint x);" "uint atomicCounterDecrement(atomic_uint x);"
@ -841,27 +842,26 @@ void TBuiltIns::initialize(int version, EProfile profile)
"\n"); "\n");
} }
if (profile != EEsProfile) {
//============================================================================ //============================================================================
// //
// Prototypes for all control functions. // Prototypes for all control functions.
// //
//============================================================================ //============================================================================
bool esBarrier = (profile == EEsProfile && version >= 310);
if (version >= 150) if (profile != EEsProfile && version >= 150)
stageBuiltins[EShLangTessControl].append( stageBuiltins[EShLangTessControl].append(
"void barrier();" "void barrier();"
); );
if (version >= 430) if ((profile != EEsProfile && version >= 430) || esBarrier)
stageBuiltins[EShLangCompute].append( stageBuiltins[EShLangCompute].append(
"void barrier();" "void barrier();"
); );
if ((profile != EEsProfile && version >= 130) || esBarrier)
if (version >= 130)
commonBuiltins.append( commonBuiltins.append(
"void memoryBarrier();" "void memoryBarrier();"
); );
if (version >= 430) { if ((profile != EEsProfile && version >= 430) || esBarrier) {
commonBuiltins.append( commonBuiltins.append(
"void memoryBarrierAtomicCounter();" "void memoryBarrierAtomicCounter();"
"void memoryBarrierBuffer();" "void memoryBarrierBuffer();"
@ -872,7 +872,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
"void groupMemoryBarrier();" "void groupMemoryBarrier();"
); );
} }
}
//============================================================================ //============================================================================
// //
// Prototypes for built-in functions seen by fragment shaders only. // Prototypes for built-in functions seen by fragment shaders only.
@ -1088,7 +1088,8 @@ void TBuiltIns::initialize(int version, EProfile profile)
// //
//============================================================================ //============================================================================
if (version >= 430) { if (profile != EEsProfile && version >= 430 ||
profile == EEsProfile && version >= 310) {
stageBuiltins[EShLangCompute].append( stageBuiltins[EShLangCompute].append(
"in uvec3 gl_NumWorkGroups;" "in uvec3 gl_NumWorkGroups;"
"const uvec3 gl_WorkGroupSize = uvec3(1,1,1);" "const uvec3 gl_WorkGroupSize = uvec3(1,1,1);"
@ -1276,11 +1277,11 @@ void TBuiltIns::initialize(int version, EProfile profile)
"out vec4 gl_ClipVertex;" "out vec4 gl_ClipVertex;"
); );
if (version >= 400) if (version >= 400 && profile != EEsProfile)
stageBuiltins[EShLangGeometry].append( stageBuiltins[EShLangGeometry].append(
"in int gl_InvocationID;" "in int gl_InvocationID;"
); );
if (version >= 410) if (version >= 410 && profile != EEsProfile)
stageBuiltins[EShLangGeometry].append( stageBuiltins[EShLangGeometry].append(
"out int gl_ViewportIndex;" "out int gl_ViewportIndex;"
); );
@ -1434,6 +1435,11 @@ void TBuiltIns::initialize(int version, EProfile profile)
"flat in int gl_Layer;" "flat in int gl_Layer;"
"flat in int gl_ViewportIndex;" "flat in int gl_ViewportIndex;"
); );
if (version >= 450)
stageBuiltins[EShLangFragment].append(
"bool gl_HelperInvocation;" // needs qualifier fixed later
);
} else { } else {
// ES profile // ES profile
@ -1444,13 +1450,18 @@ void TBuiltIns::initialize(int version, EProfile profile)
"mediump vec4 gl_FragColor;" // needs qualifier fixed later "mediump vec4 gl_FragColor;" // needs qualifier fixed later
"mediump vec2 gl_PointCoord;" // needs qualifier fixed later "mediump vec2 gl_PointCoord;" // needs qualifier fixed later
); );
else if (version == 300) else if (version >= 300) {
stageBuiltins[EShLangFragment].append( stageBuiltins[EShLangFragment].append(
"highp vec4 gl_FragCoord;" // needs qualifier fixed later "highp vec4 gl_FragCoord;" // needs qualifier fixed later
" bool gl_FrontFacing;" // needs qualifier fixed later " bool gl_FrontFacing;" // needs qualifier fixed later
"mediump vec2 gl_PointCoord;" // needs qualifier fixed later "mediump vec2 gl_PointCoord;" // needs qualifier fixed later
"highp float gl_FragDepth;" // needs qualifier fixed later "highp float gl_FragDepth;" // needs qualifier fixed later
); );
if (version >= 310)
stageBuiltins[EShLangFragment].append(
"bool gl_HelperInvocation;" // needs qualifier fixed later
);
}
stageBuiltins[EShLangFragment].append( stageBuiltins[EShLangFragment].append(
"highp float gl_FragDepthEXT;" // GL_EXT_frag_depth "highp float gl_FragDepthEXT;" // GL_EXT_frag_depth
); );
@ -1554,7 +1565,7 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int versi
// textureSize // textureSize
// //
if (version < 430 && sampler.image) if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430)))
return; return;
if (profile == EEsProfile) if (profile == EEsProfile)
@ -1607,6 +1618,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
commonBuiltins.append(prefixes[sampler.type]); commonBuiltins.append(prefixes[sampler.type]);
commonBuiltins.append("vec4);\n"); commonBuiltins.append("vec4);\n");
if (profile != EEsProfile) {
if (sampler.type == EbtInt || sampler.type == EbtUint) { if (sampler.type == EbtInt || sampler.type == EbtUint) {
const char* dataType = sampler.type == EbtInt ? "int" : "uint"; const char* dataType = sampler.type == EbtInt ? "int" : "uint";
@ -1642,6 +1654,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
commonBuiltins.append(dataType); commonBuiltins.append(dataType);
commonBuiltins.append(");\n"); commonBuiltins.append(");\n");
} }
}
} }
// //
@ -1848,6 +1861,9 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int vers
for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets
if (profile == EEsProfile && offset == 2)
continue;
for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument
if (comp > 0 && sampler.shadow) if (comp > 0 && sampler.shadow)
@ -2156,24 +2172,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
s.append(builtInConstant); s.append(builtInConstant);
} }
// atomic counters
if (version >= 420) {
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBindings = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBufferSize = %d;", resources.);
}
// images // images
if (version >= 130) { if (version >= 130) {
snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits); snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits);
@ -2198,13 +2196,43 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
s.append(builtInConstant); s.append(builtInConstant);
} }
// compute // enhanced layouts
if (version >= 430) { if (version >= 430) {
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = {%d,%d,%d};", resources.maxComputeWorkGroupCountX, snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackBuffers = %d;", resources.maxTransformFeedbackBuffers);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackInterleavedComponents = %d;", resources.maxTransformFeedbackInterleavedComponents);
s.append(builtInConstant);
}
}
// TODO: atomic counters
if (profile == EEsProfile && version >= 310 || profile != EEsProfile && version >= 420) {
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBindings = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBufferSize = %d;", resources.);
}
if (profile != EEsProfile && version >= 420) {
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources.);
}
// compute
if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 430)) {
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupCountX,
resources.maxComputeWorkGroupCountY, resources.maxComputeWorkGroupCountY,
resources.maxComputeWorkGroupCountZ); resources.maxComputeWorkGroupCountZ);
s.append(builtInConstant); s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = {%d,%d,%d};", resources.maxComputeWorkGroupSizeX, snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupSizeX,
resources.maxComputeWorkGroupSizeY, resources.maxComputeWorkGroupSizeY,
resources.maxComputeWorkGroupSizeZ); resources.maxComputeWorkGroupSizeZ);
s.append(builtInConstant); s.append(builtInConstant);
@ -2221,15 +2249,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
s.append(builtInConstant); s.append(builtInConstant);
} }
// enhanced layouts
if (version >= 430) {
snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackBuffers = %d;", resources.maxTransformFeedbackBuffers);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackInterleavedComponents = %d;", resources.maxTransformFeedbackInterleavedComponents);
s.append(builtInConstant);
}
}
s.append("\n"); s.append("\n");
} }
@ -2290,6 +2309,7 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
SpecialQualifier("gl_FragColor", EvqFragColor, symbolTable); SpecialQualifier("gl_FragColor", EvqFragColor, symbolTable);
SpecialQualifier("gl_FragDepth", EvqFragDepth, symbolTable); SpecialQualifier("gl_FragDepth", EvqFragDepth, symbolTable);
SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, symbolTable); SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, symbolTable);
SpecialQualifier("gl_HelperInvocation", EvqIn, symbolTable);
if (version == 100) { if (version == 100) {
symbolTable.setFunctionExtensions("dFdx", 1, &GL_OES_standard_derivatives); symbolTable.setFunctionExtensions("dFdx", 1, &GL_OES_standard_derivatives);
symbolTable.setFunctionExtensions("dFdy", 1, &GL_OES_standard_derivatives); symbolTable.setFunctionExtensions("dFdy", 1, &GL_OES_standard_derivatives);
@ -2339,7 +2359,7 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
} }
// GL_ARB_shader_image_load_store // GL_ARB_shader_image_load_store
if (version < 420) if (profile != EEsProfile && version < 420)
symbolTable.setFunctionExtensions("memoryBarrier", 1, &GL_ARB_shader_image_load_store); symbolTable.setFunctionExtensions("memoryBarrier", 1, &GL_ARB_shader_image_load_store);
// All the image access functions are protected by checks on the type of the first argument. // All the image access functions are protected by checks on the type of the first argument.
@ -2495,7 +2515,7 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
// //
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources)
{ {
if (version >= 430 && version < 440) { if (profile != EEsProfile && version >= 430 && version < 440) {
symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &GL_ARB_enhanced_layouts); symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &GL_ARB_enhanced_layouts);
symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &GL_ARB_enhanced_layouts); symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &GL_ARB_enhanced_layouts);
} }

View File

@ -82,15 +82,16 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
case EShLangFragment: case EShLangFragment:
defaultPrecision[EbtInt] = EpqMedium; defaultPrecision[EbtInt] = EpqMedium;
defaultPrecision[EbtUint] = EpqMedium; defaultPrecision[EbtUint] = EpqMedium;
defaultPrecision[EbtSampler] = EpqLow;
break; break;
default: default:
defaultPrecision[EbtInt] = EpqHigh; defaultPrecision[EbtInt] = EpqHigh;
defaultPrecision[EbtUint] = EpqHigh; defaultPrecision[EbtUint] = EpqHigh;
defaultPrecision[EbtFloat] = EpqHigh; defaultPrecision[EbtFloat] = EpqHigh;
defaultPrecision[EbtSampler] = EpqLow;
break; break;
} }
defaultPrecision[EbtSampler] = EpqLow;
defaultPrecision[EbtAtomicUint] = EpqHigh;
} }
globalUniformDefaults.clear(); globalUniformDefaults.clear();
@ -1216,7 +1217,7 @@ void TParseContext::nonOpBuiltInCheck(TSourceLoc loc, const TFunction& fnCandida
if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) { if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) {
TString featureString = fnCandidate.getName() + "(...)"; TString featureString = fnCandidate.getName() + "(...)";
const char* feature = featureString.c_str(); const char* feature = featureString.c_str();
requireProfile(loc, ~EEsProfile, feature); profileRequires(loc, EEsProfile, 310, 0, feature);
int compArg = -1; // track which argument, if any, is the constant component argument int compArg = -1; // track which argument, if any, is the constant component argument
if (fnCandidate.getName().compare("textureGatherOffset") == 0) { if (fnCandidate.getName().compare("textureGatherOffset") == 0) {
@ -2067,7 +2068,9 @@ void TParseContext::mergeQualifiers(TSourceLoc loc, TQualifier& dst, const TQual
error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", ""); error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", "");
// Ordering // Ordering
if (! force && version < 420 && ! extensionsTurnedOn(1, &GL_ARB_shading_language_420pack)) { if (! force && ((profile != EEsProfile && version < 420) ||
profile == EEsProfile && version < 310)
&& ! extensionsTurnedOn(1, &GL_ARB_shading_language_420pack)) {
// non-function parameters // non-function parameters
if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
error(loc, "invariant qualifier must appear first", "", ""); error(loc, "invariant qualifier must appear first", "", "");
@ -2173,7 +2176,10 @@ void TParseContext::precisionQualifierCheck(TSourceLoc loc, TPublicType& publicT
if (profile != EEsProfile || parsingBuiltins) if (profile != EEsProfile || parsingBuiltins)
return; return;
if (publicType.basicType == EbtFloat || publicType.basicType == EbtUint || publicType.basicType == EbtInt || publicType.basicType == EbtSampler) { if (publicType.basicType == EbtAtomicUint && publicType.qualifier.precision != EpqNone && publicType.qualifier.precision != EpqHigh)
error(loc, "atomic counters can only be highp", "atomic_uint", "");
if (publicType.basicType == EbtFloat || publicType.basicType == EbtUint || publicType.basicType == EbtInt || publicType.basicType == EbtSampler || publicType.basicType == EbtAtomicUint) {
if (publicType.qualifier.precision == EpqNone) { if (publicType.qualifier.precision == EpqNone) {
if (messages & EShMsgRelaxedErrors) if (messages & EShMsgRelaxedErrors)
warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(publicType.basicType), "substituting 'mediump'"); warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(publicType.basicType), "substituting 'mediump'");
@ -2262,10 +2268,21 @@ void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int size)
} }
} }
void TParseContext::structArrayCheck(TSourceLoc loc, TType* type)
{
const TTypeList& structure = *type->getStruct();
for (int m = 0; m < (int)structure.size(); ++m) {
const TType& member = *structure[m].type;
if (member.isArray() && ! member.isExplicitlySizedArray())
arraySizeRequiredCheck(structure[m].loc, 0);
}
}
void TParseContext::arrayDimError(TSourceLoc loc) void TParseContext::arrayDimError(TSourceLoc loc)
{ {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "arrays of arrays"); requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "arrays of arrays");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "arrays of arrays"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "arrays of arrays");
profileRequires(loc, EEsProfile, 310, 0, "arrays of arrays");
} }
void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes* sizes1, TArraySizes* sizes2) void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes* sizes1, TArraySizes* sizes2)
@ -2955,15 +2972,20 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
return; return;
} }
if (id == TQualifier::getLayoutPackingString(ElpStd430)) { if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "std430"); requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "std430"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "std430");
profileRequires(loc, EEsProfile, 310, 0, "std430");
publicType.qualifier.layoutPacking = ElpStd430; publicType.qualifier.layoutPacking = ElpStd430;
return; return;
} }
for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) { for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) {
if (id == TQualifier::getLayoutFormatString(format)) { if (id == TQualifier::getLayoutFormatString(format)) {
requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "image load store"); if ((format > ElfEsFloatGuard && format < ElfFloatGuard) ||
(format > ElfEsIntGuard && format < ElfIntGuard) ||
(format > ElfEsUintGuard && format < ElfCount))
requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "image load-store format");
profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shader_image_load_store, "image load store"); profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shader_image_load_store, "image load store");
profileRequires(loc, EEsProfile, 310, GL_ARB_shader_image_load_store, "image load store");
publicType.qualifier.layoutFormat = format; publicType.qualifier.layoutFormat = format;
return; return;
} }
@ -3097,8 +3119,9 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
if (id == "offset") { if (id == "offset") {
const char* feature = "uniform buffer-member offset"; const char* feature = "uniform buffer-member offset";
requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature); requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
profileRequires(loc, EEsProfile, 310, 0, feature);
publicType.qualifier.layoutOffset = value; publicType.qualifier.layoutOffset = value;
return; return;
} else if (id == "align") { } else if (id == "align") {
@ -3121,8 +3144,8 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
publicType.qualifier.layoutLocation = value; publicType.qualifier.layoutLocation = value;
return; return;
} else if (id == "binding") { } else if (id == "binding") {
requireProfile(loc, ~EEsProfile, "binding");
profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, "binding"); profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, "binding");
profileRequires(loc, EEsProfile, 310, 0, "binding");
if ((unsigned int)value >= TQualifier::layoutBindingEnd) if ((unsigned int)value >= TQualifier::layoutBindingEnd)
error(loc, "binding is too large", id.c_str(), ""); error(loc, "binding is too large", id.c_str(), "");
else else
@ -3460,35 +3483,44 @@ void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& quali
case EvqVaryingIn: case EvqVaryingIn:
{ {
const char* feature = "location qualifier on input"; const char* feature = "location qualifier on input";
if (profile == EEsProfile) if (profile == EEsProfile && version < 310)
requireStage(loc, EShLangVertex, feature); requireStage(loc, EShLangVertex, feature);
else
requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature); requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
if (language == EShLangVertex) { if (language == EShLangVertex) {
const char* exts[2] = { GL_ARB_separate_shader_objects, GL_ARB_explicit_attrib_location }; const char* exts[2] = { GL_ARB_separate_shader_objects, GL_ARB_explicit_attrib_location };
profileRequires(loc, ~EEsProfile, 330, 2, exts, feature); profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
} else profileRequires(loc, EEsProfile, 300, 0, feature);
} else {
profileRequires(loc, ~EEsProfile, 410, GL_ARB_separate_shader_objects, feature); profileRequires(loc, ~EEsProfile, 410, GL_ARB_separate_shader_objects, feature);
profileRequires(loc, EEsProfile, 310, 0, feature);
}
break; break;
} }
case EvqVaryingOut: case EvqVaryingOut:
{ {
const char* feature = "location qualifier on output"; const char* feature = "location qualifier on output";
if (profile == EEsProfile) if (profile == EEsProfile && version < 310)
requireStage(loc, EShLangFragment, feature); requireStage(loc, EShLangFragment, feature);
else
requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature); requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
if (language == EShLangFragment) { if (language == EShLangFragment) {
const char* exts[2] = { GL_ARB_separate_shader_objects, GL_ARB_explicit_attrib_location }; const char* exts[2] = { GL_ARB_separate_shader_objects, GL_ARB_explicit_attrib_location };
profileRequires(loc, ~EEsProfile, 330, 2, exts, feature); profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
} else profileRequires(loc, EEsProfile, 300, 0, feature);
} else {
profileRequires(loc, ~EEsProfile, 410, GL_ARB_separate_shader_objects, feature); profileRequires(loc, ~EEsProfile, 410, GL_ARB_separate_shader_objects, feature);
profileRequires(loc, EEsProfile, 310, 0, feature);
}
break; break;
} }
case EvqUniform: case EvqUniform:
case EvqBuffer: case EvqBuffer:
{ {
const char* feature = "location qualifier on uniform or buffer"; const char* feature = "location qualifier on uniform or buffer";
requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature); requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, feature); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, feature);
profileRequires(loc, EEsProfile, 310, 0, feature);
break; break;
} }
default: default:
@ -4155,8 +4187,9 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
profileRequires(loc, ENoProfile, 140, 0, "uniform block"); profileRequires(loc, ENoProfile, 140, 0, "uniform block");
break; break;
case EvqBuffer: case EvqBuffer:
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "buffer block"); requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "buffer block"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "buffer block");
profileRequires(loc, EEsProfile, 310, 0, "buffer block");
break; break;
case EvqVaryingIn: case EvqVaryingIn:
requireProfile(loc, ~EEsProfile, "input block"); requireProfile(loc, ~EEsProfile, "input block");
@ -4186,6 +4219,8 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), ""); error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
if (memberType.isRuntimeSizedArray() && member < typeList.size() - 1) if (memberType.isRuntimeSizedArray() && member < typeList.size() - 1)
error(memberLoc, "only the last member of a buffer block can be run-time sized", memberType.getFieldName().c_str(), ""); error(memberLoc, "only the last member of a buffer block can be run-time sized", memberType.getFieldName().c_str(), "");
if (memberType.isImplicitlySizedArray())
requireProfile(memberLoc, ~EEsProfile, "implicitly-sized array in a block");
TBasicType basicType = memberType.getBasicType(); TBasicType basicType = memberType.getBasicType();
if (basicType == EbtSampler) if (basicType == EbtSampler)

View File

@ -117,6 +117,7 @@ public:
void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size); void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size);
bool arrayQualifierError(TSourceLoc, const TQualifier&); bool arrayQualifierError(TSourceLoc, const TQualifier&);
void arraySizeRequiredCheck(TSourceLoc, int size); void arraySizeRequiredCheck(TSourceLoc, int size);
void structArrayCheck(TSourceLoc, TType* structure);
void arrayDimError(TSourceLoc); void arrayDimError(TSourceLoc);
void arrayDimCheck(TSourceLoc, TArraySizes* sizes1, TArraySizes* sizes2); void arrayDimCheck(TSourceLoc, TArraySizes* sizes1, TArraySizes* sizes2);
void arrayDimCheck(TSourceLoc, const TType*, TArraySizes*); void arrayDimCheck(TSourceLoc, const TType*, TArraySizes*);

View File

@ -668,17 +668,24 @@ int TScanContext::tokenizeIdentifier()
return keyword; return keyword;
case BUFFER: case BUFFER:
if (parseContext.version < 430) if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
(parseContext.profile != EEsProfile && parseContext.version < 430))
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
case ATOMIC_UINT: case ATOMIC_UINT:
if (parseContext.profile == EEsProfile && parseContext.version >= 310)
return keyword;
else
return es30ReservedFromGLSL(420); return es30ReservedFromGLSL(420);
case COHERENT: case COHERENT:
case RESTRICT: case RESTRICT:
case READONLY: case READONLY:
case WRITEONLY: case WRITEONLY:
if (parseContext.profile == EEsProfile && parseContext.version >= 310)
return keyword;
else
return es30ReservedFromGLSL(parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store) ? 130 : 420); return es30ReservedFromGLSL(parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store) ? 130 : 420);
case VOLATILE: case VOLATILE:
@ -743,28 +750,30 @@ int TScanContext::tokenizeIdentifier()
case IMAGE1D: case IMAGE1D:
case IIMAGE1D: case IIMAGE1D:
case UIMAGE1D: case UIMAGE1D:
case IMAGE1DARRAY:
case IIMAGE1DARRAY:
case UIMAGE1DARRAY:
case IMAGE2DRECT:
case IIMAGE2DRECT:
case UIMAGE2DRECT:
case IMAGEBUFFER:
case IIMAGEBUFFER:
case UIMAGEBUFFER:
return firstGenerationImage(false);
case IMAGE2D: case IMAGE2D:
case IIMAGE2D: case IIMAGE2D:
case UIMAGE2D: case UIMAGE2D:
case IMAGE3D: case IMAGE3D:
case IIMAGE3D: case IIMAGE3D:
case UIMAGE3D: case UIMAGE3D:
case IMAGE2DRECT:
case IIMAGE2DRECT:
case UIMAGE2DRECT:
case IMAGECUBE: case IMAGECUBE:
case IIMAGECUBE: case IIMAGECUBE:
case UIMAGECUBE: case UIMAGECUBE:
case IMAGEBUFFER:
case IIMAGEBUFFER:
case UIMAGEBUFFER:
case IMAGE1DARRAY:
case IIMAGE1DARRAY:
case UIMAGE1DARRAY:
case IMAGE2DARRAY: case IMAGE2DARRAY:
case IIMAGE2DARRAY: case IIMAGE2DARRAY:
case UIMAGE2DARRAY: case UIMAGE2DARRAY:
return firstGenerationImage(); return firstGenerationImage(true);
case IMAGECUBEARRAY: case IMAGECUBEARRAY:
case IIMAGECUBEARRAY: case IIMAGECUBEARRAY:
@ -1068,11 +1077,13 @@ int TScanContext::dMat()
return identifierOrType(); return identifierOrType();
} }
int TScanContext::firstGenerationImage() int TScanContext::firstGenerationImage(bool inEs310)
{ {
afterType = true; afterType = true;
if (parseContext.symbolTable.atBuiltInLevel() || (parseContext.profile != EEsProfile && (parseContext.version >= 420 || parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store)))) if (parseContext.symbolTable.atBuiltInLevel() ||
(parseContext.profile != EEsProfile && (parseContext.version >= 420 || parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store))) ||
(inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310))
return keyword; return keyword;
if ((parseContext.profile == EEsProfile && parseContext.version >= 300) || if ((parseContext.profile == EEsProfile && parseContext.version >= 300) ||

View File

@ -64,7 +64,7 @@ protected:
int precisionKeyword(); int precisionKeyword();
int matNxM(); int matNxM();
int dMat(); int dMat();
int firstGenerationImage(); int firstGenerationImage(bool inEs310);
int secondGenerationImage(); int secondGenerationImage();
TParseContext& parseContext; TParseContext& parseContext;

View File

@ -78,11 +78,13 @@ int MapVersionToIndex(int version)
case 420: return 10; case 420: return 10;
case 430: return 11; case 430: return 11;
case 440: return 12; case 440: return 12;
case 310: return 13;
case 450: return 14;
default: // | default: // |
return 0; // | return 0; // |
} // | } // |
} // V } // V
const int VersionCount = 13; // number of case statements above const int VersionCount = 15; // number of case statements above
int MapProfileToIndex(EProfile profile) int MapProfileToIndex(EProfile profile)
{ {
@ -197,7 +199,8 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
} }
if (profile != EEsProfile && version >= 150) if (profile != EEsProfile && version >= 150)
InitializeStageSymbolTable(builtIns, version, profile, EShLangGeometry, infoSink, commonTable, symbolTables); InitializeStageSymbolTable(builtIns, version, profile, EShLangGeometry, infoSink, commonTable, symbolTables);
if (profile != EEsProfile && version >= 430) if ((profile != EEsProfile && version >= 430) ||
(profile == EEsProfile && version >= 310))
InitializeStageSymbolTable(builtIns, version, profile, EShLangCompute, infoSink, commonTable, symbolTables); InitializeStageSymbolTable(builtIns, version, profile, EShLangCompute, infoSink, commonTable, symbolTables);
return true; return true;
@ -303,9 +306,9 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
// Get a good profile... // Get a good profile...
if (profile == ENoProfile) { if (profile == ENoProfile) {
if (version == 300) { if (version == 300 || version == 310) {
correct = false; correct = false;
infoSink.info.message(EPrefixError, "#version: version 300 requires specifying the 'es' profile"); infoSink.info.message(EPrefixError, "#version: versions 300 and 310 require specifying the 'es' profile");
profile = EEsProfile; profile = EEsProfile;
} else if (version == 100) } else if (version == 100)
profile = EEsProfile; profile = EEsProfile;
@ -322,16 +325,16 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
profile = EEsProfile; profile = EEsProfile;
else else
profile = ENoProfile; profile = ENoProfile;
} else if (version == 300) { } else if (version == 300 || version == 310) {
if (profile != EEsProfile) { if (profile != EEsProfile) {
correct = false; correct = false;
infoSink.info.message(EPrefixError, "#version: version 300 supports only the es profile"); infoSink.info.message(EPrefixError, "#version: versions 300 and 310 support only the es profile");
} }
profile = EEsProfile; profile = EEsProfile;
} else { } else {
if (profile == EEsProfile) { if (profile == EEsProfile) {
correct = false; correct = false;
infoSink.info.message(EPrefixError, "#version: only version 300 supports the es profile"); infoSink.info.message(EPrefixError, "#version: only version 300 and 310 support the es profile");
if (version >= FirstProfileVersion) if (version >= FirstProfileVersion)
profile = ECoreProfile; profile = ECoreProfile;
else else
@ -361,10 +364,11 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
} }
break; break;
case EShLangCompute: case EShLangCompute:
if (version < 430 || (profile != ECoreProfile && profile != ECompatibilityProfile)) { if ((profile == EEsProfile && version < 310) ||
(profile != EEsProfile && version < 430)) {
correct = false; correct = false;
infoSink.info.message(EPrefixError, "#version: compute shaders require non-es profile and version 430 or above"); infoSink.info.message(EPrefixError, "#version: compute shaders require es profile with version 310 or above, or non-es profile with version 430 or above");
version = 430; version = profile == EEsProfile ? 310 : 430;
profile = ECoreProfile; profile = ECoreProfile;
} }
break; break;
@ -395,9 +399,21 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
// versions are complete // versions are complete
break; break;
default: case 310:
case 330:
case 400:
case 410:
case 420:
case 430:
case 440:
case 450:
infoSink.info << "Warning, version " << version << " is not yet complete; most version-specific features are present, but some are missing.\n"; infoSink.info << "Warning, version " << version << " is not yet complete; most version-specific features are present, but some are missing.\n";
break; break;
default:
infoSink.info << "Warning, version " << version << " is unknown.\n";
break;
} }
return correct; return correct;

View File

@ -1216,8 +1216,8 @@ storage_qualifier
$$.qualifier.storage = EvqBuffer; $$.qualifier.storage = EvqBuffer;
} }
| SHARED { | SHARED {
parseContext.requireProfile($1.loc, ~EEsProfile, "shared"); parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, 0, "shared");
parseContext.profileRequires($1.loc, ECoreProfile, 430, 0, "shared"); parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared");
parseContext.requireStage($1.loc, EShLangCompute, "shared"); parseContext.requireStage($1.loc, EShLangCompute, "shared");
$$.init($1.loc); $$.init($1.loc);
$$.qualifier.storage = EvqShared; $$.qualifier.storage = EvqShared;
@ -1964,6 +1964,7 @@ precision_qualifier
struct_specifier struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE { : STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($5, *$2.string); TType* structure = new TType($5, *$2.string);
parseContext.structArrayCheck($2.loc, structure);
TVariable* userTypeDef = new TVariable($2.string, *structure, true); TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! parseContext.symbolTable.insert(*userTypeDef)) if (! parseContext.symbolTable.insert(*userTypeDef))
parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct"); parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct");
@ -2055,8 +2056,6 @@ struct_declarator
$$.type->setFieldName(*$1.string); $$.type->setFieldName(*$1.string);
} }
| IDENTIFIER array_specifier { | IDENTIFIER array_specifier {
if (parseContext.profile == EEsProfile)
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());
parseContext.arrayDimCheck($1.loc, $2.arraySizes, 0); parseContext.arrayDimCheck($1.loc, $2.arraySizes, 0);
$$.type = new TType(EbtVoid); $$.type = new TType(EbtVoid);