Commit 7b47dabd authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Avoid some unnecessary invalidations of the the onscreen depth buffer.

This can happen for example when the application switches to a different depth/stencil for offscreen rendering and back again.
parent 4f004a55
......@@ -563,6 +563,18 @@ void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *c
device->contexts = new_array;
}
void device_switch_onscreen_ds(IWineD3DDeviceImpl *device,
struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil)
{
if (device->onscreen_depth_stencil)
{
surface_load_ds_location(device->onscreen_depth_stencil, context, SFLAG_DS_OFFSCREEN);
surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_DS_OFFSCREEN);
IWineD3DSurface_Release((IWineD3DSurface *)device->onscreen_depth_stencil);
}
device->onscreen_depth_stencil = depth_stencil;
IWineD3DSurface_AddRef((IWineD3DSurface *)device->onscreen_depth_stencil);
}
/**********************************************************
* IUnknown parts follows
......@@ -1853,6 +1865,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface,
This->shader_backend->shader_free_private(iface);
/* Release the buffers (with sanity checks)*/
if (This->onscreen_depth_stencil)
{
IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil);
This->onscreen_depth_stencil = NULL;
}
TRACE("Releasing the depth stencil buffer at %p\n", This->depth_stencil);
if (This->depth_stencil && IWineD3DSurface_Release((IWineD3DSurface *)This->depth_stencil))
{
......@@ -4429,6 +4447,10 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfac
if (Flags & WINED3DCLEAR_ZBUFFER)
{
DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
if (location == SFLAG_DS_ONSCREEN && depth_stencil != This->onscreen_depth_stencil)
device_switch_onscreen_ds(This, context, depth_stencil);
if (!(depth_stencil->Flags & location) && !is_full_clear(depth_stencil, vp, scissor_rect, clear_rect))
surface_load_ds_location(depth_stencil, context, location);
surface_modify_ds_location(depth_stencil, location);
......@@ -5915,14 +5937,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice *
|| This->depth_stencil->Flags & SFLAG_DISCARD)
{
surface_modify_ds_location(This->depth_stencil, SFLAG_DS_DISCARDED);
}
else
{
struct wined3d_context *context = context_acquire(This,
(IWineD3DSurface *)This->render_targets[0], CTXUSAGE_RESOURCELOAD);
surface_load_ds_location(This->depth_stencil, context, SFLAG_DS_OFFSCREEN);
surface_modify_ds_location(This->depth_stencil, SFLAG_DS_OFFSCREEN);
context_release(context);
if (This->depth_stencil == This->onscreen_depth_stencil)
{
IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil);
This->onscreen_depth_stencil = NULL;
}
}
}
......@@ -6449,6 +6468,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
}
}
if (This->onscreen_depth_stencil)
{
IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil);
This->onscreen_depth_stencil = NULL;
}
/* Reset the depth stencil */
if (pPresentationParameters->EnableAutoDepthStencil)
IWineD3DDevice_SetDepthStencilSurface(iface, (IWineD3DSurface *)This->auto_depth_stencil);
......
......@@ -612,7 +612,11 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]
|| This->stateBlock->renderState[WINED3DRS_ZENABLE])
{
if (location == SFLAG_DS_ONSCREEN && This->depth_stencil != This->onscreen_depth_stencil)
device_switch_onscreen_ds(This, context, This->depth_stencil);
surface_load_ds_location(This->depth_stencil, context, location);
}
if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE])
surface_modify_ds_location(This->depth_stencil, location);
}
......
......@@ -465,6 +465,11 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
|| This->device->depth_stencil->Flags & SFLAG_DISCARD)
{
surface_modify_ds_location(This->device->depth_stencil, SFLAG_DS_DISCARDED);
if (This->device->depth_stencil == This->device->onscreen_depth_stencil)
{
IWineD3DSurface_Release((IWineD3DSurface *)This->device->onscreen_depth_stencil);
This->device->onscreen_depth_stencil = NULL;
}
}
}
......
......@@ -1668,6 +1668,7 @@ struct IWineD3DDeviceImpl
/* Render Target Support */
IWineD3DSurfaceImpl **render_targets;
IWineD3DSurfaceImpl *auto_depth_stencil;
IWineD3DSurfaceImpl *onscreen_depth_stencil;
IWineD3DSurfaceImpl *depth_stencil;
/* palettes texture management */
......@@ -1737,6 +1738,8 @@ void device_resource_add(IWineD3DDeviceImpl *This, IWineD3DResource *resource) D
void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource) DECLSPEC_HIDDEN;
void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup) DECLSPEC_HIDDEN;
void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, struct wined3d_context *context,
IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN;
void device_update_stream_info(IWineD3DDeviceImpl *device, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count,
const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) DECLSPEC_HIDDEN;
......
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