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