From 265f5fb80e76371d8bf2c886e6b3b19e506d8a3b Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Wed, 13 Aug 2014 01:04:28 +0000 Subject: [PATCH] Finish virtually all of the remaining atomic counter functionality. Still need offset collision detection. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27712 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/310.comp | 11 ++++++ Test/420.vert | 4 +++ Test/atomic_uint.frag | 18 ++++++++++ Test/baseResults/310.comp.out | 35 ++++++++++++++++++- Test/baseResults/420.vert.out | 5 ++- Test/baseResults/430.vert.out | 6 ++-- Test/baseResults/atomic_uint.frag.out | 50 ++++++++++++++++++++++++++- Test/baseResults/specExamples.vert.out | 14 ++++---- Test/specExamples.vert | 2 +- glslang/Include/Types.h | 1 + glslang/MachineIndependent/Initialize.cpp | 52 ++++++++++++++++++++--------- glslang/MachineIndependent/Intermediate.cpp | 1 + glslang/MachineIndependent/ParseHelper.cpp | 21 ++++++++---- glslang/MachineIndependent/Scan.cpp | 3 +- glslang/MachineIndependent/Versions.cpp | 4 ++- glslang/MachineIndependent/Versions.h | 1 + 16 files changed, 191 insertions(+), 37 deletions(-) diff --git a/Test/310.comp b/Test/310.comp index 2f172fe..345224f 100644 --- a/Test/310.comp +++ b/Test/310.comp @@ -139,3 +139,14 @@ void mainAC() } layout(binding = 1) uniform mediump atomic_uint counterBad; // ERROR, not highp + +layout(binding = 2, offset = 4) uniform atomic_uint countArr[4]; +uniform int i; + +void opac() +{ + int a[3]; + a[counter]; // ERROR + countArr[2]; + countArr[i]; +} diff --git a/Test/420.vert b/Test/420.vert index 93a9874..7e61207 100644 --- a/Test/420.vert +++ b/Test/420.vert @@ -142,3 +142,7 @@ 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 + +uniform offcheck { + layout(offset = 16) int foo; // ERROR +} offcheckI; diff --git a/Test/atomic_uint.frag b/Test/atomic_uint.frag index a837150..43ef0c9 100644 --- a/Test/atomic_uint.frag +++ b/Test/atomic_uint.frag @@ -19,3 +19,21 @@ void main() uint val = atomicCounter(counter); atomicCounterDecrement(counter); } + +layout(binding = 1, offset = 3) uniform atomic_uint countArr[4]; +uniform int i; + +void opac() +{ + counter + counter; // ERROR + -counter; // ERROR + int a[3]; + a[counter]; // ERROR + countArr[2]; + countArr[i]; + counter = 4; // ERROR +} + +in atomic_uint acin; // ERROR +atomic_uint acg; // ERROR + diff --git a/Test/baseResults/310.comp.out b/Test/baseResults/310.comp.out index e45336c..9f7040d 100644 --- a/Test/baseResults/310.comp.out +++ b/Test/baseResults/310.comp.out @@ -39,7 +39,10 @@ ERROR: 0:128: 'atomic_uint' : samplers and atomic_uints cannot be output paramet ERROR: 0:130: 'return' : type does not match, or is not convertible to, the function's return type ERROR: 0:136: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: non_uniform_counter ERROR: 0:141: 'atomic_uint' : atomic counters can only be highp -ERROR: 39 compilation errors. No code generated. +ERROR: 0:141: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings +ERROR: 0:143: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings +ERROR: 0:149: '[]' : scalar integer expression required +ERROR: 42 compilation errors. No code generated. Shader version: 310 @@ -171,6 +174,19 @@ ERROR: node is still EOpNull! 0:137 'counter' (layout(binding=0 ) uniform highp atomic_uint) 0:138 Function Call: atomicCounterDecrement(au1; (highp uint) 0:138 'counter' (layout(binding=0 ) uniform highp atomic_uint) +0:146 Function Definition: opac( (void) +0:146 Function Parameters: +0:? Sequence +0:149 indirect index (highp int) +0:149 'a' (3-element array of highp int) +0:149 'counter' (layout(binding=0 ) uniform highp atomic_uint) +0:150 direct index (layout(binding=2 offset=4 ) highp atomic_uint) +0:150 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) +0:150 Constant: +0:150 2 (const int) +0:151 indirect index (layout(binding=2 offset=4 ) highp atomic_uint) +0:151 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) +0:151 'i' (uniform highp int) 0:? Linker Objects 0:? 'gl_WorkGroupSize' (const highp 3-component vector of uint) 0:? 2 (const uint) @@ -211,6 +227,8 @@ ERROR: node is still EOpNull! 0:? 'i6bad' (layout(r8ui ) uniform highp iimage2D) 0:? 'counter' (layout(binding=0 ) uniform highp atomic_uint) 0:? 'counterBad' (layout(binding=1 ) uniform mediump atomic_uint) +0:? 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) +0:? 'i' (uniform highp int) Linked compute stage: @@ -345,6 +363,19 @@ ERROR: node is still EOpNull! 0:137 'counter' (layout(binding=0 ) uniform highp atomic_uint) 0:138 Function Call: atomicCounterDecrement(au1; (highp uint) 0:138 'counter' (layout(binding=0 ) uniform highp atomic_uint) +0:146 Function Definition: opac( (void) +0:146 Function Parameters: +0:? Sequence +0:149 indirect index (highp int) +0:149 'a' (3-element array of highp int) +0:149 'counter' (layout(binding=0 ) uniform highp atomic_uint) +0:150 direct index (layout(binding=2 offset=4 ) highp atomic_uint) +0:150 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) +0:150 Constant: +0:150 2 (const int) +0:151 indirect index (layout(binding=2 offset=4 ) highp atomic_uint) +0:151 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) +0:151 'i' (uniform highp int) 0:? Linker Objects 0:? 'gl_WorkGroupSize' (const highp 3-component vector of uint) 0:? 2 (const uint) @@ -385,4 +416,6 @@ ERROR: node is still EOpNull! 0:? 'i6bad' (layout(r8ui ) uniform highp iimage2D) 0:? 'counter' (layout(binding=0 ) uniform highp atomic_uint) 0:? 'counterBad' (layout(binding=1 ) uniform mediump atomic_uint) +0:? 'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint) +0:? 'i' (uniform highp int) diff --git a/Test/baseResults/420.vert.out b/Test/baseResults/420.vert.out index 2d8bf8b..ca3c81e 100644 --- a/Test/baseResults/420.vert.out +++ b/Test/baseResults/420.vert.out @@ -47,7 +47,8 @@ ERROR: 0:141: 'rgba32f' : does not apply to unsigned integer images ERROR: 0:142: 'r8_snorm' : does not apply to signed integer images ERROR: 0:143: 'rgba32ui' : does not apply to signed integer images ERROR: 0:144: 'r8ui' : does not apply to signed integer images -ERROR: 46 compilation errors. No code generated. +ERROR: 0:147: 'offset on block member' : not supported for this version or the enabled extensions +ERROR: 47 compilation errors. No code generated. Shader version: 420 @@ -287,6 +288,7 @@ ERROR: node is still EOpNull! 0:? 'i4bad' (layout(r8_snorm ) uniform iimage2D) 0:? 'i5bad' (layout(rgba32ui ) uniform iimage2D) 0:? 'i6bad' (layout(r8ui ) uniform iimage2D) +0:? 'offcheckI' (layout(column_major shared ) uniform block{layout(column_major shared offset=16 ) uniform int foo}) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) @@ -531,6 +533,7 @@ ERROR: node is still EOpNull! 0:? 'i4bad' (layout(r8_snorm ) uniform iimage2D) 0:? 'i5bad' (layout(rgba32ui ) uniform iimage2D) 0:? 'i6bad' (layout(r8ui ) uniform iimage2D) +0:? 'offcheckI' (layout(column_major shared ) uniform block{layout(column_major shared offset=16 ) uniform int foo}) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) diff --git a/Test/baseResults/430.vert.out b/Test/baseResults/430.vert.out index de38acb..b087e34 100644 --- a/Test/baseResults/430.vert.out +++ b/Test/baseResults/430.vert.out @@ -21,12 +21,12 @@ ERROR: 0:58: 'location on block member' : not supported for this version or the ERROR: 0:59: 'location on block member' : not supported for this version or the enabled extensions ERROR: 0:62: 'uniform buffer-member align' : not supported for this version or the enabled extensions ERROR: 0:64: 'uniform buffer-member align' : not supported for this version or the enabled extensions -ERROR: 0:65: 'uniform buffer-member offset' : not supported for this version or the enabled extensions ERROR: 0:65: 'uniform buffer-member align' : not supported for this version or the enabled extensions -ERROR: 0:66: 'uniform buffer-member offset' : not supported for this version or the enabled extensions +ERROR: 0:65: 'offset on block member' : not supported for this version or the enabled extensions +ERROR: 0:66: 'offset on block member' : not supported for this version or the enabled extensions ERROR: 0:64: 'offset/align' : can only be used with std140 or std430 layout packing ERROR: 0:65: 'align' : can only be used with std140 or std430 layout packing -ERROR: 0:71: 'uniform buffer-member offset' : not supported for this version or the enabled extensions +ERROR: 0:71: 'offset on block member' : not supported for this version or the enabled extensions ERROR: 0:74: 'gl_MaxTransformFeedbackBuffers' : required extension not requested: GL_ARB_enhanced_layouts ERROR: 0:75: 'gl_MaxTransformFeedbackInterleavedComponents' : required extension not requested: GL_ARB_enhanced_layouts ERROR: 0:78: 'transform feedback qualifier' : not supported for this version or the enabled extensions diff --git a/Test/baseResults/atomic_uint.frag.out b/Test/baseResults/atomic_uint.frag.out index 248df2e..71d413d 100644 --- a/Test/baseResults/atomic_uint.frag.out +++ b/Test/baseResults/atomic_uint.frag.out @@ -3,7 +3,15 @@ Warning, version 420 is not yet complete; most version-specific features are pre 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: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: 0:23: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings +ERROR: 0:28: '+' : wrong operand types: no operation '+' exists that takes a left-hand operand of type 'layout(binding=0 ) uniform atomic_uint' and a right operand of type 'layout(binding=0 ) uniform atomic_uint' (or there is no acceptable conversion) +ERROR: 0:29: '-' : wrong operand type no operation '-' exists that takes an operand of type layout(binding=0 ) uniform atomic_uint (or there is no acceptable conversion) +ERROR: 0:31: '[]' : scalar integer expression required +ERROR: 0:34: 'assign' : l-value required "counter" (can't modify a uniform) +ERROR: 0:34: 'assign' : cannot convert from 'const int' to 'layout(binding=0 ) uniform atomic_uint' +ERROR: 0:37: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: acin +ERROR: 0:38: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: acg +ERROR: 11 compilation errors. No code generated. Shader version: 420 @@ -34,8 +42,28 @@ ERROR: node is still EOpNull! 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:26 Function Definition: opac( (void) +0:26 Function Parameters: +0:28 Sequence +0:28 'counter' (layout(binding=0 ) uniform atomic_uint) +0:29 'counter' (layout(binding=0 ) uniform atomic_uint) +0:31 indirect index (int) +0:31 'a' (3-element array of int) +0:31 'counter' (layout(binding=0 ) uniform atomic_uint) +0:32 direct index (layout(binding=1 offset=3 ) atomic_uint) +0:32 'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint) +0:32 Constant: +0:32 2 (const int) +0:33 indirect index (layout(binding=1 offset=3 ) atomic_uint) +0:33 'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint) +0:33 'i' (uniform int) +0:34 'counter' (layout(binding=0 ) uniform atomic_uint) 0:? Linker Objects 0:? 'counter' (layout(binding=0 ) uniform atomic_uint) +0:? 'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint) +0:? 'i' (uniform int) +0:? 'acin' (smooth in atomic_uint) +0:? 'acg' (atomic_uint) Linked fragment stage: @@ -69,6 +97,26 @@ ERROR: node is still EOpNull! 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:26 Function Definition: opac( (void) +0:26 Function Parameters: +0:28 Sequence +0:28 'counter' (layout(binding=0 ) uniform atomic_uint) +0:29 'counter' (layout(binding=0 ) uniform atomic_uint) +0:31 indirect index (int) +0:31 'a' (3-element array of int) +0:31 'counter' (layout(binding=0 ) uniform atomic_uint) +0:32 direct index (layout(binding=1 offset=3 ) atomic_uint) +0:32 'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint) +0:32 Constant: +0:32 2 (const int) +0:33 indirect index (layout(binding=1 offset=3 ) atomic_uint) +0:33 'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint) +0:33 'i' (uniform int) +0:34 'counter' (layout(binding=0 ) uniform atomic_uint) 0:? Linker Objects 0:? 'counter' (layout(binding=0 ) uniform atomic_uint) +0:? 'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint) +0:? 'i' (uniform int) +0:? 'acin' (smooth in atomic_uint) +0:? 'acg' (atomic_uint) diff --git a/Test/baseResults/specExamples.vert.out b/Test/baseResults/specExamples.vert.out index 551c9de..3189787 100644 --- a/Test/baseResults/specExamples.vert.out +++ b/Test/baseResults/specExamples.vert.out @@ -17,15 +17,15 @@ ERROR: 0:47: 'stream' : there is no such layout identifier for this stage taking ERROR: 0:50: 'stream' : there is no such layout identifier for this stage taking an assigned value ERROR: 0:55: 'stream' : there is no such layout identifier for this stage taking an assigned value ERROR: 0:80: 's17' : redefinition -ERROR: 0:85: 'uniform buffer-member offset' : not supported for this version or the enabled extensions -ERROR: 0:85: 'offset' : cannot specify on a variable declaration -ERROR: 0:89: 'uniform buffer-member offset' : not supported for this version or the enabled extensions +ERROR: 0:85: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings +ERROR: 0:87: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings WARNING: 0:89: 'layout' : useless application of layout qualifier ERROR: 0:91: 'bar' : redefinition -ERROR: 0:92: 'uniform buffer-member offset' : not supported for this version or the enabled extensions -ERROR: 0:92: 'bar' : redefinition -ERROR: 0:94: 'uniform buffer-member offset' : not supported for this version or the enabled extensions +ERROR: 0:92: 'offset' : a binding is required ERROR: 0:94: 'a2' : redefinition +ERROR: 0:95: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings +ERROR: 0:96: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings +ERROR: 0:97: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings ERROR: 0:106: '' : vertex input cannot be further qualified ERROR: 0:106: 'redeclaration' : cannot change storage, memory, or auxiliary qualification of gl_FrontColor ERROR: 0:112: 'ColorIvn' : identifier not previously declared @@ -291,6 +291,7 @@ ERROR: node is still EOpNull! 0:? 's17' (layout(binding=3 ) uniform sampler2D) 0:? 'a2' (layout(binding=2 offset=4 ) uniform atomic_uint) 0:? 'bar' (layout(binding=2 ) uniform atomic_uint) +0:? 'bar23' (layout(offset=8 ) uniform atomic_uint) 0:? 'b2' (layout(binding=2 ) uniform atomic_uint) 0:? 'c2' (layout(binding=3 ) uniform atomic_uint) 0:? 'd2' (layout(binding=2 ) uniform atomic_uint) @@ -567,6 +568,7 @@ ERROR: node is still EOpNull! 0:? 's17' (layout(binding=3 ) uniform sampler2D) 0:? 'a2' (layout(binding=2 offset=4 ) uniform atomic_uint) 0:? 'bar' (layout(binding=2 ) uniform atomic_uint) +0:? 'bar23' (layout(offset=8 ) uniform atomic_uint) 0:? 'b2' (layout(binding=2 ) uniform atomic_uint) 0:? 'c2' (layout(binding=3 ) uniform atomic_uint) 0:? 'd2' (layout(binding=2 ) uniform atomic_uint) diff --git a/Test/specExamples.vert b/Test/specExamples.vert index 628f746..a9c9178 100644 --- a/Test/specExamples.vert +++ b/Test/specExamples.vert @@ -89,7 +89,7 @@ layout (binding = 2) uniform atomic_uint bar; layout (binding = 2, offset = 4) uniform atomic_uint; layout (binding = 2) uniform atomic_uint bar; // offset is 4 -layout (offset = 8) uniform atomic_uint bar; // error, no default binding +layout (offset = 8) uniform atomic_uint bar23; // error, no default binding layout (binding=3, offset=4) uniform atomic_uint a2; // offset = 4 layout (binding=2) uniform atomic_uint b2; // offset = 0 diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 40c6b45..7bf06a4 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -523,6 +523,7 @@ public: return hasMatrix() || hasPacking() || hasOffset() || + hasBinding() || hasAlign(); } bool hasMatrix() const diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 42e5c7f..dcd11b8 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -743,7 +743,7 @@ void TBuiltIns::initialize(int version, EProfile profile) // // Atomic counter functions. // - if ((profile != EEsProfile && version >= 420) || + if ((profile != EEsProfile && version >= 300) || (profile == EEsProfile && version >= 310)) { commonBuiltins.append( "uint atomicCounterIncrement(atomic_uint x);" @@ -2205,24 +2205,37 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf } } - // 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.); + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources. maxVertexAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounters = %d;", resources. maxFragmentAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounters = %d;", resources. maxCombinedAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBindings = %d;", resources. maxAtomicCounterBindings); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounterBuffers = %d;", resources. maxVertexAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounterBuffers = %d;", resources. maxFragmentAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounterBuffers = %d;", resources. maxCombinedAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBufferSize = %d;", resources. maxAtomicCounterBufferSize); + s.append(builtInConstant); } 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.); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources. maxTessControlAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources. maxTessEvaluationAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources. maxGeometryAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources. maxTessControlAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources. maxTessEvaluationAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources. maxGeometryAtomicCounterBuffers); + s.append(builtInConstant); } @@ -2363,6 +2376,13 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb 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. + // GL_ARB_shader_atomic_counters + if (profile != EEsProfile && version < 420) { + symbolTable.setFunctionExtensions("atomicCounterIncrement", 1, &GL_ARB_shader_atomic_counters); + symbolTable.setFunctionExtensions("atomicCounterDecrement", 1, &GL_ARB_shader_atomic_counters); + symbolTable.setFunctionExtensions("atomicCounter" , 1, &GL_ARB_shader_atomic_counters); + } + symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &GL_EXT_frag_depth); break; diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index c3c06d4..cf4265f 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -386,6 +386,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt switch (node->getBasicType()) { case EbtVoid: return 0; + case EbtAtomicUint: case EbtSampler: if (op != EOpFunctionCall) return 0; diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index df0f34a..13681d9 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -3118,9 +3118,10 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, std::transform(id.begin(), id.end(), id.begin(), ::tolower); if (id == "offset") { - const char* feature = "uniform buffer-member offset"; + const char* feature = "uniform offset"; requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature); + const char* exts[2] = { GL_ARB_enhanced_layouts, GL_ARB_shader_atomic_counters }; + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 2, exts, feature); profileRequires(loc, EEsProfile, 310, 0, feature); publicType.qualifier.layoutOffset = value; return; @@ -3342,8 +3343,12 @@ void TParseContext::layoutObjectCheck(TSourceLoc loc, const TSymbol& symbol) if (qualifier.hasPacking()) error(loc, "cannot specify packing on a variable declaration", "layout", ""); // "The offset qualifier can only be used on block members of blocks..." - if (qualifier.hasOffset()) + if (qualifier.hasOffset() && type.getBasicType() != EbtAtomicUint) error(loc, "cannot specify on a variable declaration", "offset", ""); + if (qualifier.hasOffset() && ! qualifier.hasBinding() && type.getBasicType() == EbtAtomicUint) + error(loc, "a binding is required", "offset", ""); + if (qualifier.hasBinding() && qualifier.layoutBinding >= resources.maxAtomicCounterBindings && type.getBasicType() == EbtAtomicUint) + error(loc, "cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings", "binding", ""); // "The align qualifier can only be used on blocks or block members..." if (qualifier.hasAlign()) error(loc, "cannot specify on a variable declaration", "align", ""); @@ -3356,7 +3361,7 @@ void TParseContext::layoutObjectCheck(TSourceLoc loc, const TSymbol& symbol) } } -// Do error layout error checking with respect to a type. +// Do layout error checking with respect to a type. void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type) { const TQualifier& qualifier = type.getQualifier(); @@ -3440,10 +3445,10 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type) } } - // "The offset qualifier can only be used on block members of blocks..." + // "The offset qualifier can only be used on block members of blocks..." if (qualifier.hasOffset()) { if (type.getBasicType() == EbtBlock) - error(loc, "only applies to block members, not blocks", "offset", ""); + error(loc, "only applies to block members, not blocks", "offset", ""); } // Image format @@ -4221,6 +4226,10 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr 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"); + if (memberQualifier.hasOffset()) { + requireProfile(memberLoc, ~EEsProfile, "offset on block member"); + profileRequires(memberLoc, ~EEsProfile, 440, GL_ARB_enhanced_layouts, "offset on block member"); + } TBasicType basicType = memberType.getBasicType(); if (basicType == EbtSampler) diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp index 1a459ba..1a92e3e 100644 --- a/glslang/MachineIndependent/Scan.cpp +++ b/glslang/MachineIndependent/Scan.cpp @@ -674,7 +674,8 @@ int TScanContext::tokenizeIdentifier() return keyword; case ATOMIC_UINT: - if (parseContext.profile == EEsProfile && parseContext.version >= 310) + if (parseContext.profile == EEsProfile && parseContext.version >= 310 || + parseContext.extensionsTurnedOn(1, &GL_ARB_shader_atomic_counters)) return keyword; else return es30ReservedFromGLSL(420); diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index feb233a..0562bdd 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -167,6 +167,7 @@ void TParseContext::initializeExtensionBehavior() extensionBehavior[GL_ARB_shader_texture_lod] = EBhDisable; extensionBehavior[GL_ARB_explicit_attrib_location] = EBhDisablePartial; // "index" for fragment outputs is missing extensionBehavior[GL_ARB_shader_image_load_store] = EBhDisable; + extensionBehavior[GL_ARB_shader_atomic_counters] = EBhDisable; } // Get code that is not part of a shared symbol table, is specific to this shader, @@ -205,7 +206,8 @@ const char* TParseContext::getPreamble() "#define GL_ARB_texture_cube_map_array 1\n" "#define GL_ARB_shader_texture_lod 1\n" "#define GL_ARB_explicit_attrib_location 1\n" - "#define GL_ARB_shader_image_load_store 1\n"; + "#define GL_ARB_shader_image_load_store 1\n" + "#define GL_ARB_shader_atomic_counters 1\n"; } } diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index 0f51ddc..f8a6da4 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -91,6 +91,7 @@ const char* const GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_arr const char* const GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod"; const char* const GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location"; const char* const GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store"; +const char* const GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters"; } // end namespace glslang -- 2.7.4