Stefan Dösinger : wined3d: Stop fixing up a VBO if the declaration changes too often.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Sep 25 14:45:31 CDT 2006


Module: wine
Branch: master
Commit: 674af50174993baaed43a267e0d3d05ce8e81e71
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=674af50174993baaed43a267e0d3d05ce8e81e71

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sat Sep 23 18:02:22 2006 +0200

wined3d: Stop fixing up a VBO if the declaration changes too often.

---

 dlls/wined3d/vertexbuffer.c    |   36 ++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |    1 +
 2 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c
index bf734b5..5046d42 100644
--- a/dlls/wined3d/vertexbuffer.c
+++ b/dlls/wined3d/vertexbuffer.c
@@ -26,6 +26,9 @@ #include "wined3d_private.h"
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
 
+#define VB_MAXDECLCHANGES     100     /* After that number we stop converting */
+#define VB_RESETDECLCHANGE    1000    /* Reset the changecount after that number of draws */
+
 /* *******************************************
    IWineD3DVertexBuffer IUnknown parts follow
    ******************************************* */
@@ -278,6 +281,39 @@ static void     WINAPI IWineD3DVertexBuf
     }
 
     declChanged = IWineD3DVertexBufferImpl_FindDecl(This);
+
+    /* If applications change the declaration over and over, reconverting all the time is a huge
+     * performance hit. So count the declaration changes and release the VBO if there are too much
+     * of them(and thus stop converting)
+     */
+    if(declChanged) {
+        This->declChanges++;
+        This->draws = 0;
+
+        if(This->declChanges > VB_MAXDECLCHANGES) {
+            if(This->resource.allocatedMemory) {
+                FIXME("Too much declaration changes, stopping converting\n");
+                ENTER_GL();
+                GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
+                checkGLcall("glDeleteBuffersARB");
+                LEAVE_GL();
+                This->vbo = 0;
+                return;
+            }
+            /* Otherwise do not bother to release the VBO. If we're doing direct locking now,
+             * and the declarations changed the code below will fetch the VBO's contents, convert
+             * and on the next decl change the data will be in sysmem too and we can just release the VBO
+             */
+        }
+    } else {
+        /* However, it is perfectly fine to change the declaration every now and then. We don't want a game that
+         * changes it every minute drop the VBO after VB_MAX_DECL_CHANGES minutes. So count draws without
+         * decl changes and reset the decl change count after a specific number of them
+         */
+        This->draws++;
+        if(This->draws > VB_RESETDECLCHANGE) This->declChanges = 0;
+    }
+
     if(declChanged) {
         /* The declaration changed, reload the whole buffer */
         WARN("Reloading buffer because of decl change\n");
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9b36a70..a4fae10 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -655,6 +655,7 @@ typedef struct IWineD3DVertexBufferImpl
     UINT                      dirtystart, dirtyend;
     LONG                      lockcount;
 
+    LONG                      declChanges, draws;
     /* Last description of the buffer */
     WineDirect3DVertexStridedData strided;
 } IWineD3DVertexBufferImpl;




More information about the wine-cvs mailing list