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

Stefan Dösinger stefan at codeweavers.com
Sat Sep 23 11:02:22 CDT 2006


The sort of fixups done with vertices in a VBO strongly depends on the vertex 
declaration. This means that if the decl change the whole buffer has to be 
reconverted and reloaded.

If declaration changes occur regularily this will be a huge performance hit. 
Therefore release the VBO and thus stop converting if that occurs.
-------------- next part --------------
From 293f543e9b00269b3d5ca72e9741f67b6655b5b3 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=F6singer?= <stefan at codeweavers.com>
Date: Sat, 23 Sep 2006 17:43:27 +0200
Subject: [PATCH] WineD3D: Stop converting when too much decl changes occur
(cherry picked from a70f94f4ce7996229b7e2984adb17c3dd156d5ad commit)
---
 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;
-- 
1.4.1.1



More information about the wine-patches mailing list