Henri Verbeet : wined3d: Avoid some unnecessary invalidations of the the onscreen depth buffer.
Alexandre Julliard
julliard at winehq.org
Wed Apr 21 10:40:20 CDT 2010
Module: wine
Branch: master
Commit: 7b47dabd0951a3eeaca38d1997419a836b158b6d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7b47dabd0951a3eeaca38d1997419a836b158b6d
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Tue Apr 20 22:38:41 2010 +0200
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.
---
dlls/wined3d/device.c | 41 ++++++++++++++++++++++++++++++++-------
dlls/wined3d/drawprim.c | 4 +++
dlls/wined3d/swapchain.c | 5 ++++
dlls/wined3d/wined3d_private.h | 3 ++
4 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 00d94fa..52d82b2 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -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);
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index fd19930..4579a54 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -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);
}
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 389efc2..02e6bf7 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -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;
+ }
}
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 97f5095..260e3c7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -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;
More information about the wine-cvs
mailing list