Commit b938c3ce by Alexis Hetu Committed by Alexis Hétu

Uniform blocks implementation

- Added support for uniform blocks in OutputASM::declareUniform - Added basic implementation of Program::applyUniformBuffers() to be completed later on when uniform buffers are implemented Change-Id: I919b59d4557bb10bb302e6b6bd0ada79553ca8bb Reviewed-on: https://swiftshader-review.googlesource.com/3651Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent f2a8c37e
......@@ -75,13 +75,16 @@ namespace glsl
ConstantUnion constants[4];
};
Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex)
Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId) :
type(type), precision(precision), name(name), arraySize(arraySize), registerIndex(registerIndex), blockId(blockId)
{
}
UniformBlock::UniformBlock(const std::string& name, const std::string& instanceName, unsigned int dataSize, unsigned int arraySize,
TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId) :
name(name), instanceName(instanceName), dataSize(dataSize), arraySize(arraySize), layout(layout),
isRowMajorLayout(isRowMajorLayout), registerIndex(registerIndex), blockId(blockId)
{
this->type = type;
this->precision = precision;
this->name = name;
this->arraySize = arraySize;
this->registerIndex = registerIndex;
}
Attribute::Attribute()
......@@ -2399,55 +2402,73 @@ namespace glsl
}
}
void OutputASM::declareUniform(const TType &type, const TString &name, int index)
void OutputASM::declareUniform(const TType &type, const TString &name, int offset, int blockId)
{
const TStructure *structure = type.getStruct();
const TInterfaceBlock *block = (type.isInterfaceBlock() || (blockId == -1)) ? type.getInterfaceBlock() : nullptr;
ActiveUniforms &activeUniforms = shaderObject->activeUniforms;
if(!structure)
if(block)
{
ActiveUniformBlocks &activeUniformBlocks = shaderObject->activeUniformBlocks;
blockId = activeUniformBlocks.size();
unsigned int dataSize = block->objectSize() * 4; // FIXME: assuming 4 bytes per element
activeUniformBlocks.push_back(UniformBlock(block->name().c_str(), block->hasInstanceName() ? block->instanceName().c_str() : std::string(), dataSize,
block->arraySize(), block->blockStorage(), block->matrixPacking() == EmpRowMajor, offset, blockId));
}
if(!structure && !block)
{
activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), index));
if(blockId >= 0)
{
shaderObject->activeUniformBlocks[blockId].fields.push_back(activeUniforms.size());
}
activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), offset, blockId));
if(isSamplerRegister(type))
{
for(int i = 0; i < type.totalRegisterCount(); i++)
{
shader->declareSampler(index + i);
shader->declareSampler(offset + i);
}
}
}
else
{
const TFieldList& fields = structure->fields();
const TFieldList& fields = structure ? structure->fields() : block->fields();
const bool containerHasName = structure || block->hasInstanceName();
const TString &containerName = structure ? name : (containerHasName ? block->instanceName() : TString());
if(type.isArray())
{
int elementIndex = index;
int elementOffset = offset;
for(int i = 0; i < type.getArraySize(); i++)
{
int fieldOffset = (blockId == -1) ? elementOffset : 0;
for(size_t j = 0; j < fields.size(); j++)
{
const TType &fieldType = *(fields[j]->type());
const TString &fieldName = fields[j]->name();
const TString uniformName = name + "[" + str(i) + "]." + fieldName;
declareUniform(fieldType, uniformName, elementIndex);
elementIndex += fieldType.totalRegisterCount();
const TString uniformName = containerHasName ? containerName + "[" + str(i) + "]." + fieldName : fieldName;
declareUniform(fieldType, uniformName, fieldOffset, blockId);
fieldOffset += fieldType.totalRegisterCount();
}
elementOffset = fieldOffset;
}
}
else
{
int fieldIndex = index;
int fieldOffset = (blockId == -1) ? offset : 0;
for(size_t i = 0; i < fields.size(); i++)
{
const TType &fieldType = *(fields[i]->type());
const TString &fieldName = fields[i]->name();
const TString uniformName = name + "." + fieldName;
declareUniform(fieldType, uniformName, fieldIndex);
fieldIndex += fieldType.totalRegisterCount();
const TString uniformName = containerHasName ? containerName + "." + fieldName : fieldName;
declareUniform(fieldType, uniformName, fieldOffset, blockId);
fieldOffset += fieldType.totalRegisterCount();
}
}
}
......
......@@ -32,7 +32,7 @@ namespace glsl
{
struct Uniform
{
Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex);
Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId);
GLenum type;
GLenum precision;
......@@ -40,10 +40,34 @@ namespace glsl
int arraySize;
int registerIndex;
int blockId;
};
typedef std::vector<Uniform> ActiveUniforms;
struct UniformBlock
{
UniformBlock(const std::string& name, const std::string& instanceName, unsigned int dataSize, unsigned int arraySize,
TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId);
const std::string& getName() const { return (instanceName.length() > 0) ? instanceName : name; }
std::string name;
std::string instanceName;
unsigned int dataSize;
unsigned int arraySize;
TLayoutBlockStorage layout;
bool isRowMajorLayout;
std::vector<int> fields;
int registerIndex;
int blockId;
};
typedef std::vector<UniformBlock> ActiveUniformBlocks;
struct Attribute
{
Attribute();
......@@ -99,6 +123,7 @@ namespace glsl
VaryingList varyings;
ActiveUniforms activeUniforms;
ActiveAttributes activeAttributes;
ActiveUniformBlocks activeUniformBlocks;
};
struct Function
......@@ -180,7 +205,7 @@ namespace glsl
int allocate(VariableArray &list, TIntermTyped *variable);
void free(VariableArray &list, TIntermTyped *variable);
void declareUniform(const TType &type, const TString &name, int index);
void declareUniform(const TType &type, const TString &name, int offset, int blockId = -1);
GLenum glVariableType(const TType &type);
GLenum glVariablePrecision(const TType &type);
......
......@@ -3031,6 +3031,7 @@ void Context::applyShaders()
}
programObject->applyUniforms();
programObject->applyUniformBuffers();
}
void Context::applyTextures()
......
......@@ -34,17 +34,11 @@ namespace es2
// Helper struct representing a single shader uniform
struct Uniform
{
struct BlockMemberInfo
struct BlockInfo
{
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset), arrayStride(arrayStride), matrixStride(matrixStride), isRowMajorMatrix(isRowMajorMatrix)
{}
static BlockMemberInfo getDefaultBlockInfo()
{
return BlockMemberInfo(-1, -1, -1, false);
}
BlockInfo(const glsl::Uniform& uniform, int blockIndex, bool rowMajorLayout);
int index;
int offset;
int arrayStride;
int matrixStride;
......@@ -52,7 +46,7 @@ namespace es2
};
Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
const int blockIndex, const BlockMemberInfo &blockInfo);
const BlockInfo &blockInfo);
~Uniform();
......@@ -64,8 +58,7 @@ namespace es2
const GLenum precision;
const std::string name;
const unsigned int arraySize;
const int blockIndex;
const BlockMemberInfo blockInfo;
const BlockInfo blockInfo;
unsigned char *data;
bool dirty;
......@@ -78,7 +71,12 @@ namespace es2
struct UniformBlock
{
// use GL_INVALID_INDEX for non-array elements
UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize);
UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes);
void setRegisterIndex(GLenum shader, unsigned int registerIndex);
// For std::find on UniformBlockArray
inline bool operator==(const UniformBlock& other) const { return name == other.name; }
bool isArrayElement() const;
bool isReferencedByVertexShader() const;
......@@ -172,6 +170,7 @@ namespace es2
void dirtyAllUniforms();
void applyUniforms();
void applyUniformBuffers();
void link();
bool isLinked() const;
......@@ -225,7 +224,10 @@ namespace es2
int getAttributeBinding(const glsl::Attribute &attribute);
bool linkUniforms(const Shader *shader);
bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex);
bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader);
bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2);
bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo);
bool defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block);
bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);
bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);
bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);
......@@ -293,7 +295,7 @@ namespace es2
UniformArray uniforms;
typedef std::vector<UniformLocation> UniformIndex;
UniformIndex uniformIndex;
typedef std::vector<UniformBlock*> UniformBlockArray;
typedef std::vector<UniformBlock> UniformBlockArray;
UniformBlockArray uniformBlocks;
typedef std::vector<LinkedVarying> LinkedVaryingArray;
LinkedVaryingArray transformFeedbackLinkedVaryings;
......
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