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()
attributes.clear();
outputVariables.clear();
uniforms.clear();
expandedUniforms.clear();
varyings.clear();
expandedVaryings.clear();
interfaceBlocks.clear();
builtInFunctionEmulator.Cleanup();
......@@ -487,12 +489,17 @@ void TCompiler::collectVariables(TIntermNode* root)
{
CollectVariables collect(&attributes, &uniforms, &varyings, hashFunction);
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()
{
VariablePacker packer;
return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms);
}
void TCompiler::initializeGLPosition(TIntermNode* root)
......
......@@ -71,7 +71,9 @@ class TCompiler : public TShHandleBase
const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
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> &getExpandedVaryings() const { return expandedVaryings; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
ShHashFunction64 getHashFunction() const { return hashFunction; }
......@@ -136,7 +138,9 @@ class TCompiler : public TShHandleBase
std::vector<sh::Attribute> attributes;
std::vector<sh::Attribute> outputVariables;
std::vector<sh::Uniform> uniforms;
std::vector<sh::Uniform> expandedUniforms;
std::vector<sh::Varying> varyings;
std::vector<sh::Varying> expandedVaryings;
std::vector<sh::InterfaceBlock> interfaceBlocks;
private:
......
......@@ -64,9 +64,9 @@ static const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShader
case SH_ACTIVE_ATTRIBUTES:
return ReturnVariable(compiler->getAttributes(), index);
case SH_ACTIVE_UNIFORMS:
return ReturnVariable(compiler->getUniforms(), index);
return ReturnVariable(compiler->getExpandedUniforms(), index);
case SH_VARYINGS:
return ReturnVariable(compiler->getVaryings(), index);
return ReturnVariable(compiler->getExpandedVaryings(), index);
default:
UNREACHABLE();
return NULL;
......@@ -250,7 +250,7 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
*params = compiler->getInfoSink().obj.size() + 1;
break;
case SH_ACTIVE_UNIFORMS:
*params = compiler->getUniforms().size();
*params = compiler->getExpandedUniforms().size();
break;
case SH_ACTIVE_UNIFORM_MAX_LENGTH:
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
......@@ -262,7 +262,7 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
break;
case SH_VARYINGS:
*params = compiler->getVaryings().size();
*params = compiler->getExpandedVaryings().size();
break;
case SH_VARYING_MAX_LENGTH:
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
......
......@@ -8,120 +8,95 @@
#include "compiler/translator/VariableInfo.h"
#include "compiler/translator/util.h"
namespace {
TString arrayBrackets(int index)
{
TStringStream stream;
stream << "[" << index << "]";
return stream.str();
}
template <typename VarT>
void getBuiltInVariableInfo(const TType &type,
const TString &name,
const TString &mappedName,
std::vector<VarT> &infoList);
template <typename VarT>
void getUserDefinedVariableInfo(const TType &type,
const TString &name,
const TString &mappedName,
std::vector<VarT> &infoList,
ShHashFunction64 hashFunction);
static void ExpandUserDefinedVariable(const VarT &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<VarT> *expanded);
// Returns info for an attribute, uniform, or varying.
template <typename VarT>
void getVariableInfo(const TType &type,
const TString &name,
const TString &mappedName,
std::vector<VarT> &infoList,
ShHashFunction64 hashFunction)
static void ExpandVariable(const VarT &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<VarT> *expanded)
{
if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
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, hashFunction);
if (variable.isStruct())
{
if (variable.isArray())
{
for (size_t elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++)
{
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 {
getBuiltInVariableInfo(type, name, mappedName, infoList);
}
}
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
{
ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded);
}
}
else
{
varInfo.name = name.c_str();
varInfo.mappedName = mappedName.c_str();
varInfo.arraySize = 0;
VarT expandedVar = variable;
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>
void getUserDefinedVariableInfo(const TType &type,
const TString &name,
const TString &mappedName,
std::vector<VarT> &infoList,
ShHashFunction64 hashFunction)
static void ExpandUserDefinedVariable(const VarT &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
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() ?
type.getInterfaceBlock()->fields() :
type.getStruct()->fields();
for (size_t i = 0; i < fields.size(); ++i)
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
const TType& fieldType = *(fields[i]->type());
const TString& fieldName = fields[i]->name();
getVariableInfo(fieldType,
name + "." + fieldName,
mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
infoList,
hashFunction);
const VarT &field = fields[fieldIndex];
ExpandVariable(field,
name + "." + field.name,
mappedName + "." + field.mappedName,
markStaticUse,
expanded);
}
}
template <class VarT>
VarT* findVariable(const TType &type,
const TString &name,
std::vector<VarT> *infoList)
static VarT* findVariable(const TString &name,
std::vector<VarT> *infoList)
{
// TODO(zmo): optimize this function.
TString myName = name;
if (type.isArray())
myName += "[0]";
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 NULL;
}
} // namespace anonymous
CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings,
......@@ -148,14 +123,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (sh::IsVarying(symbol->getQualifier()))
{
var = findVariable(symbol->getType(), symbol->getSymbol(), mVaryings);
var = findVariable(symbol->getSymbol(), mVaryings);
}
else
{
switch (symbol->getQualifier())
{
case EvqUniform:
var = findVariable(symbol->getType(), symbol->getSymbol(), mUniforms);
var = findVariable(symbol->getSymbol(), mUniforms);
break;
case EvqFragCoord:
if (!mFragCoordAdded)
......@@ -210,19 +185,51 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
}
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,
std::vector<VarT> *infoList) const
{
TString processedSymbol;
if (mHashFunction == NULL)
processedSymbol = variable->getSymbol();
else
processedSymbol = TIntermTraverser::hash(variable->getSymbol(), mHashFunction);
getVariableInfo(variable->getType(),
variable->getSymbol(),
processedSymbol,
*infoList,
mHashFunction);
NameHashingTraverser<VarT> traverser(infoList, mHashFunction);
traverser.traverse(variable->getType(), variable->getSymbol());
}
template <typename VarT>
......@@ -281,3 +288,16 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
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 @@
#include "common/shadervars.h"
// Traverses intermediate tree to collect all attributes, uniforms, varyings.
class CollectVariables : public TIntermTraverser {
public:
class CollectVariables : public TIntermTraverser
{
public:
CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings,
......@@ -21,7 +22,7 @@ public:
virtual void visitSymbol(TIntermSymbol *symbol);
virtual bool visitAggregate(Visit, TIntermAggregate *node);
private:
private:
std::vector<sh::Attribute> *mAttribs;
std::vector<sh::Uniform> *mUniforms;
std::vector<sh::Varying> *mVaryings;
......@@ -39,4 +40,9 @@ private:
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_
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