Commit cbefa20e by zmo@google.com

Implement user-defined name hashing.

ANGLEBUG=315 Review URL: https://codereview.appspot.com/6818109 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1388 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 54a5c033
......@@ -167,7 +167,7 @@ COMPILER_EXPORT int ShFinalize();
// The 64 bits hash function. The first parameter is the input string; the
// second parameter is the string length.
typedef khronos_uint64_t (*ShHashFunction64)(const char*, size_t);
typedef khronos_uint64_t (*ShHashFunction64)(const char*, unsigned int);
//
// Implementation dependent built-in resources (constants and extensions).
......
......@@ -195,7 +195,8 @@ bool TCompiler::compile(const char* const shaderStrings[],
// Call mapLongVariableNames() before collectAttribsUniforms() so in
// collectAttribsUniforms() we already have the mapped symbol names and
// we could composite mapped and original variable names.
if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
// Also, if we hash all the names, then no need to do this for long names.
if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
mapLongVariableNames(root);
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
......@@ -244,6 +245,8 @@ void TCompiler::clearResults()
uniforms.clear();
builtInFunctionEmulator.Cleanup();
nameMap.clear();
}
bool TCompiler::detectRecursion(TIntermNode* root)
......@@ -319,7 +322,7 @@ bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
void TCompiler::collectAttribsUniforms(TIntermNode* root)
{
CollectAttribsUniforms collect(attribs, uniforms);
CollectAttribsUniforms collect(attribs, uniforms, hashFunction);
root->traverse(&collect);
}
......
......@@ -12,6 +12,7 @@
#include <limits.h>
#include <algorithm>
#include "compiler/HashNames.h"
#include "compiler/localintermediate.h"
#include "compiler/QualifierAlive.h"
#include "compiler/RemoveTree.h"
......@@ -1445,3 +1446,14 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine());
}
// static
TString TIntermTraverser::hash(const TString& name, ShHashFunction64 hashFunction)
{
if (hashFunction == NULL || name.empty())
return name;
khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
TStringStream stream;
stream << HASHED_NAME_PREFIX << std::hex << number;
TString hashedName = stream.str();
return hashedName;
}
......@@ -6,8 +6,11 @@
#include "compiler/OutputESSL.h"
TOutputESSL::TOutputESSL(TInfoSinkBase& objSink)
: TOutputGLSLBase(objSink)
TOutputESSL::TOutputESSL(TInfoSinkBase& objSink,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable)
: TOutputGLSLBase(objSink, hashFunction, nameMap, symbolTable)
{
}
......
......@@ -12,7 +12,10 @@
class TOutputESSL : public TOutputGLSLBase
{
public:
TOutputESSL(TInfoSinkBase& objSink);
TOutputESSL(TInfoSinkBase& objSink,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable);
protected:
virtual bool writeVariablePrecision(TPrecision precision);
......
......@@ -6,8 +6,11 @@
#include "compiler/OutputGLSL.h"
TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink)
: TOutputGLSLBase(objSink)
TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable)
: TOutputGLSLBase(objSink, hashFunction, nameMap, symbolTable)
{
}
......
......@@ -12,7 +12,10 @@
class TOutputGLSL : public TOutputGLSLBase
{
public:
TOutputGLSL(TInfoSinkBase& objSink);
TOutputGLSL(TInfoSinkBase& objSink,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable);
protected:
virtual bool writeVariablePrecision(TPrecision);
......
......@@ -9,35 +9,6 @@
namespace
{
TString getTypeName(const TType& type)
{
TInfoSinkBase out;
if (type.isMatrix())
{
out << "mat";
out << type.getNominalSize();
}
else if (type.isVector())
{
switch (type.getBasicType())
{
case EbtFloat: out << "vec"; break;
case EbtInt: out << "ivec"; break;
case EbtBool: out << "bvec"; break;
default: UNREACHABLE(); break;
}
out << type.getNominalSize();
}
else
{
if (type.getBasicType() == EbtStruct)
out << type.getTypeName();
else
out << type.getBasicString();
}
return TString(out.c_str());
}
TString arrayBrackets(const TType& type)
{
ASSERT(type.isArray());
......@@ -66,10 +37,16 @@ bool isSingleStatement(TIntermNode* node) {
}
} // namespace
TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink)
TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
mDeclaringVariables(false)
mDeclaringVariables(false),
mHashFunction(hashFunction),
mNameMap(nameMap),
mSymbolTable(symbolTable)
{
}
......@@ -101,7 +78,7 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
if ((type.getBasicType() == EbtStruct) &&
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
{
out << "struct " << type.getTypeName() << "{\n";
out << "struct " << hashName(type.getTypeName()) << "{\n";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
......@@ -110,7 +87,7 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
ASSERT(fieldType != NULL);
if (writeVariablePrecision(fieldType->getPrecision()))
out << " ";
out << getTypeName(*fieldType) << " " << fieldType->getFieldName();
out << getTypeName(*fieldType) << " " << hashName(fieldType->getFieldName());
if (fieldType->isArray())
out << arrayBrackets(*fieldType);
out << ";\n";
......@@ -140,7 +117,7 @@ void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args)
const TString& name = arg->getSymbol();
if (!name.empty())
out << " " << name;
out << " " << hashName(name);
if (type.isArray())
out << arrayBrackets(type);
......@@ -157,7 +134,7 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
if (type.getBasicType() == EbtStruct)
{
out << type.getTypeName() << "(";
out << hashName(type.getTypeName()) << "(";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
......@@ -196,7 +173,7 @@ void TOutputGLSLBase::visitSymbol(TIntermSymbol* node)
if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
out << mLoopUnroll.GetLoopIndexValue(node);
else
out << node->getSymbol();
out << hashVariableName(node->getSymbol());
if (mDeclaringVariables && node->getType().isArray())
out << arrayBrackets(node->getType());
......@@ -243,7 +220,7 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
{
out << ".";
// TODO(alokp): ASSERT
out << node->getType().getFieldName();
out << hashName(node->getType().getFieldName());
visitChildren = false;
}
break;
......@@ -467,7 +444,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
// Function declaration.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
out << " " << node->getName();
out << " " << hashName(node->getName());
out << "(";
writeFunctionParameters(node->getSequence());
......@@ -480,7 +457,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
// Function definition.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
out << " " << TFunction::unmangleName(node->getName());
out << " " << hashFunctionName(node->getName());
incrementDepth();
// Function definition node contains one or two children nodes
......@@ -510,8 +487,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
// Function call.
if (visit == PreVisit)
{
TString functionName = TFunction::unmangleName(node->getName());
out << functionName << "(";
out << hashFunctionName(node->getName()) << "(";
}
else if (visit == InVisit)
{
......@@ -572,7 +548,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
{
const TType& type = node->getType();
ASSERT(type.getBasicType() == EbtStruct);
out << type.getTypeName() << "(";
out << hashName(type.getTypeName()) << "(";
}
else if (visit == InVisit)
{
......@@ -718,3 +694,59 @@ void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) {
out << "{\n}\n"; // Empty code block.
}
}
TString TOutputGLSLBase::getTypeName(const TType& type)
{
TInfoSinkBase out;
if (type.isMatrix())
{
out << "mat";
out << type.getNominalSize();
}
else if (type.isVector())
{
switch (type.getBasicType())
{
case EbtFloat: out << "vec"; break;
case EbtInt: out << "ivec"; break;
case EbtBool: out << "bvec"; break;
default: UNREACHABLE(); break;
}
out << type.getNominalSize();
}
else
{
if (type.getBasicType() == EbtStruct)
out << hashName(type.getTypeName());
else
out << type.getBasicString();
}
return TString(out.c_str());
}
TString TOutputGLSLBase::hashName(const TString& name)
{
if (mHashFunction == NULL || name.empty())
return name;
NameMap::const_iterator it = mNameMap.find(name.c_str());
if (it != mNameMap.end())
return it->second.c_str();
TString hashedName = TIntermTraverser::hash(name, mHashFunction);
mNameMap[name.c_str()] = hashedName.c_str();
return hashedName;
}
TString TOutputGLSLBase::hashVariableName(const TString& name)
{
if (mSymbolTable.findBuiltIn(name) != NULL)
return name;
return hashName(name);
}
TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
{
TString name = TFunction::unmangleName(mangled_name);
if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main")
return name;
return hashName(name);
}
......@@ -16,7 +16,10 @@
class TOutputGLSLBase : public TIntermTraverser
{
public:
TOutputGLSLBase(TInfoSinkBase& objSink);
TOutputGLSLBase(TInfoSinkBase& objSink,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable);
protected:
TInfoSinkBase& objSink() { return mObjSink; }
......@@ -25,6 +28,7 @@ protected:
virtual bool writeVariablePrecision(TPrecision precision) = 0;
void writeFunctionParameters(const TIntermSequence& args);
const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
TString getTypeName(const TType& type);
virtual void visitSymbol(TIntermSymbol* node);
virtual void visitConstantUnion(TIntermConstantUnion* node);
......@@ -37,6 +41,15 @@ protected:
void visitCodeBlock(TIntermNode* node);
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
TString hashName(const TString& name);
// Same as hashName(), but without hashing built-in variables.
TString hashVariableName(const TString& name);
// Same as hashName(), but without hashing built-in functions.
TString hashFunctionName(const TString& mangled_name);
private:
TInfoSinkBase& mObjSink;
bool mDeclaringVariables;
......@@ -48,6 +61,12 @@ private:
DeclaredStructs mDeclaredStructs;
ForLoopUnroll mLoopUnroll;
// name hashing.
ShHashFunction64 mHashFunction;
NameMap& mNameMap;
TSymbolTable& mSymbolTable;
};
#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
......@@ -70,7 +70,8 @@ public:
int getMappedNameMaxLength() const;
ShHashFunction64 getHashFunction() const { return hashFunction; }
const NameMap& getNameMap() const { return nameMap; }
NameMap& getNameMap() { return nameMap; }
TSymbolTable& getSymbolTable() { return symbolTable; }
protected:
ShShaderType getShaderType() const { return shaderType; }
......
......@@ -23,7 +23,7 @@ void TranslatorESSL::translate(TIntermNode* root) {
sink, getShaderType() == SH_FRAGMENT_SHADER);
// Write translated shader.
TOutputESSL outputESSL(sink);
TOutputESSL outputESSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputESSL);
}
......
......@@ -36,6 +36,6 @@ void TranslatorGLSL::translate(TIntermNode* root) {
sink, false);
// Write translated shader.
TOutputGLSL outputGLSL(sink);
TOutputGLSL outputGLSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputGLSL);
}
......@@ -77,23 +77,25 @@ static void getBuiltInVariableInfo(const TType& type,
static void getUserDefinedVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
TVariableInfoList& infoList);
TVariableInfoList& infoList,
ShHashFunction64 hashFunction);
// Returns info for an attribute or uniform.
static void getVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
TVariableInfoList& infoList)
TVariableInfoList& infoList,
ShHashFunction64 hashFunction)
{
if (type.getBasicType() == EbtStruct) {
if (type.isArray()) {
for (int i = 0; i < type.getArraySize(); ++i) {
TString lname = name + arrayBrackets(i);
TString lmappedName = mappedName + arrayBrackets(i);
getUserDefinedVariableInfo(type, lname, lmappedName, infoList);
getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
}
} else {
getUserDefinedVariableInfo(type, name, mappedName, infoList);
getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
}
} else {
getBuiltInVariableInfo(type, name, mappedName, infoList);
......@@ -124,7 +126,8 @@ void getBuiltInVariableInfo(const TType& type,
void getUserDefinedVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
TVariableInfoList& infoList)
TVariableInfoList& infoList,
ShHashFunction64 hashFunction)
{
ASSERT(type.getBasicType() == EbtStruct);
......@@ -133,8 +136,9 @@ void getUserDefinedVariableInfo(const TType& type,
const TType* fieldType = (*structure)[i].type;
getVariableInfo(*fieldType,
name + "." + fieldType->getFieldName(),
mappedName + "." + fieldType->getFieldName(),
infoList);
mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction),
infoList,
hashFunction);
}
}
......@@ -149,9 +153,11 @@ TVariableInfo::TVariableInfo(ShDataType type, int size)
}
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
TVariableInfoList& uniforms)
TVariableInfoList& uniforms,
ShHashFunction64 hashFunction)
: mAttribs(attribs),
mUniforms(uniforms)
mUniforms(uniforms),
mHashFunction(hashFunction)
{
}
......@@ -206,10 +212,16 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
// cannot be initialized in a shader, we must have only
// TIntermSymbol nodes in the sequence.
ASSERT(variable != NULL);
TString processedSymbol;
if (mHashFunction == NULL)
processedSymbol = variable->getSymbol();
else
processedSymbol = TIntermTraverser::hash(variable->getOriginalSymbol(), mHashFunction);
getVariableInfo(variable->getType(),
variable->getOriginalSymbol(),
variable->getSymbol(),
infoList);
processedSymbol,
infoList,
mHashFunction);
}
}
break;
......
......@@ -27,7 +27,8 @@ typedef std::vector<TVariableInfo> TVariableInfoList;
class CollectAttribsUniforms : public TIntermTraverser {
public:
CollectAttribsUniforms(TVariableInfoList& attribs,
TVariableInfoList& uniforms);
TVariableInfoList& uniforms,
ShHashFunction64 hashFunction);
virtual void visitSymbol(TIntermSymbol*);
virtual void visitConstantUnion(TIntermConstantUnion*);
......@@ -41,6 +42,8 @@ public:
private:
TVariableInfoList& mAttribs;
TVariableInfoList& mUniforms;
ShHashFunction64 mHashFunction;
};
#endif // COMPILER_VARIABLE_INFO_H_
......@@ -16,6 +16,8 @@
#ifndef __INTERMEDIATE_H
#define __INTERMEDIATE_H
#include "GLSLANG/ShaderLang.h"
#include "compiler/Common.h"
#include "compiler/Types.h"
#include "compiler/ConstantUnion.h"
......@@ -545,6 +547,10 @@ public:
void incrementDepth() {depth++;}
void decrementDepth() {depth--;}
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
static TString hash(const TString& name, ShHashFunction64 hashFunction);
const bool preVisit;
const bool inVisit;
const bool postVisit;
......
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