D3D11: Optimize checks for active UBOs.

We can reduce the amount of iterations we use by using std::vectors
for storing UBO indexes, and resizing them to the max active index.
This allows us to skip inactive ranges. Reduces draw call overhead.

BUG=angleproject:959

Change-Id: I2577e5dbdce0e5ab102ca916eb7f1f35cf03f9ad
Reviewed-on: https://chromium-review.googlesource.com/277287
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 5374613..fc72504 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -1143,18 +1143,8 @@
 
 gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[])
 {
-    GLint vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
-    GLint fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
-
-    for (unsigned int registerIndex = 0; registerIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; ++registerIndex)
-    {
-        vertexUniformBuffers[registerIndex] = -1;
-    }
-
-    for (unsigned int registerIndex = 0; registerIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; ++registerIndex)
-    {
-        fragmentUniformBuffers[registerIndex] = -1;
-    }
+    mVertexUBOCache.clear();
+    mFragmentUBOCache.clear();
 
     const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
     const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
@@ -1175,21 +1165,33 @@
         if (uniformBlock->isReferencedByVertexShader())
         {
             unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
-            ASSERT(vertexUniformBuffers[registerIndex] == -1);
             ASSERT(registerIndex < data.caps->maxVertexUniformBlocks);
-            vertexUniformBuffers[registerIndex] = blockBinding;
+
+            if (mFragmentUBOCache.size() <= registerIndex)
+            {
+                mVertexUBOCache.resize(registerIndex + 1, -1);
+            }
+
+            ASSERT(mVertexUBOCache[registerIndex] == -1);
+            mVertexUBOCache[registerIndex] = blockBinding;
         }
 
         if (uniformBlock->isReferencedByFragmentShader())
         {
             unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
-            ASSERT(fragmentUniformBuffers[registerIndex] == -1);
             ASSERT(registerIndex < data.caps->maxFragmentUniformBlocks);
-            fragmentUniformBuffers[registerIndex] = blockBinding;
+
+            if (mFragmentUBOCache.size() <= registerIndex)
+            {
+                mFragmentUBOCache.resize(registerIndex + 1, -1);
+            }
+
+            ASSERT(mFragmentUBOCache[registerIndex] == -1);
+            mFragmentUBOCache[registerIndex] = blockBinding;
         }
     }
 
-    return mRenderer->setUniformBuffers(data, vertexUniformBuffers, fragmentUniformBuffers);
+    return mRenderer->setUniformBuffers(data, mVertexUBOCache, mFragmentUBOCache);
 }
 
 bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,