Commit 150f597a by Alexis Hetu Committed by Alexis Hétu

Uniform block declaration

A few aspects of block declaration are improved upon here: - Block definitions are computed and stored for later use. The data stored are the block member types and a map to convert from register offsets, based on the internal memory layout, to the std140 layout. - Declaration of block members is possible. When a block member is declared prior to the entire block being declared, OutputASM::declareUniform() will first declare the whole block and return the index of the block member. If the block member is part of an already defined block, the function declares no new variables and returns the block member's register index. Change-Id: If1368bc8de20a0f86169361d76858c3f3e34bb07 Reviewed-on: https://swiftshader-review.googlesource.com/4632Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent a5bf1adc
...@@ -2898,7 +2898,7 @@ namespace glsl ...@@ -2898,7 +2898,7 @@ namespace glsl
} }
} }
void OutputASM::declareUniform(const TType &type, const TString &name, int registerIndex, int blockId, BlockLayoutEncoder* encoder) int OutputASM::declareUniform(const TType &type, const TString &name, int registerIndex, int blockId, BlockLayoutEncoder* encoder)
{ {
const TStructure *structure = type.getStruct(); const TStructure *structure = type.getStruct();
const TInterfaceBlock *block = (type.isInterfaceBlock() || (blockId == -1)) ? type.getInterfaceBlock() : nullptr; const TInterfaceBlock *block = (type.isInterfaceBlock() || (blockId == -1)) ? type.getInterfaceBlock() : nullptr;
...@@ -2906,42 +2906,79 @@ namespace glsl ...@@ -2906,42 +2906,79 @@ namespace glsl
if(!structure && !block) if(!structure && !block)
{ {
const BlockMemberInfo blockInfo = encoder ? encoder->encodeType(type) : BlockMemberInfo::getDefaultBlockInfo();
if(blockId >= 0) if(blockId >= 0)
{ {
blockDefinitions[blockId].indexMap[registerIndex] = TypedMemberInfo(blockInfo, type);
shaderObject->activeUniformBlocks[blockId].fields.push_back(activeUniforms.size()); shaderObject->activeUniformBlocks[blockId].fields.push_back(activeUniforms.size());
} }
BlockMemberInfo blockInfo = encoder ? encoder->encodeType(type) : BlockMemberInfo::getDefaultBlockInfo(); int fieldRegisterIndex = encoder ? shaderObject->activeUniformBlocks[blockId].registerIndex + BlockLayoutEncoder::getBlockRegister(blockInfo) : registerIndex;
int regIndex = encoder ? registerIndex + BlockLayoutEncoder::getBlockRegister(blockInfo) : registerIndex;
activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(),
regIndex, blockId, blockInfo)); fieldRegisterIndex, blockId, blockInfo));
if(isSamplerRegister(type)) if(isSamplerRegister(type))
{ {
for(int i = 0; i < type.totalRegisterCount(); i++) for(int i = 0; i < type.totalRegisterCount(); i++)
{ {
shader->declareSampler(regIndex + i); shader->declareSampler(fieldRegisterIndex + i);
} }
} }
} }
else if(block) else if(block)
{ {
ActiveUniformBlocks &activeUniformBlocks = shaderObject->activeUniformBlocks; ActiveUniformBlocks &activeUniformBlocks = shaderObject->activeUniformBlocks;
const TFieldList& fields = block->fields();
const TString &blockName = block->name();
int fieldRegisterIndex = registerIndex;
bool isUniformBlockMember = !type.isInterfaceBlock() && (blockId == -1);
if(isUniformBlockMember)
{
// This is a uniform that's part of a block, let's see if the block is already defined
for(size_t i = 0; i < activeUniformBlocks.size(); ++i)
{
if(activeUniformBlocks[i].name == blockName.c_str())
{
// The block is already defined, find the register for the current uniform and return it
for(size_t j = 0; j < fields.size(); j++)
{
const TString &fieldName = fields[j]->name();
if(fieldName == name)
{
return fieldRegisterIndex;
}
fieldRegisterIndex += fields[j]->type()->totalRegisterCount();
}
ASSERT(false);
return fieldRegisterIndex;
}
}
}
blockId = activeUniformBlocks.size(); blockId = activeUniformBlocks.size();
bool isRowMajor = block->matrixPacking() == EmpRowMajor; bool isRowMajor = block->matrixPacking() == EmpRowMajor;
const TString &blockName = block->name();
activeUniformBlocks.push_back(UniformBlock(blockName.c_str(), 0, block->arraySize(), activeUniformBlocks.push_back(UniformBlock(blockName.c_str(), 0, block->arraySize(),
block->blockStorage(), isRowMajor, registerIndex, blockId)); block->blockStorage(), isRowMajor, registerIndex, blockId));
blockDefinitions.push_back(BlockDefinition());
const TFieldList& fields = block->fields();
Std140BlockEncoder currentBlockEncoder(isRowMajor); Std140BlockEncoder currentBlockEncoder(isRowMajor);
currentBlockEncoder.enterAggregateType();
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();
if(isUniformBlockMember && (fieldName == name))
{
registerIndex = fieldRegisterIndex;
}
const TString uniformName = block->hasInstanceName() ? blockName + "." + fieldName : fieldName; const TString uniformName = block->hasInstanceName() ? blockName + "." + fieldName : fieldName;
declareUniform(fieldType, uniformName, registerIndex, blockId, &currentBlockEncoder); declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, &currentBlockEncoder);
fieldRegisterIndex += fieldType.totalRegisterCount();
} }
currentBlockEncoder.exitAggregateType();
activeUniformBlocks[blockId].dataSize = currentBlockEncoder.getBlockSize(); activeUniformBlocks[blockId].dataSize = currentBlockEncoder.getBlockSize();
} }
else else
...@@ -2964,11 +3001,7 @@ namespace glsl ...@@ -2964,11 +3001,7 @@ namespace glsl
const TString uniformName = name + "[" + str(i) + "]." + fieldName; const TString uniformName = name + "[" + str(i) + "]." + fieldName;
declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder); declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder);
if(!encoder) fieldRegisterIndex += fieldType.totalRegisterCount();
{
int registerCount = fieldType.totalRegisterCount();
fieldRegisterIndex += registerCount;
}
} }
if(encoder) if(encoder)
{ {
...@@ -2989,11 +3022,7 @@ namespace glsl ...@@ -2989,11 +3022,7 @@ namespace glsl
const TString uniformName = name + "." + fieldName; const TString uniformName = name + "." + fieldName;
declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder); declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder);
if(!encoder) fieldRegisterIndex += fieldType.totalRegisterCount();
{
int registerCount = fieldType.totalRegisterCount();
fieldRegisterIndex += registerCount;
}
} }
if(encoder) if(encoder)
{ {
...@@ -3001,6 +3030,8 @@ namespace glsl ...@@ -3001,6 +3030,8 @@ namespace glsl
} }
} }
} }
return registerIndex;
} }
GLenum OutputASM::glVariableType(const TType &type) GLenum OutputASM::glVariableType(const TType &type)
......
...@@ -293,7 +293,7 @@ namespace glsl ...@@ -293,7 +293,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 registerIndex, int blockId = -1, BlockLayoutEncoder* encoder = nullptr); int declareUniform(const TType &type, const TString &name, int registerIndex, int blockId = -1, BlockLayoutEncoder* encoder = nullptr);
GLenum glVariableType(const TType &type); GLenum glVariableType(const TType &type);
GLenum glVariablePrecision(const TType &type); GLenum glVariablePrecision(const TType &type);
...@@ -315,6 +315,20 @@ namespace glsl ...@@ -315,6 +315,20 @@ namespace glsl
VariableArray samplers; VariableArray samplers;
VariableArray fragmentOutputs; VariableArray fragmentOutputs;
struct TypedMemberInfo : public BlockMemberInfo
{
TypedMemberInfo() {}
TypedMemberInfo(const BlockMemberInfo& b, const TType& t) : BlockMemberInfo(b), type(t) {}
TType type;
};
struct BlockDefinition
{
typedef std::map<int, TypedMemberInfo> IndexMap;
IndexMap indexMap;
};
std::vector<BlockDefinition> blockDefinitions;
Scope emitScope; Scope emitScope;
Scope currentScope; Scope currentScope;
......
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