Module: wine Branch: master Commit: 674af50174993baaed43a267e0d3d05ce8e81e71 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=674af50174993baaed43a267...
Author: Stefan Dösinger stefan@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;