Commit da163edb by Alexis Hetu Committed by Alexis Hétu

Sampler allocation fix

Because samplers can be stored within structures, register allocation of entire structures within the samplers registers was pushing sampler indices outside of the allowed limit. In order to solve this, sampler registers now exclusively contain samplers, and utility functions to compute sampler only type size were added to make this possible. Bug chromium:797264 Change-Id: Ic5a6f09665c39661944444cd736547bce4dff2ab Reviewed-on: https://swiftshader-review.googlesource.com/15728Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent f919b866
...@@ -1946,9 +1946,9 @@ namespace glsl ...@@ -1946,9 +1946,9 @@ namespace glsl
const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields(); const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();
int elements = 0; int elements = 0;
for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++) for(const auto &field : fields)
{ {
const TType &fieldType = *((*field)->type()); const TType &fieldType = *(field->type());
if(fieldType.totalRegisterCount() <= registers) if(fieldType.totalRegisterCount() <= registers)
{ {
...@@ -1998,9 +1998,9 @@ namespace glsl ...@@ -1998,9 +1998,9 @@ namespace glsl
const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields(); const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();
int elements = 0; int elements = 0;
for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++) for(const auto &field : fields)
{ {
const TType &fieldType = *((*field)->type()); const TType &fieldType = *(field->type());
if(fieldType.totalRegisterCount() <= registers) if(fieldType.totalRegisterCount() <= registers)
{ {
...@@ -2800,9 +2800,9 @@ namespace glsl ...@@ -2800,9 +2800,9 @@ namespace glsl
{ {
const TFieldList &fields = type.getStruct()->fields(); const TFieldList &fields = type.getStruct()->fields();
int fieldVar = var; int fieldVar = var;
for(size_t i = 0; i < fields.size(); i++) for(const auto &field : fields)
{ {
const TType& fieldType = *(fields[i]->type()); const TType& fieldType = *(field->type());
setPixelShaderInputs(fieldType, fieldVar, flat); setPixelShaderInputs(fieldType, fieldVar, flat);
fieldVar += fieldType.totalRegisterCount(); fieldVar += fieldType.totalRegisterCount();
} }
...@@ -2894,10 +2894,10 @@ namespace glsl ...@@ -2894,10 +2894,10 @@ namespace glsl
int fieldRegisterIndex = registerIndex; int fieldRegisterIndex = registerIndex;
const TFieldList &fields = type.getStruct()->fields(); const TFieldList &fields = type.getStruct()->fields();
for(size_t i = 0; i < fields.size(); i++) for(const auto &field : fields)
{ {
const TType& fieldType = *(fields[i]->type()); const TType& fieldType = *(field->type());
declareVarying(fieldType, varyingName + "." + fields[i]->name(), fieldRegisterIndex); declareVarying(fieldType, varyingName + "." + field->name(), fieldRegisterIndex);
if(fieldRegisterIndex >= 0) if(fieldRegisterIndex >= 0)
{ {
fieldRegisterIndex += fieldType.totalRegisterCount(); fieldRegisterIndex += fieldType.totalRegisterCount();
...@@ -2951,7 +2951,7 @@ namespace glsl ...@@ -2951,7 +2951,7 @@ namespace glsl
int blockMemberIndex = blockMemberLookup(type, name, index); int blockMemberIndex = blockMemberLookup(type, name, index);
if(blockMemberIndex == -1) if(blockMemberIndex == -1)
{ {
declareUniform(type, name, index); declareUniform(type, name, index, false);
} }
else else
{ {
...@@ -3052,7 +3052,7 @@ namespace glsl ...@@ -3052,7 +3052,7 @@ namespace glsl
{ {
case EOpIndexDirect: case EOpIndexDirect:
ASSERT(left->isArray()); ASSERT(left->isArray());
offset = index * leftType.elementRegisterCount(); offset = index * leftType.samplerRegisterCount();
break; break;
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
ASSERT(leftType.isStruct()); ASSERT(leftType.isStruct());
...@@ -3061,7 +3061,7 @@ namespace glsl ...@@ -3061,7 +3061,7 @@ namespace glsl
for(int i = 0; i < index; i++) for(int i = 0; i < index; i++)
{ {
offset += fields[i]->type()->totalRegisterCount(); offset += fields[i]->type()->totalSamplerRegisterCount();
} }
} }
break; break;
...@@ -3096,12 +3096,12 @@ namespace glsl ...@@ -3096,12 +3096,12 @@ namespace glsl
if(index == -1) if(index == -1)
{ {
index = allocate(samplers, sampler); index = allocate(samplers, sampler, true);
if(sampler->getQualifier() == EvqUniform) if(sampler->getQualifier() == EvqUniform)
{ {
const char *name = sampler->getSymbol().c_str(); const char *name = sampler->getSymbol().c_str();
declareUniform(type, name, index); declareUniform(type, name, index, true);
} }
} }
...@@ -3187,13 +3187,13 @@ namespace glsl ...@@ -3187,13 +3187,13 @@ namespace glsl
return -1; return -1;
} }
int OutputASM::allocate(VariableArray &list, TIntermTyped *variable) int OutputASM::allocate(VariableArray &list, TIntermTyped *variable, bool samplersOnly)
{ {
int index = lookup(list, variable); int index = lookup(list, variable);
if(index == -1) if(index == -1)
{ {
unsigned int registerCount = variable->blockRegisterCount(); unsigned int registerCount = variable->blockRegisterCount(samplersOnly);
for(unsigned int i = 0; i < list.size(); i++) for(unsigned int i = 0; i < list.size(); i++)
{ {
...@@ -3281,7 +3281,7 @@ namespace glsl ...@@ -3281,7 +3281,7 @@ namespace glsl
return -1; return -1;
} }
void OutputASM::declareUniform(const TType &type, const TString &name, int registerIndex, int blockId, BlockLayoutEncoder* encoder) void OutputASM::declareUniform(const TType &type, const TString &name, int registerIndex, bool samplersOnly, 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;
...@@ -3296,15 +3296,19 @@ namespace glsl ...@@ -3296,15 +3296,19 @@ namespace glsl
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;
activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), bool isSampler = IsSampler(type.getBasicType());
fieldRegisterIndex, blockId, blockInfo)); if(isSampler && samplersOnly)
if(IsSampler(type.getBasicType()))
{ {
for(int i = 0; i < type.totalRegisterCount(); i++) for(int i = 0; i < type.totalRegisterCount(); i++)
{ {
shader->declareSampler(fieldRegisterIndex + i); shader->declareSampler(fieldRegisterIndex + i);
} }
} }
if(!isSampler || samplersOnly)
{
activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(),
fieldRegisterIndex, blockId, blockInfo));
}
} }
else if(block) else if(block)
{ {
...@@ -3322,10 +3326,10 @@ namespace glsl ...@@ -3322,10 +3326,10 @@ namespace glsl
Std140BlockEncoder currentBlockEncoder(isRowMajor); Std140BlockEncoder currentBlockEncoder(isRowMajor);
currentBlockEncoder.enterAggregateType(); currentBlockEncoder.enterAggregateType();
for(size_t i = 0; i < fields.size(); i++) for(const auto &field : fields)
{ {
const TType &fieldType = *(fields[i]->type()); const TType &fieldType = *(field->type());
const TString &fieldName = fields[i]->name(); const TString &fieldName = field->name();
if(isUniformBlockMember && (fieldName == name)) if(isUniformBlockMember && (fieldName == name))
{ {
registerIndex = fieldRegisterIndex; registerIndex = fieldRegisterIndex;
...@@ -3333,7 +3337,7 @@ namespace glsl ...@@ -3333,7 +3337,7 @@ namespace glsl
const TString uniformName = block->hasInstanceName() ? blockName + "." + fieldName : fieldName; const TString uniformName = block->hasInstanceName() ? blockName + "." + fieldName : fieldName;
declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, &currentBlockEncoder); declareUniform(fieldType, uniformName, fieldRegisterIndex, samplersOnly, blockId, &currentBlockEncoder);
fieldRegisterIndex += fieldType.totalRegisterCount(); fieldRegisterIndex += fieldType.totalRegisterCount();
} }
currentBlockEncoder.exitAggregateType(); currentBlockEncoder.exitAggregateType();
...@@ -3352,14 +3356,14 @@ namespace glsl ...@@ -3352,14 +3356,14 @@ namespace glsl
{ {
encoder->enterAggregateType(); encoder->enterAggregateType();
} }
for(size_t j = 0; j < fields.size(); j++) for(const auto &field : fields)
{ {
const TType &fieldType = *(fields[j]->type()); const TType &fieldType = *(field->type());
const TString &fieldName = fields[j]->name(); const TString &fieldName = field->name();
const TString uniformName = name + "[" + str(i) + "]." + fieldName; const TString uniformName = name + "[" + str(i) + "]." + fieldName;
declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder); declareUniform(fieldType, uniformName, fieldRegisterIndex, samplersOnly, blockId, encoder);
fieldRegisterIndex += fieldType.totalRegisterCount(); fieldRegisterIndex += samplersOnly ? fieldType.totalSamplerRegisterCount() : fieldType.totalRegisterCount();
} }
if(encoder) if(encoder)
{ {
...@@ -3373,14 +3377,14 @@ namespace glsl ...@@ -3373,14 +3377,14 @@ namespace glsl
{ {
encoder->enterAggregateType(); encoder->enterAggregateType();
} }
for(size_t i = 0; i < fields.size(); i++) for(const auto &field : fields)
{ {
const TType &fieldType = *(fields[i]->type()); const TType &fieldType = *(field->type());
const TString &fieldName = fields[i]->name(); const TString &fieldName = field->name();
const TString uniformName = name + "." + fieldName; const TString uniformName = name + "." + fieldName;
declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder); declareUniform(fieldType, uniformName, fieldRegisterIndex, samplersOnly, blockId, encoder);
fieldRegisterIndex += fieldType.totalRegisterCount(); fieldRegisterIndex += samplersOnly ? fieldType.totalSamplerRegisterCount() : fieldType.totalRegisterCount();
} }
if(encoder) if(encoder)
{ {
......
...@@ -305,10 +305,10 @@ namespace glsl ...@@ -305,10 +305,10 @@ namespace glsl
int lookup(VariableArray &list, TIntermTyped *variable); int lookup(VariableArray &list, TIntermTyped *variable);
int lookup(VariableArray &list, TInterfaceBlock *block); int lookup(VariableArray &list, TInterfaceBlock *block);
int blockMemberLookup(const TType &type, const TString &name, int registerIndex); int blockMemberLookup(const TType &type, const TString &name, int registerIndex);
int allocate(VariableArray &list, TIntermTyped *variable); int allocate(VariableArray &list, TIntermTyped *variable, bool samplersOnly = false);
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); void declareUniform(const TType &type, const TString &name, int registerIndex, bool samplersOnly, 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);
......
...@@ -318,6 +318,24 @@ public: ...@@ -318,6 +318,24 @@ public:
} }
} }
int samplerRegisterCount() const
{
if(structure)
{
int registerCount = 0;
const TFieldList& fields = isInterfaceBlock() ? interfaceBlock->fields() : structure->fields();
for(size_t i = 0; i < fields.size(); i++)
{
registerCount += fields[i]->type()->totalSamplerRegisterCount();
}
return registerCount;
}
return IsSampler(getBasicType()) ? 1 : 0;
}
int elementRegisterCount() const int elementRegisterCount() const
{ {
if(structure || isInterfaceBlock()) if(structure || isInterfaceBlock())
...@@ -360,6 +378,18 @@ public: ...@@ -360,6 +378,18 @@ public:
return totalRegisterCount(); return totalRegisterCount();
} }
int totalSamplerRegisterCount() const
{
if(array)
{
return arraySize * samplerRegisterCount();
}
else
{
return samplerRegisterCount();
}
}
int totalRegisterCount() const int totalRegisterCount() const
{ {
if(array) if(array)
......
...@@ -330,7 +330,7 @@ public: ...@@ -330,7 +330,7 @@ public:
TString getCompleteString() const { return type.getCompleteString(); } TString getCompleteString() const { return type.getCompleteString(); }
int totalRegisterCount() const { return type.totalRegisterCount(); } int totalRegisterCount() const { return type.totalRegisterCount(); }
int blockRegisterCount() const { return type.blockRegisterCount(); } int blockRegisterCount(bool samplersOnly) const { return samplersOnly ? type.totalSamplerRegisterCount() : type.blockRegisterCount(); }
int elementRegisterCount() const { return type.elementRegisterCount(); } int elementRegisterCount() const { return type.elementRegisterCount(); }
int registerSize() const { return type.registerSize(); } int registerSize() const { return type.registerSize(); }
int getArraySize() const { return type.getArraySize(); } int getArraySize() const { return type.getArraySize(); }
......
...@@ -1474,8 +1474,11 @@ namespace sw ...@@ -1474,8 +1474,11 @@ namespace sw
void Shader::declareSampler(int i) void Shader::declareSampler(int i)
{ {
if(i >= 0 && i < 16)
{
usedSamplers |= 1 << i; usedSamplers |= 1 << i;
} }
}
const Shader::Instruction *Shader::getInstruction(size_t i) const const Shader::Instruction *Shader::getInstruction(size_t i) const
{ {
......
...@@ -1586,7 +1586,7 @@ namespace sw ...@@ -1586,7 +1586,7 @@ namespace sw
void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1) void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
{ {
Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[16]) + src1.index * sizeof(Texture); Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + src1.index * sizeof(Texture);
dst = SamplerCore::textureSize(texture, lod); dst = SamplerCore::textureSize(texture, lod);
} }
......
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