Henri Verbeet : ddraw: Verify that the surface is not a depth buffer in SetRenderTarget().

Alexandre Julliard julliard at winehq.org
Thu Sep 19 17:21:01 CDT 2013


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Thu Sep 19 10:16:47 2013 +0200

ddraw: Verify that the surface is not a depth buffer in SetRenderTarget().

This check is even more inconsistent between versions. Notice how the v2
interface is particularly broken because it never AddRef()'s the new iface.
This check also seems to be the original source for the questionable behaviour
in d3d_device_set_render_target() of storing the new iface before checking the
result of the wined3d_device_set_render_target(). (In particular,
SetRenderTargetTest() in tests/d3d.c tests for this behavious.)

---

 dlls/ddraw/device.c |   36 +++++++++++++++++++++++++++++++++---
 1 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index af343bb..f1b1346 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -1821,12 +1821,13 @@ static HRESULT d3d_device_set_render_target(struct d3d_device *device,
         return DDERR_INVALIDPARAMS;
     }
 
-    IUnknown_AddRef(rt_iface);
-    IUnknown_Release(device->rt_iface);
-    device->rt_iface = rt_iface;
     if (FAILED(hr = wined3d_device_set_render_target(device->wined3d_device,
             0, target->wined3d_surface, FALSE)))
         return hr;
+
+    IUnknown_AddRef(rt_iface);
+    IUnknown_Release(device->rt_iface);
+    device->rt_iface = rt_iface;
     d3d_device_update_depth_stencil(device);
 
     return D3D_OK;
@@ -1864,6 +1865,16 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface,
         return DDERR_INVALIDPARAMS;
     }
 
+    if (target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
+    {
+        WARN("Surface %p is a depth buffer.\n", target_impl);
+        IDirectDrawSurface7_AddRef(target);
+        IUnknown_Release(device->rt_iface);
+        device->rt_iface = (IUnknown *)target;
+        wined3d_mutex_unlock();
+        return DDERR_INVALIDPIXELFORMAT;
+    }
+
     hr = d3d_device_set_render_target(device, target_impl, (IUnknown *)target);
     wined3d_mutex_unlock();
     return hr;
@@ -1913,6 +1924,16 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface,
         return DDERR_INVALIDCAPS;
     }
 
+    if (target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
+    {
+        WARN("Surface %p is a depth buffer.\n", target_impl);
+        IDirectDrawSurface4_AddRef(target);
+        IUnknown_Release(device->rt_iface);
+        device->rt_iface = (IUnknown *)target;
+        wined3d_mutex_unlock();
+        return DDERR_INVALIDPIXELFORMAT;
+    }
+
     if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
     {
         WARN("Surface %p is not in video memory.\n", target_impl);
@@ -1953,6 +1974,15 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface,
         return DDERR_INVALIDCAPS;
     }
 
+    if (target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
+    {
+        WARN("Surface %p is a depth buffer.\n", target_impl);
+        IUnknown_Release(device->rt_iface);
+        device->rt_iface = (IUnknown *)target;
+        wined3d_mutex_unlock();
+        return DDERR_INVALIDPIXELFORMAT;
+    }
+
     if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
     {
         WARN("Surface %p is not in video memory.\n", target_impl);




More information about the wine-cvs mailing list