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