Commit 6fe8e64c authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ddraw: Sync wined3d render target in d3d_device_sync_rendertarget().

parent aa8487a4
......@@ -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);
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment