Commit bfa91f47 by Jamie Madill

Redesign HLSL scoped structures to a unique ID.

A unique ID gives a more flexible renaming scheme than our current method of using nested scope identifiers. The reduced complexity allows for fewer points of breakage and fixes an outstanding bug with scoped structures (with added test). BUG=angle:618 Change-Id: I6551248bb9fa2d185ab67248721f898dd50151f0 Reviewed-on: https://chromium-review.googlesource.com/202183Reviewed-by: 's avatarNicolas Capens <nicolascapens@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 0abd523d
...@@ -136,8 +136,6 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc ...@@ -136,8 +136,6 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
mScopeDepth = 0;
mUniqueIndex = 0; mUniqueIndex = 0;
mContainsLoopDiscontinuity = false; mContainsLoopDiscontinuity = false;
...@@ -2257,17 +2255,6 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2257,17 +2255,6 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
outputLineDirective(node->getLine().first_line); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
mScopeDepth++;
if (mScopeBracket.size() < mScopeDepth)
{
mScopeBracket.push_back(0); // New scope level
}
else
{
mScopeBracket[mScopeDepth - 1]++; // New scope at existing level
}
} }
for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++) for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++)
...@@ -2283,8 +2270,6 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2283,8 +2270,6 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
outputLineDirective(node->getLine().last_line); outputLineDirective(node->getLine().last_line);
out << "}\n"; out << "}\n";
mScopeDepth--;
} }
return false; return false;
...@@ -2299,7 +2284,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2299,7 +2284,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (variable->getType().getStruct()) if (variable->getType().getStruct())
{ {
addConstructor(variable->getType(), scopedStruct(variable->getType().getStruct()->name()), NULL); addConstructor(variable->getType(), structNameString(*variable->getType().getStruct()), NULL);
} }
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
...@@ -2426,7 +2411,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2426,7 +2411,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (symbol->getType().getStruct()) if (symbol->getType().getStruct())
{ {
addConstructor(symbol->getType(), scopedStruct(symbol->getType().getStruct()->name()), NULL); addConstructor(symbol->getType(), structNameString(*symbol->getType().getStruct()), NULL);
} }
out << argumentString(symbol); out << argumentString(symbol);
...@@ -2694,8 +2679,11 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -2694,8 +2679,11 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
outputTriplet(visit, "mat4(", ", ", ")"); outputTriplet(visit, "mat4(", ", ", ")");
break; break;
case EOpConstructStruct: case EOpConstructStruct:
addConstructor(node->getType(), scopedStruct(node->getType().getStruct()->name()), &node->getSequence()); {
outputTriplet(visit, structLookup(node->getType().getStruct()->name()) + "_ctor(", ", ", ")"); const TString &structName = structNameString(*node->getType().getStruct());
addConstructor(node->getType(), structName, &node->getSequence());
outputTriplet(visit, structName + "_ctor(", ", ", ")");
}
break; break;
case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break;
case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break;
...@@ -3320,7 +3308,7 @@ TString OutputHLSL::typeString(const TType &type) ...@@ -3320,7 +3308,7 @@ TString OutputHLSL::typeString(const TType &type)
const TString& typeName = structure->name(); const TString& typeName = structure->name();
if (typeName != "") if (typeName != "")
{ {
return structLookup(typeName); return structNameString(*type.getStruct());
} }
else // Nameless structure, define in place else // Nameless structure, define in place
{ {
...@@ -3527,7 +3515,7 @@ TString OutputHLSL::structureTypeName(const TStructure &structure, bool useHLSLR ...@@ -3527,7 +3515,7 @@ TString OutputHLSL::structureTypeName(const TStructure &structure, bool useHLSLR
prefix += "rm"; prefix += "rm";
} }
return prefix + structLookup(structure.name()); return prefix + structNameString(structure);
} }
void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
...@@ -3752,7 +3740,7 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con ...@@ -3752,7 +3740,7 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
const TStructure* structure = type.getStruct(); const TStructure* structure = type.getStruct();
if (structure) if (structure)
{ {
out << structLookup(structure->name()) + "_ctor("; out << structNameString(*structure) + "_ctor(";
const TFieldList& fields = structure->fields(); const TFieldList& fields = structure->fields();
...@@ -3806,46 +3794,14 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con ...@@ -3806,46 +3794,14 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
return constUnion; return constUnion;
} }
TString OutputHLSL::scopeString(unsigned int depthLimit) TString OutputHLSL::structNameString(const TStructure &structure)
{
TString string;
for (unsigned int i = 0; i < mScopeBracket.size() && i < depthLimit; i++)
{
string += str(mScopeBracket[i]) + "_";
}
return "ss_" + string;
}
TString OutputHLSL::scopedStruct(const TString &typeName)
{
if (typeName == "")
{
return typeName;
}
return scopeString(mScopeDepth) + typeName;
}
TString OutputHLSL::structLookup(const TString &typeName)
{ {
for (int depth = mScopeDepth; depth >= 0; depth--) if (structure.name().empty())
{ {
TString scopedName = scopeString(depth) + typeName; return "";
for (StructNames::iterator structName = mStructNames.begin(); structName != mStructNames.end(); structName++)
{
if (*structName == scopedName)
{
return scopedName;
}
}
} }
UNREACHABLE(); // Should have found a matching constructor return "ss_" + str(structure.uniqueId()) + structure.name();
return typeName;
} }
TString OutputHLSL::decorate(const TString &string) TString OutputHLSL::decorate(const TString &string)
......
...@@ -74,9 +74,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -74,9 +74,7 @@ class OutputHLSL : public TIntermTraverser
void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters); void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters);
const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion); const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion);
TString scopeString(unsigned int depthLimit); TString structNameString(const TStructure &structure);
TString scopedStruct(const TString &typeName);
TString structLookup(const TString &typeName);
TParseContext &mContext; TParseContext &mContext;
const ShShaderOutput mOutputType; const ShShaderOutput mOutputType;
...@@ -162,10 +160,6 @@ class OutputHLSL : public TIntermTraverser ...@@ -162,10 +160,6 @@ class OutputHLSL : public TIntermTraverser
typedef std::list<TString> StructDeclarations; typedef std::list<TString> StructDeclarations;
StructDeclarations mStructDeclarations; StructDeclarations mStructDeclarations;
typedef std::vector<int> ScopeBracket;
ScopeBracket mScopeBracket;
unsigned int mScopeDepth;
int mUniqueIndex; // For creating unique names int mUniqueIndex; // For creating unique names
bool mContainsLoopDiscontinuity; bool mContainsLoopDiscontinuity;
......
...@@ -2567,6 +2567,8 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou ...@@ -2567,6 +2567,8 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou
TStructure* structure = new TStructure(structName, fieldList); TStructure* structure = new TStructure(structName, fieldList);
TType* structureType = new TType(structure); TType* structureType = new TType(structure);
structure->setUniqueId(TSymbolTable::nextUniqueId());
if (!structName->empty()) if (!structName->empty())
{ {
if (reservedErrorCheck(nameLine, *structName)) if (reservedErrorCheck(nameLine, *structName))
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <stdio.h> #include <stdio.h>
#include <algorithm> #include <algorithm>
int TSymbolTableLevel::uniqueId = 0; int TSymbolTable::uniqueIdCounter = 0;
// //
// Functions have buried pointers to delete. // Functions have buried pointers to delete.
...@@ -38,6 +38,30 @@ TSymbolTableLevel::~TSymbolTableLevel() ...@@ -38,6 +38,30 @@ TSymbolTableLevel::~TSymbolTableLevel()
delete (*it).second; delete (*it).second;
} }
bool TSymbolTableLevel::insert(const TString &name, TSymbol &symbol)
{
symbol.setUniqueId(TSymbolTable::nextUniqueId());
// returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(name, &symbol));
return result.second;
}
bool TSymbolTableLevel::insert(TSymbol &symbol)
{
return insert(symbol.getMangledName(), symbol);
}
TSymbol *TSymbolTableLevel::find(const TString &name) const
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
return 0;
else
return (*it).second;
}
// //
// Change all function entries in the table with the non-mangled name // Change all function entries in the table with the non-mangled name
// to be related to the provided built-in operation. This is a low // to be related to the provided built-in operation. This is a low
......
...@@ -288,29 +288,10 @@ class TSymbolTableLevel ...@@ -288,29 +288,10 @@ class TSymbolTableLevel
} }
~TSymbolTableLevel(); ~TSymbolTableLevel();
bool insert(const TString &name, TSymbol &symbol) bool insert(const TString &name, TSymbol &symbol);
{ bool insert(TSymbol &symbol);
symbol.setUniqueId(++uniqueId);
// returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(name, &symbol));
return result.second; TSymbol *find(const TString &name) const;
}
bool insert(TSymbol &symbol)
{
return insert(symbol.getMangledName(), symbol);
}
TSymbol *find(const TString &name) const
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
return 0;
else
return (*it).second;
}
void relateToOperator(const char *name, TOperator op); void relateToOperator(const char *name, TOperator op);
void relateToExtension(const char *name, const TString &ext); void relateToExtension(const char *name, const TString &ext);
...@@ -429,6 +410,11 @@ class TSymbolTable ...@@ -429,6 +410,11 @@ class TSymbolTable
// for the specified TBasicType // for the specified TBasicType
TPrecision getDefaultPrecision(TBasicType type); TPrecision getDefaultPrecision(TBasicType type);
static int nextUniqueId()
{
return ++uniqueIdCounter;
}
private: private:
ESymbolLevel currentLevel() const ESymbolLevel currentLevel() const
{ {
...@@ -438,6 +424,8 @@ class TSymbolTable ...@@ -438,6 +424,8 @@ class TSymbolTable
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;
static int uniqueIdCounter;
}; };
#endif // _SYMBOL_TABLE_INCLUDED_ #endif // _SYMBOL_TABLE_INCLUDED_
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
struct TPublicType; struct TPublicType;
class TType; class TType;
class TSymbol;
class TField class TField
{ {
...@@ -115,7 +116,8 @@ class TStructure : public TFieldListCollection ...@@ -115,7 +116,8 @@ class TStructure : public TFieldListCollection
POOL_ALLOCATOR_NEW_DELETE(); POOL_ALLOCATOR_NEW_DELETE();
TStructure(const TString *name, TFieldList *fields) TStructure(const TString *name, TFieldList *fields)
: TFieldListCollection(name, fields), : TFieldListCollection(name, fields),
mDeepestNesting(0) mDeepestNesting(0),
mUniqueId(0)
{ {
} }
...@@ -129,6 +131,17 @@ class TStructure : public TFieldListCollection ...@@ -129,6 +131,17 @@ class TStructure : public TFieldListCollection
bool equals(const TStructure &other) const; bool equals(const TStructure &other) const;
void setUniqueId(int uniqueId)
{
mUniqueId = uniqueId;
}
int uniqueId() const
{
ASSERT(mUniqueId != 0);
return mUniqueId;
}
private: private:
DISALLOW_COPY_AND_ASSIGN(TStructure); DISALLOW_COPY_AND_ASSIGN(TStructure);
virtual TString mangledNamePrefix() const virtual TString mangledNamePrefix() const
...@@ -138,6 +151,7 @@ class TStructure : public TFieldListCollection ...@@ -138,6 +151,7 @@ class TStructure : public TFieldListCollection
int calculateDeepestNesting() const; int calculateDeepestNesting() const;
mutable int mDeepestNesting; mutable int mDeepestNesting;
int mUniqueId;
}; };
class TInterfaceBlock : public TFieldListCollection class TInterfaceBlock : public TFieldListCollection
......
...@@ -12,19 +12,79 @@ protected: ...@@ -12,19 +12,79 @@ protected:
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
} }
virtual void SetUp()
{
ANGLETest::SetUp();
mVertexShaderSource = SHADER_SOURCE
(
attribute vec4 inputAttribute;
void main()
{
gl_Position = inputAttribute;
}
);
}
std::string mVertexShaderSource;
}; };
TEST_F(GLSLStructTest, scoped_structs_bug) TEST_F(GLSLStructTest, nameless_scoped_structs)
{ {
const std::string vertexShaderSource = SHADER_SOURCE const std::string fragmentShaderSource = SHADER_SOURCE
( (
attribute vec4 inputAttribute; precision mediump float;
void main() void main()
{ {
gl_Position = inputAttribute; struct
{
float q;
} b;
gl_FragColor = vec4(1, 0, 0, 1);
gl_FragColor.a += b.q;
} }
); );
GLuint program = compileProgram(mVertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program);
}
TEST_F(GLSLStructTest, scoped_structs_order_bug)
{
const std::string fragmentShaderSource = SHADER_SOURCE
(
precision mediump float;
struct T
{
float f;
};
void main()
{
T a;
struct T
{
float q;
};
T b;
gl_FragColor = vec4(1, 0, 0, 1);
gl_FragColor.a += a.f;
gl_FragColor.a += b.q;
}
);
GLuint program = compileProgram(mVertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program);
}
TEST_F(GLSLStructTest, scoped_structs_bug)
{
const std::string fragmentShaderSource = SHADER_SOURCE const std::string fragmentShaderSource = SHADER_SOURCE
( (
precision mediump float; precision mediump float;
...@@ -51,6 +111,6 @@ TEST_F(GLSLStructTest, scoped_structs_bug) ...@@ -51,6 +111,6 @@ TEST_F(GLSLStructTest, scoped_structs_bug)
} }
); );
GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource); GLuint program = compileProgram(mVertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program); EXPECT_NE(0u, program);
} }
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