From a915c407ec1d54c7511bd591269b29a5a76b8da4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Fri, 1 Jan 2010 22:04:05 +0100
Subject: [PATCH 05/12] WineD3D: Avoid double buffered dynamic buffers

---
 dlls/wined3d/buffer.c |   38 ++++++++++++++++++++++++++------------
 1 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index e22d311..b423072 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -97,6 +97,18 @@ static inline BOOL buffer_is_fully_dirty(struct wined3d_buffer *This)
     return FALSE;
 }
 
+/* Context activation is done by the caller */
+static void delete_gl_buffer(struct wined3d_buffer *This)
+{
+    if(!This->buffer_object) return;
+
+    ENTER_GL();
+    GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
+    checkGLcall("glDeleteBuffersARB");
+    LEAVE_GL();
+    This->buffer_object = 0;
+}
+
 /* Context activation is done by the caller. */
 static void buffer_create_buffer_object(struct wined3d_buffer *This)
 {
@@ -203,13 +215,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
 fail:
     /* Clean up all vbo init, but continue because we can work without a vbo :-) */
     ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n");
-    if (This->buffer_object)
-    {
-        ENTER_GL();
-        GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
-        LEAVE_GL();
-    }
-    This->buffer_object = 0;
+    delete_gl_buffer(This);
     buffer_clear_dirty_areas(This);
 }
 
@@ -668,6 +674,18 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
     LEAVE_GL();
     This->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
 
+    /* Double buffered dynamic buffers don't work too well because
+     * the glBufferSubData API doesn't allow relaxed fencing, and
+     * thus such a buffer is usually slower than no VBO at all.
+     */
+    if(This->resource.usage & WINED3DUSAGE_DYNAMIC)
+    {
+        delete_gl_buffer(This);
+        This->flags &= ~WINED3D_BUFFER_CREATEBO;
+
+        IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_STREAMSRC);
+    }
+
     return This->resource.allocatedMemory;
 }
 
@@ -691,11 +709,7 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
             This->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER;
         }
 
-        ENTER_GL();
-        GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
-        checkGLcall("glDeleteBuffersARB");
-        LEAVE_GL();
-        This->buffer_object = 0;
+        delete_gl_buffer(This);
         This->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */
         buffer_clear_dirty_areas(This);
 
-- 
1.6.4.4

