From 880f9c714ec701b071da012fc4009bb51a011765 Mon Sep 17 00:00:00 2001
From: Jim Cameron <jim_24601@btinternet.com>
Date: Thu, 9 Oct 2008 22:11:14 +0100
Subject: Protect current depth-stencil surface from deletion

---
 dlls/d3d9/device.c  |   20 ++++++++++++++++++++
 dlls/d3d9/surface.c |    2 +-
 2 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 8aab230..36306d5 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -715,12 +715,32 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9EX
 static HRESULT  WINAPI  IDirect3DDevice9Impl_SetDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pZStencilSurface) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     IDirect3DSurface9Impl *pSurface;
+    IDirect3DSurface9Impl *pPrev = NULL;
+    IWineD3DSurface *pWineD3DSurface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
     EnterCriticalSection(&d3d9_cs);
+    /* Retrieve the previous depth-stencil surface, if it exists */
+    hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pWineD3DSurface);
+    if (hr == WINED3D_OK) {
+        IWineD3DSurface_GetParent(pWineD3DSurface,(IUnknown**)&pPrev);
+        IWineD3DSurface_Release(pWineD3DSurface);
+    }
     hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL==pSurface ? NULL : pSurface->wineD3DSurface);
+    if (hr == WINED3D_OK) {
+        /* Protect user-supplied surfaces from deletion while they are
+           selected into the device. */
+        if (pSurface != NULL && !pSurface->isImplicit) {
+            InterlockedIncrement(&pSurface->refPrivate);
+        }
+        if (pPrev != NULL && !pPrev->isImplicit) {
+            InterlockedDecrement(&pPrev->refPrivate);
+        }
+    }
+    /* If there was no external reference, will be deleted */
+    if (pPrev != NULL) IUnknown_Release((IUnknown*) pPrev);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c
index 54558b4..8787380 100644
--- a/dlls/d3d9/surface.c
+++ b/dlls/d3d9/surface.c
@@ -77,7 +77,7 @@ static ULONG WINAPI IDirect3DSurface9Impl_Release(LPDIRECT3DSURFACE9 iface) {
 
         if (ref == 0) {
             if (This->parentDevice) IUnknown_Release(This->parentDevice);
-            if (!This->isImplicit) {
+            if (!This->isImplicit && This->refPrivate == 0) {
                 EnterCriticalSection(&d3d9_cs);
                 IWineD3DSurface_Release(This->wineD3DSurface);
                 LeaveCriticalSection(&d3d9_cs);
-- 
1.5.4.3

