Finish implementing compute shaders, within #version 430, partly based on a submission.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27674 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2014-08-11 02:32:30 +00:00
parent ddea678e3e
commit 79cddfcb56
17 changed files with 239 additions and 43 deletions

View File

@ -1,12 +1,38 @@
#version 430 core #version 430 core
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;
void main() void main()
{ {
memoryBarrierAtomicCounter(); barrier();
memoryBarrierBuffer(); memoryBarrier();
memoryBarrierShared(); memoryBarrierAtomicCounter();
memoryBarrierImage(); memoryBarrierBuffer();
groupMemoryBarrier(); memoryBarrierShared();
memoryBarrierImage();
groupMemoryBarrier();
} }
layout(location = 2) in vec3 v3; 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];

View File

@ -142,3 +142,16 @@ out bblck5 {
layout(xfb_offset=0) vec4 bbv1; layout(xfb_offset=0) vec4 bbv1;
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;
void fooBarrier()
{
barrier(); // ERROR
memoryBarrier();
memoryBarrierAtomicCounter();
memoryBarrierBuffer();
memoryBarrierShared(); // ERROR
memoryBarrierImage();
groupMemoryBarrier(); // ERROR
}

View File

@ -15,10 +15,9 @@ 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:50: 'shared' : not supported with this profile: es
ERROR: 0:50: 'shared' : not supported in this stage: vertex ERROR: 0:50: 'shared' : not supported in this stage: vertex
ERROR: 0:50: '' : memory qualifiers can only be used on image types
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: 19 compilation errors. No code generated. ERROR: 18 compilation errors. No code generated.
Shader version: 300 Shader version: 300

View File

@ -1,36 +1,81 @@
430.comp 430.comp
Warning, version 430 is not yet complete; most version-specific features are present, but some are missing. Warning, version 430 is not yet complete; most version-specific features are present, but some are missing.
ERROR: 0:12: 'location qualifier on input' : not supported in this stage: compute ERROR: 0:4: 'local_size' : cannot change previously set size
ERROR: 1 compilation errors. No code generated. ERROR: 0:5: 'local_size' : too large; see gl_MaxComputeWorkGroupSize
ERROR: 0:26: 'in' : global storage input qualifier cannot be used in a compute shader
ERROR: 0:26: 'location qualifier on input' : not supported in this stage: compute
ERROR: 0:27: 'in' : global storage input qualifier cannot be used in a compute shader
ERROR: 0:28: 'out' : global storage output qualifier cannot be used in a compute shader
ERROR: 0:31: 'shared' : cannot apply layout qualifiers to a shared variable
ERROR: 0:31: 'location' : can only appy to uniform, buffer, in, or out storage qualifiers
ERROR: 0:32: 'shared' : cannot initialize this type of qualifier
ERROR: 0:34: 'local_size' : can only apply to 'in'
ERROR: 0:34: 'local_size' : can only apply to 'in'
ERROR: 0:34: 'local_size' : can only apply to 'in'
ERROR: 12 compilation errors. No code generated.
Shader version: 430 Shader version: 430
local_size = (2, 1, 4096)
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:3 Function Definition: main( (void) 0:15 Function Definition: main( (void)
0:3 Function Parameters: 0:15 Function Parameters:
0:5 Sequence 0:17 Sequence
0:5 MemoryBarrierAtomicCounter (void) 0:17 Barrier (void)
0:6 MemoryBarrierBuffer (void) 0:18 MemoryBarrier (void)
0:7 MemoryBarrierShared (void) 0:19 MemoryBarrierAtomicCounter (void)
0:8 MemoryBarrierImage (void) 0:20 MemoryBarrierBuffer (void)
0:9 GroupMemoryBarrier (void) 0:21 MemoryBarrierShared (void)
0:22 MemoryBarrierImage (void)
0:23 GroupMemoryBarrier (void)
0:? Linker Objects 0:? Linker Objects
0:? 'gl_WorkGroupSize' (const 3-component vector of uint)
0:? 2 (const uint)
0:? 1 (const uint)
0:? 4096 (const uint)
0:? 'total' (const int)
0:? 66592 (const int)
0:? 'v3' (layout(location=2 ) in 3-component vector of float) 0:? 'v3' (layout(location=2 ) in 3-component vector of float)
0:? 'f' (in float)
0:? 'fo' (out float)
0:? 's' (shared 4-component vector of float)
0:? 'sl' (layout(location=2 ) shared 4-component vector of float)
0:? 'fs' (shared float)
0:? 'arrX' (2-element array of int)
0:? 'arrY' (1-element array of int)
0:? 'arrZ' (4096-element array of int)
Linked compute stage: Linked compute stage:
Shader version: 430 Shader version: 430
local_size = (2, 1, 4096)
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:3 Function Definition: main( (void) 0:15 Function Definition: main( (void)
0:3 Function Parameters: 0:15 Function Parameters:
0:5 Sequence 0:17 Sequence
0:5 MemoryBarrierAtomicCounter (void) 0:17 Barrier (void)
0:6 MemoryBarrierBuffer (void) 0:18 MemoryBarrier (void)
0:7 MemoryBarrierShared (void) 0:19 MemoryBarrierAtomicCounter (void)
0:8 MemoryBarrierImage (void) 0:20 MemoryBarrierBuffer (void)
0:9 GroupMemoryBarrier (void) 0:21 MemoryBarrierShared (void)
0:22 MemoryBarrierImage (void)
0:23 GroupMemoryBarrier (void)
0:? Linker Objects 0:? Linker Objects
0:? 'gl_WorkGroupSize' (const 3-component vector of uint)
0:? 2 (const uint)
0:? 1 (const uint)
0:? 4096 (const uint)
0:? 'total' (const int)
0:? 66592 (const int)
0:? 'v3' (layout(location=2 ) in 3-component vector of float) 0:? 'v3' (layout(location=2 ) in 3-component vector of float)
0:? 'f' (in float)
0:? 'fo' (out float)
0:? 's' (shared 4-component vector of float)
0:? 'sl' (layout(location=2 ) shared 4-component vector of float)
0:? 'fs' (shared float)
0:? 'arrX' (2-element array of int)
0:? 'arrY' (1-element array of int)
0:? 'arrZ' (4096-element array of int)

View File

@ -44,7 +44,11 @@ ERROR: 0:92: 'transform feedback qualifier' : not supported for this version or
ERROR: 0:93: 'transform feedback qualifier' : not supported for this version or the enabled extensions ERROR: 0:93: 'transform feedback qualifier' : not supported for this version or the enabled extensions
ERROR: 0:93: 'transform feedback qualifier' : not supported for this version or the enabled extensions ERROR: 0:93: 'transform feedback qualifier' : not supported for this version or the enabled extensions
ERROR: 0:93: 'transform feedback qualifier' : not supported for this version or the enabled extensions ERROR: 0:93: 'transform feedback qualifier' : not supported for this version or the enabled extensions
ERROR: 44 compilation errors. No code generated. ERROR: 0:146: 'shared' : not supported in this stage: vertex
ERROR: 0:150: 'barrier' : no matching overloaded function found
ERROR: 0:154: 'memoryBarrierShared' : no matching overloaded function found
ERROR: 0:156: 'groupMemoryBarrier' : no matching overloaded function found
ERROR: 48 compilation errors. No code generated.
Shader version: 430 Shader version: 430
@ -70,6 +74,19 @@ ERROR: node is still EOpNull!
0:31 'v3' (volatile in 3-component vector of float) 0:31 'v3' (volatile in 3-component vector of float)
0:31 'v2' (in 2-component vector of float) 0:31 'v2' (in 2-component vector of float)
0:31 'cv3' (in 3-component vector of float) 0:31 'cv3' (in 3-component vector of float)
0:148 Function Definition: fooBarrier( (void)
0:148 Function Parameters:
0:150 Sequence
0:150 Constant:
0:150 0.000000
0:151 MemoryBarrier (void)
0:152 MemoryBarrierAtomicCounter (void)
0:153 MemoryBarrierBuffer (void)
0:154 Constant:
0:154 0.000000
0:155 MemoryBarrierImage (void)
0:156 Constant:
0:156 0.000000
0:? Linker Objects 0:? Linker Objects
0:? 'v4' (layout(location=3 ) 4-component vector of float) 0:? 'v4' (layout(location=3 ) 4-component vector of float)
0:? 'uv4' (layout(location=4 ) uniform 4-component vector of float) 0:? 'uv4' (layout(location=4 ) uniform 4-component vector of float)
@ -109,6 +126,7 @@ ERROR: node is still EOpNull!
0:? 'bh' (layout(xfb_buffer=1 xfb_offset=32 xfb_stride=80 ) smooth out 4-component vector of float) 0:? 'bh' (layout(xfb_buffer=1 xfb_offset=32 xfb_stride=80 ) smooth out 4-component vector of float)
0:? 'bbinst4' (layout(xfb_stride=80 ) out block{layout(xfb_buffer=1 xfb_offset=16 ) out 4-component vector of float bbv1}) 0:? 'bbinst4' (layout(xfb_stride=80 ) out block{layout(xfb_buffer=1 xfb_offset=16 ) out 4-component vector of float bbv1})
0:? 'bbinst5' (out block{layout(xfb_buffer=1 xfb_offset=0 ) out 4-component vector of float bbv1, layout(xfb_buffer=1 xfb_offset=64 xfb_stride=80 ) out 4-component vector of float bbv2}) 0:? 'bbinst5' (out block{layout(xfb_buffer=1 xfb_offset=0 ) out 4-component vector of float bbv1, layout(xfb_buffer=1 xfb_offset=64 xfb_stride=80 ) out 4-component vector of float bbv2})
0:? 'sharedv' (shared 4-component vector of float)
0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_VertexID' (gl_VertexId int)
0:? 'gl_InstanceID' (gl_InstanceId int) 0:? 'gl_InstanceID' (gl_InstanceId int)
@ -142,6 +160,19 @@ ERROR: node is still EOpNull!
0:31 'v3' (volatile in 3-component vector of float) 0:31 'v3' (volatile in 3-component vector of float)
0:31 'v2' (in 2-component vector of float) 0:31 'v2' (in 2-component vector of float)
0:31 'cv3' (in 3-component vector of float) 0:31 'cv3' (in 3-component vector of float)
0:148 Function Definition: fooBarrier( (void)
0:148 Function Parameters:
0:150 Sequence
0:150 Constant:
0:150 0.000000
0:151 MemoryBarrier (void)
0:152 MemoryBarrierAtomicCounter (void)
0:153 MemoryBarrierBuffer (void)
0:154 Constant:
0:154 0.000000
0:155 MemoryBarrierImage (void)
0:156 Constant:
0:156 0.000000
0:? Linker Objects 0:? Linker Objects
0:? 'v4' (layout(location=3 ) 4-component vector of float) 0:? 'v4' (layout(location=3 ) 4-component vector of float)
0:? 'uv4' (layout(location=4 ) uniform 4-component vector of float) 0:? 'uv4' (layout(location=4 ) uniform 4-component vector of float)
@ -181,6 +212,7 @@ ERROR: node is still EOpNull!
0:? 'bh' (layout(xfb_buffer=1 xfb_offset=32 xfb_stride=80 ) smooth out 4-component vector of float) 0:? 'bh' (layout(xfb_buffer=1 xfb_offset=32 xfb_stride=80 ) smooth out 4-component vector of float)
0:? 'bbinst4' (layout(xfb_stride=80 ) out block{layout(xfb_buffer=1 xfb_offset=16 ) out 4-component vector of float bbv1}) 0:? 'bbinst4' (layout(xfb_stride=80 ) out block{layout(xfb_buffer=1 xfb_offset=16 ) out 4-component vector of float bbv1})
0:? 'bbinst5' (out block{layout(xfb_buffer=1 xfb_offset=0 ) out 4-component vector of float bbv1, layout(xfb_buffer=1 xfb_offset=64 xfb_stride=80 ) out 4-component vector of float bbv2}) 0:? 'bbinst5' (out block{layout(xfb_buffer=1 xfb_offset=0 ) out 4-component vector of float bbv1, layout(xfb_buffer=1 xfb_offset=64 xfb_stride=80 ) out 4-component vector of float bbv2})
0:? 'sharedv' (shared 4-component vector of float)
0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_VertexID' (gl_VertexId int)
0:? 'gl_InstanceID' (gl_InstanceId int) 0:? 'gl_InstanceID' (gl_InstanceId int)

View File

@ -40,7 +40,6 @@ ERROR: 0:122: '' : memory qualifiers can only be used on image types
ERROR: 0:128: '' : memory qualifiers can only be used on image types ERROR: 0:128: '' : memory qualifiers can only be used on image types
ERROR: 0:129: '' : memory qualifiers can only be used on image types ERROR: 0:129: '' : memory qualifiers can only be used on image types
ERROR: 0:132: 'shared' : not supported in this stage: vertex ERROR: 0:132: 'shared' : not supported in this stage: vertex
ERROR: 0:132: '' : memory qualifiers can only be used on image types
ERROR: 0:134: '' : function does not return a value: funcA ERROR: 0:134: '' : function does not return a value: funcA
ERROR: 0:136: '' : function does not return a value: funcB ERROR: 0:136: '' : function does not return a value: funcB
ERROR: 0:153: '' : function does not return a value: func3 ERROR: 0:153: '' : function does not return a value: func3
@ -48,7 +47,7 @@ ERROR: 0:170: 'coherent' : argument cannot drop memory qualifier when passed to
ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array
ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array
ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array
ERROR: 46 compilation errors. No code generated. ERROR: 45 compilation errors. No code generated.
Shader version: 430 Shader version: 430

View File

@ -57,10 +57,9 @@ Link Validation
+ location match + location match
- block matching - block matching
- component/binding/index/offset match check - component/binding/index/offset match check
- compute shader layout(local_size_*) matching + compute shader layout(local_size_*) matching
+ mixed es/non-es profiles are an error + mixed es/non-es profiles are an error
- matching redeclarations of interface blocks - matching redeclarations of interface blocks
- 4.3: early_fragment_tests contradictions
- 4.3: implicit array sizing is cross shader within a stage - 4.3: implicit array sizing is cross shader within a stage
- 4.4: If gl_FragCoord is redeclared in any fragment shader in a program, it must be redeclared in all the fragment shaders in that program that have a static use gl_FragCoord - 4.4: If gl_FragCoord is redeclared in any fragment shader in a program, it must be redeclared in all the fragment shaders in that program that have a static use gl_FragCoord
@ -211,7 +210,7 @@ Shader Functionality to Implement/Finish
- Arrays of other objects (uniform blocks) containing implicitly sized arrays will have the same implicit size for all - Arrays of other objects (uniform blocks) containing implicitly sized arrays will have the same implicit size for all
elements of the array. elements of the array.
- Arrays of arrays are now supported, as per the GL_ARB_arrays_of_arrays extension. - Arrays of arrays are now supported, as per the GL_ARB_arrays_of_arrays extension.
- Compute shaders are now supported, as per the GL_ARB_compute_shader extension. + Compute shaders are now supported, as per the GL_ARB_compute_shader extension.
- Added imageSize() built-ins to query the dimensions of an image. - Added imageSize() built-ins to query the dimensions of an image.
- All choice of depth or stencil texturing, for a packed depth-stencil texture, as per the - All choice of depth or stencil texturing, for a packed depth-stencil texture, as per the
GL_ARB_stencil_texturing extension. GL_ARB_stencil_texturing extension.

View File

@ -69,6 +69,7 @@ enum TStorageQualifier {
EvqVaryingOut, // pipeline ouput, read/write EvqVaryingOut, // pipeline ouput, read/write
EvqUniform, // read only, shader with app EvqUniform, // read only, shader with app
EvqBuffer, // read only, shader with app EvqBuffer, // read only, shader with app
EvqShared, // compute shader's read/write 'shared' qualifier
// parameters // parameters
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
@ -109,6 +110,8 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
case EvqVaryingIn: return "in"; break; case EvqVaryingIn: return "in"; break;
case EvqVaryingOut: return "out"; break; case EvqVaryingOut: return "out"; break;
case EvqUniform: return "uniform"; break; case EvqUniform: return "uniform"; break;
case EvqBuffer: return "buffer"; break;
case EvqShared: return "shared"; break;
case EvqIn: return "in"; break; case EvqIn: return "in"; break;
case EvqOut: return "out"; break; case EvqOut: return "out"; break;
case EvqInOut: return "inout"; break; case EvqInOut: return "inout"; break;

View File

@ -342,7 +342,7 @@ public:
bool isMemory() const bool isMemory() const
{ {
return shared || coherent || volatil || restrict || readonly || writeonly; return coherent || volatil || restrict || readonly || writeonly;
} }
bool isInterpolation() const bool isInterpolation() const
{ {
@ -693,6 +693,7 @@ struct TShaderQualifiers {
TVertexSpacing spacing; TVertexSpacing spacing;
TVertexOrder order; TVertexOrder order;
bool pointMode; bool pointMode;
int localSize[3]; // compute shader
bool earlyFragmentTests; // fragment input bool earlyFragmentTests; // fragment input
void init() void init()
@ -705,6 +706,9 @@ struct TShaderQualifiers {
spacing = EvsNone; spacing = EvsNone;
order = EvoNone; order = EvoNone;
pointMode = false; pointMode = false;
localSize[0] = 1;
localSize[1] = 1;
localSize[2] = 1;
earlyFragmentTests = false; earlyFragmentTests = false;
} }
@ -728,6 +732,10 @@ struct TShaderQualifiers {
order = src.order; order = src.order;
if (src.pointMode) if (src.pointMode)
pointMode = true; pointMode = true;
for (int i = 0; i < 3; ++i) {
if (src.localSize[i] > 1)
localSize[i] = src.localSize[i];
}
if (src.earlyFragmentTests) if (src.earlyFragmentTests)
earlyFragmentTests = true; earlyFragmentTests = true;
} }

View File

@ -1079,14 +1079,14 @@ void TBuiltIns::initialize(int version, EProfile profile)
if (version >= 430) { if (version >= 430) {
stageBuiltins[EShLangCompute].append( stageBuiltins[EShLangCompute].append(
"in uvec3 gl_NumWorkGroups;" "in uvec3 gl_NumWorkGroups;"
// TODO: 4.3 functionality: compute shader: constant with no initializer "const uvec3 gl_WorkGroupSize;" "const uvec3 gl_WorkGroupSize = uvec3(1,1,1);"
"in uvec3 gl_WorkGroupID;" "in uvec3 gl_WorkGroupID;"
"in uvec3 gl_LocalInvocationID;" "in uvec3 gl_LocalInvocationID;"
"in uvec3 gl_GlobalInvocationID;" "in uvec3 gl_GlobalInvocationID;"
"in uint gl_LocalInvocationIndex;" "in uint gl_LocalInvocationIndex;"
"\n"); "\n");
} }

View File

@ -1969,6 +1969,8 @@ void TParseContext::globalQualifierCheck(TSourceLoc loc, const TQualifier& quali
break; break;
case EShLangCompute: case EShLangCompute:
if (! symbolTable.atBuiltInLevel())
error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
break; break;
default: default:
@ -2002,9 +2004,10 @@ void TParseContext::globalQualifierCheck(TSourceLoc loc, const TQualifier& quali
return; return;
} }
break; break;
case EShLangCompute: case EShLangCompute:
error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
break; break;
default: default:
@ -3178,6 +3181,18 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
break; break;
case EShLangCompute: case EShLangCompute:
if (id == "local_size_x") {
publicType.shaderQualifiers.localSize[0] = value;
return;
}
if (id == "local_size_y") {
publicType.shaderQualifiers.localSize[1] = value;
return;
}
if (id == "local_size_z") {
publicType.shaderQualifiers.localSize[2] = value;
return;
}
break; break;
default: default:
@ -3401,6 +3416,9 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type)
// if there are blocks, atomic counters, variables, etc. // if there are blocks, atomic counters, variables, etc.
void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& qualifier) void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& qualifier)
{ {
if (qualifier.storage == EvqShared && qualifier.hasLayout())
error(loc, "cannot apply layout qualifiers to a shared variable", "shared", "");
// "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)." // "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)."
if (qualifier.layoutComponent != TQualifier::layoutComponentEnd && qualifier.layoutLocation == TQualifier::layoutLocationEnd) if (qualifier.layoutComponent != TQualifier::layoutComponentEnd && qualifier.layoutLocation == TQualifier::layoutLocationEnd)
error(loc, "must specify 'location' to use 'component'", "component", ""); error(loc, "must specify 'location' to use 'component'", "component", "");
@ -3490,6 +3508,10 @@ void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TShaderQualifiers
else else
assert(0); assert(0);
} }
for (int i = 0; i < 3; ++i) {
if (shaderQualifiers.localSize[i] > 1)
error(loc, message, "local_size", "");
}
} }
// //
@ -4561,6 +4583,34 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
else else
error(loc, "can only apply to 'in'", "point_mode", ""); error(loc, "can only apply to 'in'", "point_mode", "");
} }
for (int i = 0; i < 3; ++i) {
if (publicType.shaderQualifiers.localSize[i] > 1) {
if (publicType.qualifier.storage == EvqVaryingIn) {
if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i]))
error(loc, "cannot change previously set size", "local_size", "");
else {
int max;
switch (i) {
case 0: max = resources.maxComputeWorkGroupSizeX; break;
case 1: max = resources.maxComputeWorkGroupSizeY; break;
case 2: max = resources.maxComputeWorkGroupSizeZ; break;
default: break;
}
if (intermediate.getLocalSize(i) > (unsigned int)max)
error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", "");
// Fix the existing constant gl_WorkGroupSize with this new information.
bool builtIn;
TSymbol* symbol = symbolTable.find("gl_WorkGroupSize", &builtIn);
if (builtIn)
makeEditable(symbol);
TVariable* workGroupSize = symbol->getAsVariable();
workGroupSize->getWritableConstArray()[i].setUConst(intermediate.getLocalSize(i));
}
} else
error(loc, "can only apply to 'in'", "local_size", "");
}
}
if (publicType.shaderQualifiers.earlyFragmentTests) { if (publicType.shaderQualifiers.earlyFragmentTests) {
if (publicType.qualifier.storage == EvqVaryingIn) if (publicType.qualifier.storage == EvqVaryingIn)
intermediate.setEarlyFragmentTests(); intermediate.setEarlyFragmentTests();

View File

@ -242,8 +242,7 @@ TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf)
if (! copyOf.unionArray.empty()) { if (! copyOf.unionArray.empty()) {
assert(! copyOf.type.isStruct()); assert(! copyOf.type.isStruct());
TConstUnionArray newArray(1); TConstUnionArray newArray(copyOf.unionArray, 0, copyOf.unionArray.size());
newArray[0] = copyOf.unionArray[0];
unionArray = newArray; unionArray = newArray;
} }
} }

View File

@ -154,6 +154,7 @@ public:
virtual TType& getWritableType() { assert(writable); return type; } virtual TType& getWritableType() { assert(writable); return type; }
virtual bool isUserType() const { return userType; } virtual bool isUserType() const { return userType; }
virtual const TConstUnionArray& getConstArray() const { return unionArray; } virtual const TConstUnionArray& getConstArray() const { return unionArray; }
virtual TConstUnionArray& getWritableConstArray() { assert(writable); return unionArray; }
virtual void setConstArray(const TConstUnionArray& constArray) { unionArray = constArray; } virtual void setConstArray(const TConstUnionArray& constArray) { unionArray = constArray; }
virtual void dump(TInfoSink &infoSink) const; virtual void dump(TInfoSink &infoSink) const;

View File

@ -1220,7 +1220,7 @@ storage_qualifier
parseContext.profileRequires($1.loc, ECoreProfile, 430, 0, "shared"); parseContext.profileRequires($1.loc, ECoreProfile, 430, 0, "shared");
parseContext.requireStage($1.loc, EShLangCompute, "shared"); parseContext.requireStage($1.loc, EShLangCompute, "shared");
$$.init($1.loc); $$.init($1.loc);
$$.qualifier.shared = true; $$.qualifier.storage = EvqShared;
} }
| COHERENT { | COHERENT {
$$.init($1.loc); $$.init($1.loc);

View File

@ -429,7 +429,7 @@ void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstU
case EbtFloat: case EbtFloat:
case EbtDouble: case EbtDouble:
{ {
const int maxSize = 300; const int maxSize = 300;
char buf[maxSize]; char buf[maxSize];
snprintf(buf, maxSize, "%f", constUnion[i].getDConst()); snprintf(buf, maxSize, "%f", constUnion[i].getDConst());
@ -438,7 +438,7 @@ void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstU
break; break;
case EbtInt: case EbtInt:
{ {
const int maxSize = 300; const int maxSize = 300;
char buf[maxSize]; char buf[maxSize];
snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int"); snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int");
@ -447,7 +447,7 @@ void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstU
break; break;
case EbtUint: case EbtUint:
{ {
const int maxSize = 300; const int maxSize = 300;
char buf[maxSize]; char buf[maxSize];
snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint"); snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint");
@ -616,9 +616,10 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
break; break;
case EShLangCompute: case EShLangCompute:
infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";
break; break;
default: default:
break; break;
} }

View File

@ -117,6 +117,13 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
if (unit.pointMode) if (unit.pointMode)
pointMode = true; pointMode = true;
for (int i = 0; i < 3; ++i) {
if (localSize[i] > 1)
localSize[i] = unit.localSize[i];
else if (localSize[i] != unit.localSize[i])
error(infoSink, "Contradictory local size");
}
if (unit.xfbMode) if (unit.xfbMode)
xfbMode = true; xfbMode = true;
for (size_t b = 0; b < xfbBuffers.size(); ++b) { for (size_t b = 0; b < xfbBuffers.size(); ++b) {

View File

@ -114,6 +114,9 @@ public:
invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), xfbMode(false) vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), xfbMode(false)
{ {
localSize[0] = 1;
localSize[1] = 1;
localSize[2] = 1;
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
} }
void setLimits(const TBuiltInResource& r) { resources = r; } void setLimits(const TBuiltInResource& r) { resources = r; }
@ -221,6 +224,16 @@ public:
TVertexOrder getVertexOrder() const { return vertexOrder; } TVertexOrder getVertexOrder() const { return vertexOrder; }
void setPointMode() { pointMode = true; } void setPointMode() { pointMode = true; }
bool getPointMode() const { return pointMode; } bool getPointMode() const { return pointMode; }
bool setLocalSize(int dim, int size)
{
if (localSize[dim] > 1)
return size == localSize[dim];
localSize[dim] = size;
return true;
}
unsigned int getLocalSize(int dim) const { return localSize[dim]; }
void setXfbMode() { xfbMode = true; } void setXfbMode() { xfbMode = true; }
bool getXfbMode() const { return xfbMode; } bool getXfbMode() const { return xfbMode; }
bool setOutputPrimitive(TLayoutGeometry p) bool setOutputPrimitive(TLayoutGeometry p)
@ -289,6 +302,7 @@ protected:
TVertexSpacing vertexSpacing; TVertexSpacing vertexSpacing;
TVertexOrder vertexOrder; TVertexOrder vertexOrder;
bool pointMode; bool pointMode;
int localSize[3];
bool earlyFragmentTests; bool earlyFragmentTests;
bool xfbMode; bool xfbMode;