[12/20] WineD3D: Do not keep internal references on vertex buffers

Stefan Dösinger stefan at codeweavers.com
Sat Jan 6 11:26:08 CST 2007


-------------- next part --------------
From 4fc53f3f60b4ef109ad2022d394c850f87f83bbc Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Sat, 6 Jan 2007 16:50:33 +0100
Subject: [PATCH] WineD3D: Do not keep internal references on vertex buffers

---
 dlls/ddraw/ddraw_private.h |    3 ++-
 dlls/ddraw/device.c        |    7 ++++++-
 dlls/ddraw/direct3d.c      |    1 +
 dlls/ddraw/vertexbuffer.c  |   26 ++++++++++++++++++++++++++
 dlls/wined3d/device.c      |   11 -----------
 dlls/wined3d/stateblock.c  |    7 -------
 6 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index ca3bc76..b05e15a 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -578,8 +578,9 @@ struct IDirect3DVertexBufferImpl
     ICOM_VFIELD_MULTI(IDirect3DVertexBuffer);
     LONG                 ref;
 
-    /*** WineD3D link ***/
+    /*** WineD3D and ddraw links ***/
     IWineD3DVertexBuffer *wineD3DVertexBuffer;
+    IDirectDrawImpl *ddraw;
 
     /*** Storage for D3D7 specific things ***/
     DWORD                Caps;
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 90835a7..4ba3154 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -288,7 +288,7 @@ IDirect3DDeviceImpl_7_Release(IDirect3DD
         IParent *IndexBufferParent;
         DWORD i;
 
-        /* Free the index buffer */
+        /* Free the index buffer. */
         IWineD3DDevice_SetIndices(This->wineD3DDevice,
                                   NULL,
                                   0);
@@ -300,6 +300,11 @@ IDirect3DDeviceImpl_7_Release(IDirect3DD
             ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
         }
 
+        /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
+         * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
+         * IDirect3DVertexBuffer::Release will unset it.
+         */
+
         /* Restore the render targets */
         if(This->OffScreenTarget)
         {
diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c
index 8de0c1c..4896ba7 100644
--- a/dlls/ddraw/direct3d.c
+++ b/dlls/ddraw/direct3d.c
@@ -997,6 +997,7 @@ IDirect3DImpl_7_CreateVertexBuffer(IDire
     ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, IDirect3DVertexBuffer1_Vtbl);
 
     object->Caps = Desc->dwCaps;
+    object->ddraw = This;
 
     hr = IWineD3DDevice_CreateVertexBuffer(This->wineD3DDevice,
                                            get_flexible_vertex_size(Desc->dwFVF) * Desc->dwNumVertices,
diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c
index 8dda6dc..46a9c31 100644
--- a/dlls/ddraw/vertexbuffer.c
+++ b/dlls/ddraw/vertexbuffer.c
@@ -164,6 +164,32 @@ IDirect3DVertexBufferImpl_Release(IDirec
 
     if (ref == 0)
     {
+        IWineD3DVertexBuffer *curVB = NULL;
+        UINT offset, stride;
+
+        /* D3D7 Vertex buffers don't stay bound in the device, they are passed as a parameter
+         * to drawPrimitiveVB. DrawPrimitiveVB sets them as the stream source in wined3d,
+         * and they should get unset there before they are destroyed
+         */
+        IWineD3DDevice_GetStreamSource(This->ddraw->wineD3DDevice,
+                                       0 /* Stream number */,
+                                       &curVB,
+                                       &offset,
+                                       &stride);
+        if(curVB == This->wineD3DVertexBuffer)
+        {
+            IWineD3DDevice_SetStreamSource(This->ddraw->wineD3DDevice,
+                                        0 /* Steam number */,
+                                        NULL /* stream data */,
+                                        0 /* Offset */,
+                                        0 /* stride */);
+        }
+        if(curVB)
+        {
+            IWineD3DVertexBuffer_Release(curVB); /* For the GetStreamSource */
+        }
+
+
         IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer);
         HeapFree(GetProcessHeap(), 0, This);
         return 0;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 1a71afa..e43a2e6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2248,11 +2248,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         }
         vbImpl->stream = StreamNumber;
         vbImpl->Flags |= VBFLAG_STREAM;
-        IWineD3DVertexBuffer_AddRef(pStreamData);
     }
     if (oldSrc != NULL) {
         ((IWineD3DVertexBufferImpl *) oldSrc)->Flags &= ~VBFLAG_STREAM;
-        IWineD3DVertexBuffer_Release(oldSrc);
     }
 
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
@@ -4731,11 +4729,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl
              debug_d3dprimitivetype(PrimitiveType),
              PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
 
-    /* release the stream source */
-    if (This->stateBlock->streamSource[0] != NULL) {
-        IWineD3DVertexBuffer_Release(This->stateBlock->streamSource[0]);
-    }
-
     /* Note in the following, it's not this type, but that's the purpose of streamIsUP */
     This->stateBlock->streamSource[0] = (IWineD3DVertexBuffer *)pVertexStreamZeroData;
     This->stateBlock->streamStride[0] = VertexStreamZeroStride;
@@ -4777,10 +4770,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         idxStride = 4;
     }
 
-    /* release the stream and index data */
-    if (This->stateBlock->streamSource[0] != NULL) {
-        IWineD3DVertexBuffer_Release(This->stateBlock->streamSource[0]);
-    }
     if (This->stateBlock->pIndexData) {
         IWineD3DIndexBuffer_Release(This->stateBlock->pIndexData);
     }
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 439f0d2..0b3f6e8 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -232,13 +232,6 @@ static ULONG  WINAPI IWineD3DStateBlockI
         if (This->blockType == WINED3DSBT_INIT) {
             int counter;
             FIXME("Releasing primary stateblock\n");
-            /* Free any streams still bound */
-            for (counter = 0 ; counter < MAX_STREAMS ; counter++) {
-                if (This->streamSource[counter] != NULL) {
-                    IWineD3DVertexBuffer_Release(This->streamSource[counter]);
-                    This->streamSource[counter] = NULL;
-                }
-            }
 
             /* free any index data */
             if (This->pIndexData) {
-- 
1.4.2.4



More information about the wine-patches mailing list