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