Module: wine Branch: master Commit: 7b47dabd0951a3eeaca38d1997419a836b158b6d URL: http://source.winehq.org/git/wine.git/?a=commit;h=7b47dabd0951a3eeaca38d1997...
Author: Henri Verbeet hverbeet@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;