From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/ddraw.c | 23 ----------------- dlls/ddraw/ddraw_private.h | 1 + dlls/ddraw/device.c | 51 ++++++++++++++++++++++++++++++++------ dlls/ddraw/viewport.c | 6 +++-- 4 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 21497cd7a8b..121944b1000 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -793,7 +793,6 @@ static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface) static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, DWORD cooplevel, BOOL restore_mode_on_normal) { - struct wined3d_rendertarget_view *rtv = NULL, *dsv = NULL; struct wined3d_stateblock *stateblock; BOOL restore_state = FALSE; struct d3d_device *device; @@ -937,16 +936,6 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ERR("Failed to create stateblock, hr %#lx.\n", hr); goto done; } - - rtv = wined3d_device_context_get_rendertarget_view(ddraw->immediate_context, 0); - /* Rendering to the wined3d frontbuffer. */ - if (rtv && !wined3d_rendertarget_view_get_sub_resource_parent(rtv)) - rtv = NULL; - else if (rtv) - wined3d_rendertarget_view_incref(rtv); - - if ((dsv = wined3d_device_context_get_depth_stencil_view(ddraw->immediate_context))) - wined3d_rendertarget_view_incref(dsv); }
ddraw_destroy_swapchain(ddraw); @@ -957,18 +946,6 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (restore_state) { - if (dsv) - { - wined3d_device_context_set_depth_stencil_view(ddraw->immediate_context, dsv); - wined3d_rendertarget_view_decref(dsv); - } - - if (rtv) - { - wined3d_device_context_set_rendertarget_views(ddraw->immediate_context, 0, 1, &rtv, FALSE); - wined3d_rendertarget_view_decref(rtv); - } - wined3d_stateblock_apply(stateblock, device->state); wined3d_stateblock_decref(stateblock); } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index f5b38f8f9d6..e5a8327204c 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -327,6 +327,7 @@ struct d3d_device struct wined3d_device_context *immediate_context; struct ddraw *ddraw; IUnknown *rt_iface; + struct ddraw_surface *target, *target_ds;
struct wined3d_streaming_buffer vertex_buffer, index_buffer;
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 59027a34ae1..cdcc332f235 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -336,6 +336,8 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) TRACE("Releasing render target %p.\n", This->rt_iface); rt_iface = This->rt_iface; This->rt_iface = NULL; + This->target = NULL; + This->target_ds = NULL; if (This->version != 1) IUnknown_Release(rt_iface); TRACE("Render target release done.\n"); @@ -1844,6 +1846,7 @@ static HRESULT d3d_device_set_render_target(struct d3d_device *device, IUnknown_AddRef(rt_iface); IUnknown_Release(device->rt_iface); device->rt_iface = rt_iface; + device->target = target; d3d_device_update_depth_stencil(device);
return D3D_OK; @@ -1887,6 +1890,8 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface, IDirectDrawSurface7_AddRef(target); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return DDERR_INVALIDPIXELFORMAT; } @@ -1946,6 +1951,8 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, IDirectDrawSurface4_AddRef(target); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return DDERR_INVALIDPIXELFORMAT; } @@ -1956,6 +1963,8 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, IDirectDrawSurface4_AddRef(target); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return D3D_OK; } @@ -1995,6 +2004,8 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, WARN("Surface %p is a depth buffer.\n", target_impl); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return DDERR_INVALIDPIXELFORMAT; } @@ -2005,6 +2016,8 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, IDirectDrawSurface_AddRef(target); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return D3D_OK; } @@ -3367,16 +3380,36 @@ static HRESULT WINAPI d3d_device2_MultiplyTransform(IDirect3DDevice2 *iface, *****************************************************************************/ static void d3d_device_sync_rendertarget(struct d3d_device *device) { - struct wined3d_rendertarget_view *rtv; + struct wined3d_rendertarget_view *rtv, *dsv; + + rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL; + if (rtv) + { + if (FAILED(wined3d_device_context_set_rendertarget_views(device->immediate_context, 0, 1, &rtv, FALSE))) + ERR("wined3d_device_context_set_rendertarget_views failed.\n"); + } + else if (!device->target) + { + /* NULL device->target may appear when the game was setting invalid render target which in some cases + * still keeps the invalid render target in the device even while returning an error. + * + * TODO: make render go nowhere instead of lefover render target (like it seems to work on Windows on HW devices + * while may just crash on software devices. */ + FIXME("Keeping leftover render target.\n"); + } + + dsv = device->target_ds ? ddraw_surface_get_rendertarget_view(device->target_ds) : NULL; + if (FAILED(wined3d_device_context_set_depth_stencil_view(device->immediate_context, dsv))) + ERR("wined3d_device_context_set_depth_stencil_view failed.\n");
if (device->hardware_device) return;
- if ((rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0))) + if (rtv) ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW);
- if ((rtv = wined3d_device_context_get_depth_stencil_view(device->immediate_context))) - ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW); + if (dsv) + ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(dsv), DDRAW_SURFACE_RW); }
void d3d_device_sync_surfaces(struct d3d_device *device) @@ -5171,7 +5204,8 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi return DDERR_INVALIDPARAMS;
wined3d_mutex_lock(); - if (!(rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0))) + rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL; + if (!rtv) { wined3d_mutex_unlock(); return DDERR_INVALIDCAPS; @@ -6756,7 +6790,6 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device IDirectDrawSurface7 *depthStencil = NULL; IDirectDrawSurface7 *render_target; static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, {0} }; - struct ddraw_surface *dsi;
if (device->rt_iface && SUCCEEDED(IUnknown_QueryInterface(device->rt_iface, &IID_IDirectDrawSurface7, (void **)&render_target))) @@ -6768,12 +6801,13 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device { TRACE("Setting wined3d depth stencil to NULL\n"); wined3d_device_context_set_depth_stencil_view(device->immediate_context, NULL); + device->target_ds = NULL; return WINED3D_ZB_FALSE; }
- dsi = impl_from_IDirectDrawSurface7(depthStencil); + device->target_ds = impl_from_IDirectDrawSurface7(depthStencil); wined3d_device_context_set_depth_stencil_view(device->immediate_context, - ddraw_surface_get_rendertarget_view(dsi)); + ddraw_surface_get_rendertarget_view(device->target_ds));
IDirectDrawSurface7_Release(depthStencil); return WINED3D_ZB_TRUE; @@ -6869,6 +6903,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c }
device->rt_iface = rt_iface; + device->target = target; if (version != 1) IUnknown_AddRef(device->rt_iface);
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index 98b03c60d72..707b0f5498c 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -405,7 +405,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
if (device->version > 1) { - if (!(rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0))) + rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL; + if (!rtv) { wined3d_mutex_unlock(); return DDERR_INVALIDCAPS; @@ -1034,7 +1035,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVI
if (device->version > 1) { - if (!(rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0))) + rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL; + if (!rtv) { wined3d_mutex_unlock(); return DDERR_INVALIDCAPS;