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
This commit is contained in:
John Kessenich 2014-08-12 03:52:51 +00:00
parent cc7f4eb5a0
commit bedb1bc2db
12 changed files with 165 additions and 46 deletions

View file

@ -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.

View file

@ -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", "");

View file

@ -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);

View file

@ -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;

View file

@ -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());

View file

@ -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;
}
}