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 ...@@ -75,13 +75,16 @@ namespace glsl
ConstantUnion constants[4]; 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() Attribute::Attribute()
...@@ -2399,55 +2402,73 @@ namespace glsl ...@@ -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 TStructure *structure = type.getStruct();
const TInterfaceBlock *block = (type.isInterfaceBlock() || (blockId == -1)) ? type.getInterfaceBlock() : nullptr;
ActiveUniforms &activeUniforms = shaderObject->activeUniforms; 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)) if(isSamplerRegister(type))
{ {
for(int i = 0; i < type.totalRegisterCount(); i++) for(int i = 0; i < type.totalRegisterCount(); i++)
{ {
shader->declareSampler(index + i); shader->declareSampler(offset + i);
} }
} }
} }
else 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()) if(type.isArray())
{ {
int elementIndex = index; int elementOffset = offset;
for(int i = 0; i < type.getArraySize(); i++) for(int i = 0; i < type.getArraySize(); i++)
{ {
int fieldOffset = (blockId == -1) ? elementOffset : 0;
for(size_t j = 0; j < fields.size(); j++) for(size_t j = 0; j < fields.size(); j++)
{ {
const TType &fieldType = *(fields[j]->type()); const TType &fieldType = *(fields[j]->type());
const TString &fieldName = fields[j]->name(); const TString &fieldName = fields[j]->name();
const TString uniformName = name + "[" + str(i) + "]." + fieldName; const TString uniformName = containerHasName ? containerName + "[" + str(i) + "]." + fieldName : fieldName;
declareUniform(fieldType, uniformName, elementIndex); declareUniform(fieldType, uniformName, fieldOffset, blockId);
elementIndex += fieldType.totalRegisterCount(); fieldOffset += fieldType.totalRegisterCount();
} }
elementOffset = fieldOffset;
} }
} }
else else
{ {
int fieldIndex = index; int fieldOffset = (blockId == -1) ? offset : 0;
for(size_t i = 0; i < fields.size(); i++) for(size_t i = 0; i < fields.size(); i++)
{ {
const TType &fieldType = *(fields[i]->type()); const TType &fieldType = *(fields[i]->type());
const TString &fieldName = fields[i]->name(); const TString &fieldName = fields[i]->name();
const TString uniformName = name + "." + fieldName; const TString uniformName = containerHasName ? containerName + "." + fieldName : fieldName;
declareUniform(fieldType, uniformName, fieldIndex); declareUniform(fieldType, uniformName, fieldOffset, blockId);
fieldIndex += fieldType.totalRegisterCount(); fieldOffset += fieldType.totalRegisterCount();
} }
} }
} }
......
...@@ -32,7 +32,7 @@ namespace glsl ...@@ -32,7 +32,7 @@ namespace glsl
{ {
struct Uniform 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 type;
GLenum precision; GLenum precision;
...@@ -40,10 +40,34 @@ namespace glsl ...@@ -40,10 +40,34 @@ namespace glsl
int arraySize; int arraySize;
int registerIndex; int registerIndex;
int blockId;
}; };
typedef std::vector<Uniform> ActiveUniforms; 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 struct Attribute
{ {
Attribute(); Attribute();
...@@ -99,6 +123,7 @@ namespace glsl ...@@ -99,6 +123,7 @@ namespace glsl
VaryingList varyings; VaryingList varyings;
ActiveUniforms activeUniforms; ActiveUniforms activeUniforms;
ActiveAttributes activeAttributes; ActiveAttributes activeAttributes;
ActiveUniformBlocks activeUniformBlocks;
}; };
struct Function struct Function
...@@ -180,7 +205,7 @@ namespace glsl ...@@ -180,7 +205,7 @@ namespace glsl
int allocate(VariableArray &list, TIntermTyped *variable); int allocate(VariableArray &list, TIntermTyped *variable);
void free(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 glVariableType(const TType &type);
GLenum glVariablePrecision(const TType &type); GLenum glVariablePrecision(const TType &type);
......
...@@ -3031,6 +3031,7 @@ void Context::applyShaders() ...@@ -3031,6 +3031,7 @@ void Context::applyShaders()
} }
programObject->applyUniforms(); programObject->applyUniforms();
programObject->applyUniformBuffers();
} }
void Context::applyTextures() void Context::applyTextures()
......
...@@ -35,9 +35,30 @@ namespace es2 ...@@ -35,9 +35,30 @@ namespace es2
return buffer; return buffer;
} }
Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex, bool rowMajorLayout)
{
if(blockIndex >= 0)
{
index = blockIndex;
offset = uniform.registerIndex;
arrayStride = UniformTypeSize(uniform.type) * uniform.arraySize;
isRowMajorMatrix = rowMajorLayout;
int rowCount = VariableRowCount(uniform.type);
matrixStride = (rowCount > 1) ? (isRowMajorMatrix ? rowCount : VariableColumnCount(uniform.type)) * UniformTypeSize(UniformComponentType(uniform.type)) : 0;
}
else
{
index = -1;
offset = -1;
arrayStride = -1;
matrixStride = -1;
isRowMajorMatrix = false;
}
}
Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
const int blockIndex, const BlockMemberInfo &blockInfo) const BlockInfo &blockInfo)
: type(type), precision(precision), name(name), arraySize(arraySize), blockIndex(blockIndex), blockInfo(blockInfo) : type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo)
{ {
int bytes = UniformTypeSize(type) * size(); int bytes = UniformTypeSize(type) * size();
data = new unsigned char[bytes]; data = new unsigned char[bytes];
...@@ -68,11 +89,26 @@ namespace es2 ...@@ -68,11 +89,26 @@ namespace es2
return size() * VariableRegisterCount(type); return size() * VariableRegisterCount(type);
} }
UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize) : UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes) :
name(name), elementIndex(elementIndex), dataSize(dataSize), psRegisterIndex(GL_INVALID_INDEX), vsRegisterIndex(GL_INVALID_INDEX) name(name), elementIndex(elementIndex), dataSize(dataSize), memberUniformIndexes(memberUniformIndexes), psRegisterIndex(GL_INVALID_INDEX), vsRegisterIndex(GL_INVALID_INDEX)
{ {
} }
void UniformBlock::setRegisterIndex(GLenum shader, unsigned int registerIndex)
{
switch(shader)
{
case GL_VERTEX_SHADER:
vsRegisterIndex = registerIndex;
break;
case GL_FRAGMENT_SHADER:
psRegisterIndex = registerIndex;
break;
default:
UNREACHABLE(shader);
}
}
bool UniformBlock::isArrayElement() const bool UniformBlock::isArrayElement() const
{ {
return elementIndex != GL_INVALID_INDEX; return elementIndex != GL_INVALID_INDEX;
...@@ -348,7 +384,7 @@ namespace es2 ...@@ -348,7 +384,7 @@ namespace es2
{ {
ASSERT(uniformBlockIndex < getActiveUniformBlockCount()); ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex]; const UniformBlock &uniformBlock = uniformBlocks[uniformBlockIndex];
switch(pname) switch(pname)
{ {
...@@ -387,7 +423,7 @@ namespace es2 ...@@ -387,7 +423,7 @@ namespace es2
unsigned int numUniformBlocks = getActiveUniformBlockCount(); unsigned int numUniformBlocks = getActiveUniformBlockCount();
for(unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) for(unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
{ {
const UniformBlock &uniformBlock = *uniformBlocks[blockIndex]; const UniformBlock &uniformBlock = uniformBlocks[blockIndex];
if(uniformBlock.name == baseName) if(uniformBlock.name == baseName)
{ {
const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
...@@ -1087,6 +1123,48 @@ namespace es2 ...@@ -1087,6 +1123,48 @@ namespace es2
} }
} }
void Program::applyUniformBuffers()
{
GLint vertexUniformBuffers[IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS];
GLint fragmentUniformBuffers[IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS];
for(unsigned int registerIndex = 0; registerIndex < IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; ++registerIndex)
{
vertexUniformBuffers[registerIndex] = -1;
}
for(unsigned int registerIndex = 0; registerIndex < IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; ++registerIndex)
{
fragmentUniformBuffers[registerIndex] = -1;
}
for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
{
UniformBlock &uniformBlock = uniformBlocks[uniformBlockIndex];
GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
// Unnecessary to apply an unreferenced standard or shared UBO
if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())
{
continue;
}
if(uniformBlock.isReferencedByVertexShader())
{
unsigned int registerIndex = uniformBlock.vsRegisterIndex;
ASSERT(vertexUniformBuffers[registerIndex] == -1);
vertexUniformBuffers[registerIndex] = blockBinding;
}
if(uniformBlock.isReferencedByFragmentShader())
{
unsigned int registerIndex = uniformBlock.psRegisterIndex;
ASSERT(fragmentUniformBuffers[registerIndex] == -1);
fragmentUniformBuffers[registerIndex] = blockBinding;
}
}
}
bool Program::linkVaryings() bool Program::linkVaryings()
{ {
for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input) for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input)
...@@ -1233,6 +1311,12 @@ namespace es2 ...@@ -1233,6 +1311,12 @@ namespace es2
return; return;
} }
// Link uniform blocks before uniforms to make it easy to assign block indices to fields
if(!linkUniformBlocks(vertexShader, fragmentShader))
{
return;
}
if(!linkUniforms(fragmentShader)) if(!linkUniforms(fragmentShader))
{ {
return; return;
...@@ -1345,7 +1429,18 @@ namespace es2 ...@@ -1345,7 +1429,18 @@ namespace es2
{ {
const glsl::Uniform &uniform = activeUniforms[uniformIndex]; const glsl::Uniform &uniform = activeUniforms[uniformIndex];
if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex)) int blockIndex = -1;
bool isRowMajorMatrix = false;
if(uniform.blockId >= 0)
{
const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks;
ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size());
UniformBlockArray::iterator it = std::find(uniformBlocks.begin(), uniformBlocks.end(), UniformBlock(activeUniformBlocks[uniform.blockId].getName(), GL_INVALID_INDEX, 0, std::vector<unsigned int>()));
ASSERT(it != uniformBlocks.end());
blockIndex = (it - uniformBlocks.begin()) / sizeof(UniformBlockArray::iterator);
isRowMajorMatrix = activeUniformBlocks[uniform.blockId].isRowMajorLayout;
}
if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex, isRowMajorMatrix)))
{ {
return false; return false;
} }
...@@ -1354,7 +1449,7 @@ namespace es2 ...@@ -1354,7 +1449,7 @@ namespace es2
return true; return true;
} }
bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex) bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo)
{ {
if(IsSamplerUniform(type)) if(IsSamplerUniform(type))
{ {
...@@ -1460,7 +1555,7 @@ namespace es2 ...@@ -1460,7 +1555,7 @@ namespace es2
} }
else else
{ {
uniform = new Uniform(type, precision, name, arraySize, -1, Uniform::BlockMemberInfo::getDefaultBlockInfo()); uniform = new Uniform(type, precision, name, arraySize, blockInfo);
} }
if(!uniform) if(!uniform)
...@@ -1510,6 +1605,117 @@ namespace es2 ...@@ -1510,6 +1605,117 @@ namespace es2
return true; return true;
} }
bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2)
{
// validate blocks for the same member types
if(block1.fields.size() != block2.fields.size())
{
return false;
}
if(block1.arraySize != block2.arraySize)
{
return false;
}
if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout)
{
return false;
}
const unsigned int numBlockMembers = block1.fields.size();
for(unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
{
const glsl::Uniform& member1 = shader1->activeUniforms[block1.fields[blockMemberIndex]];
const glsl::Uniform& member2 = shader2->activeUniforms[block2.fields[blockMemberIndex]];
if(member1.name != member2.name ||
member1.arraySize != member2.arraySize ||
member1.precision != member2.precision ||
member1.type != member2.type)
{
return false;
}
}
return true;
}
bool Program::linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader)
{
const glsl::ActiveUniformBlocks &vertexUniformBlocks = vertexShader->activeUniformBlocks;
const glsl::ActiveUniformBlocks &fragmentUniformBlocks = fragmentShader->activeUniformBlocks;
// Check that interface blocks defined in the vertex and fragment shaders are identical
typedef std::map<std::string, const glsl::UniformBlock*> UniformBlockMap;
UniformBlockMap linkedUniformBlocks;
for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
{
const glsl::UniformBlock &vertexUniformBlock = vertexUniformBlocks[blockIndex];
linkedUniformBlocks[vertexUniformBlock.name] = &vertexUniformBlock;
}
for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
{
const glsl::UniformBlock &fragmentUniformBlock = fragmentUniformBlocks[blockIndex];
UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentUniformBlock.name);
if(entry != linkedUniformBlocks.end())
{
const glsl::UniformBlock &vertexUniformBlock = *entry->second;
if(!areMatchingUniformBlocks(vertexUniformBlock, fragmentUniformBlock, vertexShader, fragmentShader))
{
return false;
}
}
}
for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
{
const glsl::UniformBlock &uniformBlock = vertexUniformBlocks[blockIndex];
if(!defineUniformBlock(vertexShader, uniformBlock))
{
return false;
}
}
for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
{
const glsl::UniformBlock &uniformBlock = fragmentUniformBlocks[blockIndex];
if(!defineUniformBlock(fragmentShader, uniformBlock))
{
return false;
}
}
return true;
}
bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block)
{
UniformBlockArray::iterator it = std::find(uniformBlocks.begin(), uniformBlocks.end(), UniformBlock(block.getName(), 0, 0, std::vector<unsigned int>()));
if(it == uniformBlocks.end())
{
const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;
const std::vector<int>& fields = block.fields;
std::vector<unsigned int> memberUniformIndexes;
for(size_t i = 0; i < fields.size(); ++i)
{
memberUniformIndexes.push_back(activeUniforms[fields[i]].registerIndex);
}
if(block.arraySize > 0)
{
for(unsigned int i = 0; i < block.arraySize; ++i)
{
uniformBlocks.push_back(UniformBlock(block.getName(), i, block.dataSize, memberUniformIndexes));
uniformBlocks[uniformBlocks.size() - 1].setRegisterIndex(shader->getType(), block.registerIndex);
}
}
else
{
uniformBlocks.push_back(UniformBlock(block.getName(), GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));
uniformBlocks[uniformBlocks.size() - 1].setRegisterIndex(shader->getType(), block.registerIndex);
}
}
else
{
it->setRegisterIndex(shader->getType(), block.registerIndex);
}
return true;
}
bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v) bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
{ {
int vector[MAX_UNIFORM_VECTORS][4]; int vector[MAX_UNIFORM_VECTORS][4];
...@@ -2336,6 +2542,7 @@ namespace es2 ...@@ -2336,6 +2542,7 @@ namespace es2
uniforms.pop_back(); uniforms.pop_back();
} }
uniformBlocks.clear();
uniformIndex.clear(); uniformIndex.clear();
transformFeedbackLinkedVaryings.clear(); transformFeedbackLinkedVaryings.clear();
...@@ -2571,7 +2778,7 @@ namespace es2 ...@@ -2571,7 +2778,7 @@ namespace es2
case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type); case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.size()); case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.size());
case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0)); case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex; case GL_UNIFORM_BLOCK_INDEX: return uniform.blockInfo.index;
case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset; case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride; case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride; case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
...@@ -2587,7 +2794,7 @@ namespace es2 ...@@ -2587,7 +2794,7 @@ namespace es2
{ {
ASSERT(index < getActiveUniformBlockCount()); ASSERT(index < getActiveUniformBlockCount());
const UniformBlock &uniformBlock = *uniformBlocks[index]; const UniformBlock &uniformBlock = uniformBlocks[index];
if(bufSize > 0) if(bufSize > 0)
{ {
...@@ -2624,7 +2831,7 @@ namespace es2 ...@@ -2624,7 +2831,7 @@ namespace es2
unsigned int numUniformBlocks = getActiveUniformBlockCount(); unsigned int numUniformBlocks = getActiveUniformBlockCount();
for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
{ {
const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex]; const UniformBlock &uniformBlock = uniformBlocks[uniformBlockIndex];
if(!uniformBlock.name.empty()) if(!uniformBlock.name.empty())
{ {
const int length = uniformBlock.name.length() + 1; const int length = uniformBlock.name.length() + 1;
......
...@@ -34,17 +34,11 @@ namespace es2 ...@@ -34,17 +34,11 @@ namespace es2
// Helper struct representing a single shader uniform // Helper struct representing a single shader uniform
struct Uniform struct Uniform
{ {
struct BlockMemberInfo struct BlockInfo
{ {
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix) BlockInfo(const glsl::Uniform& uniform, int blockIndex, bool rowMajorLayout);
: offset(offset), arrayStride(arrayStride), matrixStride(matrixStride), isRowMajorMatrix(isRowMajorMatrix)
{}
static BlockMemberInfo getDefaultBlockInfo()
{
return BlockMemberInfo(-1, -1, -1, false);
}
int index;
int offset; int offset;
int arrayStride; int arrayStride;
int matrixStride; int matrixStride;
...@@ -52,7 +46,7 @@ namespace es2 ...@@ -52,7 +46,7 @@ namespace es2
}; };
Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
const int blockIndex, const BlockMemberInfo &blockInfo); const BlockInfo &blockInfo);
~Uniform(); ~Uniform();
...@@ -64,8 +58,7 @@ namespace es2 ...@@ -64,8 +58,7 @@ namespace es2
const GLenum precision; const GLenum precision;
const std::string name; const std::string name;
const unsigned int arraySize; const unsigned int arraySize;
const int blockIndex; const BlockInfo blockInfo;
const BlockMemberInfo blockInfo;
unsigned char *data; unsigned char *data;
bool dirty; bool dirty;
...@@ -78,7 +71,12 @@ namespace es2 ...@@ -78,7 +71,12 @@ namespace es2
struct UniformBlock struct UniformBlock
{ {
// use GL_INVALID_INDEX for non-array elements // 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 isArrayElement() const;
bool isReferencedByVertexShader() const; bool isReferencedByVertexShader() const;
...@@ -172,6 +170,7 @@ namespace es2 ...@@ -172,6 +170,7 @@ namespace es2
void dirtyAllUniforms(); void dirtyAllUniforms();
void applyUniforms(); void applyUniforms();
void applyUniformBuffers();
void link(); void link();
bool isLinked() const; bool isLinked() const;
...@@ -225,7 +224,10 @@ namespace es2 ...@@ -225,7 +224,10 @@ namespace es2
int getAttributeBinding(const glsl::Attribute &attribute); int getAttributeBinding(const glsl::Attribute &attribute);
bool linkUniforms(const Shader *shader); 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 applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);
bool applyUniform2bv(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); bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);
...@@ -293,7 +295,7 @@ namespace es2 ...@@ -293,7 +295,7 @@ namespace es2
UniformArray uniforms; UniformArray uniforms;
typedef std::vector<UniformLocation> UniformIndex; typedef std::vector<UniformLocation> UniformIndex;
UniformIndex uniformIndex; UniformIndex uniformIndex;
typedef std::vector<UniformBlock*> UniformBlockArray; typedef std::vector<UniformBlock> UniformBlockArray;
UniformBlockArray uniformBlocks; UniformBlockArray uniformBlocks;
typedef std::vector<LinkedVarying> LinkedVaryingArray; typedef std::vector<LinkedVarying> LinkedVaryingArray;
LinkedVaryingArray transformFeedbackLinkedVaryings; 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