Commit 9d2ffb1d by Jamie Madill

Refactor sh::Uniform and sh::ShaderVariable into a shader variable base type…

Refactor sh::Uniform and sh::ShaderVariable into a shader variable base type with different child types. This change gives us better memory usage (many fields are unnecessary in different types) with better static typing and clear type abstraction for specific methods that might take Attributes or Varyings, etc. TRAC #23754 Signed-off-by: Nicolas Capens Signed-off-by: Shannon Woods
parent 912cbfe8
......@@ -18,42 +18,42 @@ BlockLayoutEncoder::BlockLayoutEncoder(std::vector<BlockMemberInfo> *blockInfoOu
{
}
void BlockLayoutEncoder::encodeFields(const std::vector<Uniform> &fields)
void BlockLayoutEncoder::encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields)
{
for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
const Uniform &uniform = fields[fieldIndex];
const InterfaceBlockField &variable = fields[fieldIndex];
if (uniform.fields.size() > 0)
if (variable.fields.size() > 0)
{
const unsigned int elementCount = std::max(1u, uniform.arraySize);
const unsigned int elementCount = std::max(1u, variable.arraySize);
for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
{
enterAggregateType();
encodeFields(uniform.fields);
encodeInterfaceBlockFields(variable.fields);
exitAggregateType();
}
}
else
{
encodeType(uniform);
encodeInterfaceBlockField(variable);
}
}
}
void BlockLayoutEncoder::encodeType(const Uniform &uniform)
void BlockLayoutEncoder::encodeInterfaceBlockField(const InterfaceBlockField &field)
{
int arrayStride;
int matrixStride;
ASSERT(uniform.fields.empty());
getBlockLayoutInfo(uniform.type, uniform.arraySize, uniform.isRowMajorMatrix, &arrayStride, &matrixStride);
ASSERT(field.fields.empty());
getBlockLayoutInfo(field.type, field.arraySize, field.isRowMajorMatrix, &arrayStride, &matrixStride);
const BlockMemberInfo memberInfo(mCurrentOffset * ComponentSize, arrayStride * ComponentSize, matrixStride * ComponentSize, uniform.isRowMajorMatrix);
const BlockMemberInfo memberInfo(mCurrentOffset * ComponentSize, arrayStride * ComponentSize, matrixStride * ComponentSize, field.isRowMajorMatrix);
mBlockInfoOut->push_back(memberInfo);
advanceOffset(uniform.type, uniform.arraySize, uniform.isRowMajorMatrix, arrayStride, matrixStride);
advanceOffset(field.type, field.arraySize, field.isRowMajorMatrix, arrayStride, matrixStride);
}
void BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
......
......@@ -15,7 +15,8 @@
namespace sh
{
struct Uniform;
struct ShaderVariable;
struct InterfaceBlockField;
struct BlockMemberInfo;
class BlockLayoutEncoder
......@@ -23,8 +24,8 @@ class BlockLayoutEncoder
public:
BlockLayoutEncoder(std::vector<BlockMemberInfo> *blockInfoOut);
void encodeFields(const std::vector<Uniform> &fields);
void encodeType(const Uniform &uniform);
void encodeInterfaceBlockFields(const std::vector<InterfaceBlockField> &fields);
void encodeInterfaceBlockField(const InterfaceBlockField &field);
void encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix);
size_t getBlockSize() { return mCurrentOffset * ComponentSize; }
......
......@@ -185,7 +185,7 @@ TInfoSinkBase &OutputHLSL::getBodyStream()
return mBody;
}
const ActiveUniforms &OutputHLSL::getUniforms()
const std::vector<Uniform> &OutputHLSL::getUniforms()
{
return mActiveUniforms;
}
......@@ -195,12 +195,12 @@ const ActiveInterfaceBlocks &OutputHLSL::getInterfaceBlocks() const
return mActiveInterfaceBlocks;
}
const ActiveShaderVariables &OutputHLSL::getOutputVariables() const
const std::vector<Attribute> &OutputHLSL::getOutputVariables() const
{
return mActiveOutputVariables;
}
const ActiveShaderVariables &OutputHLSL::getAttributes() const
const std::vector<Attribute> &OutputHLSL::getAttributes() const
{
return mActiveAttributes;
}
......@@ -444,7 +444,7 @@ void setBlockLayout(InterfaceBlock *interfaceBlock, BlockLayoutType newLayout)
case BLOCKLAYOUT_PACKED:
{
HLSLBlockEncoder hlslEncoder(&interfaceBlock->blockInfo);
hlslEncoder.encodeFields(interfaceBlock->activeUniforms);
hlslEncoder.encodeInterfaceBlockFields(interfaceBlock->fields);
interfaceBlock->dataSize = hlslEncoder.getBlockSize();
}
break;
......@@ -452,7 +452,7 @@ void setBlockLayout(InterfaceBlock *interfaceBlock, BlockLayoutType newLayout)
case BLOCKLAYOUT_STANDARD:
{
Std140BlockEncoder stdEncoder(&interfaceBlock->blockInfo);
stdEncoder.encodeFields(interfaceBlock->activeUniforms);
stdEncoder.encodeInterfaceBlockFields(interfaceBlock->fields);
interfaceBlock->dataSize = stdEncoder.getBlockSize();
}
break;
......@@ -559,7 +559,7 @@ void OutputHLSL::header()
{
const TField &field = *fieldList[typeIndex];
const TString &fullUniformName = interfaceBlockFieldString(interfaceBlock, field);
declareUniformToList(*field.type(), fullUniformName, typeIndex, activeBlock.activeUniforms);
declareInterfaceBlockField(*field.type(), fullUniformName, activeBlock.fields);
}
mInterfaceBlockRegister += std::max(1u, arraySize);
......@@ -621,9 +621,9 @@ void OutputHLSL::header()
attributes += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
ShaderVariable shaderVar(glVariableType(type), glVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), type.getLayoutQualifier().location);
mActiveAttributes.push_back(shaderVar);
Attribute attributeVar(glVariableType(type), glVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), type.getLayoutQualifier().location);
mActiveAttributes.push_back(attributeVar);
}
for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++)
......@@ -656,8 +656,8 @@ void OutputHLSL::header()
out << "static " + typeString(variableType) + " out_" + variableName + arrayString(variableType) +
" = " + initializer(variableType) + ";\n";
ShaderVariable outputVar(glVariableType(variableType), glVariablePrecision(variableType), variableName.c_str(),
(unsigned int)variableType.getArraySize(), layoutQualifier.location);
Attribute outputVar(glVariableType(variableType), glVariablePrecision(variableType), variableName.c_str(),
(unsigned int)variableType.getArraySize(), layoutQualifier.location);
mActiveOutputVariables.push_back(outputVar);
}
}
......@@ -3570,18 +3570,52 @@ int OutputHLSL::uniformRegister(TIntermSymbol *uniform)
return index;
}
void OutputHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, ActiveUniforms& output)
void OutputHLSL::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);
output.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), (unsigned int)type.getArraySize(), (unsigned int)registerIndex, isRowMajorMatrix));
InterfaceBlockField field(glVariableType(type), glVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), isRowMajorMatrix);
output.push_back(field);
}
else
{
InterfaceBlockField structField(GL_NONE, 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);
}
}
void OutputHLSL::declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform>& output)
{
const TStructure *structure = type.getStruct();
if (!structure)
{
const bool isRowMajorMatrix = (type.isMatrix() && type.getLayoutQualifier().matrixPacking == EmpRowMajor);
Uniform uniform(glVariableType(type), glVariablePrecision(type), name.c_str(),
(unsigned int)type.getArraySize(), (unsigned int)registerIndex);
output.push_back(uniform);
}
else
{
Uniform structUniform(GL_NONE, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), (unsigned int)registerIndex, false);
Uniform structUniform(GL_NONE, GL_NONE, name.c_str(), (unsigned int)type.getArraySize(), (unsigned int)registerIndex);
int fieldRegister = registerIndex;
const TFieldList &fields = structure->fields();
......
......@@ -32,10 +32,10 @@ class OutputHLSL : public TIntermTraverser
void output();
TInfoSinkBase &getBodyStream();
const ActiveUniforms &getUniforms();
const std::vector<Uniform> &getUniforms();
const ActiveInterfaceBlocks &getInterfaceBlocks() const;
const ActiveShaderVariables &getOutputVariables() const;
const ActiveShaderVariables &getAttributes() const;
const std::vector<Attribute> &getOutputVariables() const;
const std::vector<Attribute> &getAttributes() const;
TString typeString(const TType &type);
TString textureString(const TType &type);
......@@ -176,7 +176,8 @@ class OutputHLSL : public TIntermTraverser
TString registerString(TIntermSymbol *operand);
int samplerRegister(TIntermSymbol *sampler);
int uniformRegister(TIntermSymbol *uniform);
void declareUniformToList(const TType &type, const TString &name, int registerIndex, ActiveUniforms& output);
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);
void declareUniform(const TType &type, const TString &name, int index);
TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field);
......@@ -197,10 +198,10 @@ class OutputHLSL : public TIntermTraverser
static bool isVaryingOut(TQualifier qualifier);
static bool isVarying(TQualifier qualifier);
ActiveUniforms mActiveUniforms;
std::vector<Uniform> mActiveUniforms;
ActiveInterfaceBlocks mActiveInterfaceBlocks;
ActiveShaderVariables mActiveOutputVariables;
ActiveShaderVariables mActiveAttributes;
std::vector<Attribute> mActiveOutputVariables;
std::vector<Attribute> mActiveAttributes;
std::map<TString, int> mStd140StructElementIndexes;
std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
......
......@@ -15,18 +15,18 @@ public:
TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
const sh::ActiveUniforms &getUniforms() { return mActiveUniforms; }
const std::vector<sh::Uniform> &getUniforms() { return mActiveUniforms; }
const sh::ActiveInterfaceBlocks &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
const sh::ActiveShaderVariables &getOutputVariables() { return mActiveOutputVariables; }
const sh::ActiveShaderVariables &getAttributes() { return mActiveAttributes; }
const std::vector<sh::Attribute> &getOutputVariables() { return mActiveOutputVariables; }
const std::vector<sh::Attribute> &getAttributes() { return mActiveAttributes; }
protected:
virtual void translate(TIntermNode* root);
sh::ActiveUniforms mActiveUniforms;
std::vector<sh::Uniform> mActiveUniforms;
sh::ActiveInterfaceBlocks mActiveInterfaceBlocks;
sh::ActiveShaderVariables mActiveOutputVariables;
sh::ActiveShaderVariables mActiveAttributes;
std::vector<sh::Attribute> mActiveOutputVariables;
std::vector<sh::Attribute> mActiveAttributes;
ShShaderOutput mOutputType;
};
......
......@@ -9,31 +9,36 @@
namespace sh
{
ShaderVariable::ShaderVariable()
: type(GL_NONE),
precision(GL_NONE),
arraySize(0),
ShaderVariable::ShaderVariable(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn)
: type(typeIn),
precision(precisionIn),
name(nameIn),
arraySize(arraySizeIn)
{
}
Uniform::Uniform(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, unsigned int registerIndexIn)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
registerIndex(registerIndexIn)
{
}
Attribute::Attribute()
: ShaderVariable(GL_NONE, GL_NONE, "", 0),
location(-1)
{
}
ShaderVariable::ShaderVariable(GLenum type, GLenum precision, const char *name, unsigned int arraySize, int location)
: type(type),
precision(precision),
name(name),
arraySize(arraySize),
location(location)
Attribute::Attribute(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, int locationIn)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
location(locationIn)
{
}
Uniform::Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex, bool isRowMajorMatrix)
InterfaceBlockField::InterfaceBlockField(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, bool isRowMajorMatrix)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn),
isRowMajorMatrix(isRowMajorMatrix)
{
this->type = type;
this->precision = precision;
this->name = name;
this->arraySize = arraySize;
this->registerIndex = registerIndex;
this->isRowMajorMatrix = isRowMajorMatrix;
}
BlockMemberInfo::BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
......
......@@ -19,34 +19,41 @@ namespace sh
struct ShaderVariable
{
ShaderVariable();
ShaderVariable(GLenum type, GLenum precision, const char *name, unsigned int arraySize, int location);
GLenum type;
GLenum precision;
std::string name;
unsigned int arraySize;
int location;
ShaderVariable(GLenum type, GLenum precision, const char *name, unsigned int arraySize);
};
typedef std::vector<ShaderVariable> ActiveShaderVariables;
struct Uniform : public ShaderVariable
{
unsigned int registerIndex;
std::vector<Uniform> fields;
struct Uniform
Uniform(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, unsigned int registerIndexIn);
bool isStruct() const { return !fields.empty(); }
};
struct Attribute : public ShaderVariable
{
Uniform(GLenum type, GLenum precision, const char *name, unsigned int arraySize, unsigned int registerIndex, bool isRowMajorMatrix);
int location;
GLenum type;
GLenum precision;
std::string name;
unsigned int arraySize;
Attribute();
Attribute(GLenum type, GLenum precision, const char *name, unsigned int arraySize, int location);
};
unsigned int registerIndex;
struct InterfaceBlockField : public ShaderVariable
{
bool isRowMajorMatrix;
std::vector<InterfaceBlockField> fields;
std::vector<Uniform> fields;
};
InterfaceBlockField(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn, bool isRowMajorMatrix);
typedef std::vector<Uniform> ActiveUniforms;
bool isStruct() const { return !fields.empty(); }
};
struct BlockMemberInfo
{
......@@ -75,11 +82,11 @@ struct InterfaceBlock
std::string name;
unsigned int arraySize;
ActiveUniforms activeUniforms;
size_t dataSize;
std::vector<BlockMemberInfo> blockInfo;
BlockLayoutType layout;
bool isRowMajorLayout;
std::vector<InterfaceBlockField> fields;
std::vector<BlockMemberInfo> blockInfo;
unsigned int registerIndex;
};
......
......@@ -158,12 +158,17 @@ class ProgramBinary : public RefCountObject
typedef sh::BlockMemberInfoArray::const_iterator BlockInfoItr;
bool areMatchingUniforms(InfoLog &infoLog, const std::string& uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
bool linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms);
template <class ShaderVarType>
bool linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar);
bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable, const sh::ShaderVariable &fragmentVariable);
bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
bool linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform> &vertexUniforms, const std::vector<sh::Uniform> &fragmentUniforms);
bool defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog);
bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock);
bool linkUniformBlocks(InfoLog &infoLog, const sh::ActiveInterfaceBlocks &vertexUniformBlocks, const sh::ActiveInterfaceBlocks &fragmentUniformBlocks);
void defineUniformBlockMembers(const sh::ActiveUniforms &uniforms, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes);
void defineUniformBlockMembers(const std::vector<sh::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes);
bool defineUniformBlock(InfoLog &infoLog, GLenum shader, const sh::InterfaceBlock &interfaceBlock);
bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex);
void defineOutputVariables(FragmentShader *fragmentShader);
......@@ -188,7 +193,7 @@ class ProgramBinary : public RefCountObject
rx::ShaderExecutable *mVertexExecutable;
rx::ShaderExecutable *mGeometryExecutable;
sh::ShaderVariable mLinkedAttribute[MAX_VERTEX_ATTRIBS];
sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
struct Sampler
......
......@@ -115,7 +115,7 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
getSourceImpl(mHlsl, bufSize, length, buffer);
}
const sh::ActiveUniforms &Shader::getUniforms() const
const std::vector<sh::Uniform> &Shader::getUniforms() const
{
return mActiveUniforms;
}
......@@ -396,7 +396,7 @@ void Shader::compileToHLSL(void *compiler)
void *activeUniforms;
ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms;
mActiveUniforms = *(std::vector<sh::Uniform>*)activeUniforms;
void *activeInterfaceBlocks;
ShGetInfoPointer(compiler, SH_ACTIVE_INTERFACE_BLOCKS_ARRAY, &activeInterfaceBlocks);
......@@ -655,7 +655,7 @@ void VertexShader::parseAttributes()
{
void *activeAttributes;
ShGetInfoPointer(mVertexCompiler, SH_ACTIVE_ATTRIBUTES_ARRAY, &activeAttributes);
mActiveAttributes = *(sh::ActiveShaderVariables*)activeAttributes;
mActiveAttributes = *(std::vector<sh::Attribute>*)activeAttributes;
}
}
......@@ -686,7 +686,7 @@ void FragmentShader::compile()
{
void *activeOutputVariables;
ShGetInfoPointer(mFragmentCompiler, SH_ACTIVE_OUTPUT_VARIABLES_ARRAY, &activeOutputVariables);
mActiveOutputVariables = *(sh::ActiveShaderVariables*)activeOutputVariables;
mActiveOutputVariables = *(std::vector<sh::Attribute>*)activeOutputVariables;
}
}
......@@ -697,7 +697,7 @@ void FragmentShader::uncompile()
mActiveOutputVariables.clear();
}
const sh::ActiveShaderVariables &FragmentShader::getOutputVariables() const
const std::vector<sh::Attribute> &FragmentShader::getOutputVariables() const
{
return mActiveOutputVariables;
}
......
......@@ -77,7 +77,7 @@ class Shader
void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
int getTranslatedSourceLength() const;
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
const sh::ActiveUniforms &getUniforms() const;
const std::vector<sh::Uniform> &getUniforms() const;
const sh::ActiveInterfaceBlocks &getInterfaceBlocks() const;
virtual void compile() = 0;
......@@ -136,7 +136,7 @@ class Shader
std::string mSource;
std::string mHlsl;
std::string mInfoLog;
sh::ActiveUniforms mActiveUniforms;
std::vector<sh::Uniform> mActiveUniforms;
sh::ActiveInterfaceBlocks mActiveInterfaceBlocks;
ResourceManager *mResourceManager;
......@@ -161,7 +161,7 @@ class VertexShader : public Shader
void parseAttributes();
sh::ActiveShaderVariables mActiveAttributes;
std::vector<sh::Attribute> mActiveAttributes;
};
class FragmentShader : public Shader
......@@ -174,12 +174,12 @@ class FragmentShader : public Shader
virtual GLenum getType();
virtual void compile();
virtual void uncompile();
const sh::ActiveShaderVariables &getOutputVariables() const;
const std::vector<sh::Attribute> &getOutputVariables() const;
private:
DISALLOW_COPY_AND_ASSIGN(FragmentShader);
sh::ActiveShaderVariables mActiveOutputVariables;
std::vector<sh::Attribute> mActiveOutputVariables;
};
}
......
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