-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Am 2013-09-04 08:56, schrieb Henri Verbeet: > We never render directly to the front buffer, and in case of e.g. a > P8 front buffer, we would fail surface creation if we were to > enforce format restrictions. This patch uncovers a problem I am not quite sure how to solve.
We set the frontbuffer as render target in wined3d_device_init_3d if there's no backbuffer, i.e., when ddraw is used. In theory this doesn't matter because we're not rendering to it, just blitting. Similarly, dlls/ddraw/device.c calls set_render_target to set the ddraw frontbuffer on release. The call fails now, but that doesn't cause any visible problems yet. There is a zombie wined3d surface left, but it goes away on ddraw shutdown or when a new ddraw IDirect3DDevice is created. However, when we create wined3d textures for standalone surfaces, the ddraw surface isn't destroyed until the wined3d surface goes away because we're waiting for the callback. This keeps the ddraw surface alive as well. The ddraw tests notice this because keeping the IDirectDrawSurface alive means keeping an IDirect3DDevice1 alive as well. The device holds a reference to the attached viewport(s), which triggers a failure in the ddraw1 tests. The test failure was lingering before, I fixed this by adding a similar set_render_target call to ddraw_surface_release_iface_destroy. See the attached patches for reference. The easiest solution seems to create a separate dummy render target that ddraw can use to unset application targets. That still leaves the problem that we're initializing wined3d with an invalid render target now. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBAgAGBQJSJ6NiAAoJEN0/YqbEcdMwqEsP/3We5UyaUsuUmh8DuqpUDozy OPFdfg0defIGBB3xdcRPYtwz265jsThxK8ek/vb24E1fJXJsm7zE1CJq1jUh/Beo X1zkewvL29WpriNvh11AW0+FIrE2XMwmr/5ekHQMXM4Evv2aRWG6zmWj0Wv1zR+x EcFgHE7J6boOIHtogPoge8KHiVULjxm91Dpnariab0YzUNDUfaHUXopWH0N4hb3T W5ds4cnHLOapOk8ihDfyAcBXOH4JlvConKKG4zDtbcuovp01yLR+eF03m/eBqt5m 0x3VpPyyaIJpFtOERAi9CqbN0Xuy3wOLmtgHsjy8Qh1wKr/I+DmkuakcsJYELmrY Ou7n+fDRceJyxdqP8vGtwlsP7Skkyxet/KYt7xbWsMcIcMjFDv6KW6YMyOGg2aJM O4o8gEFH3zgBQqLBsOf+O85GbQ2ZTLFoRaWkbRYFYYBaypd+S4TBRn9i0gL0Qw/q KImvYV47HcBK0uTuuV0dG/2YzUs/JraKGMU0sVmUNiDqfOm7+R+NAlU86jQ4PNo+ G0cV2IpEt9Bk/06XmSWI944X7NTe/ZDXs8Fa5MveLk87wETzg54F3RK2AoyHPY59 UK/3nisrRmUDeRZHiRp53E6eSW7VSXoHUgqeHt04fvLheMXpAnuibKJcKGTYqYMe kfkNuq73chpb9uZhe0EJ =PCrO -----END PGP SIGNATURE-----
>From 14219846c7e4b8b2b95fb26221a99c5144437fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <ste...@codeweavers.com> Date: Mon, 2 Sep 2013 17:46:42 +0200 Subject: [PATCH 10/13] ddraw: Unset the render target when it is destroyed Reply-To: wine-devel <wine-devel@winehq.org> --- dlls/ddraw/surface.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 62d3218..037ada9 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -495,6 +495,7 @@ ULONG ddraw_surface_release_iface(struct ddraw_surface *This) if (iface_count == 0) { IUnknown *release_iface = This->ifaceToRelease; + struct wined3d_surface *rt; /* Complex attached surfaces are destroyed implicitly when the root is released */ wined3d_mutex_lock(); @@ -504,6 +505,14 @@ ULONG ddraw_surface_release_iface(struct ddraw_surface *This) wined3d_mutex_unlock(); return iface_count; } + + rt = wined3d_device_get_render_target(This->ddraw->wined3d_device, 0); + if (rt == This->wined3d_surface) + { + wined3d_device_set_render_target(This->ddraw->wined3d_device, 0, + This->ddraw->wined3d_frontbuffer, TRUE); + } + if (This->wined3d_texture) /* If it's a texture, destroy the wined3d texture. */ wined3d_texture_decref(This->wined3d_texture); else -- 1.8.1.5
>From 9cb01bbda830b0bc548d254503aac53c437d284c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <ste...@codeweavers.com> Date: Mon, 2 Sep 2013 17:51:19 +0200 Subject: [PATCH 12/13] ddraw: Create textures for all surfaces Reply-To: wine-devel <wine-devel@winehq.org> --- dlls/ddraw/ddraw.c | 16 +++++++++++++--- dlls/ddraw/surface.c | 9 +++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 26f1984..99ec4f7 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -2863,12 +2863,22 @@ static HRESULT CreateSurface(struct ddraw *ddraw, DDSURFACEDESC2 *DDSD, } } + hr = ddraw_surface_create_texture(object, flags); + if (FAILED(hr)) + { + if (version == 7) + IDirectDrawSurface7_Release(&object->IDirectDrawSurface7_iface); + else if (version == 4) + IDirectDrawSurface4_Release(&object->IDirectDrawSurface4_iface); + else + IDirectDrawSurface_Release(&object->IDirectDrawSurface_iface); + + return hr; + } + if (desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) ddraw->primary = object; - /* Create a WineD3DTexture if a texture was requested */ - if (desc2.ddsCaps.dwCaps & DDSCAPS_TEXTURE) - ddraw_surface_create_texture(object, flags); return hr; } diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 037ada9..c6badd4 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -5649,6 +5649,15 @@ HRESULT ddraw_surface_create_texture(struct ddraw_surface *surface, DWORD surfac if (FAILED(hr)) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); + switch (hr) + { + case WINED3DERR_INVALIDCALL: + hr = DDERR_INVALIDPARAMS; + break; + + default: + FIXME("Unexpected wined3d error %#x.\n", hr); + } return hr; } -- 1.8.1.5
0010-ddraw-Unset-the-render-target-when-it-is-destroyed.patch.sig
Description: PGP signature
0012-ddraw-Create-textures-for-all-surfaces.patch.sig
Description: PGP signature