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/common/blocklayout.cpp b/src/common/blocklayout.cpp
index 45f516f..f7c9b8f 100644
--- a/src/common/blocklayout.cpp
+++ b/src/common/blocklayout.cpp
@@ -227,6 +227,11 @@
     }
 }
 
+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 @@
     {
         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