Commit da6254bf by Martin Radev Committed by Commit Bot

Keep track of shader built-in declarations separately per ESSL version

The patch decouples the list of unmangled built-ins' names into levels based on the ESSL version they are from. This is required because ESSL31 and above built-ins' names should not conflict with user-declared functions in ESSL3 shaders. BUG=angleproject:1666 TEST=angle_unittest Change-Id: I731918a058629c7b6d9d15eb7eac19ce47280315 Reviewed-on: https://chromium-review.googlesource.com/420324Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent ce6bbfc8
...@@ -2548,9 +2548,11 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF ...@@ -2548,9 +2548,11 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
TFunction *prevDec = TFunction *prevDec =
static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion())); static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
if (getShaderVersion() >= 300 && symbolTable.hasUnmangledBuiltIn(function->getName().c_str())) if (getShaderVersion() >= 300 &&
symbolTable.hasUnmangledBuiltInForShaderVersion(function->getName().c_str(),
getShaderVersion()))
{ {
// With ESSL 3.00, names of built-in functions cannot be redeclared as functions. // With ESSL 3.00 and above, names of built-in functions cannot be redeclared as functions.
// Therefore overloading or redefining builtin functions is an error. // Therefore overloading or redefining builtin functions is an error.
error(location, "Name of a built-in function cannot be redeclared as function", error(location, "Name of a built-in function cannot be redeclared as function",
function->getName().c_str()); function->getName().c_str());
......
...@@ -248,7 +248,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -248,7 +248,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
{ {
if (ptype1->getBasicType() == EbtGSampler2D) if (ptype1->getBasicType() == EbtGSampler2D)
{ {
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
...@@ -259,7 +259,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -259,7 +259,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
} }
else if (ptype1->getBasicType() == EbtGSampler3D) else if (ptype1->getBasicType() == EbtGSampler3D)
{ {
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
...@@ -270,7 +270,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -270,7 +270,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
} }
else if (ptype1->getBasicType() == EbtGSamplerCube) else if (ptype1->getBasicType() == EbtGSamplerCube)
{ {
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
...@@ -281,7 +281,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -281,7 +281,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
} }
else if (ptype1->getBasicType() == EbtGSampler2DArray) else if (ptype1->getBasicType() == EbtGSampler2DArray)
{ {
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
bool gvec4 = (rvalue->getBasicType() == EbtGVec4); bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
...@@ -292,7 +292,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -292,7 +292,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
} }
else if (IsGImage(ptype1->getBasicType())) else if (IsGImage(ptype1->getBasicType()))
{ {
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
const TType *floatType = TCache::getType(EbtFloat, 4); const TType *floatType = TCache::getType(EbtFloat, 4);
const TType *intType = TCache::getType(EbtInt, 4); const TType *intType = TCache::getType(EbtInt, 4);
...@@ -330,7 +330,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -330,7 +330,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3)) else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
{ {
ASSERT(!ptype4 && !ptype5); ASSERT(!ptype4 && !ptype5);
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
SpecificType(ptype2, 1), SpecificType(ptype3, 1)); SpecificType(ptype2, 1), SpecificType(ptype3, 1));
insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
...@@ -343,7 +343,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -343,7 +343,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3)) else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
{ {
ASSERT(!ptype4 && !ptype5); ASSERT(!ptype4 && !ptype5);
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
VectorType(ptype2, 2), VectorType(ptype3, 2)); VectorType(ptype2, 2), VectorType(ptype3, 2));
insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
...@@ -377,7 +377,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, ...@@ -377,7 +377,7 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level,
function->addParameter(TConstParameter(ptype5)); function->addParameter(TConstParameter(ptype5));
} }
ASSERT(hasUnmangledBuiltIn(name)); ASSERT(hasUnmangledBuiltInAtLevel(name, level));
insert(level, function); insert(level, function);
} }
} }
...@@ -407,4 +407,43 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const ...@@ -407,4 +407,43 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
return prec; return prec;
} }
void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
{
ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
table[level]->insertUnmangledBuiltInName(std::string(name));
}
bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
{
ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
return table[level]->hasUnmangledBuiltIn(std::string(name));
}
bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
{
ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
{
if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
{
--level;
}
if (level == ESSL3_BUILTINS && shaderVersion < 300)
{
--level;
}
if (level == ESSL1_BUILTINS && shaderVersion != 100)
{
--level;
}
if (table[level]->hasUnmangledBuiltIn(name))
{
return true;
}
}
return false;
}
} // namespace sh } // namespace sh
...@@ -242,10 +242,23 @@ class TSymbolTableLevel ...@@ -242,10 +242,23 @@ class TSymbolTableLevel
void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; } void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; }
void insertUnmangledBuiltInName(const std::string &name)
{
mUnmangledBuiltInNames.insert(name);
}
bool hasUnmangledBuiltIn(const std::string &name)
{
return mUnmangledBuiltInNames.count(name) > 0;
}
protected: protected:
tLevel level; tLevel level;
std::set<std::string> mInvariantVaryings; std::set<std::string> mInvariantVaryings;
bool mGlobalInvariant; bool mGlobalInvariant;
private:
std::set<std::string> mUnmangledBuiltInNames;
}; };
// Define ESymbolLevel as int rather than an enum since level can go // Define ESymbolLevel as int rather than an enum since level can go
...@@ -360,7 +373,7 @@ class TSymbolTable : angle::NonCopyable ...@@ -360,7 +373,7 @@ class TSymbolTable : angle::NonCopyable
const TType *ptype4 = 0, const TType *ptype4 = 0,
const TType *ptype5 = 0) const TType *ptype5 = 0)
{ {
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
insertBuiltIn(level, EOpNull, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, EOpNull, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
} }
...@@ -374,7 +387,7 @@ class TSymbolTable : angle::NonCopyable ...@@ -374,7 +387,7 @@ class TSymbolTable : angle::NonCopyable
const TType *ptype4 = 0, const TType *ptype4 = 0,
const TType *ptype5 = 0) const TType *ptype5 = 0)
{ {
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
insertBuiltIn(level, EOpNull, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, EOpNull, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
} }
...@@ -388,7 +401,7 @@ class TSymbolTable : angle::NonCopyable ...@@ -388,7 +401,7 @@ class TSymbolTable : angle::NonCopyable
const TType *ptype4 = 0, const TType *ptype4 = 0,
const TType *ptype5 = 0) const TType *ptype5 = 0)
{ {
insertUnmangledBuiltIn(name); insertUnmangledBuiltInName(name, level);
insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
} }
...@@ -452,26 +465,22 @@ class TSymbolTable : angle::NonCopyable ...@@ -452,26 +465,22 @@ class TSymbolTable : angle::NonCopyable
static int nextUniqueId() { return ++uniqueIdCounter; } static int nextUniqueId() { return ++uniqueIdCounter; }
bool hasUnmangledBuiltIn(const char *name) // Checks whether there is a built-in accessible by a shader with the specified version.
{ bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion);
return mUnmangledBuiltinNames.count(std::string(name)) > 0;
}
private: private:
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); } ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
// Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00. // Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and
void insertUnmangledBuiltIn(const char *name) // above.
{ void insertUnmangledBuiltInName(const char *name, ESymbolLevel level);
mUnmangledBuiltinNames.insert(std::string(name));
} bool hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level);
std::vector<TSymbolTableLevel *> table; std::vector<TSymbolTableLevel *> table;
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel; typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector<PrecisionStackLevel *> precisionStack; std::vector<PrecisionStackLevel *> precisionStack;
std::set<std::string> mUnmangledBuiltinNames;
static int uniqueIdCounter; static int uniqueIdCounter;
}; };
......
...@@ -3328,4 +3328,22 @@ TEST_F(MalformedComputeShaderTest, SharedGlobalLayoutDeclaration) ...@@ -3328,4 +3328,22 @@ TEST_F(MalformedComputeShaderTest, SharedGlobalLayoutDeclaration)
{ {
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
} }
}
// Declaring a function with the same name as a built-in from a higher ESSL version should not cause
// a redeclaration error.
TEST_F(MalformedShaderTest, BuiltinESSL31FunctionDeclaredInESSL30Shader)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"void imageSize() {}\n"
"void main() {\n"
" imageSize();\n"
"}\n";
if (!compile(shaderString))
{
FAIL() << "Shader compilation failed, expecting success " << mInfoLog;
}
} }
\ No newline at end of file
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