[PATCH 4/4] wined3d: Handle discarded depth-stencil surfaces with SFLAG_LOST.

Matteo Bruni mbruni at codeweavers.com
Thu Jan 12 10:05:20 CST 2012


SFLAG_INSYSMEM is already set by surface_add_dirty_rect() for all
surfaces anyway.
---
 dlls/wined3d/device.c          |    2 +-
 dlls/wined3d/surface.c         |   43 ++++++++++++++++++++++++++--------------
 dlls/wined3d/swapchain.c       |    2 +-
 dlls/wined3d/wined3d_private.h |    5 ----
 4 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index ea22424..075f42e 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4937,7 +4937,7 @@ HRESULT CDECL wined3d_device_set_depth_stencil(struct wined3d_device *device, st
         if (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
                 || prev->flags & SFLAG_DISCARD)
         {
-            surface_modify_ds_location(prev, SFLAG_DS_DISCARDED,
+            surface_modify_ds_location(prev, SFLAG_LOST,
                     prev->resource.width, prev->resource.height);
             if (prev == device->onscreen_depth_stencil)
             {
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 64e8646..3b21f87 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -764,7 +764,8 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface)
             return WINED3DERR_INVALIDCALL;
     }
 
-    surface->flags |= SFLAG_INSYSMEM;
+    if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
+        surface->flags |= SFLAG_LOST;
 
     return WINED3D_OK;
 }
@@ -5568,16 +5569,9 @@ void surface_modify_ds_location(struct wined3d_surface *surface,
 {
     TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h);
 
-    if (location & ~SFLAG_LOCATIONS)
+    if (location & ~(SFLAG_LOCATIONS | SFLAG_LOST))
         FIXME("Invalid location (%#x) specified.\n", location);
 
-    if (!(surface->flags & SFLAG_ALLOCATED))
-        location &= ~SFLAG_INTEXTURE;
-    if (!(surface->rb_resolved))
-        location &= ~SFLAG_INRB_RESOLVED;
-    if (!(surface->rb_multisample))
-        location &= ~SFLAG_INRB_MULTISAMPLE;
-
     if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE))
             || (!(surface->flags & SFLAG_INTEXTURE) && (location & SFLAG_INTEXTURE)))
     {
@@ -5590,7 +5584,7 @@ void surface_modify_ds_location(struct wined3d_surface *surface,
 
     surface->ds_current_size.cx = w;
     surface->ds_current_size.cy = h;
-    surface->flags &= ~SFLAG_LOCATIONS;
+    surface->flags &= ~(SFLAG_LOCATIONS | SFLAG_LOST);
     surface->flags |= location;
 }
 
@@ -5631,13 +5625,32 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co
         return;
     }
 
+    if (surface->flags & SFLAG_LOST)
+    {
+        TRACE("Surface was discarded, no need copy data.\n");
+        switch (location)
+        {
+            case SFLAG_INTEXTURE:
+                surface_prepare_texture(surface, context, FALSE);
+                break;
+            case SFLAG_INRB_MULTISAMPLE:
+                surface_prepare_rb(surface, context->gl_info, TRUE);
+                break;
+            case SFLAG_INDRAWABLE:
+                /* Nothing to do */
+                break;
+            default:
+                FIXME("Unhandled location %#x", location);
+        }
+        surface->flags &= ~SFLAG_LOST;
+        surface->flags |= location;
+        surface->ds_current_size.cx = surface->resource.width;
+        surface->ds_current_size.cy = surface->resource.height;
+        return;
+    }
+
     if (!(surface->flags & SFLAG_LOCATIONS))
     {
-        /* This mostly happens when a depth / stencil is used without being
-         * cleared first. In principle we could upload from sysmem, or
-         * explicitly clear before first usage. For the moment there don't
-         * appear to be a lot of applications depending on this, so a FIXME
-         * should do. */
         FIXME("No up to date depth stencil location.\n");
         surface->flags |= location;
         surface->ds_current_size.cx = surface->resource.width;
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index feefc98..d363b63 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -641,7 +641,7 @@ static HRESULT swapchain_gl_present(struct wined3d_swapchain *swapchain, const R
         if (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
                 || fb->depth_stencil->flags & SFLAG_DISCARD)
         {
-            surface_modify_ds_location(fb->depth_stencil, SFLAG_DS_DISCARDED,
+            surface_modify_ds_location(fb->depth_stencil, SFLAG_LOST,
                     fb->depth_stencil->resource.width,
                     fb->depth_stencil->resource.height);
             if (fb->depth_stencil == swapchain->device->onscreen_depth_stencil)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index c9bd795..d0a1a07 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2179,11 +2179,6 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
                              SFLAG_INRB_MULTISAMPLE | \
                              SFLAG_INRB_RESOLVED)
 
-#define SFLAG_DS_DISCARDED  (SFLAG_INTEXTURE        | \
-                             SFLAG_INDRAWABLE       | \
-                             SFLAG_INRB_MULTISAMPLE | \
-                             SFLAG_INRB_RESOLVED)
-
 typedef enum {
     NO_CONVERSION,
     CONVERT_PALETTED,
-- 
1.7.3.4




More information about the wine-patches mailing list