From 3581d8e8d8f610adc1f36816ee4549f8ffb93fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sat, 6 Jan 2007 18:26:08 +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 ca3bc763234..b05e15a30d8 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 90835a76980..4ba3154750b 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -288,7 +288,7 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) 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(IDirect3DDevice7 *iface) 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 8de0c1c05e8..4896ba7d2ac 100644 --- a/dlls/ddraw/direct3d.c +++ b/dlls/ddraw/direct3d.c @@ -997,6 +997,7 @@ IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface, 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 8dda6dc1fe9..46a9c312ae9 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -164,6 +164,32 @@ IDirect3DVertexBufferImpl_Release(IDirect3DVertexBuffer7 *iface) 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 1a71afaaf00..e43a2e6248c 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2248,11 +2248,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface, } 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_DrawPrimitiveUP(IWineD3DDevice *iface, 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_DrawIndexedPrimitiveUP(IWineD3DDevice * 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 439f0d23eac..0b3f6e8cc0e 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -232,13 +232,6 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { 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) {