Commit ec93b1d0 by Alexis Hetu Committed by Alexis Hétu

Imported a few ES3 fixes from Angle

Imported some of the more trivial bug fixes: - Added a few missing interface block cases - Added checks for varying structs - Added checks for unsized arrays - Added first-class array check for pre ES3 compilation - Added check that ES3 functions do not use builtin names (ES3 only) - Added more binary operator checks Change-Id: I3d75453f17e1123478ef7da0998e869970a7fb7d Reviewed-on: https://swiftshader-review.googlesource.com/8289Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 15060bb0
...@@ -62,6 +62,134 @@ static bool ValidateMultiplication(TOperator op, const TType &left, const TType ...@@ -62,6 +62,134 @@ static bool ValidateMultiplication(TOperator op, const TType &left, const TType
} }
} }
TOperator TypeToConstructorOperator(const TType &type)
{
switch(type.getBasicType())
{
case EbtFloat:
if(type.isMatrix())
{
switch(type.getNominalSize())
{
case 2:
switch(type.getSecondarySize())
{
case 2:
return EOpConstructMat2;
case 3:
return EOpConstructMat2x3;
case 4:
return EOpConstructMat2x4;
default:
break;
}
break;
case 3:
switch(type.getSecondarySize())
{
case 2:
return EOpConstructMat3x2;
case 3:
return EOpConstructMat3;
case 4:
return EOpConstructMat3x4;
default:
break;
}
break;
case 4:
switch(type.getSecondarySize())
{
case 2:
return EOpConstructMat4x2;
case 3:
return EOpConstructMat4x3;
case 4:
return EOpConstructMat4;
default:
break;
}
break;
}
}
else
{
switch(type.getNominalSize())
{
case 1:
return EOpConstructFloat;
case 2:
return EOpConstructVec2;
case 3:
return EOpConstructVec3;
case 4:
return EOpConstructVec4;
default:
break;
}
}
break;
case EbtInt:
switch(type.getNominalSize())
{
case 1:
return EOpConstructInt;
case 2:
return EOpConstructIVec2;
case 3:
return EOpConstructIVec3;
case 4:
return EOpConstructIVec4;
default:
break;
}
break;
case EbtUInt:
switch(type.getNominalSize())
{
case 1:
return EOpConstructUInt;
case 2:
return EOpConstructUVec2;
case 3:
return EOpConstructUVec3;
case 4:
return EOpConstructUVec4;
default:
break;
}
break;
case EbtBool:
switch(type.getNominalSize())
{
case 1:
return EOpConstructBool;
case 2:
return EOpConstructBVec2;
case 3:
return EOpConstructBVec3;
case 4:
return EOpConstructBVec4;
default:
break;
}
break;
case EbtStruct:
return EOpConstructStruct;
default:
break;
}
return EOpNull;
}
const char* getOperatorString(TOperator op) { const char* getOperatorString(TOperator op) {
switch (op) { switch (op) {
case EOpInitialize: return "="; case EOpInitialize: return "=";
...@@ -657,6 +785,17 @@ bool TIntermediate::postProcess(TIntermNode* root) ...@@ -657,6 +785,17 @@ bool TIntermediate::postProcess(TIntermNode* root)
// //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// static
TIntermTyped *TIntermTyped::CreateIndexNode(int index)
{
ConstantUnion *u = new ConstantUnion[1];
u[0].setIConst(index);
TType type(EbtInt, EbpUndefined, EvqConstExpr, 1);
TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
return node;
}
// //
// Say whether or not an operation node changes the value of a variable. // Say whether or not an operation node changes the value of a variable.
// //
......
...@@ -142,6 +142,7 @@ public: ...@@ -142,6 +142,7 @@ public:
bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier); bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *); bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation); void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
void checkInputOutputTypeIsValidES3(const TQualifier qualifier, const TPublicType &type, const TSourceLoc &qualifierLocation);
const TExtensionBehavior& extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); } const TExtensionBehavior& extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
bool supportsExtension(const char* extension); bool supportsExtension(const char* extension);
......
...@@ -121,6 +121,17 @@ bool TStructure::containsArrays() const ...@@ -121,6 +121,17 @@ bool TStructure::containsArrays() const
return false; return false;
} }
bool TStructure::containsType(TBasicType type) const
{
for(size_t i = 0; i < mFields->size(); ++i)
{
const TType *fieldType = (*mFields)[i]->type();
if(fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
return true;
}
return false;
}
bool TStructure::containsSamplers() const bool TStructure::containsSamplers() const
{ {
for(size_t i = 0; i < mFields->size(); ++i) for(size_t i = 0; i < mFields->size(); ++i)
......
...@@ -369,6 +369,7 @@ public: ...@@ -369,6 +369,7 @@ public:
{ {
if(ptype1->getBasicType() == EbtGSampler2D) if(ptype1->getBasicType() == EbtGSampler2D)
{ {
insertUnmangledBuiltIn(name);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
...@@ -376,6 +377,7 @@ public: ...@@ -376,6 +377,7 @@ public:
} }
else if(ptype1->getBasicType() == EbtGSampler3D) else if(ptype1->getBasicType() == EbtGSampler3D)
{ {
insertUnmangledBuiltIn(name);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
...@@ -383,6 +385,7 @@ public: ...@@ -383,6 +385,7 @@ public:
} }
else if(ptype1->getBasicType() == EbtGSamplerCube) else if(ptype1->getBasicType() == EbtGSamplerCube)
{ {
insertUnmangledBuiltIn(name);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
...@@ -390,6 +393,7 @@ public: ...@@ -390,6 +393,7 @@ public:
} }
else if(ptype1->getBasicType() == EbtGSampler2DArray) else if(ptype1->getBasicType() == EbtGSampler2DArray)
{ {
insertUnmangledBuiltIn(name);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
...@@ -398,6 +402,7 @@ public: ...@@ -398,6 +402,7 @@ public:
else if(IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3)) else if(IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
{ {
ASSERT(!ptype4); ASSERT(!ptype4);
insertUnmangledBuiltIn(name);
insertBuiltIn(level, op, ext, GenType(rvalue, 1), name, GenType(ptype1, 1), GenType(ptype2, 1), GenType(ptype3, 1)); insertBuiltIn(level, op, ext, GenType(rvalue, 1), name, GenType(ptype1, 1), GenType(ptype2, 1), GenType(ptype3, 1));
insertBuiltIn(level, op, ext, GenType(rvalue, 2), name, GenType(ptype1, 2), GenType(ptype2, 2), GenType(ptype3, 2)); insertBuiltIn(level, op, ext, GenType(rvalue, 2), name, GenType(ptype1, 2), GenType(ptype2, 2), GenType(ptype3, 2));
insertBuiltIn(level, op, ext, GenType(rvalue, 3), name, GenType(ptype1, 3), GenType(ptype2, 3), GenType(ptype3, 3)); insertBuiltIn(level, op, ext, GenType(rvalue, 3), name, GenType(ptype1, 3), GenType(ptype2, 3), GenType(ptype3, 3));
...@@ -406,6 +411,7 @@ public: ...@@ -406,6 +411,7 @@ public:
else if(IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3)) else if(IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
{ {
ASSERT(!ptype4); ASSERT(!ptype4);
insertUnmangledBuiltIn(name);
insertBuiltIn(level, op, ext, VecType(rvalue, 2), name, VecType(ptype1, 2), VecType(ptype2, 2), VecType(ptype3, 2)); insertBuiltIn(level, op, ext, VecType(rvalue, 2), name, VecType(ptype1, 2), VecType(ptype2, 2), VecType(ptype3, 2));
insertBuiltIn(level, op, ext, VecType(rvalue, 3), name, VecType(ptype1, 3), VecType(ptype2, 3), VecType(ptype3, 3)); insertBuiltIn(level, op, ext, VecType(rvalue, 3), name, VecType(ptype1, 3), VecType(ptype2, 3), VecType(ptype3, 3));
insertBuiltIn(level, op, ext, VecType(rvalue, 4), name, VecType(ptype1, 4), VecType(ptype2, 4), VecType(ptype3, 4)); insertBuiltIn(level, op, ext, VecType(rvalue, 4), name, VecType(ptype1, 4), VecType(ptype2, 4), VecType(ptype3, 4));
...@@ -441,17 +447,20 @@ public: ...@@ -441,17 +447,20 @@ public:
function->addParameter(param5); function->addParameter(param5);
} }
ASSERT(hasUnmangledBuiltIn(name));
insert(level, *function); insert(level, *function);
} }
} }
void insertBuiltIn(ESymbolLevel level, TOperator op, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0) void insertBuiltIn(ESymbolLevel level, TOperator op, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
{ {
insertUnmangledBuiltIn(name);
insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
} }
void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0) void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
{ {
insertUnmangledBuiltIn(name);
insertBuiltIn(level, EOpNull, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, EOpNull, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
} }
...@@ -518,6 +527,12 @@ public: ...@@ -518,6 +527,12 @@ public:
void setGlobalInvariant() { mGlobalInvariant = true; } void setGlobalInvariant() { mGlobalInvariant = true; }
bool getGlobalInvariant() const { return mGlobalInvariant; } bool getGlobalInvariant() const { return mGlobalInvariant; }
bool hasUnmangledBuiltIn(const char *name) { return mUnmangledBuiltinNames.count(std::string(name)) > 0; }
private:
// Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00.
void insertUnmangledBuiltIn(const char *name) { mUnmangledBuiltinNames.insert(std::string(name)); }
protected: protected:
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); } ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
...@@ -525,6 +540,8 @@ protected: ...@@ -525,6 +540,8 @@ protected:
typedef std::map< TBasicType, TPrecision > PrecisionStackLevel; typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
std::vector< PrecisionStackLevel > precisionStack; std::vector< PrecisionStackLevel > precisionStack;
std::set<std::string> mUnmangledBuiltinNames;
std::set<std::string> mInvariantVaryings; std::set<std::string> mInvariantVaryings;
bool mGlobalInvariant; bool mGlobalInvariant;
}; };
......
...@@ -132,6 +132,7 @@ public: ...@@ -132,6 +132,7 @@ public:
return mDeepestNesting; return mDeepestNesting;
} }
bool containsArrays() const; bool containsArrays() const;
bool containsType(TBasicType type) const;
bool containsSamplers() const; bool containsSamplers() const;
bool equals(const TStructure &other) const; bool equals(const TStructure &other) const;
...@@ -381,6 +382,7 @@ public: ...@@ -381,6 +382,7 @@ public:
int getSecondarySize() const { return secondarySize; } int getSecondarySize() const { return secondarySize; }
bool isArray() const { return array ? true : false; } bool isArray() const { return array ? true : false; }
bool isUnsizedArray() const { return array && arraySize == 0; }
int getArraySize() const { return arraySize; } int getArraySize() const { return arraySize; }
void setArraySize(int s) { array = true; arraySize = s; } void setArraySize(int s) { array = true; arraySize = s; }
int getMaxArraySize () const { return maxArraySize; } int getMaxArraySize () const { return maxArraySize; }
...@@ -468,6 +470,11 @@ public: ...@@ -468,6 +470,11 @@ public:
return structure ? structure->containsArrays() : false; return structure ? structure->containsArrays() : false;
} }
bool isStructureContainingType(TBasicType t) const
{
return structure ? structure->containsType(t) : false;
}
bool isStructureContainingSamplers() const bool isStructureContainingSamplers() const
{ {
return structure ? structure->containsSamplers() : false; return structure ? structure->containsSamplers() : false;
...@@ -576,6 +583,16 @@ struct TPublicType ...@@ -576,6 +583,16 @@ struct TPublicType
return userDef->isStructureContainingArrays(); return userDef->isStructureContainingArrays();
} }
bool isStructureContainingType(TBasicType t) const
{
if(!userDef)
{
return false;
}
return userDef->isStructureContainingType(t);
}
bool isMatrix() const bool isMatrix() const
{ {
return primarySize > 1 && secondarySize > 1; return primarySize > 1 && secondarySize > 1;
......
...@@ -238,6 +238,7 @@ enum TOperator { ...@@ -238,6 +238,7 @@ enum TOperator {
EOpBitwiseOrAssign EOpBitwiseOrAssign
}; };
extern TOperator TypeToConstructorOperator(const TType &type);
extern const char* getOperatorString(TOperator op); extern const char* getOperatorString(TOperator op);
class TIntermTraverser; class TIntermTraverser;
...@@ -334,6 +335,7 @@ public: ...@@ -334,6 +335,7 @@ public:
int registerSize() const { return type.registerSize(); } int registerSize() const { return type.registerSize(); }
int getArraySize() const { return type.getArraySize(); } int getArraySize() const { return type.getArraySize(); }
static TIntermTyped *CreateIndexNode(int index);
protected: protected:
TType type; TType type;
}; };
......
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