Cache applied constant buffers.

Issue #451

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 34f2ed3..2c5bb57 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -633,7 +633,12 @@
                 return false;
             }
 
-            vertexConstantBuffers[uniformBufferIndex] = constantBuffer;
+            if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial())
+            {
+                mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex,
+                                                     1, &constantBuffer);
+                mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial();
+            }
         }
     }
 
@@ -650,13 +655,17 @@
                 return false;
             }
 
+            if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial())
+            {
+                mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex,
+                                                     1, &constantBuffer);
+                mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial();
+            }
+
             pixelConstantBuffers[uniformBufferIndex] = constantBuffer;
         }
     }
 
-    mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers(), getMaxVertexShaderUniformBuffers(), vertexConstantBuffers);
-    mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers(), getMaxFragmentShaderUniformBuffers(), pixelConstantBuffers);
-
     return true;
 }
 
@@ -1462,9 +1471,18 @@
     {
         mDeviceContext->Unmap(pixelConstantBuffer, 0);
     }
-    
-    mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
-    mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
+
+    if (mCurrentVertexConstantBuffer != vertexConstantBuffer)
+    {
+        mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
+        mCurrentVertexConstantBuffer = vertexConstantBuffer;
+    }
+
+    if (mCurrentPixelConstantBuffer != pixelConstantBuffer)
+    {
+        mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
+        mCurrentPixelConstantBuffer = pixelConstantBuffer;
+    }
 
     // Driver uniforms
     if (!mDriverConstantBufferVS)
@@ -1512,7 +1530,11 @@
     }
 
     // needed for the point sprite geometry shader
-    mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
+    if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
+    {
+        mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
+        mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
+    }
 }
 
 void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
@@ -1821,6 +1843,16 @@
     memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
 
     mInputLayoutCache.markDirty();
+
+    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++)
+    {
+        mCurrentConstantBufferVS[i] = -1;
+        mCurrentConstantBufferPS[i] = -1;
+    }
+
+    mCurrentVertexConstantBuffer = NULL;
+    mCurrentPixelConstantBuffer = NULL;
+    mCurrentGeometryConstantBuffer = NULL;
 }
 
 void Renderer11::releaseDeviceResources()