From c6c5c6905e87fefffd00c7d8e68df22879aefe55 Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Thu, 12 Jan 2012 17:05:20 +0100 Subject: [PATCH] wined3d: Handle discarded depth-stencil surfaces with SFLAG_LOST. 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 8633c651e65..563a9245bcb 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 64e86468f05..3b21f878f4c 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 feefc980316..d363b6318f0 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 80162b208da..cc881d4f105 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, -- 2.11.4.GIT