wined3d: Avoid redundant FBO binds.

Apparently this is an expensive operation for certain drivers, even if the
binding doesn't actually change.
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 86e73c5..172cd6b 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -64,6 +64,30 @@
         f = *fbo;
     }
 
+    switch (target)
+    {
+        case GL_READ_FRAMEBUFFER_EXT:
+            if (context->fbo_read_binding == f) return;
+            context->fbo_read_binding = f;
+            break;
+
+        case GL_DRAW_FRAMEBUFFER_EXT:
+            if (context->fbo_draw_binding == f) return;
+            context->fbo_draw_binding = f;
+            break;
+
+        case GL_FRAMEBUFFER_EXT:
+            if (context->fbo_read_binding == f
+                    && context->fbo_draw_binding == f) return;
+            context->fbo_read_binding = f;
+            context->fbo_draw_binding = f;
+            break;
+
+        default:
+            FIXME("Unhandled target %#x.\n", target);
+            break;
+    }
+
     GL_EXTCALL(glBindFramebufferEXT(target, f));
     checkGLcall("glBindFramebuffer()");
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d02bfdc..5d61c6a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1242,6 +1242,8 @@
     struct fbo_entry        *current_fbo;
     GLuint                  src_fbo;
     GLuint                  dst_fbo;
+    GLuint                  fbo_read_binding;
+    GLuint                  fbo_draw_binding;
 
     /* Extension emulation */
     GLint                   gl_fog_source;