Commit 0538d115 by Alexis Hetu Committed by Alexis Hétu

New uniform block related utility functions

This cl adds 2 new utility function and adds one use of these in the argument() function. - getBlockId() finds a block by name and returns its ID - getTypedMemberInfo() finds which block member matches a certain register index and returns the block member's packing information and type. If the register falls within a block member (as a sub-register of a matrix or an array), the base offset of the block member is returned, along with the register index, which will then be used within the argument() function to compute the final parameter index. Change-Id: Ic0edcb3e6772cdb854301e3d0b400775e7ee72c0 Reviewed-on: https://swiftshader-review.googlesource.com/4682Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent 2ee8585b
...@@ -2050,21 +2050,105 @@ namespace glsl ...@@ -2050,21 +2050,105 @@ namespace glsl
return 0; return 0;
} }
int OutputASM::getBlockId(TIntermTyped *arg)
{
if(arg)
{
const TType &type = arg->getType();
TInterfaceBlock* block = type.getInterfaceBlock();
if(block && (type.getQualifier() == EvqUniform))
{
// Make sure the uniform block is declared
uniformRegister(arg);
const char* blockName = block->name().c_str();
// Fetch uniform block index from array of blocks
for(ActiveUniformBlocks::const_iterator it = shaderObject->activeUniformBlocks.begin(); it != shaderObject->activeUniformBlocks.end(); ++it)
{
if(blockName == it->name)
{
return it->blockId;
}
}
ASSERT(false);
}
}
return -1;
}
OutputASM::ArgumentInfo OutputASM::getArgumentInfo(TIntermTyped *arg, int index)
{
const TType &type = arg->getType();
int blockId = getBlockId(arg);
ArgumentInfo argumentInfo(BlockMemberInfo::getDefaultBlockInfo(), type, -1, -1);
if(blockId != -1)
{
argumentInfo.bufferIndex = 0;
for(int i = 0; i < blockId; ++i)
{
int blockArraySize = shaderObject->activeUniformBlocks[i].arraySize;
argumentInfo.bufferIndex += blockArraySize > 0 ? blockArraySize : 1;
}
const BlockDefinitionIndexMap& blockDefinition = blockDefinitions[blockId];
BlockDefinitionIndexMap::const_iterator itEnd = blockDefinition.end();
BlockDefinitionIndexMap::const_iterator it = itEnd;
argumentInfo.clampedIndex = index;
if(type.isInterfaceBlock())
{
// Offset index to the beginning of the selected instance
size_t blockRegisters = type.elementRegisterCount();
size_t bufferOffset = argumentInfo.clampedIndex / blockRegisters;
argumentInfo.bufferIndex += bufferOffset;
argumentInfo.clampedIndex -= bufferOffset * blockRegisters;
}
int regIndex = registerIndex(arg);
for(int i = regIndex + argumentInfo.clampedIndex; i >= regIndex; --i)
{
it = blockDefinition.find(i);
if(it != itEnd)
{
argumentInfo.clampedIndex -= (i - regIndex);
break;
}
}
ASSERT(it != itEnd);
argumentInfo.typedMemberInfo = it->second;
int registerCount = argumentInfo.typedMemberInfo.type.totalRegisterCount();
argumentInfo.clampedIndex = (argumentInfo.clampedIndex >= registerCount) ? registerCount - 1 : argumentInfo.clampedIndex;
}
else
{
argumentInfo.clampedIndex = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;
}
return argumentInfo;
}
void OutputASM::argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index) void OutputASM::argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index)
{ {
if(argument) if(argument)
{ {
TIntermTyped *arg = argument->getAsTyped(); TIntermTyped *arg = argument->getAsTyped();
const TType &type = arg->getType(); const ArgumentInfo argumentInfo = getArgumentInfo(arg, index);
index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index; const TType &type = argumentInfo.typedMemberInfo.type;
int size = registerSize(type, index); int size = registerSize(type, argumentInfo.clampedIndex);
parameter.type = registerType(arg); parameter.type = registerType(arg);
parameter.bufferIndex = argumentInfo.bufferIndex;
if(arg->getQualifier() == EvqConstExpr) if(arg->getQualifier() == EvqConstExpr)
{ {
int component = componentCount(type, index); int component = componentCount(type, argumentInfo.clampedIndex);
ConstantUnion *constants = arg->getAsConstantUnion()->getUnionArrayPointer(); ConstantUnion *constants = arg->getAsConstantUnion()->getUnionArrayPointer();
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
...@@ -2085,7 +2169,7 @@ namespace glsl ...@@ -2085,7 +2169,7 @@ namespace glsl
} }
else else
{ {
parameter.index = registerIndex(arg) + index; parameter.index = registerIndex(arg) + argumentInfo.clampedIndex;
if(isSamplerRegister(arg)) if(isSamplerRegister(arg))
{ {
...@@ -2119,6 +2203,11 @@ namespace glsl ...@@ -2119,6 +2203,11 @@ namespace glsl
} }
} }
} }
else if(parameter.bufferIndex != -1)
{
int stride = (argumentInfo.typedMemberInfo.matrixStride > 0) ? argumentInfo.typedMemberInfo.matrixStride : argumentInfo.typedMemberInfo.arrayStride;
parameter.index = argumentInfo.typedMemberInfo.offset + argumentInfo.clampedIndex * stride;
}
} }
if(!IsSampler(arg->getBasicType())) if(!IsSampler(arg->getBasicType()))
...@@ -2943,7 +3032,7 @@ namespace glsl ...@@ -2943,7 +3032,7 @@ namespace glsl
const BlockMemberInfo blockInfo = encoder ? encoder->encodeType(type) : BlockMemberInfo::getDefaultBlockInfo(); const BlockMemberInfo blockInfo = encoder ? encoder->encodeType(type) : BlockMemberInfo::getDefaultBlockInfo();
if(blockId >= 0) if(blockId >= 0)
{ {
blockDefinitions[blockId].indexMap[registerIndex] = TypedMemberInfo(blockInfo, type); blockDefinitions[blockId][registerIndex] = TypedMemberInfo(blockInfo, type);
shaderObject->activeUniformBlocks[blockId].fields.push_back(activeUniforms.size()); shaderObject->activeUniformBlocks[blockId].fields.push_back(activeUniforms.size());
} }
int fieldRegisterIndex = encoder ? shaderObject->activeUniformBlocks[blockId].registerIndex + BlockLayoutEncoder::getBlockRegister(blockInfo) : registerIndex; int fieldRegisterIndex = encoder ? shaderObject->activeUniformBlocks[blockId].registerIndex + BlockLayoutEncoder::getBlockRegister(blockInfo) : registerIndex;
...@@ -2994,7 +3083,7 @@ namespace glsl ...@@ -2994,7 +3083,7 @@ namespace glsl
bool isRowMajor = block->matrixPacking() == EmpRowMajor; bool isRowMajor = block->matrixPacking() == EmpRowMajor;
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()); blockDefinitions.push_back(BlockDefinitionIndexMap());
Std140BlockEncoder currentBlockEncoder(isRowMajor); Std140BlockEncoder currentBlockEncoder(isRowMajor);
currentBlockEncoder.enterAggregateType(); currentBlockEncoder.enterAggregateType();
......
...@@ -321,13 +321,19 @@ namespace glsl ...@@ -321,13 +321,19 @@ namespace glsl
TypedMemberInfo(const BlockMemberInfo& b, const TType& t) : BlockMemberInfo(b), type(t) {} TypedMemberInfo(const BlockMemberInfo& b, const TType& t) : BlockMemberInfo(b), type(t) {}
TType type; TType type;
}; };
struct ArgumentInfo
struct BlockDefinition
{ {
typedef std::map<int, TypedMemberInfo> IndexMap; ArgumentInfo(const BlockMemberInfo& b, const TType& t, int clampedIndex, int bufferIndex) :
IndexMap indexMap; typedMemberInfo(b, t), clampedIndex(clampedIndex), bufferIndex(bufferIndex) {}
TypedMemberInfo typedMemberInfo;
int clampedIndex;
int bufferIndex;
}; };
std::vector<BlockDefinition> blockDefinitions; int getBlockId(TIntermTyped *argument);
ArgumentInfo getArgumentInfo(TIntermTyped *argument, int index);
typedef std::map<int, TypedMemberInfo> BlockDefinitionIndexMap;
std::vector<BlockDefinitionIndexMap> 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