diff --git a/Test/atomic_uint.frag b/Test/atomic_uint.frag new file mode 100644 index 00000000..972cf282 --- /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 00000000..246cf8b0 --- /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 b082a850..551c9de9 100644 --- a/Test/baseResults/specExamples.vert.out +++ b/Test/baseResults/specExamples.vert.out @@ -18,9 +18,7 @@ ERROR: 0:50: 'stream' : there is no such layout identifier for this stage taking 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: 'uniform buffer-member offset' : not supported for this version or 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: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: 41 compilation errors. No code generated. +ERROR: 36 compilation errors. No code generated. Shader version: 430 @@ -294,11 +289,11 @@ ERROR: node is still EOpNull! 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 @@ ERROR: node is still EOpNull! 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 36d1c3cf..286c1fd0 100644 --- a/Test/testlist +++ b/Test/testlist @@ -69,6 +69,7 @@ numeral.frag 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 fd449512..32cf83a3 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -49,6 +49,7 @@ enum TBasicType { EbtInt, EbtUint, EbtBool, + EbtAtomicUint, EbtSampler, EbtStruct, EbtBlock, diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index cb434678..bc89e1fb 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -1111,6 +1111,7 @@ public: 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 d2b849be..73466e7c 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -740,6 +740,18 @@ void TBuiltIns::initialize(int version, EProfile profile) "\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 16c6b92e..efc5d938 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -1587,6 +1587,9 @@ bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermType 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 @@ bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunctio 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 @@ void TParseContext::samplerCheck(TSourceLoc loc, const TType& type, const TStrin 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 @@ void TParseContext::precisionQualifierCheck(TSourceLoc loc, TPublicType& publicT 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::arrayObjectCheck(TSourceLoc loc, const TType& type, const ch 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 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type) // 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 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, 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 c9bbf176..2c36c2ea 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -124,6 +124,7 @@ public: 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 @@ public: 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 6309b34c..f1479a5b 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -63,6 +63,7 @@ void TType::buildMangledName(TString& mangledName) 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 1e206933..e34231c4 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -900,13 +900,13 @@ parameter_declaration $$.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 @@ parameter_declaration $$.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 @@ type_specifier_nonarray $$.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 6c1299bf..fa5a9128 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -530,12 +530,13 @@ public: 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 @@ public: } 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; } }