From 79cddfcb564cfc75fcc7ad67402119470e401fff Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 11 Aug 2014 02:32:30 +0000 Subject: [PATCH] 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 --- Test/430.comp | 38 ++++++++++-- Test/430.vert | 13 +++++ Test/baseResults/300layout.vert.out | 3 +- Test/baseResults/430.comp.out | 81 ++++++++++++++++++++------ Test/baseResults/430.vert.out | 34 ++++++++++- Test/baseResults/specExamples.vert.out | 3 +- Todo.txt | 5 +- glslang/Include/BaseTypes.h | 3 + glslang/Include/Types.h | 10 +++- glslang/MachineIndependent/Initialize.cpp | 4 +- glslang/MachineIndependent/ParseHelper.cpp | 52 ++++++++++++++++- glslang/MachineIndependent/SymbolTable.cpp | 3 +- glslang/MachineIndependent/SymbolTable.h | 1 + glslang/MachineIndependent/glslang.y | 2 +- glslang/MachineIndependent/intermOut.cpp | 9 +-- glslang/MachineIndependent/linkValidate.cpp | 7 +++ glslang/MachineIndependent/localintermediate.h | 14 +++++ 17 files changed, 239 insertions(+), 43 deletions(-) diff --git a/Test/430.comp b/Test/430.comp index 7905454..13a812d 100644 --- a/Test/430.comp +++ b/Test/430.comp @@ -1,12 +1,38 @@ #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() { - memoryBarrierAtomicCounter(); - memoryBarrierBuffer(); - memoryBarrierShared(); - memoryBarrierImage(); - groupMemoryBarrier(); + barrier(); + memoryBarrier(); + memoryBarrierAtomicCounter(); + memoryBarrierBuffer(); + 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]; diff --git a/Test/430.vert b/Test/430.vert index 145aabf..399a895 100644 --- a/Test/430.vert +++ b/Test/430.vert @@ -142,3 +142,16 @@ out bblck5 { layout(xfb_offset=0) vec4 bbv1; layout(xfb_stride=80, xfb_buffer=1, xfb_offset=64) vec4 bbv2; } bbinst5; + +shared vec4 sharedv; + +void fooBarrier() +{ + barrier(); // ERROR + memoryBarrier(); + memoryBarrierAtomicCounter(); + memoryBarrierBuffer(); + memoryBarrierShared(); // ERROR + memoryBarrierImage(); + groupMemoryBarrier(); // ERROR +} diff --git a/Test/baseResults/300layout.vert.out b/Test/baseResults/300layout.vert.out index f954252..52de07b 100644 --- a/Test/baseResults/300layout.vert.out +++ b/Test/baseResults/300layout.vert.out @@ -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:50: 'shared' : not supported with this profile: es 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:57: 'location' : overlapping use of location 40 -ERROR: 19 compilation errors. No code generated. +ERROR: 18 compilation errors. No code generated. Shader version: 300 diff --git a/Test/baseResults/430.comp.out b/Test/baseResults/430.comp.out index d8f981a..4e3f8fd 100644 --- a/Test/baseResults/430.comp.out +++ b/Test/baseResults/430.comp.out @@ -1,36 +1,81 @@ 430.comp 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: 1 compilation errors. No code generated. +ERROR: 0:4: 'local_size' : cannot change previously set size +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 +local_size = (2, 1, 4096) ERROR: node is still EOpNull! -0:3 Function Definition: main( (void) -0:3 Function Parameters: -0:5 Sequence -0:5 MemoryBarrierAtomicCounter (void) -0:6 MemoryBarrierBuffer (void) -0:7 MemoryBarrierShared (void) -0:8 MemoryBarrierImage (void) -0:9 GroupMemoryBarrier (void) +0:15 Function Definition: main( (void) +0:15 Function Parameters: +0:17 Sequence +0:17 Barrier (void) +0:18 MemoryBarrier (void) +0:19 MemoryBarrierAtomicCounter (void) +0:20 MemoryBarrierBuffer (void) +0:21 MemoryBarrierShared (void) +0:22 MemoryBarrierImage (void) +0:23 GroupMemoryBarrier (void) 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:? '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: Shader version: 430 +local_size = (2, 1, 4096) ERROR: node is still EOpNull! -0:3 Function Definition: main( (void) -0:3 Function Parameters: -0:5 Sequence -0:5 MemoryBarrierAtomicCounter (void) -0:6 MemoryBarrierBuffer (void) -0:7 MemoryBarrierShared (void) -0:8 MemoryBarrierImage (void) -0:9 GroupMemoryBarrier (void) +0:15 Function Definition: main( (void) +0:15 Function Parameters: +0:17 Sequence +0:17 Barrier (void) +0:18 MemoryBarrier (void) +0:19 MemoryBarrierAtomicCounter (void) +0:20 MemoryBarrierBuffer (void) +0:21 MemoryBarrierShared (void) +0:22 MemoryBarrierImage (void) +0:23 GroupMemoryBarrier (void) 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:? '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) diff --git a/Test/baseResults/430.vert.out b/Test/baseResults/430.vert.out index 641bab2..4e8b1ef 100644 --- a/Test/baseResults/430.vert.out +++ b/Test/baseResults/430.vert.out @@ -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: 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 @@ -70,6 +74,19 @@ ERROR: node is still EOpNull! 0:31 'v3' (volatile in 3-component vector of float) 0:31 'v2' (in 2-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:? 'v4' (layout(location=3 ) 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:? '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:? 'sharedv' (shared 4-component vector of float) 0:? 'gl_VertexID' (gl_VertexId 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 'v2' (in 2-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:? 'v4' (layout(location=3 ) 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:? '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:? 'sharedv' (shared 4-component vector of float) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) diff --git a/Test/baseResults/specExamples.vert.out b/Test/baseResults/specExamples.vert.out index 3b20d8f..9d02d02 100644 --- a/Test/baseResults/specExamples.vert.out +++ b/Test/baseResults/specExamples.vert.out @@ -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:129: '' : memory qualifiers can only be used on image types 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:136: '' : function does not return a value: funcB 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:193: '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 diff --git a/Todo.txt b/Todo.txt index c4e1a70..1a6095c 100644 --- a/Todo.txt +++ b/Todo.txt @@ -57,10 +57,9 @@ Link Validation + location match - block matching - 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 - matching redeclarations of interface blocks - - 4.3: early_fragment_tests contradictions - 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 @@ -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 elements of the array. - 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. - All choice of depth or stencil texturing, for a packed depth-stencil texture, as per the GL_ARB_stencil_texturing extension. diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h index 1690df8..5b9b2f5 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -69,6 +69,7 @@ enum TStorageQualifier { EvqVaryingOut, // pipeline ouput, read/write EvqUniform, // read only, shader with app EvqBuffer, // read only, shader with app + EvqShared, // compute shader's read/write 'shared' qualifier // parameters 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 EvqVaryingOut: return "out"; break; case EvqUniform: return "uniform"; break; + case EvqBuffer: return "buffer"; break; + case EvqShared: return "shared"; break; case EvqIn: return "in"; break; case EvqOut: return "out"; break; case EvqInOut: return "inout"; break; diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index ef1dcd9..4d5c354 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -342,7 +342,7 @@ public: bool isMemory() const { - return shared || coherent || volatil || restrict || readonly || writeonly; + return coherent || volatil || restrict || readonly || writeonly; } bool isInterpolation() const { @@ -693,6 +693,7 @@ struct TShaderQualifiers { TVertexSpacing spacing; TVertexOrder order; bool pointMode; + int localSize[3]; // compute shader bool earlyFragmentTests; // fragment input void init() @@ -705,6 +706,9 @@ struct TShaderQualifiers { spacing = EvsNone; order = EvoNone; pointMode = false; + localSize[0] = 1; + localSize[1] = 1; + localSize[2] = 1; earlyFragmentTests = false; } @@ -728,6 +732,10 @@ struct TShaderQualifiers { order = src.order; if (src.pointMode) pointMode = true; + for (int i = 0; i < 3; ++i) { + if (src.localSize[i] > 1) + localSize[i] = src.localSize[i]; + } if (src.earlyFragmentTests) earlyFragmentTests = true; } diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 4ea7c96..d2b849b 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -1079,14 +1079,14 @@ void TBuiltIns::initialize(int version, EProfile profile) if (version >= 430) { stageBuiltins[EShLangCompute].append( "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_LocalInvocationID;" "in uvec3 gl_GlobalInvocationID;" "in uint gl_LocalInvocationIndex;" - + "\n"); } diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 6187402..4da9aa7 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -1969,6 +1969,8 @@ void TParseContext::globalQualifierCheck(TSourceLoc loc, const TQualifier& quali break; case EShLangCompute: + if (! symbolTable.atBuiltInLevel()) + error(loc, "global storage input qualifier cannot be used in a compute shader", "in", ""); break; default: @@ -2002,9 +2004,10 @@ void TParseContext::globalQualifierCheck(TSourceLoc loc, const TQualifier& quali return; } - break; + break; case EShLangCompute: + error(loc, "global storage output qualifier cannot be used in a compute shader", "out", ""); break; default: @@ -3178,6 +3181,18 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, break; 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; default: @@ -3401,6 +3416,9 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type) // if there are blocks, atomic counters, variables, etc. 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)." if (qualifier.layoutComponent != TQualifier::layoutComponentEnd && qualifier.layoutLocation == TQualifier::layoutLocationEnd) error(loc, "must specify 'location' to use 'component'", "component", ""); @@ -3490,6 +3508,10 @@ void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TShaderQualifiers else 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 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.qualifier.storage == EvqVaryingIn) intermediate.setEarlyFragmentTests(); diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index 9a2f3b2..6309b34 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -242,8 +242,7 @@ TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf) if (! copyOf.unionArray.empty()) { assert(! copyOf.type.isStruct()); - TConstUnionArray newArray(1); - newArray[0] = copyOf.unionArray[0]; + TConstUnionArray newArray(copyOf.unionArray, 0, copyOf.unionArray.size()); unionArray = newArray; } } diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index afc8a2c..c08569a 100644 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -154,6 +154,7 @@ public: virtual TType& getWritableType() { assert(writable); return type; } virtual bool isUserType() const { return userType; } virtual const TConstUnionArray& getConstArray() const { return unionArray; } + virtual TConstUnionArray& getWritableConstArray() { assert(writable); return unionArray; } virtual void setConstArray(const TConstUnionArray& constArray) { unionArray = constArray; } virtual void dump(TInfoSink &infoSink) const; diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index 912bd03..bc9ac87 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -1220,7 +1220,7 @@ storage_qualifier parseContext.profileRequires($1.loc, ECoreProfile, 430, 0, "shared"); parseContext.requireStage($1.loc, EShLangCompute, "shared"); $$.init($1.loc); - $$.qualifier.shared = true; + $$.qualifier.storage = EvqShared; } | COHERENT { $$.init($1.loc); diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index 8cc62f7..955f31a 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -429,7 +429,7 @@ void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstU case EbtFloat: case EbtDouble: { - const int maxSize = 300; + const int maxSize = 300; char buf[maxSize]; snprintf(buf, maxSize, "%f", constUnion[i].getDConst()); @@ -438,7 +438,7 @@ void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstU break; case EbtInt: { - const int maxSize = 300; + const int maxSize = 300; char buf[maxSize]; snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int"); @@ -447,7 +447,7 @@ void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstU break; case EbtUint: { - const int maxSize = 300; + const int maxSize = 300; char buf[maxSize]; snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint"); @@ -616,9 +616,10 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) break; case EShLangCompute: + infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n"; break; - default: + default: break; } diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index b53bc31..1c4d5b8 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -117,6 +117,13 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) if (unit.pointMode) 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) xfbMode = true; for (size_t b = 0; b < xfbBuffers.size(); ++b) { diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 00d7ba2..463aa86 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -114,6 +114,9 @@ public: invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), xfbMode(false) { + localSize[0] = 1; + localSize[1] = 1; + localSize[2] = 1; xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); } void setLimits(const TBuiltInResource& r) { resources = r; } @@ -221,6 +224,16 @@ public: TVertexOrder getVertexOrder() const { return vertexOrder; } void setPointMode() { pointMode = true; } 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; } bool getXfbMode() const { return xfbMode; } bool setOutputPrimitive(TLayoutGeometry p) @@ -289,6 +302,7 @@ protected: TVertexSpacing vertexSpacing; TVertexOrder vertexOrder; bool pointMode; + int localSize[3]; bool earlyFragmentTests; bool xfbMode; -- 2.7.4