Commit 3c20f806 by Nicolas Capens

Implement shader compiler support for uint scalars.

Bug 19331817 Change-Id: Ie901756ef4fdbab1dfa6ae01c77104fc84de247f Reviewed-on: https://swiftshader-review.googlesource.com/2312Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent 309a1d98
...@@ -38,6 +38,7 @@ enum TBasicType ...@@ -38,6 +38,7 @@ enum TBasicType
EbtVoid, EbtVoid,
EbtFloat, EbtFloat,
EbtInt, EbtInt,
EbtUInt,
EbtBool, EbtBool,
EbtGuardSamplerBegin, // non type: see implementation of IsSampler() EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
EbtSampler2D, EbtSampler2D,
...@@ -57,6 +58,7 @@ inline const char* getBasicString(TBasicType t) ...@@ -57,6 +58,7 @@ inline const char* getBasicString(TBasicType t)
case EbtVoid: return "void"; case EbtVoid: return "void";
case EbtFloat: return "float"; case EbtFloat: return "float";
case EbtInt: return "int"; case EbtInt: return "int";
case EbtUInt: return "uint";
case EbtBool: return "bool"; case EbtBool: return "bool";
case EbtSampler2D: return "sampler2D"; case EbtSampler2D: return "sampler2D";
case EbtSamplerCube: return "samplerCube"; case EbtSamplerCube: return "samplerCube";
......
...@@ -26,6 +26,7 @@ public: ...@@ -26,6 +26,7 @@ public:
switch (constant.type) switch (constant.type)
{ {
case EbtInt: setFConst(static_cast<float>(constant.getIConst())); break; case EbtInt: setFConst(static_cast<float>(constant.getIConst())); break;
case EbtUInt: setFConst(static_cast<float>(constant.getUConst())); break;
case EbtBool: setFConst(static_cast<float>(constant.getBConst())); break; case EbtBool: setFConst(static_cast<float>(constant.getBConst())); break;
case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break; case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
default: return false; default: return false;
...@@ -35,15 +36,27 @@ public: ...@@ -35,15 +36,27 @@ public:
switch (constant.type) switch (constant.type)
{ {
case EbtInt: setIConst(static_cast<int>(constant.getIConst())); break; case EbtInt: setIConst(static_cast<int>(constant.getIConst())); break;
case EbtUInt: setIConst(static_cast<int>(constant.getUConst())); break;
case EbtBool: setIConst(static_cast<int>(constant.getBConst())); break; case EbtBool: setIConst(static_cast<int>(constant.getBConst())); break;
case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break; case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
default: return false; default: return false;
} }
break; break;
case EbtUInt:
switch (constant.type)
{
case EbtInt: setUConst(static_cast<unsigned int>(constant.getIConst())); break;
case EbtUInt: setUConst(static_cast<unsigned int>(constant.getUConst())); break;
case EbtBool: setUConst(static_cast<unsigned int>(constant.getBConst())); break;
case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
default: return false;
}
break;
case EbtBool: case EbtBool:
switch (constant.type) switch (constant.type)
{ {
case EbtInt: setBConst(constant.getIConst() != 0); break; case EbtInt: setBConst(constant.getIConst() != 0); break;
case EbtUInt: setBConst(constant.getUConst() != 0); break;
case EbtBool: setBConst(constant.getBConst()); break; case EbtBool: setBConst(constant.getBConst()); break;
case EbtFloat: setBConst(constant.getFConst() != 0.0f); break; case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
default: return false; default: return false;
...@@ -53,6 +66,7 @@ public: ...@@ -53,6 +66,7 @@ public:
switch (constant.type) switch (constant.type)
{ {
case EbtInt: setIConst(constant.getIConst()); break; case EbtInt: setIConst(constant.getIConst()); break;
case EbtUInt: setUConst(constant.getUConst()); break;
case EbtBool: setBConst(constant.getBConst()); break; case EbtBool: setBConst(constant.getBConst()); break;
case EbtFloat: setFConst(constant.getFConst()); break; case EbtFloat: setFConst(constant.getFConst()); break;
default: return false; default: return false;
...@@ -66,10 +80,12 @@ public: ...@@ -66,10 +80,12 @@ public:
} }
void setIConst(int i) {iConst = i; type = EbtInt; } void setIConst(int i) {iConst = i; type = EbtInt; }
void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
void setFConst(float f) {fConst = f; type = EbtFloat; } void setFConst(float f) {fConst = f; type = EbtFloat; }
void setBConst(bool b) {bConst = b; type = EbtBool; } void setBConst(bool b) {bConst = b; type = EbtBool; }
int getIConst() const { return iConst; } int getIConst() const { return iConst; }
unsigned int getUConst() const { return uConst; }
float getFConst() const { return fConst; } float getFConst() const { return fConst; }
bool getBConst() const { return bConst; } bool getBConst() const { return bConst; }
...@@ -91,6 +107,11 @@ public: ...@@ -91,6 +107,11 @@ public:
return i == iConst; return i == iConst;
} }
bool operator==(const unsigned int u) const
{
return u == uConst;
}
bool operator==(const float f) const bool operator==(const float f) const
{ {
return f == fConst; return f == fConst;
...@@ -109,6 +130,8 @@ public: ...@@ -109,6 +130,8 @@ public:
switch (type) { switch (type) {
case EbtInt: case EbtInt:
return constant.iConst == iConst; return constant.iConst == iConst;
case EbtUInt:
return constant.uConst == uConst;
case EbtFloat: case EbtFloat:
return constant.fConst == fConst; return constant.fConst == fConst;
case EbtBool: case EbtBool:
...@@ -125,6 +148,11 @@ public: ...@@ -125,6 +148,11 @@ public:
return !operator==(i); return !operator==(i);
} }
bool operator!=(const unsigned int u) const
{
return !operator==(u);
}
bool operator!=(const float f) const bool operator!=(const float f) const
{ {
return !operator==(f); return !operator==(f);
...@@ -146,6 +174,8 @@ public: ...@@ -146,6 +174,8 @@ public:
switch (type) { switch (type) {
case EbtInt: case EbtInt:
return iConst > constant.iConst; return iConst > constant.iConst;
case EbtUInt:
return uConst > constant.uConst;
case EbtFloat: case EbtFloat:
return fConst > constant.fConst; return fConst > constant.fConst;
default: default:
...@@ -161,6 +191,8 @@ public: ...@@ -161,6 +191,8 @@ public:
switch (type) { switch (type) {
case EbtInt: case EbtInt:
return iConst < constant.iConst; return iConst < constant.iConst;
case EbtUInt:
return uConst < constant.uConst;
case EbtFloat: case EbtFloat:
return fConst < constant.fConst; return fConst < constant.fConst;
default: default:
...@@ -176,6 +208,7 @@ public: ...@@ -176,6 +208,7 @@ public:
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break;
case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break; case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -189,6 +222,7 @@ public: ...@@ -189,6 +222,7 @@ public:
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break;
case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break; case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -202,6 +236,7 @@ public: ...@@ -202,6 +236,7 @@ public:
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break;
case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break; case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -215,6 +250,7 @@ public: ...@@ -215,6 +250,7 @@ public:
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -227,6 +263,7 @@ public: ...@@ -227,6 +263,7 @@ public:
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -236,9 +273,13 @@ public: ...@@ -236,9 +273,13 @@ public:
ConstantUnion operator<<(const ConstantUnion& constant) const ConstantUnion operator<<(const ConstantUnion& constant) const
{ {
ConstantUnion returnValue; ConstantUnion returnValue;
assert(type == constant.type); // The signedness of the second parameter might be different, but we
// don't care, since the result is undefined if the second parameter is
// negative, and aliasing should not be a problem with unions.
assert(constant.type == EbtInt || constant.type == EbtUInt);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -248,9 +289,10 @@ public: ...@@ -248,9 +289,10 @@ public:
ConstantUnion operator&(const ConstantUnion& constant) const ConstantUnion operator&(const ConstantUnion& constant) const
{ {
ConstantUnion returnValue; ConstantUnion returnValue;
assert(type == constant.type); assert(constant.type == EbtInt || constant.type == EbtUInt);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -263,6 +305,7 @@ public: ...@@ -263,6 +305,7 @@ public:
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst | constant.uConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -275,6 +318,7 @@ public: ...@@ -275,6 +318,7 @@ public:
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst ^ constant.uConst); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
...@@ -310,6 +354,7 @@ private: ...@@ -310,6 +354,7 @@ private:
union { union {
int iConst; // used for ivec, scalar ints int iConst; // used for ivec, scalar ints
unsigned int uConst; // used for uvec, scalar uints
bool bConst; // used for bvec, scalar bools bool bConst; // used for bvec, scalar bools
float fConst; // used for vec, mat, scalar floats float fConst; // used for vec, mat, scalar floats
} ; } ;
......
...@@ -601,6 +601,7 @@ bool TIntermOperator::isConstructor() const ...@@ -601,6 +601,7 @@ bool TIntermOperator::isConstructor() const
case EOpConstructIVec3: case EOpConstructIVec3:
case EOpConstructIVec4: case EOpConstructIVec4:
case EOpConstructInt: case EOpConstructInt:
case EOpConstructUInt:
case EOpConstructBVec2: case EOpConstructBVec2:
case EOpConstructBVec3: case EOpConstructBVec3:
case EOpConstructBVec4: case EOpConstructBVec4:
...@@ -981,6 +982,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -981,6 +982,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
} else } else
tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst()); tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
break; break;
case EbtUInt:
if (rightUnionArray[i] == 0) {
infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
tempConstArray[i].setUConst(UINT_MAX);
} else
tempConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
break;
default: default:
infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine()); infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
return 0; return 0;
...@@ -1196,6 +1204,9 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1196,6 +1204,9 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtInt: case EbtInt:
leftUnionArray[i].setFConst(static_cast<float>(node->getIConst(i))); leftUnionArray[i].setFConst(static_cast<float>(node->getIConst(i)));
break; break;
case EbtUInt:
leftUnionArray[i].setFConst(static_cast<float>(node->getUConst(i)));
break;
case EbtBool: case EbtBool:
leftUnionArray[i].setFConst(static_cast<float>(node->getBConst(i))); leftUnionArray[i].setFConst(static_cast<float>(node->getBConst(i)));
break; break;
...@@ -1212,6 +1223,9 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1212,6 +1223,9 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtInt: case EbtInt:
leftUnionArray[i].setIConst(static_cast<int>(node->getIConst(i))); leftUnionArray[i].setIConst(static_cast<int>(node->getIConst(i)));
break; break;
case EbtUInt:
leftUnionArray[i].setIConst(static_cast<int>(node->getUConst(i)));
break;
case EbtBool: case EbtBool:
leftUnionArray[i].setIConst(static_cast<int>(node->getBConst(i))); leftUnionArray[i].setIConst(static_cast<int>(node->getBConst(i)));
break; break;
...@@ -1223,11 +1237,33 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1223,11 +1237,33 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
return 0; return 0;
} }
break; break;
case EbtUInt:
switch (node->getType().getBasicType()) {
case EbtInt:
leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getIConst(i)));
break;
case EbtUInt:
leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getUConst(i)));
break;
case EbtBool:
leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getBConst(i)));
break;
case EbtFloat:
leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getFConst(i)));
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
return 0;
}
break;
case EbtBool: case EbtBool:
switch (node->getType().getBasicType()) { switch (node->getType().getBasicType()) {
case EbtInt: case EbtInt:
leftUnionArray[i].setBConst(node->getIConst(i) != 0); leftUnionArray[i].setBConst(node->getIConst(i) != 0);
break; break;
case EbtUInt:
leftUnionArray[i].setBConst(node->getUConst(i) != 0);
break;
case EbtBool: case EbtBool:
leftUnionArray[i].setBConst(node->getBConst(i)); leftUnionArray[i].setBConst(node->getBConst(i));
break; break;
......
...@@ -391,7 +391,7 @@ bool TParseContext::constErrorCheck(TIntermTyped* node) ...@@ -391,7 +391,7 @@ bool TParseContext::constErrorCheck(TIntermTyped* node)
// //
bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
{ {
if (node->getBasicType() == EbtInt && node->getNominalSize() == 1) if (node->isScalarInt())
return false; return false;
error(node->getLine(), "integer expression required", token); error(node->getLine(), "integer expression required", token);
...@@ -657,17 +657,35 @@ bool TParseContext::containsSampler(TType& type) ...@@ -657,17 +657,35 @@ bool TParseContext::containsSampler(TType& type)
bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
{ {
TIntermConstantUnion* constant = expr->getAsConstantUnion(); TIntermConstantUnion* constant = expr->getAsConstantUnion();
if (constant == 0 || constant->getBasicType() != EbtInt) {
if (constant == 0 || !constant->isScalarInt())
{
error(line, "array size must be a constant integer expression", ""); error(line, "array size must be a constant integer expression", "");
return true; return true;
} }
size = constant->getIConst(0); if (constant->getBasicType() == EbtUInt)
{
unsigned int uintSize = constant->getUConst(0);
if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
{
error(line, "array size too large", "");
size = 1;
return true;
}
if (size <= 0) { size = static_cast<int>(uintSize);
error(line, "array size must be a positive integer", ""); }
size = 1; else
return true; {
size = constant->getIConst(0);
if (size <= 0)
{
error(line, "array size must be a positive integer", "");
size = 1;
return true;
}
} }
return false; return false;
......
...@@ -49,6 +49,7 @@ void TType::buildMangledName(TString& mangledName) ...@@ -49,6 +49,7 @@ void TType::buildMangledName(TString& mangledName)
switch (type) { switch (type) {
case EbtFloat: mangledName += 'f'; break; case EbtFloat: mangledName += 'f'; break;
case EbtInt: mangledName += 'i'; break; case EbtInt: mangledName += 'i'; break;
case EbtUInt: mangledName += 'u'; break;
case EbtBool: mangledName += 'b'; break; case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break; case EbtSampler2D: mangledName += "s2"; break;
case EbtSamplerCube: mangledName += "sC"; break; case EbtSamplerCube: mangledName += "sC"; break;
......
...@@ -338,7 +338,11 @@ public: ...@@ -338,7 +338,11 @@ public:
} }
// Searches down the precisionStack for a precision qualifier for the specified TBasicType // Searches down the precisionStack for a precision qualifier for the specified TBasicType
TPrecision getDefaultPrecision( TBasicType type){ TPrecision getDefaultPrecision( TBasicType type)
{
// unsigned integers use the same precision as signed
if (type == EbtUInt) type = EbtInt;
if( type != EbtFloat && type != EbtInt ) return EbpUndefined; if( type != EbtFloat && type != EbtInt ) return EbpUndefined;
int level = static_cast<int>(precisionStack.size()) - 1; int level = static_cast<int>(precisionStack.size()) - 1;
assert( level >= 0); // Just to be safe. Should not happen. assert( level >= 0); // Just to be safe. Should not happen.
......
...@@ -146,6 +146,7 @@ public: ...@@ -146,6 +146,7 @@ public:
bool isScalar() const { return size == 1 && !matrix && !structure; } bool isScalar() const { return size == 1 && !matrix && !structure; }
bool isRegister() const { return !matrix && !structure && !array; } // Fits in a 4-element register bool isRegister() const { return !matrix && !structure && !array; } // Fits in a 4-element register
bool isStruct() const { return structure != 0; } bool isStruct() const { return structure != 0; }
bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
TTypeList* getStruct() const { return structure; } TTypeList* getStruct() const { return structure; }
void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); } void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
......
...@@ -79,6 +79,10 @@ public: ...@@ -79,6 +79,10 @@ public:
case EbtFloat: case EbtFloat:
mUsesFloatLoopIndex = true; mUsesFloatLoopIndex = true;
break; break;
case EbtUInt:
mUsesIntLoopIndex = true;
MarkLoopForUnroll(symbol, mLoopStack);
break;
case EbtInt: case EbtInt:
mUsesIntLoopIndex = true; mUsesIntLoopIndex = true;
MarkLoopForUnroll(symbol, mLoopStack); MarkLoopForUnroll(symbol, mLoopStack);
...@@ -269,7 +273,7 @@ bool ValidateLimitations::validateForLoopInit(TIntermLoop* node, ...@@ -269,7 +273,7 @@ bool ValidateLimitations::validateForLoopInit(TIntermLoop* node,
} }
// The loop index has type int or float. // The loop index has type int or float.
TBasicType type = symbol->getBasicType(); TBasicType type = symbol->getBasicType();
if ((type != EbtInt) && (type != EbtFloat)) { if ((type != EbtInt) && (type != EbtUInt) && (type != EbtFloat)) {
error(symbol->getLine(), error(symbol->getLine(),
"Invalid type for loop index", getBasicString(type)); "Invalid type for loop index", getBasicString(type));
return false; return false;
...@@ -492,7 +496,7 @@ bool ValidateLimitations::validateIndexing(TIntermBinary* node) ...@@ -492,7 +496,7 @@ bool ValidateLimitations::validateIndexing(TIntermBinary* node)
bool valid = true; bool valid = true;
TIntermTyped* index = node->getRight(); TIntermTyped* index = node->getRight();
// The index expression must have integral type. // The index expression must have integral type.
if (!index->isScalar() || (index->getBasicType() != EbtInt)) { if (!index->isScalarInt()) {
error(index->getLine(), error(index->getLine(),
"Index expression must have integral type", "Index expression must have integral type",
index->getCompleteString().c_str()); index->getCompleteString().c_str());
......
...@@ -56,6 +56,7 @@ static int check_type(yyscan_t yyscanner); ...@@ -56,6 +56,7 @@ static int check_type(yyscan_t yyscanner);
static int reserved_word(yyscan_t yyscanner); static int reserved_word(yyscan_t yyscanner);
static int ES2_reserved_ES3_keyword(TParseContext *context, int token); static int ES2_reserved_ES3_keyword(TParseContext *context, int token);
static int ES2_keyword_ES3_reserved(TParseContext *context, int token); static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
static int ES2_identifier_ES3_keyword(TParseContext *context, int token);
%} %}
%option noyywrap nounput never-interactive %option noyywrap nounput never-interactive
...@@ -118,6 +119,7 @@ O [0-7] ...@@ -118,6 +119,7 @@ O [0-7]
"float" { context->lexAfterType = true; return(FLOAT_TYPE); } "float" { context->lexAfterType = true; return(FLOAT_TYPE); }
"int" { context->lexAfterType = true; return(INT_TYPE); } "int" { context->lexAfterType = true; return(INT_TYPE); }
"uint" { return ES2_identifier_ES3_keyword(context, UINT_TYPE); }
"void" { context->lexAfterType = true; return(VOID_TYPE); } "void" { context->lexAfterType = true; return(VOID_TYPE); }
"bool" { context->lexAfterType = true; return(BOOL_TYPE); } "bool" { context->lexAfterType = true; return(BOOL_TYPE); }
"true" { yylval->lex.b = true; return(BOOLCONSTANT); } "true" { yylval->lex.b = true; return(BOOLCONSTANT); }
...@@ -409,6 +411,21 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token) ...@@ -409,6 +411,21 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token)
return token; return token;
} }
int ES2_identifier_ES3_keyword(TParseContext *context, int token)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->scanner;
// not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
if (context->shaderVersion < 300)
{
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
}
return token;
}
void yyerror(TParseContext* context, const char* reason) { void yyerror(TParseContext* context, const char* reason) {
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
......
...@@ -121,7 +121,7 @@ extern void yyerror(TParseContext* context, const char* reason); ...@@ -121,7 +121,7 @@ extern void yyerror(TParseContext* context, const char* reason);
%} %}
%token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION %token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
...@@ -219,14 +219,6 @@ primary_expression ...@@ -219,14 +219,6 @@ primary_expression
$$ = $1; $$ = $1;
} }
| INTCONSTANT { | INTCONSTANT {
//
// INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
// check for overflow for constants
//
if (abs($1.i) >= (1 << 16)) {
context->error($1.line, " integer constant overflow", "");
context->recover();
}
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst($1.i); unionArray->setIConst($1.i);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line);
...@@ -1628,15 +1620,14 @@ type_specifier_nonarray ...@@ -1628,15 +1620,14 @@ type_specifier_nonarray
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line); $$.setBasic(EbtInt, qual, $1.line);
} }
| UINT_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtUInt, qual, $1.line);
}
| BOOL_TYPE { | BOOL_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line); $$.setBasic(EbtBool, qual, $1.line);
} }
// | UNSIGNED INT_TYPE {
// PACK_UNPACK_ONLY("unsigned", $1.line);
// TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
// $$.setBasic(EbtInt, qual, $1.line);
// }
| VEC2 { | VEC2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
...@@ -2190,4 +2181,3 @@ function_definition ...@@ -2190,4 +2181,3 @@ function_definition
int glslang_parse(TParseContext* context) { int glslang_parse(TParseContext* context) {
return yyparse(context); return yyparse(context);
} }
...@@ -49,98 +49,99 @@ ...@@ -49,98 +49,99 @@
BOOL_TYPE = 265, BOOL_TYPE = 265,
FLOAT_TYPE = 266, FLOAT_TYPE = 266,
INT_TYPE = 267, INT_TYPE = 267,
BREAK = 268, UINT_TYPE = 268,
CONTINUE = 269, BREAK = 269,
DO = 270, CONTINUE = 270,
ELSE = 271, DO = 271,
FOR = 272, ELSE = 272,
IF = 273, FOR = 273,
DISCARD = 274, IF = 274,
RETURN = 275, DISCARD = 275,
SWITCH = 276, RETURN = 276,
CASE = 277, SWITCH = 277,
DEFAULT = 278, CASE = 278,
BVEC2 = 279, DEFAULT = 279,
BVEC3 = 280, BVEC2 = 280,
BVEC4 = 281, BVEC3 = 281,
IVEC2 = 282, BVEC4 = 282,
IVEC3 = 283, IVEC2 = 283,
IVEC4 = 284, IVEC3 = 284,
VEC2 = 285, IVEC4 = 285,
VEC3 = 286, VEC2 = 286,
VEC4 = 287, VEC3 = 287,
MATRIX2 = 288, VEC4 = 288,
MATRIX3 = 289, MATRIX2 = 289,
MATRIX4 = 290, MATRIX3 = 290,
IN_QUAL = 291, MATRIX4 = 291,
OUT_QUAL = 292, IN_QUAL = 292,
INOUT_QUAL = 293, OUT_QUAL = 293,
UNIFORM = 294, INOUT_QUAL = 294,
VARYING = 295, UNIFORM = 295,
CENTROID = 296, VARYING = 296,
FLAT = 297, CENTROID = 297,
SMOOTH = 298, FLAT = 298,
STRUCT = 299, SMOOTH = 299,
VOID_TYPE = 300, STRUCT = 300,
WHILE = 301, VOID_TYPE = 301,
SAMPLER2D = 302, WHILE = 302,
SAMPLERCUBE = 303, SAMPLER2D = 303,
SAMPLER_EXTERNAL_OES = 304, SAMPLERCUBE = 304,
SAMPLER2DRECT = 305, SAMPLER_EXTERNAL_OES = 305,
SAMPLER3D = 306, SAMPLER2DRECT = 306,
SAMPLER3DRECT = 307, SAMPLER3D = 307,
SAMPLER2DSHADOW = 308, SAMPLER3DRECT = 308,
IDENTIFIER = 309, SAMPLER2DSHADOW = 309,
TYPE_NAME = 310, IDENTIFIER = 310,
FLOATCONSTANT = 311, TYPE_NAME = 311,
INTCONSTANT = 312, FLOATCONSTANT = 312,
BOOLCONSTANT = 313, INTCONSTANT = 313,
FIELD_SELECTION = 314, BOOLCONSTANT = 314,
LEFT_OP = 315, FIELD_SELECTION = 315,
RIGHT_OP = 316, LEFT_OP = 316,
INC_OP = 317, RIGHT_OP = 317,
DEC_OP = 318, INC_OP = 318,
LE_OP = 319, DEC_OP = 319,
GE_OP = 320, LE_OP = 320,
EQ_OP = 321, GE_OP = 321,
NE_OP = 322, EQ_OP = 322,
AND_OP = 323, NE_OP = 323,
OR_OP = 324, AND_OP = 324,
XOR_OP = 325, OR_OP = 325,
MUL_ASSIGN = 326, XOR_OP = 326,
DIV_ASSIGN = 327, MUL_ASSIGN = 327,
ADD_ASSIGN = 328, DIV_ASSIGN = 328,
MOD_ASSIGN = 329, ADD_ASSIGN = 329,
LEFT_ASSIGN = 330, MOD_ASSIGN = 330,
RIGHT_ASSIGN = 331, LEFT_ASSIGN = 331,
AND_ASSIGN = 332, RIGHT_ASSIGN = 332,
XOR_ASSIGN = 333, AND_ASSIGN = 333,
OR_ASSIGN = 334, XOR_ASSIGN = 334,
SUB_ASSIGN = 335, OR_ASSIGN = 335,
LEFT_PAREN = 336, SUB_ASSIGN = 336,
RIGHT_PAREN = 337, LEFT_PAREN = 337,
LEFT_BRACKET = 338, RIGHT_PAREN = 338,
RIGHT_BRACKET = 339, LEFT_BRACKET = 339,
LEFT_BRACE = 340, RIGHT_BRACKET = 340,
RIGHT_BRACE = 341, LEFT_BRACE = 341,
DOT = 342, RIGHT_BRACE = 342,
COMMA = 343, DOT = 343,
COLON = 344, COMMA = 344,
EQUAL = 345, COLON = 345,
SEMICOLON = 346, EQUAL = 346,
BANG = 347, SEMICOLON = 347,
DASH = 348, BANG = 348,
TILDE = 349, DASH = 349,
PLUS = 350, TILDE = 350,
STAR = 351, PLUS = 351,
SLASH = 352, STAR = 352,
PERCENT = 353, SLASH = 353,
LEFT_ANGLE = 354, PERCENT = 354,
RIGHT_ANGLE = 355, LEFT_ANGLE = 355,
VERTICAL_BAR = 356, RIGHT_ANGLE = 356,
CARET = 357, VERTICAL_BAR = 357,
AMPERSAND = 358, CARET = 358,
QUESTION = 359 AMPERSAND = 359,
QUESTION = 360
}; };
#endif #endif
......
...@@ -223,6 +223,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -223,6 +223,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
case EOpConstructIVec2: out << "Construct ivec2"; break; case EOpConstructIVec2: out << "Construct ivec2"; break;
case EOpConstructIVec3: out << "Construct ivec3"; break; case EOpConstructIVec3: out << "Construct ivec3"; break;
case EOpConstructIVec4: out << "Construct ivec4"; break; case EOpConstructIVec4: out << "Construct ivec4"; break;
case EOpConstructUInt: out << "Construct uint"; break;
case EOpConstructMat2: out << "Construct mat2"; break; case EOpConstructMat2: out << "Construct mat2"; break;
case EOpConstructMat3: out << "Construct mat3"; break; case EOpConstructMat3: out << "Construct mat3"; break;
case EOpConstructMat4: out << "Construct mat4"; break; case EOpConstructMat4: out << "Construct mat4"; break;
...@@ -325,6 +326,10 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node) ...@@ -325,6 +326,10 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
out << node->getUnionArrayPointer()[i].getIConst(); out << node->getUnionArrayPointer()[i].getIConst();
out << " (const int)\n"; out << " (const int)\n";
break; break;
case EbtUInt:
out << node->getUnionArrayPointer()[i].getUConst();
out << " (const uint)\n";
break;
default: default:
out.message(EPrefixInternalError, "Unknown constant", node->getLine()); out.message(EPrefixInternalError, "Unknown constant", node->getLine());
break; break;
......
...@@ -145,6 +145,7 @@ enum TOperator { ...@@ -145,6 +145,7 @@ enum TOperator {
// //
EOpConstructInt, EOpConstructInt,
EOpConstructUInt,
EOpConstructBool, EOpConstructBool,
EOpConstructFloat, EOpConstructFloat,
EOpConstructVec2, EOpConstructVec2,
...@@ -248,6 +249,7 @@ public: ...@@ -248,6 +249,7 @@ public:
bool isArray() const { return type.isArray(); } bool isArray() const { return type.isArray(); }
bool isVector() const { return type.isVector(); } bool isVector() const { return type.isVector(); }
bool isScalar() const { return type.isScalar(); } bool isScalar() const { return type.isScalar(); }
bool isScalarInt() const { return type.isScalarInt(); }
bool isRegister() const { return type.isRegister(); } // Fits in a 4-element register bool isRegister() const { return type.isRegister(); } // Fits in a 4-element register
bool isStruct() const { return type.isStruct(); } bool isStruct() const { return type.isStruct(); }
const char* getBasicString() const { return type.getBasicString(); } const char* getBasicString() const { return type.getBasicString(); }
...@@ -356,6 +358,7 @@ public: ...@@ -356,6 +358,7 @@ public:
ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; } ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; } int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
int getUConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getUConst() : 0; }
float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; } float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; } bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment