From 3ec639e38c90166bf2134817c05903320d43d80d Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 12 Aug 2009 09:44:22 +0200 Subject: [PATCH] wined3d: Fix swapchain draw buffer cleanup. Destroying the first back buffer before the other ones might cause an already freed surface to be used as target in FindContext(). --- dlls/wined3d/swapchain.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 2910ef913bd..d8d3733f56d 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -45,23 +45,32 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma); - /* release the ref to the front and back buffer parents */ - if(This->frontBuffer) { + /* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is + * the last buffer to be destroyed, FindContext() depends on that. */ + if (This->frontBuffer) + { IWineD3DSurface_SetContainer(This->frontBuffer, 0); - if(D3DCB_DestroyRenderTarget(This->frontBuffer) > 0) { - FIXME("(%p) Something's still holding the front buffer\n",This); + if (D3DCB_DestroyRenderTarget(This->frontBuffer)) + { + FIXME("(%p) Something's still holding the front buffer (%p).\n", + This, This->frontBuffer); } + This->frontBuffer = NULL; } - if(This->backBuffer) { - UINT i; - for(i = 0; i < This->presentParms.BackBufferCount; i++) { + if (This->backBuffer) + { + UINT i = This->presentParms.BackBufferCount; + + while (i--) + { IWineD3DSurface_SetContainer(This->backBuffer[i], 0); - if(D3DCB_DestroyRenderTarget(This->backBuffer[i]) > 0) { - FIXME("(%p) Something's still holding the back buffer\n",This); - } + if (D3DCB_DestroyRenderTarget(This->backBuffer[i])) + FIXME("(%p) Something's still holding back buffer %u (%p).\n", + This, i, This->backBuffer[i]); } HeapFree(GetProcessHeap(), 0, This->backBuffer); + This->backBuffer = NULL; } for (i = 0; i < This->num_contexts; ++i)