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/200045
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index cecb94d..cf76407 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -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 @@
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 @@
{
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);
}
}
}