Partial implementation of atomic counters.


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27701 e7fa87d3-cd2b-0410-9028-fcbf551c1848
diff --git a/Test/atomic_uint.frag b/Test/atomic_uint.frag
new file mode 100644
index 0000000..972cf28
--- /dev/null
+++ b/Test/atomic_uint.frag
@@ -0,0 +1,20 @@
+#version 420 core
+
+layout(binding = 0) uniform atomic_uint counter;
+
+uint func(atomic_uint c)
+{
+    return atomicCounterIncrement(c);
+}
+
+uint func2(out atomic_uint c) // ERROR
+{
+    return counter;
+}
+
+void main()
+{
+     atomic_uint non_uniform_counter; // ERROR
+     uint val = atomicCounter(counter);
+     atomicCounterDecrement(counter);
+}
diff --git a/Test/baseResults/atomic_uint.frag.out b/Test/baseResults/atomic_uint.frag.out
new file mode 100644
index 0000000..246cf8b
--- /dev/null
+++ b/Test/baseResults/atomic_uint.frag.out
@@ -0,0 +1,68 @@
+atomic_uint.frag

+Warning, version 420 is not yet complete; most version-specific features are present, but some are missing.

+ERROR: 0:10: 'atomic_uint' : samplers and atomic_uints cannot be output parameters 

+ERROR: 0:12: 'return' : type does not match, or is not convertible to, the function's return type 

+ERROR: 0:17: 'atomic_uint' : atomic_uints can only be used in uniform variables or function parameters: non_uniform_counter

+ERROR: 3 compilation errors.  No code generated.

+

+

+Shader version: 420

+ERROR: node is still EOpNull!

+0:5  Function Definition: func(au1; (uint)

+0:5    Function Parameters: 

+0:5      'c' (in atomic_uint)

+0:7    Sequence

+0:7      Branch: Return with expression

+0:7        Function Call: atomicCounterIncrement(au1; (uint)

+0:7          'c' (in atomic_uint)

+0:10  Function Definition: func2(au1; (uint)

+0:10    Function Parameters: 

+0:10      'c' (out atomic_uint)

+0:12    Sequence

+0:12      Branch: Return with expression

+0:12        'counter' (layout(binding=0 ) uniform atomic_uint)

+0:15  Function Definition: main( (void)

+0:15    Function Parameters: 

+0:?     Sequence

+0:18      Sequence

+0:18        move second child to first child (uint)

+0:18          'val' (uint)

+0:18          Function Call: atomicCounter(au1; (uint)

+0:18            'counter' (layout(binding=0 ) uniform atomic_uint)

+0:19      Function Call: atomicCounterDecrement(au1; (uint)

+0:19        'counter' (layout(binding=0 ) uniform atomic_uint)

+0:?   Linker Objects

+0:?     'counter' (layout(binding=0 ) uniform atomic_uint)

+

+

+Linked fragment stage:

+

+

+Shader version: 420

+ERROR: node is still EOpNull!

+0:5  Function Definition: func(au1; (uint)

+0:5    Function Parameters: 

+0:5      'c' (in atomic_uint)

+0:7    Sequence

+0:7      Branch: Return with expression

+0:7        Function Call: atomicCounterIncrement(au1; (uint)

+0:7          'c' (in atomic_uint)

+0:10  Function Definition: func2(au1; (uint)

+0:10    Function Parameters: 

+0:10      'c' (out atomic_uint)

+0:12    Sequence

+0:12      Branch: Return with expression

+0:12        'counter' (layout(binding=0 ) uniform atomic_uint)

+0:15  Function Definition: main( (void)

+0:15    Function Parameters: 

+0:?     Sequence

+0:18      Sequence

+0:18        move second child to first child (uint)

+0:18          'val' (uint)

+0:18          Function Call: atomicCounter(au1; (uint)

+0:18            'counter' (layout(binding=0 ) uniform atomic_uint)

+0:19      Function Call: atomicCounterDecrement(au1; (uint)

+0:19        'counter' (layout(binding=0 ) uniform atomic_uint)

+0:?   Linker Objects

+0:?     'counter' (layout(binding=0 ) uniform atomic_uint)

+

diff --git a/Test/baseResults/specExamples.vert.out b/Test/baseResults/specExamples.vert.out
index b082a85..551c9de 100644
--- a/Test/baseResults/specExamples.vert.out
+++ b/Test/baseResults/specExamples.vert.out
@@ -18,9 +18,7 @@
 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: 'binding' : requires block, or sampler/image, or atomic-counter type 

 ERROR: 0:85: 'offset' : cannot specify on a variable declaration 

-ERROR: 0:87: 'binding' : requires block, or sampler/image, or atomic-counter type 

 ERROR: 0:89: 'uniform buffer-member offset' : not supported for this version or the enabled extensions 

 WARNING: 0:89: 'layout' : useless application of layout qualifier 

 ERROR: 0:91: 'bar' : redefinition 

@@ -28,9 +26,6 @@
 ERROR: 0:92: 'bar' : redefinition 

 ERROR: 0:94: 'uniform buffer-member offset' : not supported for this version or the enabled extensions 

 ERROR: 0:94: 'a2' : redefinition 

-ERROR: 0:95: 'binding' : requires block, or sampler/image, or atomic-counter type 

-ERROR: 0:96: 'binding' : requires block, or sampler/image, or atomic-counter type 

-ERROR: 0:97: 'binding' : requires block, or sampler/image, or atomic-counter type 

 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 

@@ -43,7 +38,7 @@
 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: 41 compilation errors.  No code generated.

+ERROR: 36 compilation errors.  No code generated.

 

 

 Shader version: 430

@@ -294,11 +289,11 @@
 0:?     'anon@3' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=0 ) uniform 4X4 matrix of float M1, layout(column_major std140 offset=64 ) uniform 4X4 matrix of float M2, layout(row_major std140 offset=128 ) uniform 3X3 matrix of float N1})

 0:?     'anon@4' (layout(column_major shared ) uniform block{layout(column_major shared ) uniform 4X4 matrix of float M13, layout(row_major shared ) uniform 4X4 matrix of float m14, layout(column_major shared ) uniform 3X3 matrix of float N12})

 0:?     's17' (layout(binding=3 ) uniform sampler2D)

-0:?     'a2' (layout(binding=2 offset=4 ) uniform int)

-0:?     'bar' (layout(binding=2 ) uniform int)

-0:?     'b2' (layout(binding=2 ) uniform int)

-0:?     'c2' (layout(binding=3 ) uniform int)

-0:?     'd2' (layout(binding=2 ) uniform int)

+0:?     'a2' (layout(binding=2 offset=4 ) uniform atomic_uint)

+0:?     'bar' (layout(binding=2 ) 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)

 0:?     'anon@5' (out block{invariant gl_Position 4-component vector of float gl_Position, gl_PointSize float gl_PointSize, out implicitly-sized array of float gl_ClipDistance, gl_ClipVertex 4-component vector of float gl_ClipVertex, flat out 4-component vector of float gl_FrontColor, out 4-component vector of float gl_BackColor, out 4-component vector of float gl_FrontSecondaryColor, out 4-component vector of float gl_BackSecondaryColor, out implicitly-sized array of 4-component vector of float gl_TexCoord, out float gl_FogFragCoord})

 0:?     'anon@5' (out block{invariant gl_Position 4-component vector of float gl_Position, gl_PointSize float gl_PointSize, out implicitly-sized array of float gl_ClipDistance, gl_ClipVertex 4-component vector of float gl_ClipVertex, flat out 4-component vector of float gl_FrontColor, out 4-component vector of float gl_BackColor, out 4-component vector of float gl_FrontSecondaryColor, out 4-component vector of float gl_BackSecondaryColor, out implicitly-sized array of 4-component vector of float gl_TexCoord, out float gl_FogFragCoord})

 0:?     'ColorInv' (smooth out 3-component vector of float)

@@ -570,11 +565,11 @@
 0:?     'anon@3' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=0 ) uniform 4X4 matrix of float M1, layout(column_major std140 offset=64 ) uniform 4X4 matrix of float M2, layout(row_major std140 offset=128 ) uniform 3X3 matrix of float N1})

 0:?     'anon@4' (layout(column_major shared ) uniform block{layout(column_major shared ) uniform 4X4 matrix of float M13, layout(row_major shared ) uniform 4X4 matrix of float m14, layout(column_major shared ) uniform 3X3 matrix of float N12})

 0:?     's17' (layout(binding=3 ) uniform sampler2D)

-0:?     'a2' (layout(binding=2 offset=4 ) uniform int)

-0:?     'bar' (layout(binding=2 ) uniform int)

-0:?     'b2' (layout(binding=2 ) uniform int)

-0:?     'c2' (layout(binding=3 ) uniform int)

-0:?     'd2' (layout(binding=2 ) uniform int)

+0:?     'a2' (layout(binding=2 offset=4 ) uniform atomic_uint)

+0:?     'bar' (layout(binding=2 ) 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)

 0:?     'anon@5' (out block{invariant gl_Position 4-component vector of float gl_Position, gl_PointSize float gl_PointSize, out 1-element array of float gl_ClipDistance, gl_ClipVertex 4-component vector of float gl_ClipVertex, flat out 4-component vector of float gl_FrontColor, out 4-component vector of float gl_BackColor, out 4-component vector of float gl_FrontSecondaryColor, out 4-component vector of float gl_BackSecondaryColor, out 1-element array of 4-component vector of float gl_TexCoord, out float gl_FogFragCoord})

 0:?     'anon@5' (out block{invariant gl_Position 4-component vector of float gl_Position, gl_PointSize float gl_PointSize, out 1-element array of float gl_ClipDistance, gl_ClipVertex 4-component vector of float gl_ClipVertex, flat out 4-component vector of float gl_FrontColor, out 4-component vector of float gl_BackColor, out 4-component vector of float gl_FrontSecondaryColor, out 4-component vector of float gl_BackSecondaryColor, out 1-element array of 4-component vector of float gl_TexCoord, out float gl_FogFragCoord})

 0:?     'ColorInv' (smooth out 3-component vector of float)

diff --git a/Test/testlist b/Test/testlist
index 36d1c3c..286c1fd 100644
--- a/Test/testlist
+++ b/Test/testlist
@@ -69,6 +69,7 @@
 440.vert
 440.frag
 dce.frag
+atomic_uint.frag
 ../../LunarGLASS/test/aggOps.frag
 ../../LunarGLASS/test/always-discard.frag
 ../../LunarGLASS/test/always-discard2.frag
diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h
index fd44951..32cf83a 100644
--- a/glslang/Include/BaseTypes.h
+++ b/glslang/Include/BaseTypes.h
@@ -49,6 +49,7 @@
     EbtInt,
     EbtUint,
     EbtBool,
+    EbtAtomicUint,
     EbtSampler,
     EbtStruct,
     EbtBlock,
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index cb43467..bc89e1f 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -1111,6 +1111,7 @@
         case EbtInt:               return "int";
         case EbtUint:              return "uint";
         case EbtBool:              return "bool";
+        case EbtAtomicUint:        return "atomic_uint";
         case EbtSampler:           return "sampler/image";
         case EbtStruct:            return "structure";
         case EbtBlock:             return "block";
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index d2b849b..73466e7 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -740,6 +740,18 @@
             "\n");
     }
 
+    //
+    // Atomic counter functions.
+    //
+    if (profile != EEsProfile && version >= 420) {
+        commonBuiltins.append(
+            "uint atomicCounterIncrement(atomic_uint x);"
+            "uint atomicCounterDecrement(atomic_uint x);"
+            "uint atomicCounter(atomic_uint x);"
+
+            "\n");
+    }
+
     //============================================================================
     //
     // Prototypes for built-in functions seen by vertex shaders only.
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 16c6b92..efc5d93 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -1587,6 +1587,9 @@
         case EbtSampler:
             message = "can't modify a sampler";
             break;
+        case EbtAtomicUint:
+            message = "can't modify an atomic_uint";
+            break;
         case EbtVoid:
             message = "can't modify void";
             break;
@@ -1841,6 +1844,10 @@
         error(loc, "cannot convert a sampler", "constructor", "");
         return true;
     }
+    if (op != EOpConstructStruct && typed->getBasicType() == EbtAtomicUint) {
+        error(loc, "cannot convert an atomic_uint", "constructor", "");
+        return true;
+    }
     if (typed->getBasicType() == EbtVoid) {
         error(loc, "cannot convert a void", "constructor", "");
         return true;
@@ -1882,12 +1889,23 @@
     if (type.getQualifier().storage == EvqUniform)
         return;
 
-    if (type.getBasicType() == EbtStruct && containsSampler(type))
+    if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler))
         error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str());
     else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform)
         error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
 }
 
+void TParseContext::atomicUintCheck(TSourceLoc loc, const TType& type, const TString& identifier)
+{
+    if (type.getQualifier().storage == EvqUniform)
+        return;
+
+    if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAtomicUint))
+        error(loc, "non-uniform struct contains an atomic_uint:", type.getBasicTypeString().c_str(), identifier.c_str());
+    else if (type.getBasicType() == EbtAtomicUint && type.getQualifier().storage != EvqUniform)
+        error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
+}
+
 //
 // move from parameter/unknown qualifiers to pipeline in/out qualifiers
 //
@@ -2168,21 +2186,21 @@
         error(loc, "type cannot have precision qualifier", TType::getBasicString(publicType.basicType), "");
 }
 
-void TParseContext::parameterSamplerCheck(TSourceLoc loc, TStorageQualifier qualifier, const TType& type)
+void TParseContext::parameterTypeCheck(TSourceLoc loc, TStorageQualifier qualifier, const TType& type)
 {
-    if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && type.getBasicType() == EbtSampler)
-        error(loc, "samplers cannot be output parameters", type.getBasicTypeString().c_str(), "");
+    if ((qualifier == EvqOut || qualifier == EvqInOut) && (type.getBasicType() == EbtSampler || type.getBasicType() == EbtAtomicUint))
+        error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
 }
 
-bool TParseContext::containsSampler(const TType& type)
+bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType basicType)
 {
-    if (type.getBasicType() == EbtSampler)
+    if (type.getBasicType() == basicType)
         return true;
 
     if (type.getBasicType() == EbtStruct) {
         const TTypeList& structure = *type.getStruct();
         for (unsigned int i = 0; i < structure.size(); ++i) {
-            if (containsSampler(*structure[i].type))
+            if (containsFieldWithBasicType(*structure[i].type, basicType))
                 return true;
         }
     }
@@ -2731,7 +2749,7 @@
 
 void TParseContext::opaqueCheck(TSourceLoc loc, const TType& type, const char* op)
 {
-    if (containsSampler(type))
+    if (containsFieldWithBasicType(type, EbtSampler))
         error(loc, "can't use with samplers or structs containing samplers", op, "");
 }
 
@@ -3388,9 +3406,8 @@
         // an array of size N, all elements of the array from binding through binding + N – 1 must be within this
         // range."
         //
-        if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock)
+        if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock && type.getBasicType() != EbtAtomicUint)
             error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
-            // TODO: 4.2 functionality: atomic counter: include in test above
         if (type.getBasicType() == EbtSampler) {
             int lastBinding = qualifier.layoutBinding;
             if (type.isArray())
@@ -3659,6 +3676,7 @@
 
     invariantCheck(loc, type, identifier);
     samplerCheck(loc, type, identifier);
+    atomicUintCheck(loc, type, identifier);
 
     if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
         error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index c9bbf17..2c36c2e 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -124,6 +124,7 @@
     void boolCheck(TSourceLoc, const TIntermTyped*);
     void boolCheck(TSourceLoc, const TPublicType&);
     void samplerCheck(TSourceLoc, const TType&, const TString& identifier);
+    void atomicUintCheck(TSourceLoc, const TType&, const TString& identifier);
     void pipeInOutFix(TSourceLoc, TQualifier&);
     void globalQualifierCheck(TSourceLoc, const TQualifier&, const TPublicType&);
     bool structQualifierErrorCheck(TSourceLoc, const TPublicType& pType);
@@ -132,8 +133,8 @@
     int computeSamplerTypeIndex(TSampler&);
     TPrecisionQualifier getDefaultPrecision(TPublicType&);
     void precisionQualifierCheck(TSourceLoc, TPublicType&);
-    void parameterSamplerCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type);
-    bool containsSampler(const TType& type);
+    void parameterTypeCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type);
+    bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
     TSymbol* redeclareBuiltinVariable(TSourceLoc, const TString&, const TQualifier&, const TShaderQualifiers&, bool& newDeclaration);
     void redeclareBuiltinBlock(TSourceLoc, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
     void paramCheckFix(TSourceLoc, const TStorageQualifier&, TType& type);
diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp
index 6309b34..f1479a5 100644
--- a/glslang/MachineIndependent/SymbolTable.cpp
+++ b/glslang/MachineIndependent/SymbolTable.cpp
@@ -63,6 +63,7 @@
     case EbtInt:                mangledName += 'i';      break;
     case EbtUint:               mangledName += 'u';      break;
     case EbtBool:               mangledName += 'b';      break;
+    case EbtAtomicUint:         mangledName += "au";     break;
     case EbtSampler:
         switch (sampler.type) {
         case EbtInt:   mangledName += "i"; break;
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
index 1e20693..e34231c 100644
--- a/glslang/MachineIndependent/glslang.y
+++ b/glslang/MachineIndependent/glslang.y
@@ -900,13 +900,13 @@
             $$.param.type->getQualifier().precision = $1.qualifier.precision;

         

         parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);

-        parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);

+        parseContext.parameterTypeCheck($2.loc, $1.qualifier.storage, *$$.param.type);

         parseContext.paramCheckFix($1.loc, $1.qualifier, *$$.param.type);

     }

     | parameter_declarator {

         $$ = $1;

 

-        parseContext.parameterSamplerCheck($1.loc, EvqIn, *$1.param.type);

+        parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type);

         parseContext.paramCheckFix($1.loc, EvqTemporary, *$$.param.type);

     }

     //

@@ -918,13 +918,13 @@
             $$.param.type->getQualifier().precision = $1.qualifier.precision;

         

         parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);

-        parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);

+        parseContext.parameterTypeCheck($2.loc, $1.qualifier.storage, *$$.param.type);

         parseContext.paramCheckFix($1.loc, $1.qualifier, *$$.param.type);

     }

     | parameter_type_specifier {

         $$ = $1;

 

-        parseContext.parameterSamplerCheck($1.loc, EvqIn, *$1.param.type);

+        parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type);

         parseContext.paramCheckFix($1.loc, EvqTemporary, *$$.param.type);

     }

     ;

@@ -1546,9 +1546,8 @@
         $$.setMatrix(4, 4);

     }

     | ATOMIC_UINT {

-        // TODO: 4.2 functionality: add atomic_uint type

         $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());

-        $$.basicType = EbtInt;

+        $$.basicType = EbtAtomicUint;

     }

     | SAMPLER1D {

         $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());

diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp
index 6c1299b..fa5a912 100644
--- a/glslang/MachineIndependent/reflection.cpp
+++ b/glslang/MachineIndependent/reflection.cpp
@@ -530,12 +530,13 @@
         if (type.isVector()) {

             int offset = type.getVectorSize() - 2;

             switch (type.getBasicType()) {

-            case EbtFloat:     return GL_FLOAT_VEC2        + offset;

-            case EbtDouble:    return GL_DOUBLE_VEC2       + offset;

-            case EbtInt:       return GL_INT_VEC2          + offset;

-            case EbtUint:      return GL_UNSIGNED_INT_VEC2 + offset;

-            case EbtBool:      return GL_BOOL_VEC2         + offset;

-            default:           return 0;

+            case EbtFloat:      return GL_FLOAT_VEC2                  + offset;

+            case EbtDouble:     return GL_DOUBLE_VEC2                 + offset;

+            case EbtInt:        return GL_INT_VEC2                    + offset;

+            case EbtUint:       return GL_UNSIGNED_INT_VEC2           + offset;

+            case EbtBool:       return GL_BOOL_VEC2                   + offset;

+            case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset;

+            default:            return 0;

             }

         }

         if (type.isMatrix()) {

@@ -594,12 +595,13 @@
         }

         if (type.getVectorSize() == 1) {

             switch (type.getBasicType()) {

-            case EbtFloat:     return GL_FLOAT;

-            case EbtDouble:    return GL_DOUBLE;

-            case EbtInt:       return GL_INT;

-            case EbtUint:      return GL_UNSIGNED_INT;

-            case EbtBool:      return GL_BOOL;

-            default:           return 0;

+            case EbtFloat:      return GL_FLOAT;

+            case EbtDouble:     return GL_DOUBLE;

+            case EbtInt:        return GL_INT;

+            case EbtUint:       return GL_UNSIGNED_INT;

+            case EbtBool:       return GL_BOOL;

+            case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER;

+            default:            return 0;

             }

         }