[6/6] WineD3D: Use VBOs on dynamic buffers, but do not convert

Stefan Dösinger stefan at codeweavers.com
Fri Jan 12 12:06:25 CST 2007


-------------- next part --------------
From 719a0828f899332285c6f5bbf6f55faec53250b7 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Fri, 12 Jan 2007 17:01:22 +0100
Subject: [PATCH] WineD3D: Use VBOs for dynamic buffers, but do not convert

---
 dlls/wined3d/device.c       |    2 +-
 dlls/wined3d/vertexbuffer.c |   45 ++++++++++++++++++++++++++++++------------
 2 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index c64dc33..4845d1c 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -532,7 +532,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
      * more. In this call we can convert dx7 buffers too.
      */
     conv = ((FVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) || (FVF & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR));
-    if( GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) && Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && 
+    if( GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) && Pool != WINED3DPOOL_SYSTEMMEM &&
         (dxVersion > 7 || !conv) ) {
         CreateVBO(object);
 
diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c
index 6ef7533..1fcd653 100644
--- a/dlls/wined3d/vertexbuffer.c
+++ b/dlls/wined3d/vertexbuffer.c
@@ -249,6 +249,26 @@ inline BOOL WINAPI IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T
     return FALSE;
 }
 
+static void IWineD3DVertexBufferImpl_ReleaseVBO(IWineD3DVertexBufferImpl *This) {
+    /* Fetches all Data from the VBO into system memory and destroys the VBO. Used if the
+     * declaration changes too often, or if a dynamic vb was set up for conversion.
+     *
+     * Assumes that This->resource.allocatedMemory is allocated.
+     */
+    ENTER_GL();
+    GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
+    checkGLcall("glDeleteBuffersARB");
+    LEAVE_GL();
+    This->vbo = 0;
+
+    /* The stream source state handler might have read the memory of the vertex buffer already
+     * and got the memory in the vbo which is not valid any longer. Dirtify the stream source
+     * to force a reload. This happens only once per affected vertexbuffer and should occur rather
+     * rarely
+     */
+    IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_STREAMSRC);
+}
+
 static void     WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *iface) {
     IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
     BYTE *data;
@@ -291,19 +311,7 @@ static void     WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
         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;
-
-                /* The stream source state handler might have read the memory of the vertex buffer already
-                 * and got the memory in the vbo which is not valid any longer. Dirtify the stream source
-                 * to force a reload. This happens only once per changed vertexbuffer and should occur rather
-                 * rarely
-                 */
-                IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_STREAMSRC);
-
+                IWineD3DVertexBufferImpl_ReleaseVBO(This);
                 return;
             }
             /* Otherwise do not bother to release the VBO. If we're doing direct locking now,
@@ -384,6 +392,17 @@ static void     WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
         return;
     }
 
+    /* If we get here the buffer will be converted. Do not do this on WINED3DUSAGE_DYNAMIC vbs, drawStridedSlow is faster
+     * than constant conversion of new data.
+     *
+     * The vbo is created in the first place to allow using VBOs in applications which use vertex shaders and thus do not
+     * need conversion
+     */
+    if(This->resource.usage & WINED3DUSAGE_DYNAMIC) {
+        IWineD3DVertexBufferImpl_ReleaseVBO(This);
+        return;
+    }
+
     /* OK, we have the original data from the app, the description of the buffer and the dirty area.
      * so convert the stuff
      */
-- 
1.4.4.3



More information about the wine-patches mailing list