Add UBO offset support for D3D11.1.

Also fixes the uniform count upper limit in glGetActiveUniformsiv,
as well as an assert hit with used but unbound uniform buffer.

BUG=angleproject:507
BUG=angleproject:962

Change-Id: I096fe1c9b4f0f398f3a638cd8311278987dfb7dc
Reviewed-on: https://chromium-review.googlesource.com/263404
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Gregoire Payen de La Garanderie <Gregory.Payen@imgtec.com>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 6469510..d267cbf 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -1436,6 +1436,36 @@
         }
     }
 
+    // Uniform buffer validation
+    for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
+    {
+        const gl::UniformBlock *uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
+        GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
+        const gl::Buffer *uniformBuffer = state.getIndexedUniformBuffer(blockBinding);
+
+        if (!uniformBuffer)
+        {
+            // undefined behaviour
+            context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer."));
+            return false;
+        }
+
+        size_t uniformBufferSize = state.getIndexedUniformBufferSize(blockBinding);
+
+        if (uniformBufferSize == 0)
+        {
+            // Bind the whole buffer.
+            uniformBufferSize = uniformBuffer->getSize();
+        }
+
+        if (uniformBufferSize < uniformBlock->dataSize)
+        {
+            // undefined behaviour
+            context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small."));
+            return false;
+        }
+    }
+
     // No-op if zero count
     return (count > 0);
 }