Commit 77f74853 by Jamie Madill

Add a GetVariableInfo helper method.

This method replaces the similar logic in storing uniforms, varyings, and interface blocks when collecting variable info. We can also re-use this method for both GLSL and HLSL programs. BUG=angle:466 Change-Id: Ie6c13abe0f09f38b2f9b36e117caae4833eaccbf Reviewed-on: https://chromium-review.googlesource.com/206566Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarNicolas Capens <capn@chromium.org>
parent 93455ebe
...@@ -98,6 +98,11 @@ struct Attribute : public ShaderVariable ...@@ -98,6 +98,11 @@ struct Attribute : public ShaderVariable
struct InterfaceBlockField : public ShaderVariable struct InterfaceBlockField : public ShaderVariable
{ {
InterfaceBlockField()
: ShaderVariable(0, 0, "", 0),
isRowMajorMatrix(false)
{}
InterfaceBlockField(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, bool isRowMajorMatrix) InterfaceBlockField(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, bool isRowMajorMatrix)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn), : ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
isRowMajorMatrix(isRowMajorMatrix) isRowMajorMatrix(isRowMajorMatrix)
......
...@@ -2900,31 +2900,29 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con ...@@ -2900,31 +2900,29 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
return constUnion; return constUnion;
} }
void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<Varying> &fieldsOut) class DeclareVaryingTraverser : public GetVariableTraverser<Varying>
{ {
const TStructure *structure = type.getStruct(); public:
DeclareVaryingTraverser(std::vector<Varying> *output,
InterpolationType interpolation)
: GetVariableTraverser(output),
mInterpolation(interpolation)
{}
InterpolationType interpolation = GetInterpolationType(baseTypeQualifier); private:
if (!structure) void visitVariable(Varying *varying)
{ {
sh::Varying varying(GLVariableType(type), GLVariablePrecision(type), name.c_str(), (unsigned int)type.getArraySize(), interpolation); varying->interpolation = mInterpolation;
fieldsOut.push_back(varying);
} }
else
{
sh::Varying structVarying(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), interpolation);
const TFieldList &fields = structure->fields();
structVarying.structName = structure->name().c_str(); InterpolationType mInterpolation;
};
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
const TField &field = *fields[fieldIndex];
declareVaryingToList(*field.type(), baseTypeQualifier, field.name(), structVarying.fields);
}
fieldsOut.push_back(structVarying); void OutputHLSL::declareVaryingToList(const TType &type, TQualifier baseTypeQualifier,
} const TString &name, std::vector<Varying> &fieldsOut)
{
DeclareVaryingTraverser traverser(&fieldsOut, GetInterpolationType(baseTypeQualifier));
traverser.traverse(type, name);
} }
} }
...@@ -136,54 +136,57 @@ int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TStrin ...@@ -136,54 +136,57 @@ int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TStrin
{ {
int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister); int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister);
const Uniform &uniform = declareUniformToList(type, name, registerIndex, &mActiveUniforms); declareUniformToList(type, name, registerIndex, &mActiveUniforms);
unsigned int registerCount = HLSLVariableRegisterCount(mActiveUniforms.back(), mOutputType);
if (IsSampler(type.getBasicType())) if (IsSampler(type.getBasicType()))
{ {
mSamplerRegister += HLSLVariableRegisterCount(uniform, mOutputType); mSamplerRegister += registerCount;
} }
else else
{ {
mUniformRegister += HLSLVariableRegisterCount(uniform, mOutputType); mUniformRegister += registerCount;
} }
return registerIndex; return registerIndex;
} }
Uniform UniformHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform> *output) class DeclareUniformsTraverser : public GetVariableTraverser<Uniform>
{ {
const TStructure *structure = type.getStruct(); public:
DeclareUniformsTraverser(std::vector<Uniform> *output,
unsigned int registerIndex,
ShShaderOutput outputType)
: GetVariableTraverser(output),
mRegisterIndex(registerIndex),
mOutputType(outputType)
{}
if (!structure) private:
virtual void visitVariable(Uniform *uniform)
{ {
Uniform uniform(GLVariableType(type), GLVariablePrecision(type), name.c_str(), if (!uniform->isStruct())
(unsigned int)type.getArraySize(), (unsigned int)registerIndex, 0); {
output->push_back(uniform); uniform->registerIndex = mRegisterIndex;
uniform->elementIndex = 0;
return uniform;
} }
else else
{ {
Uniform structUniform(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), // Assign register offset information.
(unsigned int)registerIndex, GL_INVALID_INDEX); // This will override the offsets in any nested structures.
HLSLVariableGetRegisterInfo(mRegisterIndex, uniform, mOutputType);
const TFieldList &fields = structure->fields(); }
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
TField *field = fields[fieldIndex];
TType *fieldType = field->type();
declareUniformToList(*fieldType, field->name(), GL_INVALID_INDEX, &structUniform.fields);
} }
// assign register offset information -- this will override the information in any sub-structures. unsigned int mRegisterIndex;
HLSLVariableGetRegisterInfo(registerIndex, &structUniform, mOutputType); ShShaderOutput mOutputType;
};
output->push_back(structUniform);
return structUniform; void UniformHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform> *output)
} {
DeclareUniformsTraverser traverser(output, registerIndex, mOutputType);
traverser.traverse(type, name);
} }
TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms) TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms)
...@@ -237,8 +240,11 @@ TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedIn ...@@ -237,8 +240,11 @@ TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedIn
for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++) for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++)
{ {
const TField &field = *fieldList[typeIndex]; const TField &field = *fieldList[typeIndex];
const TString &fullUniformName = InterfaceBlockFieldName(interfaceBlock, field); const TString &fullFieldName = InterfaceBlockFieldName(interfaceBlock, field);
declareInterfaceBlockField(*field.type(), fullUniformName, activeBlock.fields);
bool isRowMajor = (field.type()->getLayoutQualifier().matrixPacking == EmpRowMajor);
GetInterfaceBlockFieldTraverser traverser(&activeBlock.fields, isRowMajor);
traverser.traverse(*field.type(), fullFieldName);
} }
mInterfaceBlockRegister += std::max(1u, arraySize); mInterfaceBlockRegister += std::max(1u, arraySize);
...@@ -356,36 +362,4 @@ TString UniformHLSL::interfaceBlockStructString(const TInterfaceBlock &interface ...@@ -356,36 +362,4 @@ TString UniformHLSL::interfaceBlockStructString(const TInterfaceBlock &interface
"};\n\n"; "};\n\n";
} }
void UniformHLSL::declareInterfaceBlockField(const TType &type, const TString &name, std::vector<InterfaceBlockField>& output)
{
const TStructure *structure = type.getStruct();
if (!structure)
{
const bool isRowMajorMatrix = (type.isMatrix() && type.getLayoutQualifier().matrixPacking == EmpRowMajor);
InterfaceBlockField field(GLVariableType(type), GLVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), isRowMajorMatrix);
output.push_back(field);
}
else
{
InterfaceBlockField structField(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), false);
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
TField *field = fields[fieldIndex];
TType *fieldType = field->type();
// make sure to copy matrix packing information
fieldType->setLayoutQualifier(type.getLayoutQualifier());
declareInterfaceBlockField(*fieldType, field->name(), structField.fields);
}
output.push_back(structField);
}
}
} }
...@@ -40,8 +40,7 @@ class UniformHLSL ...@@ -40,8 +40,7 @@ class UniformHLSL
// Returns the uniform's register index // Returns the uniform's register index
int declareUniformAndAssignRegister(const TType &type, const TString &name); int declareUniformAndAssignRegister(const TType &type, const TString &name);
void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<InterfaceBlockField>& output); void declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform> *output);
Uniform declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform> *output);
unsigned int mUniformRegister; unsigned int mUniformRegister;
unsigned int mInterfaceBlockRegister; unsigned int mInterfaceBlockRegister;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "compiler/preprocessor/numeric_lex.h" #include "compiler/preprocessor/numeric_lex.h"
#include "common/shadervars.h" #include "common/shadervars.h"
#include "common/utilities.h"
bool atof_clamp(const char *str, float *value) bool atof_clamp(const char *str, float *value)
{ {
...@@ -279,4 +280,66 @@ InterpolationType GetInterpolationType(TQualifier qualifier) ...@@ -279,4 +280,66 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
} }
} }
template <typename VarT>
void GetVariableTraverser<VarT>::traverse(const TType &type, const TString &name)
{
const TStructure *structure = type.getStruct();
VarT variable;
variable.name = name.c_str();
variable.arraySize = static_cast<unsigned int>(type.getArraySize());
if (!structure)
{
variable.type = GLVariableType(type);
variable.precision = GLVariablePrecision(type);
}
else
{
variable.type = GL_STRUCT_ANGLEX;
mOutputStack.push(&variable.fields);
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
TField *field = fields[fieldIndex];
traverse(*field->type(), field->name());
}
mOutputStack.pop();
}
visitVariable(&variable);
ASSERT(!mOutputStack.empty());
mOutputStack.top()->push_back(variable);
}
template <typename VarT>
GetVariableTraverser<VarT>::GetVariableTraverser(std::vector<VarT> *output)
{
ASSERT(output);
mOutputStack.push(output);
}
template class GetVariableTraverser<Uniform>;
template class GetVariableTraverser<Varying>;
template class GetVariableTraverser<InterfaceBlockField>;
GetInterfaceBlockFieldTraverser::GetInterfaceBlockFieldTraverser(std::vector<InterfaceBlockField> *output, bool isRowMajorMatrix)
: GetVariableTraverser(output),
mIsRowMajorMatrix(isRowMajorMatrix)
{
}
void GetInterfaceBlockFieldTraverser::visitVariable(InterfaceBlockField *newField)
{
if (gl::IsMatrixType(newField->type))
{
newField->isRowMajorMatrix = mIsRowMajorMatrix;
}
}
} }
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#ifndef COMPILER_UTIL_H #ifndef COMPILER_UTIL_H
#define COMPILER_UTIL_H #define COMPILER_UTIL_H
#include <stack>
#include "compiler/translator/Types.h" #include "compiler/translator/Types.h"
#include "angle_gl.h" #include "angle_gl.h"
#include "common/shadervars.h" #include "common/shadervars.h"
...@@ -32,6 +34,33 @@ bool IsVarying(TQualifier qualifier); ...@@ -32,6 +34,33 @@ bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier); InterpolationType GetInterpolationType(TQualifier qualifier);
TString ArrayString(const TType &type); TString ArrayString(const TType &type);
template <typename VarT>
class GetVariableTraverser
{
public:
void traverse(const TType &type, const TString &name);
protected:
GetVariableTraverser(std::vector<VarT> *output);
// Must be overloaded
virtual void visitVariable(VarT *newVar) = 0;
private:
std::stack<std::vector<VarT> *> mOutputStack;
};
struct GetInterfaceBlockFieldTraverser : public GetVariableTraverser<InterfaceBlockField>
{
public:
GetInterfaceBlockFieldTraverser(std::vector<InterfaceBlockField> *output, bool isRowMajorMatrix);
private:
virtual void visitVariable(InterfaceBlockField *newField);
bool mIsRowMajorMatrix;
};
} }
#endif // COMPILER_UTIL_H #endif // COMPILER_UTIL_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