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