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;
};
......
......@@ -1078,11 +1078,11 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], F
void ProgramBinary::defineOutputVariables(FragmentShader *fragmentShader)
{
const sh::ActiveShaderVariables &outputVars = fragmentShader->getOutputVariables();
const std::vector<sh::Attribute> &outputVars = fragmentShader->getOutputVariables();
for (unsigned int outputVariableIndex = 0; outputVariableIndex < outputVars.size(); outputVariableIndex++)
{
const sh::ShaderVariable &outputVariable = outputVars[outputVariableIndex];
const sh::Attribute &outputVariable = outputVars[outputVariableIndex];
const int baseLocation = outputVariable.location == -1 ? 0 : outputVariable.location;
if (outputVariable.arraySize > 0)
......@@ -1208,10 +1208,10 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
"{\n";
int semanticIndex = 0;
const sh::ActiveShaderVariables &activeAttributes = vertexShader->mActiveAttributes;
const std::vector<sh::Attribute> &activeAttributes = vertexShader->mActiveAttributes;
for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
const sh::Attribute &attribute = activeAttributes[attributeIndex];
vertexHLSL += " " + gl_d3d::TypeString(TransposeMatrixType(attribute.type)) + " ";
vertexHLSL += decorateAttribute(attribute.name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
......@@ -1416,7 +1416,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
{
defineOutputVariables(fragmentShader);
const sh::ActiveShaderVariables &outputVars = fragmentShader->getOutputVariables();
const std::vector<sh::Attribute> &outputVars = fragmentShader->getOutputVariables();
for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
{
const VariableLocation &outputLocation = locationIt->second;
......@@ -2068,12 +2068,12 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
{
unsigned int usedLocations = 0;
const sh::ActiveShaderVariables &activeAttributes = vertexShader->mActiveAttributes;
const std::vector<sh::Attribute> &activeAttributes = vertexShader->mActiveAttributes;
// Link attributes that have a binding location
for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
const sh::Attribute &attribute = activeAttributes[attributeIndex];
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
if (location != -1) // Set by glBindAttribLocation or by location layout qualifier
......@@ -2112,7 +2112,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
// Link attributes that don't have a binding location
for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
const sh::Attribute &attribute = activeAttributes[attributeIndex];
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier
......@@ -2145,48 +2145,50 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
return true;
}
bool ProgramBinary::areMatchingUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable, const sh::ShaderVariable &fragmentVariable)
{
if (vertexUniform.type != fragmentUniform.type)
if (vertexVariable.type != fragmentVariable.type)
{
infoLog.append("Types for %s differ between vertex and fragment shaders", uniformName.c_str());
infoLog.append("Types for %s differ between vertex and fragment shaders", variableName.c_str());
return false;
}
else if (vertexUniform.arraySize != fragmentUniform.arraySize)
if (vertexVariable.arraySize != fragmentVariable.arraySize)
{
infoLog.append("Array sizes for %s differ between vertex and fragment shaders", uniformName.c_str());
infoLog.append("Array sizes for %s differ between vertex and fragment shaders", variableName.c_str());
return false;
}
else if (vertexUniform.precision != fragmentUniform.precision)
if (vertexVariable.precision != fragmentVariable.precision)
{
infoLog.append("Precisions for %s differ between vertex and fragment shaders", uniformName.c_str());
infoLog.append("Precisions for %s differ between vertex and fragment shaders", variableName.c_str());
return false;
}
else if (vertexUniform.fields.size() != fragmentUniform.fields.size())
{
infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", uniformName.c_str());
}
else if (vertexUniform.isRowMajorMatrix != fragmentUniform.isRowMajorMatrix)
return true;
}
template <class ShaderVarType>
bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar)
{
if (vertexVar.fields.size() != fragmentVar.fields.size())
{
infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", varName.c_str());
return false;
}
const unsigned int numMembers = vertexUniform.fields.size();
const unsigned int numMembers = vertexVar.fields.size();
for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++)
{
const sh::Uniform &vertexMember = vertexUniform.fields[memberIndex];
const sh::Uniform &fragmentMember = fragmentUniform.fields[memberIndex];
const ShaderVarType &vertexMember = vertexVar.fields[memberIndex];
const ShaderVarType &fragmentMember = fragmentVar.fields[memberIndex];
if (vertexMember.name != fragmentMember.name)
{
infoLog.append("Name mismatch for field %d of %s: (in vertex: '%s', in fragment: '%s')",
memberIndex, uniformName.c_str(), vertexMember.name.c_str(), fragmentMember.name.c_str());
memberIndex, varName.c_str(), vertexVar.name.c_str(), fragmentVar.name.c_str());
return false;
}
const std::string memberName = uniformName + "." + vertexUniform.name;
if (!areMatchingUniforms(infoLog, memberName, vertexMember, fragmentMember))
const std::string memberName = varName + "." + vertexVar.name;
if (!linkValidateVariables(infoLog, memberName, vertexMember, fragmentMember))
{
return false;
}
......@@ -2195,7 +2197,43 @@ bool ProgramBinary::areMatchingUniforms(InfoLog &infoLog, const std::string &uni
return true;
}
bool ProgramBinary::linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms)
bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
if (!linkValidateFields<sh::Uniform>(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
return true;
}
bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
if (vertexUniform.isRowMajorMatrix != fragmentUniform.isRowMajorMatrix)
{
infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
return false;
}
if (!linkValidateFields<sh::InterfaceBlockField>(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
return true;
}
bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<sh::Uniform> &vertexUniforms, const std::vector<sh::Uniform> &fragmentUniforms)
{
// Check that uniforms defined in the vertex and fragment shaders are identical
typedef std::map<std::string, const sh::Uniform*> UniformMap;
......@@ -2215,7 +2253,7 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &ver
{
const sh::Uniform &vertexUniform = *entry->second;
const std::string &uniformName = "uniform " + vertexUniform.name;
if (!areMatchingUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
if (!linkValidateVariables(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
......@@ -2306,7 +2344,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In
{
const sh::Uniform &field = constant.fields[fieldIndex];
const std::string &uniformName = constant.name + arrayString(elementIndex) + "." + field.name;
const sh::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize, elementRegisterIndex, field.isRowMajorMatrix);
const sh::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize, elementRegisterIndex);
if (!defineUniform(shader, fieldUniform, infoLog))
{
return false;
......@@ -2324,7 +2362,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In
const sh::Uniform &field = constant.fields[fieldIndex];
const std::string &uniformName = constant.name + "." + field.name;
sh::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize, fieldRegisterIndex, field.isRowMajorMatrix);
sh::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize, fieldRegisterIndex);
fieldUniform.fields = field.fields;
if (!defineUniform(shader, fieldUniform, infoLog))
......@@ -2447,7 +2485,7 @@ bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::Inter
const char* blockName = vertexInterfaceBlock.name.c_str();
// validate blocks for the same member types
if (vertexInterfaceBlock.activeUniforms.size() != fragmentInterfaceBlock.activeUniforms.size())
if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
{
infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
return false;
......@@ -2465,11 +2503,11 @@ bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::Inter
return false;
}
const unsigned int numBlockMembers = vertexInterfaceBlock.activeUniforms.size();
const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
{
const sh::Uniform &vertexMember = vertexInterfaceBlock.activeUniforms[blockMemberIndex];
const sh::Uniform &fragmentMember = fragmentInterfaceBlock.activeUniforms[blockMemberIndex];
const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
if (vertexMember.name != fragmentMember.name)
{
......@@ -2479,7 +2517,7 @@ bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::Inter
}
std::string uniformName = "interface block " + vertexInterfaceBlock.name + " member " + vertexMember.name;
if (!areMatchingUniforms(infoLog, uniformName, vertexMember, fragmentMember))
if (!linkValidateVariables(infoLog, uniformName, vertexMember, fragmentMember))
{
return false;
}
......@@ -2533,31 +2571,31 @@ bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const sh::ActiveInterfac
return true;
}
void ProgramBinary::defineUniformBlockMembers(const sh::ActiveUniforms &uniforms, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes)
void ProgramBinary::defineUniformBlockMembers(const std::vector<sh::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes)
{
for (unsigned int uniformIndex = 0; uniformIndex < uniforms.size(); uniformIndex++)
for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
{
const sh::Uniform &uniform = uniforms[uniformIndex];
const std::string &uniformName = (prefix.empty() ? uniform.name : prefix + "." + uniform.name);
const sh::InterfaceBlockField &field = fields[uniformIndex];
const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
if (!uniform.fields.empty())
if (!field.fields.empty())
{
if (uniform.arraySize > 0)
if (field.arraySize > 0)
{
for (unsigned int arrayElement = 0; arrayElement < uniform.arraySize; arrayElement++)
for (unsigned int arrayElement = 0; arrayElement < field.arraySize; arrayElement++)
{
const std::string uniformElementName = uniformName + arrayString(arrayElement);
defineUniformBlockMembers(uniform.fields, uniformElementName, blockIndex, blockInfoItr, blockUniformIndexes);
const std::string uniformElementName = fieldName + arrayString(arrayElement);
defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, blockInfoItr, blockUniformIndexes);
}
}
else
{
defineUniformBlockMembers(uniform.fields, uniformName, blockIndex, blockInfoItr, blockUniformIndexes);
defineUniformBlockMembers(field.fields, fieldName, blockIndex, blockInfoItr, blockUniformIndexes);
}
}
else
{
Uniform *newUniform = new Uniform(uniform.type, uniform.precision, uniformName, uniform.arraySize,
Uniform *newUniform = new Uniform(field.type, field.precision, fieldName, field.arraySize,
blockIndex, **blockInfoItr);
// add to uniform list, but not index, since uniform block uniforms have no location
......@@ -2578,7 +2616,7 @@ bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, GLenum shader, const sh
// define member uniforms
BlockInfoItr blockInfoItr = interfaceBlock.blockInfo.cbegin();
defineUniformBlockMembers(interfaceBlock.activeUniforms, "", blockIndex, &blockInfoItr, &blockUniformIndexes);
defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, &blockInfoItr, &blockUniformIndexes);
// create all the uniform blocks
if (interfaceBlock.arraySize > 0)
......
......@@ -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