From f2790588fee2e9e71e15770f9727fac7c1938654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ri=C4=8Dardas=20Barkauskas?= Date: Tue, 28 Jun 2011 02:32:04 +0300 Subject: 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; -- 1.7.5.4