Ričardas Barkauskas : ddraw: Fix SetRenderTarget behaviour on failure.

Alexandre Julliard julliard at winehq.org
Tue Jun 28 17:25:15 CDT 2011


Module: wine
Branch: master
Commit: 3b50ad82ad8b95538f3dd73979e602f19620a72e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3b50ad82ad8b95538f3dd73979e602f19620a72e

Author: Ričardas Barkauskas <rbarkauskas at codeweavers.com>
Date:   Tue Jun 28 02:32:04 2011 +0300

ddraw: Fix SetRenderTarget behaviour on failure.

---

 dlls/ddraw/device.c    |   40 ++++++++++++++++++++++++----------------
 dlls/ddraw/tests/d3d.c |   27 ++++++++++++++++++++++++++-
 2 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 7a5d735..9699939 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -1826,17 +1826,10 @@ static HRESULT WINAPI IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
  *  D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
  *
  *****************************************************************************/
-static HRESULT
-IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
-                                      IDirectDrawSurface7 *NewTarget,
-                                      DWORD Flags)
+static HRESULT d3d_device_set_render_target(IDirect3DDeviceImpl *This, IDirectDrawSurfaceImpl *Target)
 {
-    IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
-    IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface7(NewTarget);
     HRESULT hr;
 
-    TRACE("iface %p, target %p, flags %#x.\n", iface, NewTarget, Flags);
-
     EnterCriticalSection(&ddraw_cs);
     /* Flags: Not used */
 
@@ -1846,7 +1839,7 @@ IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
         LeaveCriticalSection(&ddraw_cs);
         return D3D_OK;
     }
-
+    This->target = Target;
     hr = wined3d_device_set_render_target(This->wined3d_device, 0,
             Target ? Target->wined3d_surface : NULL, FALSE);
     if(hr != D3D_OK)
@@ -1854,14 +1847,27 @@ IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
         LeaveCriticalSection(&ddraw_cs);
         return hr;
     }
-    IDirectDrawSurface7_AddRef(NewTarget);
-    IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface);
-    This->target = Target;
     IDirect3DDeviceImpl_UpdateDepthStencil(This);
     LeaveCriticalSection(&ddraw_cs);
     return D3D_OK;
 }
 
+static HRESULT
+IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
+                                      IDirectDrawSurface7 *NewTarget,
+                                      DWORD Flags)
+{
+    IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
+    IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface7(NewTarget);
+
+    TRACE("iface %p, target %p, flags %#x.\n", iface, NewTarget, Flags);
+    /* Flags: Not used */
+
+    IDirectDrawSurface7_AddRef(NewTarget);
+    IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface);
+    return d3d_device_set_render_target(This, Target);
+}
+
 static HRESULT WINAPI
 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
                                       IDirectDrawSurface7 *NewTarget,
@@ -1893,8 +1899,9 @@ static HRESULT WINAPI IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *if
 
     TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, Flags);
 
-    return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This,
-            Target ? &Target->IDirectDrawSurface7_iface : NULL, Flags);
+    IDirectDrawSurface4_AddRef(NewRenderTarget);
+    IDirectDrawSurface4_Release(&This->target->IDirectDrawSurface4_iface);
+    return d3d_device_set_render_target(This, Target);
 }
 
 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
@@ -1905,8 +1912,9 @@ static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *if
 
     TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, Flags);
 
-    return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This,
-            Target ? &Target->IDirectDrawSurface7_iface : NULL, Flags);
+    IDirectDrawSurface_AddRef(NewRenderTarget);
+    IDirectDrawSurface_Release(&This->target->IDirectDrawSurface_iface);
+    return d3d_device_set_render_target(This, Target);
 }
 
 /*****************************************************************************
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c
index f975612..19a7961 100644
--- a/dlls/ddraw/tests/d3d.c
+++ b/dlls/ddraw/tests/d3d.c
@@ -3260,10 +3260,11 @@ static void ComputeSphereVisibility(void)
 static void SetRenderTargetTest(void)
 {
     HRESULT hr;
-    IDirectDrawSurface7 *newrt, *failrt, *oldrt;
+    IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
     D3DVIEWPORT7 vp;
     DDSURFACEDESC2 ddsd, ddsd2;
     DWORD stateblock;
+    ULONG refcount;
 
     memset(&ddsd, 0, sizeof(ddsd));
     ddsd.dwSize = sizeof(ddsd);
@@ -3307,11 +3308,34 @@ static void SetRenderTargetTest(void)
     hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
     ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
 
+    refcount = getRefcount((IUnknown*) oldrt);
+    todo_wine ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
+
+    refcount = getRefcount((IUnknown*) failrt);
+    ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
+
     hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
     ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
 
+    refcount = getRefcount((IUnknown*) oldrt);
+    todo_wine ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
+
+    refcount = getRefcount((IUnknown*) failrt);
+    ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
+
+    hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
+    ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
+    ok(failrt == temprt, "Wrong iface returned\n");
+
+    refcount = getRefcount((IUnknown*) failrt);
+    ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
+
     hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
     ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
+
+    refcount = getRefcount((IUnknown*) failrt);
+    ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
+
     memset(&vp, 0xff, sizeof(vp));
     hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
     ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
@@ -3377,6 +3401,7 @@ static void SetRenderTargetTest(void)
     IDirectDrawSurface7_Release(oldrt);
     IDirectDrawSurface7_Release(newrt);
     IDirectDrawSurface7_Release(failrt);
+    IDirectDrawSurface7_Release(failrt);
 }
 
 static const UINT *expect_messages;




More information about the wine-cvs mailing list