Commit c600c8c3 by Jamie Madill

Fix arrays-of-struct and nested struct uniforms.

Our computation of register offsets had a few errors that messed up nested structs and arrays of structs. This fixes a WebGL test, as well as several dEQP tests. BUG=angle:505 TEST=WebGL CTS 1.0.3, dEQP-GELS3.functional.uniform-api Change-Id: Id5a0f39481e079fe5ef5ef856943dc1f91ee3639 Reviewed-on: https://chromium-review.googlesource.com/200045Reviewed-by: 's avatarNicolas Capens <nicolascapens@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 3639892d
......@@ -227,6 +227,11 @@ void HLSLBlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool i
}
}
void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters)
{
mCurrentOffset += (numRegisters * ComponentsPerRegister);
}
void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, gl::Uniform *variable, HLSLBlockEncoder *encoder, const std::vector<gl::BlockMemberInfo> &blockInfo)
{
// because this method computes offsets (element indexes) instead of any total sizes,
......@@ -236,11 +241,21 @@ void HLSLVariableGetRegisterInfo(unsigned int baseRegisterIndex, gl::Uniform *va
{
encoder->enterAggregateType();
variable->registerIndex = baseRegisterIndex;
for (size_t fieldIndex = 0; fieldIndex < variable->fields.size(); fieldIndex++)
{
HLSLVariableGetRegisterInfo(baseRegisterIndex, &variable->fields[fieldIndex], encoder, blockInfo);
}
// Since the above loop only encodes one element of an array, ensure we don't lose track of the
// current register offset
if (variable->isArray())
{
unsigned int structRegisterCount = (HLSLVariableRegisterCount(*variable) / variable->arraySize);
encoder->skipRegisters(structRegisterCount * (variable->arraySize - 1));
}
encoder->exitAggregateType();
}
else
......
......@@ -77,6 +77,7 @@ class HLSLBlockEncoder : public BlockLayoutEncoder
virtual void enterAggregateType();
virtual void exitAggregateType();
void skipRegisters(unsigned int numRegisters);
protected:
virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
......
......@@ -24,6 +24,7 @@
#include "libGLESv2/Context.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/DynamicHLSL.h"
#include "common/blocklayout.h"
#undef near
#undef far
......@@ -1810,25 +1811,6 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<gl::Uniform
return true;
}
int totalRegisterCount(const gl::Uniform &uniform)
{
int registerCount = 0;
if (!uniform.fields.empty())
{
for (unsigned int fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
{
registerCount += totalRegisterCount(uniform.fields[fieldIndex]);
}
}
else
{
registerCount = 1;
}
return (uniform.arraySize > 0) ? uniform.arraySize * registerCount : registerCount;
}
TextureType ProgramBinary::getTextureType(GLenum samplerType, InfoLog &infoLog)
{
switch(samplerType)
......@@ -1865,23 +1847,25 @@ bool ProgramBinary::defineUniform(GLenum shader, const gl::Uniform &constant, In
{
if (constant.arraySize > 0)
{
unsigned int elementRegisterIndex = constant.registerIndex;
const unsigned int elementRegisterCount = HLSLVariableRegisterCount(constant) / constant.arraySize;
for (unsigned int elementIndex = 0; elementIndex < constant.arraySize; elementIndex++)
{
const unsigned int elementRegisterOffset = elementRegisterCount * elementIndex;
for (size_t fieldIndex = 0; fieldIndex < constant.fields.size(); fieldIndex++)
{
const gl::Uniform &field = constant.fields[fieldIndex];
const std::string &uniformName = constant.name + ArrayString(elementIndex) + "." + field.name;
const unsigned int fieldRegisterIndex = field.registerIndex + elementRegisterOffset;
gl::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize,
elementRegisterIndex, field.elementIndex);
fieldRegisterIndex, field.elementIndex);
fieldUniform.fields = field.fields;
if (!defineUniform(shader, fieldUniform, infoLog))
{
return false;
}
elementRegisterIndex += totalRegisterCount(field);
}
}
}
......
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