Commit 23a8a433 by Jamie Madill

Store compact and expanded shader variables.

The current shader API ShGetVariableInfo relies on an expanded list of shader variables. That means that struct, or user-defined variables, are expanded into separate entries for the app to easily query struct members. The new API will preserve the struct layout, so we can store both to support both the old and new queries. BUG=angle:466 Change-Id: Id30a1d7d1bb49c7e745510e0d699f94ad3184b9c Reviewed-on: https://chromium-review.googlesource.com/206569Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarNicolas Capens <capn@chromium.org>
parent aae65a4e
...@@ -360,7 +360,9 @@ void TCompiler::clearResults() ...@@ -360,7 +360,9 @@ void TCompiler::clearResults()
attributes.clear(); attributes.clear();
outputVariables.clear(); outputVariables.clear();
uniforms.clear(); uniforms.clear();
expandedUniforms.clear();
varyings.clear(); varyings.clear();
expandedVaryings.clear();
interfaceBlocks.clear(); interfaceBlocks.clear();
builtInFunctionEmulator.Cleanup(); builtInFunctionEmulator.Cleanup();
...@@ -487,12 +489,17 @@ void TCompiler::collectVariables(TIntermNode* root) ...@@ -487,12 +489,17 @@ void TCompiler::collectVariables(TIntermNode* root)
{ {
CollectVariables collect(&attributes, &uniforms, &varyings, hashFunction); CollectVariables collect(&attributes, &uniforms, &varyings, hashFunction);
root->traverse(&collect); root->traverse(&collect);
// For backwards compatiblity with ShGetVariableInfo, expand struct
// uniforms and varyings into separate variables for each field.
ExpandVariables(uniforms, &expandedUniforms);
ExpandVariables(varyings, &expandedVaryings);
} }
bool TCompiler::enforcePackingRestrictions() bool TCompiler::enforcePackingRestrictions()
{ {
VariablePacker packer; VariablePacker packer;
return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms); return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms);
} }
void TCompiler::initializeGLPosition(TIntermNode* root) void TCompiler::initializeGLPosition(TIntermNode* root)
......
...@@ -71,7 +71,9 @@ class TCompiler : public TShHandleBase ...@@ -71,7 +71,9 @@ class TCompiler : public TShHandleBase
const std::vector<sh::Attribute> &getAttributes() const { return attributes; } const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; } const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
const std::vector<sh::Uniform> &getUniforms() const { return uniforms; } const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
const std::vector<sh::Uniform> &getExpandedUniforms() const { return expandedUniforms; }
const std::vector<sh::Varying> &getVaryings() const { return varyings; } const std::vector<sh::Varying> &getVaryings() const { return varyings; }
const std::vector<sh::Varying> &getExpandedVaryings() const { return expandedVaryings; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; } const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
ShHashFunction64 getHashFunction() const { return hashFunction; } ShHashFunction64 getHashFunction() const { return hashFunction; }
...@@ -136,7 +138,9 @@ class TCompiler : public TShHandleBase ...@@ -136,7 +138,9 @@ class TCompiler : public TShHandleBase
std::vector<sh::Attribute> attributes; std::vector<sh::Attribute> attributes;
std::vector<sh::Attribute> outputVariables; std::vector<sh::Attribute> outputVariables;
std::vector<sh::Uniform> uniforms; std::vector<sh::Uniform> uniforms;
std::vector<sh::Uniform> expandedUniforms;
std::vector<sh::Varying> varyings; std::vector<sh::Varying> varyings;
std::vector<sh::Varying> expandedVaryings;
std::vector<sh::InterfaceBlock> interfaceBlocks; std::vector<sh::InterfaceBlock> interfaceBlocks;
private: private:
......
...@@ -64,9 +64,9 @@ static const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShader ...@@ -64,9 +64,9 @@ static const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShader
case SH_ACTIVE_ATTRIBUTES: case SH_ACTIVE_ATTRIBUTES:
return ReturnVariable(compiler->getAttributes(), index); return ReturnVariable(compiler->getAttributes(), index);
case SH_ACTIVE_UNIFORMS: case SH_ACTIVE_UNIFORMS:
return ReturnVariable(compiler->getUniforms(), index); return ReturnVariable(compiler->getExpandedUniforms(), index);
case SH_VARYINGS: case SH_VARYINGS:
return ReturnVariable(compiler->getVaryings(), index); return ReturnVariable(compiler->getExpandedVaryings(), index);
default: default:
UNREACHABLE(); UNREACHABLE();
return NULL; return NULL;
...@@ -250,7 +250,7 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params) ...@@ -250,7 +250,7 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
*params = compiler->getInfoSink().obj.size() + 1; *params = compiler->getInfoSink().obj.size() + 1;
break; break;
case SH_ACTIVE_UNIFORMS: case SH_ACTIVE_UNIFORMS:
*params = compiler->getUniforms().size(); *params = compiler->getExpandedUniforms().size();
break; break;
case SH_ACTIVE_UNIFORM_MAX_LENGTH: case SH_ACTIVE_UNIFORM_MAX_LENGTH:
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
...@@ -262,7 +262,7 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params) ...@@ -262,7 +262,7 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
break; break;
case SH_VARYINGS: case SH_VARYINGS:
*params = compiler->getVaryings().size(); *params = compiler->getExpandedVaryings().size();
break; break;
case SH_VARYING_MAX_LENGTH: case SH_VARYING_MAX_LENGTH:
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
......
...@@ -8,120 +8,95 @@ ...@@ -8,120 +8,95 @@
#include "compiler/translator/VariableInfo.h" #include "compiler/translator/VariableInfo.h"
#include "compiler/translator/util.h" #include "compiler/translator/util.h"
namespace {
TString arrayBrackets(int index)
{
TStringStream stream;
stream << "[" << index << "]";
return stream.str();
}
template <typename VarT> template <typename VarT>
void getBuiltInVariableInfo(const TType &type, static void ExpandUserDefinedVariable(const VarT &variable,
const TString &name, const std::string &name,
const TString &mappedName, const std::string &mappedName,
std::vector<VarT> &infoList); bool markStaticUse,
std::vector<VarT> *expanded);
template <typename VarT>
void getUserDefinedVariableInfo(const TType &type,
const TString &name,
const TString &mappedName,
std::vector<VarT> &infoList,
ShHashFunction64 hashFunction);
// Returns info for an attribute, uniform, or varying. // Returns info for an attribute, uniform, or varying.
template <typename VarT> template <typename VarT>
void getVariableInfo(const TType &type, static void ExpandVariable(const VarT &variable,
const TString &name, const std::string &name,
const TString &mappedName, const std::string &mappedName,
std::vector<VarT> &infoList, bool markStaticUse,
ShHashFunction64 hashFunction) std::vector<VarT> *expanded)
{ {
if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) { if (variable.isStruct())
if (type.isArray()) { {
for (int i = 0; i < type.getArraySize(); ++i) { if (variable.isArray())
TString lname = name + arrayBrackets(i); {
TString lmappedName = mappedName + arrayBrackets(i); for (size_t elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++)
getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction); {
std::string lname = name + ArrayString(elementIndex);
std::string lmappedName = mappedName + ArrayString(elementIndex);
ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded);
} }
} else {
getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
} }
} else { else
getBuiltInVariableInfo(type, name, mappedName, infoList); {
} ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded);
} }
template <class VarT>
void getBuiltInVariableInfo(const TType &type,
const TString &name,
const TString &mappedName,
std::vector<VarT> &infoList)
{
ASSERT(type.getBasicType() != EbtStruct);
VarT varInfo;
if (type.isArray())
{
varInfo.name = (name + "[0]").c_str();
varInfo.mappedName = (mappedName + "[0]").c_str();
varInfo.arraySize = type.getArraySize();
} }
else else
{ {
varInfo.name = name.c_str(); VarT expandedVar = variable;
varInfo.mappedName = mappedName.c_str();
varInfo.arraySize = 0; expandedVar.name = name;
expandedVar.mappedName = mappedName;
// Mark all expanded fields as used if the parent is used
if (markStaticUse)
{
expandedVar.staticUse = true;
}
if (expandedVar.isArray())
{
expandedVar.name += "[0]";
expandedVar.mappedName += "[0]";
}
expanded->push_back(expandedVar);
} }
varInfo.precision = sh::GLVariablePrecision(type);
varInfo.type = sh::GLVariableType(type);
infoList.push_back(varInfo);
} }
template <class VarT> template <class VarT>
void getUserDefinedVariableInfo(const TType &type, static void ExpandUserDefinedVariable(const VarT &variable,
const TString &name, const std::string &name,
const TString &mappedName, const std::string &mappedName,
std::vector<VarT> &infoList, bool markStaticUse,
ShHashFunction64 hashFunction) std::vector<VarT> *expanded)
{ {
ASSERT(type.getBasicType() == EbtStruct || type.isInterfaceBlock()); ASSERT(variable.isStruct());
const std::vector<VarT> &fields = variable.fields;
const TFieldList& fields = type.isInterfaceBlock() ? for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
type.getInterfaceBlock()->fields() :
type.getStruct()->fields();
for (size_t i = 0; i < fields.size(); ++i)
{ {
const TType& fieldType = *(fields[i]->type()); const VarT &field = fields[fieldIndex];
const TString& fieldName = fields[i]->name(); ExpandVariable(field,
getVariableInfo(fieldType, name + "." + field.name,
name + "." + fieldName, mappedName + "." + field.mappedName,
mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction), markStaticUse,
infoList, expanded);
hashFunction);
} }
} }
template <class VarT> template <class VarT>
VarT* findVariable(const TType &type, static VarT* findVariable(const TString &name,
const TString &name, std::vector<VarT> *infoList)
std::vector<VarT> *infoList)
{ {
// TODO(zmo): optimize this function. // TODO(zmo): optimize this function.
TString myName = name;
if (type.isArray())
myName += "[0]";
for (size_t ii = 0; ii < infoList->size(); ++ii) for (size_t ii = 0; ii < infoList->size(); ++ii)
{ {
if ((*infoList)[ii].name.c_str() == myName) if ((*infoList)[ii].name.c_str() == name)
return &((*infoList)[ii]); return &((*infoList)[ii]);
} }
return NULL; return NULL;
} }
} // namespace anonymous
CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs, CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Uniform> *uniforms, std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings, std::vector<sh::Varying> *varyings,
...@@ -148,14 +123,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -148,14 +123,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (sh::IsVarying(symbol->getQualifier())) if (sh::IsVarying(symbol->getQualifier()))
{ {
var = findVariable(symbol->getType(), symbol->getSymbol(), mVaryings); var = findVariable(symbol->getSymbol(), mVaryings);
} }
else else
{ {
switch (symbol->getQualifier()) switch (symbol->getQualifier())
{ {
case EvqUniform: case EvqUniform:
var = findVariable(symbol->getType(), symbol->getSymbol(), mUniforms); var = findVariable(symbol->getSymbol(), mUniforms);
break; break;
case EvqFragCoord: case EvqFragCoord:
if (!mFragCoordAdded) if (!mFragCoordAdded)
...@@ -210,19 +185,51 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -210,19 +185,51 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
} }
template <typename VarT> template <typename VarT>
class NameHashingTraverser : public sh::GetVariableTraverser<VarT>
{
public:
NameHashingTraverser(std::vector<VarT> *output, ShHashFunction64 hashFunction)
: sh::GetVariableTraverser<VarT>(output),
mHashFunction(hashFunction)
{}
private:
void visitVariable(VarT *variable)
{
TString stringName = TString(variable->name.c_str());
variable->mappedName = TIntermTraverser::hash(stringName, mHashFunction).c_str();
}
ShHashFunction64 mHashFunction;
};
// Attributes, which cannot have struct fields, are a special case
template <>
void CollectVariables::visitVariable(const TIntermSymbol *variable,
std::vector<sh::Attribute> *infoList) const
{
ASSERT(variable);
const TType &type = variable->getType();
ASSERT(!type.getStruct());
sh::Attribute attribute;
attribute.type = sh::GLVariableType(type);
attribute.precision = sh::GLVariablePrecision(type);
attribute.name = variable->getSymbol().c_str();
attribute.arraySize = static_cast<unsigned int>(type.getArraySize());
attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str();
attribute.location = variable->getType().getLayoutQualifier().location;
infoList->push_back(attribute);
}
template <typename VarT>
void CollectVariables::visitVariable(const TIntermSymbol *variable, void CollectVariables::visitVariable(const TIntermSymbol *variable,
std::vector<VarT> *infoList) const std::vector<VarT> *infoList) const
{ {
TString processedSymbol; NameHashingTraverser<VarT> traverser(infoList, mHashFunction);
if (mHashFunction == NULL) traverser.traverse(variable->getType(), variable->getSymbol());
processedSymbol = variable->getSymbol();
else
processedSymbol = TIntermTraverser::hash(variable->getSymbol(), mHashFunction);
getVariableInfo(variable->getType(),
variable->getSymbol(),
processedSymbol,
*infoList,
mHashFunction);
} }
template <typename VarT> template <typename VarT>
...@@ -281,3 +288,16 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) ...@@ -281,3 +288,16 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
return visitChildren; return visitChildren;
} }
template <typename VarT>
void ExpandVariables(const std::vector<VarT> &compact, std::vector<VarT> *expanded)
{
for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
{
const VarT &variable = compact[variableIndex];
ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded);
}
}
template void ExpandVariables(const std::vector<sh::Uniform> &, std::vector<sh::Uniform> *);
template void ExpandVariables(const std::vector<sh::Varying> &, std::vector<sh::Varying> *);
...@@ -11,8 +11,9 @@ ...@@ -11,8 +11,9 @@
#include "common/shadervars.h" #include "common/shadervars.h"
// Traverses intermediate tree to collect all attributes, uniforms, varyings. // Traverses intermediate tree to collect all attributes, uniforms, varyings.
class CollectVariables : public TIntermTraverser { class CollectVariables : public TIntermTraverser
public: {
public:
CollectVariables(std::vector<sh::Attribute> *attribs, CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Uniform> *uniforms, std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings, std::vector<sh::Varying> *varyings,
...@@ -21,7 +22,7 @@ public: ...@@ -21,7 +22,7 @@ public:
virtual void visitSymbol(TIntermSymbol *symbol); virtual void visitSymbol(TIntermSymbol *symbol);
virtual bool visitAggregate(Visit, TIntermAggregate *node); virtual bool visitAggregate(Visit, TIntermAggregate *node);
private: private:
std::vector<sh::Attribute> *mAttribs; std::vector<sh::Attribute> *mAttribs;
std::vector<sh::Uniform> *mUniforms; std::vector<sh::Uniform> *mUniforms;
std::vector<sh::Varying> *mVaryings; std::vector<sh::Varying> *mVaryings;
...@@ -39,4 +40,9 @@ private: ...@@ -39,4 +40,9 @@ private:
void visitInfoList(const TIntermSequence &sequence, std::vector<VarT> *infoList) const; void visitInfoList(const TIntermSequence &sequence, std::vector<VarT> *infoList) const;
}; };
// Expand struct variables to flattened lists of split variables
// Implemented for sh::Varying and sh::Uniform.
template <typename VarT>
void ExpandVariables(const std::vector<VarT> &compact, std::vector<VarT> *expanded);
#endif // COMPILER_VARIABLE_INFO_H_ #endif // COMPILER_VARIABLE_INFO_H_
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