Finish virtually all of the remaining atomic counter functionality. Still need offse...
authorJohn Kessenich <cepheus@frii.com>
Wed, 13 Aug 2014 01:04:28 +0000 (01:04 +0000)
committerJohn Kessenich <cepheus@frii.com>
Wed, 13 Aug 2014 01:04:28 +0000 (01:04 +0000)
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27712 e7fa87d3-cd2b-0410-9028-fcbf551c1848

16 files changed:
Test/310.comp
Test/420.vert
Test/atomic_uint.frag
Test/baseResults/310.comp.out
Test/baseResults/420.vert.out
Test/baseResults/430.vert.out
Test/baseResults/atomic_uint.frag.out
Test/baseResults/specExamples.vert.out
Test/specExamples.vert
glslang/Include/Types.h
glslang/MachineIndependent/Initialize.cpp
glslang/MachineIndependent/Intermediate.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/Scan.cpp
glslang/MachineIndependent/Versions.cpp
glslang/MachineIndependent/Versions.h

index 2f172fe..345224f 100644 (file)
@@ -139,3 +139,14 @@ void mainAC()
 }\r
 \r
 layout(binding = 1) uniform mediump atomic_uint counterBad;  // ERROR, not highp\r
+\r
+layout(binding = 2, offset = 4) uniform atomic_uint countArr[4];\r
+uniform int i;\r
+\r
+void opac()\r
+{\r
+    int a[3];\r
+    a[counter];         // ERROR\r
+    countArr[2];\r
+    countArr[i];\r
+}\r
index 93a9874..7e61207 100644 (file)
@@ -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;
index a837150..43ef0c9 100644 (file)
@@ -19,3 +19,21 @@ void main()
      uint val = atomicCounter(counter);
      atomicCounterDecrement(counter);
 }
+\r
+layout(binding = 1, offset = 3) uniform atomic_uint countArr[4];\r
+uniform int i;\r
+\r
+void opac()\r
+{\r
+    counter + counter;  // ERROR\r
+    -counter;           // ERROR\r
+    int a[3];\r
+    a[counter];         // ERROR\r
+    countArr[2];\r
+    countArr[i];\r
+    counter = 4;        // ERROR\r
+}\r
+\r
+in atomic_uint acin;    // ERROR\r
+atomic_uint acg;        // ERROR\r
+\r
index e45336c..9f7040d 100644 (file)
@@ -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 \r
 ERROR: 0:136: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: non_uniform_counter\r
 ERROR: 0:141: 'atomic_uint' : atomic counters can only be highp \r
-ERROR: 39 compilation errors.  No code generated.\r
+ERROR: 0:141: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings \r
+ERROR: 0:143: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings \r
+ERROR: 0:149: '[]' : scalar integer expression required \r
+ERROR: 42 compilation errors.  No code generated.\r
 \r
 \r
 Shader version: 310\r
@@ -171,6 +174,19 @@ ERROR: node is still EOpNull!
 0:137            'counter' (layout(binding=0 ) uniform highp atomic_uint)\r
 0:138      Function Call: atomicCounterDecrement(au1; (highp uint)\r
 0:138        'counter' (layout(binding=0 ) uniform highp atomic_uint)\r
+0:146  Function Definition: opac( (void)\r
+0:146    Function Parameters: \r
+0:?     Sequence\r
+0:149      indirect index (highp int)\r
+0:149        'a' (3-element array of highp int)\r
+0:149        'counter' (layout(binding=0 ) uniform highp atomic_uint)\r
+0:150      direct index (layout(binding=2 offset=4 ) highp atomic_uint)\r
+0:150        'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
+0:150        Constant:\r
+0:150          2 (const int)\r
+0:151      indirect index (layout(binding=2 offset=4 ) highp atomic_uint)\r
+0:151        'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
+0:151        'i' (uniform highp int)\r
 0:?   Linker Objects\r
 0:?     'gl_WorkGroupSize' (const highp 3-component vector of uint)\r
 0:?       2 (const uint)\r
@@ -211,6 +227,8 @@ ERROR: node is still EOpNull!
 0:?     'i6bad' (layout(r8ui ) uniform highp iimage2D)\r
 0:?     'counter' (layout(binding=0 ) uniform highp atomic_uint)\r
 0:?     'counterBad' (layout(binding=1 ) uniform mediump atomic_uint)\r
+0:?     'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
+0:?     'i' (uniform highp int)\r
 \r
 \r
 Linked compute stage:\r
@@ -345,6 +363,19 @@ ERROR: node is still EOpNull!
 0:137            'counter' (layout(binding=0 ) uniform highp atomic_uint)\r
 0:138      Function Call: atomicCounterDecrement(au1; (highp uint)\r
 0:138        'counter' (layout(binding=0 ) uniform highp atomic_uint)\r
+0:146  Function Definition: opac( (void)\r
+0:146    Function Parameters: \r
+0:?     Sequence\r
+0:149      indirect index (highp int)\r
+0:149        'a' (3-element array of highp int)\r
+0:149        'counter' (layout(binding=0 ) uniform highp atomic_uint)\r
+0:150      direct index (layout(binding=2 offset=4 ) highp atomic_uint)\r
+0:150        'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
+0:150        Constant:\r
+0:150          2 (const int)\r
+0:151      indirect index (layout(binding=2 offset=4 ) highp atomic_uint)\r
+0:151        'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
+0:151        'i' (uniform highp int)\r
 0:?   Linker Objects\r
 0:?     'gl_WorkGroupSize' (const highp 3-component vector of uint)\r
 0:?       2 (const uint)\r
@@ -385,4 +416,6 @@ ERROR: node is still EOpNull!
 0:?     'i6bad' (layout(r8ui ) uniform highp iimage2D)\r
 0:?     'counter' (layout(binding=0 ) uniform highp atomic_uint)\r
 0:?     'counterBad' (layout(binding=1 ) uniform mediump atomic_uint)\r
+0:?     'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
+0:?     'i' (uniform highp int)\r
 \r
index 2d8bf8b..ca3c81e 100644 (file)
@@ -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 \r
 ERROR: 0:143: 'rgba32ui' : does not apply to signed integer images \r
 ERROR: 0:144: 'r8ui' : does not apply to signed integer images \r
-ERROR: 46 compilation errors.  No code generated.\r
+ERROR: 0:147: 'offset on block member' : not supported for this version or the enabled extensions \r
+ERROR: 47 compilation errors.  No code generated.\r
 \r
 \r
 Shader version: 420\r
@@ -287,6 +288,7 @@ ERROR: node is still EOpNull!
 0:?     'i4bad' (layout(r8_snorm ) uniform iimage2D)\r
 0:?     'i5bad' (layout(rgba32ui ) uniform iimage2D)\r
 0:?     'i6bad' (layout(r8ui ) uniform iimage2D)\r
+0:?     'offcheckI' (layout(column_major shared ) uniform block{layout(column_major shared offset=16 ) uniform int foo})\r
 0:?     'gl_VertexID' (gl_VertexId int)\r
 0:?     'gl_InstanceID' (gl_InstanceId int)\r
 \r
@@ -531,6 +533,7 @@ ERROR: node is still EOpNull!
 0:?     'i4bad' (layout(r8_snorm ) uniform iimage2D)\r
 0:?     'i5bad' (layout(rgba32ui ) uniform iimage2D)\r
 0:?     'i6bad' (layout(r8ui ) uniform iimage2D)\r
+0:?     'offcheckI' (layout(column_major shared ) uniform block{layout(column_major shared offset=16 ) uniform int foo})\r
 0:?     'gl_VertexID' (gl_VertexId int)\r
 0:?     'gl_InstanceID' (gl_InstanceId int)\r
 \r
index de38acb..b087e34 100644 (file)
@@ -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 \r
 ERROR: 0:62: 'uniform buffer-member align' : not supported for this version or the enabled extensions \r
 ERROR: 0:64: 'uniform buffer-member align' : not supported for this version or the enabled extensions \r
-ERROR: 0:65: 'uniform buffer-member offset' : not supported for this version or the enabled extensions \r
 ERROR: 0:65: 'uniform buffer-member align' : not supported for this version or the enabled extensions \r
-ERROR: 0:66: 'uniform buffer-member offset' : not supported for this version or the enabled extensions \r
+ERROR: 0:65: 'offset on block member' : not supported for this version or the enabled extensions \r
+ERROR: 0:66: 'offset on block member' : not supported for this version or the enabled extensions \r
 ERROR: 0:64: 'offset/align' : can only be used with std140 or std430 layout packing \r
 ERROR: 0:65: 'align' : can only be used with std140 or std430 layout packing \r
-ERROR: 0:71: 'uniform buffer-member offset' : not supported for this version or the enabled extensions \r
+ERROR: 0:71: 'offset on block member' : not supported for this version or the enabled extensions \r
 ERROR: 0:74: 'gl_MaxTransformFeedbackBuffers' : required extension not requested: GL_ARB_enhanced_layouts\r
 ERROR: 0:75: 'gl_MaxTransformFeedbackInterleavedComponents' : required extension not requested: GL_ARB_enhanced_layouts\r
 ERROR: 0:78: 'transform feedback qualifier' : not supported for this version or the enabled extensions \r
index 248df2e..71d413d 100644 (file)
@@ -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 \r
 ERROR: 0:12: 'return' : type does not match, or is not convertible to, the function's return type \r
 ERROR: 0:18: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: non_uniform_counter\r
-ERROR: 3 compilation errors.  No code generated.\r
+ERROR: 0:23: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings \r
+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)\r
+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)\r
+ERROR: 0:31: '[]' : scalar integer expression required \r
+ERROR: 0:34: 'assign' :  l-value required "counter" (can't modify a uniform)\r
+ERROR: 0:34: 'assign' :  cannot convert from 'const int' to 'layout(binding=0 ) uniform atomic_uint'\r
+ERROR: 0:37: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: acin\r
+ERROR: 0:38: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: acg\r
+ERROR: 11 compilation errors.  No code generated.\r
 \r
 \r
 Shader version: 420\r
@@ -34,8 +42,28 @@ ERROR: node is still EOpNull!
 0:19            'counter' (layout(binding=0 ) uniform atomic_uint)\r
 0:20      Function Call: atomicCounterDecrement(au1; (uint)\r
 0:20        'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:26  Function Definition: opac( (void)\r
+0:26    Function Parameters: \r
+0:28    Sequence\r
+0:28      'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:29      'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:31      indirect index (int)\r
+0:31        'a' (3-element array of int)\r
+0:31        'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:32      direct index (layout(binding=1 offset=3 ) atomic_uint)\r
+0:32        'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint)\r
+0:32        Constant:\r
+0:32          2 (const int)\r
+0:33      indirect index (layout(binding=1 offset=3 ) atomic_uint)\r
+0:33        'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint)\r
+0:33        'i' (uniform int)\r
+0:34      'counter' (layout(binding=0 ) uniform atomic_uint)\r
 0:?   Linker Objects\r
 0:?     'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:?     'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint)\r
+0:?     'i' (uniform int)\r
+0:?     'acin' (smooth in atomic_uint)\r
+0:?     'acg' (atomic_uint)\r
 \r
 \r
 Linked fragment stage:\r
@@ -69,6 +97,26 @@ ERROR: node is still EOpNull!
 0:19            'counter' (layout(binding=0 ) uniform atomic_uint)\r
 0:20      Function Call: atomicCounterDecrement(au1; (uint)\r
 0:20        'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:26  Function Definition: opac( (void)\r
+0:26    Function Parameters: \r
+0:28    Sequence\r
+0:28      'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:29      'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:31      indirect index (int)\r
+0:31        'a' (3-element array of int)\r
+0:31        'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:32      direct index (layout(binding=1 offset=3 ) atomic_uint)\r
+0:32        'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint)\r
+0:32        Constant:\r
+0:32          2 (const int)\r
+0:33      indirect index (layout(binding=1 offset=3 ) atomic_uint)\r
+0:33        'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint)\r
+0:33        'i' (uniform int)\r
+0:34      'counter' (layout(binding=0 ) uniform atomic_uint)\r
 0:?   Linker Objects\r
 0:?     'counter' (layout(binding=0 ) uniform atomic_uint)\r
+0:?     'countArr' (layout(binding=1 offset=3 ) uniform 4-element array of atomic_uint)\r
+0:?     'i' (uniform int)\r
+0:?     'acin' (smooth in atomic_uint)\r
+0:?     'acg' (atomic_uint)\r
 \r
index 551c9de..3189787 100644 (file)
@@ -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 \r
 ERROR: 0:55: 'stream' : there is no such layout identifier for this stage taking an assigned value \r
 ERROR: 0:80: 's17' : redefinition \r
-ERROR: 0:85: 'uniform buffer-member offset' : not supported for this version or the enabled extensions \r
-ERROR: 0:85: 'offset' : cannot specify on a variable declaration \r
-ERROR: 0:89: 'uniform buffer-member offset' : not supported for this version or the enabled extensions \r
+ERROR: 0:85: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings \r
+ERROR: 0:87: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings \r
 WARNING: 0:89: 'layout' : useless application of layout qualifier \r
 ERROR: 0:91: 'bar' : redefinition \r
-ERROR: 0:92: 'uniform buffer-member offset' : not supported for this version or the enabled extensions \r
-ERROR: 0:92: 'bar' : redefinition \r
-ERROR: 0:94: 'uniform buffer-member offset' : not supported for this version or the enabled extensions \r
+ERROR: 0:92: 'offset' : a binding is required \r
 ERROR: 0:94: 'a2' : redefinition \r
+ERROR: 0:95: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings \r
+ERROR: 0:96: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings \r
+ERROR: 0:97: 'binding' : cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings \r
 ERROR: 0:106: '' : vertex input cannot be further qualified \r
 ERROR: 0:106: 'redeclaration' : cannot change storage, memory, or auxiliary qualification of gl_FrontColor\r
 ERROR: 0:112: 'ColorIvn' : identifier not previously declared \r
@@ -291,6 +291,7 @@ ERROR: node is still EOpNull!
 0:?     's17' (layout(binding=3 ) uniform sampler2D)\r
 0:?     'a2' (layout(binding=2 offset=4 ) uniform atomic_uint)\r
 0:?     'bar' (layout(binding=2 ) uniform atomic_uint)\r
+0:?     'bar23' (layout(offset=8 ) uniform atomic_uint)\r
 0:?     'b2' (layout(binding=2 ) uniform atomic_uint)\r
 0:?     'c2' (layout(binding=3 ) uniform atomic_uint)\r
 0:?     'd2' (layout(binding=2 ) uniform atomic_uint)\r
@@ -567,6 +568,7 @@ ERROR: node is still EOpNull!
 0:?     's17' (layout(binding=3 ) uniform sampler2D)\r
 0:?     'a2' (layout(binding=2 offset=4 ) uniform atomic_uint)\r
 0:?     'bar' (layout(binding=2 ) uniform atomic_uint)\r
+0:?     'bar23' (layout(offset=8 ) uniform atomic_uint)\r
 0:?     'b2' (layout(binding=2 ) uniform atomic_uint)\r
 0:?     'c2' (layout(binding=3 ) uniform atomic_uint)\r
 0:?     'd2' (layout(binding=2 ) uniform atomic_uint)\r
index 628f746..a9c9178 100644 (file)
@@ -89,7 +89,7 @@ layout (binding = 2) uniform atomic_uint bar;
 layout (binding = 2, offset = 4) uniform atomic_uint;\r
 \r
 layout (binding = 2) uniform atomic_uint bar; // offset is 4\r
-layout (offset = 8) uniform atomic_uint bar;  // error, no default binding\r
+layout (offset = 8) uniform atomic_uint bar23;  // error, no default binding\r
 \r
 layout (binding=3, offset=4) uniform atomic_uint a2; // offset = 4\r
 layout (binding=2) uniform atomic_uint b2;           // offset = 0\r
index 40c6b45..7bf06a4 100644 (file)
@@ -523,6 +523,7 @@ public:
         return hasMatrix() ||
                hasPacking() ||
                hasOffset() ||
+               hasBinding() ||
                hasAlign();
     }
     bool hasMatrix() const
index 42e5c7f..dcd11b8 100644 (file)
@@ -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;
 
index c3c06d4..cf4265f 100644 (file)
@@ -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;
index df0f34a..13681d9 100644 (file)
@@ -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)
index 1a459ba..1a92e3e 100644 (file)
@@ -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);
index feb233a..0562bdd 100644 (file)
@@ -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";
     }
 }
 
index 0f51ddc..f8a6da4 100644 (file)
@@ -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