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
struct InterfaceBlockField : public ShaderVariable
{
InterfaceBlockField()
: ShaderVariable(0, 0, "", 0),
isRowMajorMatrix(false)
{}
InterfaceBlockField(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, bool isRowMajorMatrix)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
isRowMajorMatrix(isRowMajorMatrix)
......
......@@ -2900,31 +2900,29 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
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);
if (!structure)
private:
void visitVariable(Varying *varying)
{
sh::Varying varying(GLVariableType(type), GLVariablePrecision(type), name.c_str(), (unsigned int)type.getArraySize(), interpolation);
fieldsOut.push_back(varying);
varying->interpolation = mInterpolation;
}
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
{
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()))
{
mSamplerRegister += HLSLVariableRegisterCount(uniform, mOutputType);
mSamplerRegister += registerCount;
}
else
{
mUniformRegister += HLSLVariableRegisterCount(uniform, mOutputType);
mUniformRegister += registerCount;
}
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();
if (!structure)
{
Uniform uniform(GLVariableType(type), GLVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), (unsigned int)registerIndex, 0);
output->push_back(uniform);
return uniform;
}
else
public:
DeclareUniformsTraverser(std::vector<Uniform> *output,
unsigned int registerIndex,
ShShaderOutput outputType)
: GetVariableTraverser(output),
mRegisterIndex(registerIndex),
mOutputType(outputType)
{}
private:
virtual void visitVariable(Uniform *uniform)
{
Uniform structUniform(GL_STRUCT_ANGLEX, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(),
(unsigned int)registerIndex, GL_INVALID_INDEX);
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
if (!uniform->isStruct())
{
TField *field = fields[fieldIndex];
TType *fieldType = field->type();
declareUniformToList(*fieldType, field->name(), GL_INVALID_INDEX, &structUniform.fields);
uniform->registerIndex = mRegisterIndex;
uniform->elementIndex = 0;
}
else
{
// Assign register offset information.
// This will override the offsets in any nested structures.
HLSLVariableGetRegisterInfo(mRegisterIndex, uniform, mOutputType);
}
}
// assign register offset information -- this will override the information in any sub-structures.
HLSLVariableGetRegisterInfo(registerIndex, &structUniform, mOutputType);
output->push_back(structUniform);
unsigned int mRegisterIndex;
ShShaderOutput mOutputType;
};
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)
......@@ -237,8 +240,11 @@ TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedIn
for (unsigned int typeIndex = 0; typeIndex < fieldList.size(); typeIndex++)
{
const TField &field = *fieldList[typeIndex];
const TString &fullUniformName = InterfaceBlockFieldName(interfaceBlock, field);
declareInterfaceBlockField(*field.type(), fullUniformName, activeBlock.fields);
const TString &fullFieldName = InterfaceBlockFieldName(interfaceBlock, field);
bool isRowMajor = (field.type()->getLayoutQualifier().matrixPacking == EmpRowMajor);
GetInterfaceBlockFieldTraverser traverser(&activeBlock.fields, isRowMajor);
traverser.traverse(*field.type(), fullFieldName);
}
mInterfaceBlockRegister += std::max(1u, arraySize);
......@@ -356,36 +362,4 @@ TString UniformHLSL::interfaceBlockStructString(const TInterfaceBlock &interface
"};\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
// Returns the uniform's register index
int declareUniformAndAssignRegister(const TType &type, const TString &name);
void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<InterfaceBlockField>& output);
Uniform declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform> *output);
void declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform> *output);
unsigned int mUniformRegister;
unsigned int mInterfaceBlockRegister;
......
......@@ -10,6 +10,7 @@
#include "compiler/preprocessor/numeric_lex.h"
#include "common/shadervars.h"
#include "common/utilities.h"
bool atof_clamp(const char *str, float *value)
{
......@@ -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 @@
#ifndef COMPILER_UTIL_H
#define COMPILER_UTIL_H
#include <stack>
#include "compiler/translator/Types.h"
#include "angle_gl.h"
#include "common/shadervars.h"
......@@ -32,6 +34,33 @@ bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier);
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
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