diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8e7bd19680f..c01d53c8fc8 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -571,8 +571,9 @@ void device_switch_onscreen_ds(struct wined3d_device *device, { 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, + surface_load_ds_location(device->onscreen_depth_stencil, context, SFLAG_INTEXTURE); + + surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_INTEXTURE, device->onscreen_depth_stencil->ds_current_size.cx, device->onscreen_depth_stencil->ds_current_size.cy); wined3d_surface_decref(device->onscreen_depth_stencil); @@ -696,9 +697,9 @@ HRESULT device_clear_render_targets(struct wined3d_device *device, UINT rt_count if (flags & WINED3DCLEAR_ZBUFFER) { - DWORD location = render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; + DWORD location = render_offscreen ? fb->depth_stencil->draw_binding : SFLAG_INDRAWABLE; - if (location == SFLAG_DS_ONSCREEN && fb->depth_stencil != device->onscreen_depth_stencil) + if (!render_offscreen && fb->depth_stencil != device->onscreen_depth_stencil) device_switch_onscreen_ds(device, context, fb->depth_stencil); prepare_ds_clear(fb->depth_stencil, context, location, draw_rect, rect_count, clear_rect); } @@ -729,7 +730,9 @@ HRESULT device_clear_render_targets(struct wined3d_device *device, UINT rt_count if (flags & WINED3DCLEAR_ZBUFFER) { - surface_modify_location(fb->depth_stencil, fb->depth_stencil->draw_binding, TRUE); + DWORD location = render_offscreen ? fb->depth_stencil->draw_binding : SFLAG_INDRAWABLE; + + surface_modify_location(fb->depth_stencil, location, TRUE); glDepthMask(GL_TRUE); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE)); diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index b63d48e5b90..61fbb85f154 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -615,13 +615,13 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId * Z-compare function into account, but we could skip loading the * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note * that we never copy the stencil data.*/ - DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; + DWORD location = context->render_offscreen ? device->fb.depth_stencil->draw_binding : SFLAG_INDRAWABLE; if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) { struct wined3d_surface *ds = device->fb.depth_stencil; RECT current_rect, draw_rect, r; - if (location == SFLAG_DS_ONSCREEN && ds != device->onscreen_depth_stencil) + if (!context->render_offscreen && ds != device->onscreen_depth_stencil) device_switch_onscreen_ds(device, context, ds); if (ds->flags & location) @@ -638,7 +638,6 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId if (state->render_states[WINED3D_RS_ZWRITEENABLE]) { surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); - surface_modify_location(ds, ds->draw_binding, TRUE); } } } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 8d5dd1b9a3c..1ff55211afe 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1395,9 +1395,8 @@ static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, co wined3d_surface_depth_blt_fbo(device, src_surface, src_rect, dst_surface, dst_rect); - surface_modify_ds_location(dst_surface, SFLAG_DS_OFFSCREEN, + surface_modify_ds_location(dst_surface, SFLAG_INTEXTURE, dst_surface->ds_current_size.cx, dst_surface->ds_current_size.cy); - surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE); return WINED3D_OK; } @@ -5557,12 +5556,19 @@ 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_DS_LOCATIONS) + if (location & ~SFLAG_LOCATIONS) 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; + surface->ds_current_size.cx = w; surface->ds_current_size.cy = h; - surface->flags &= ~SFLAG_DS_LOCATIONS; + surface->flags &= ~SFLAG_LOCATIONS; surface->flags |= location; } @@ -5603,7 +5609,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co return; } - if (!(surface->flags & SFLAG_DS_LOCATIONS)) + 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 @@ -5617,7 +5623,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co return; } - if (location == SFLAG_DS_OFFSCREEN) + if (location == SFLAG_INTEXTURE) { GLint old_binding = 0; GLenum bind_target; @@ -5684,7 +5690,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ } - else if (location == SFLAG_DS_ONSCREEN) + else if (location == SFLAG_INDRAWABLE) { TRACE("Copying depth texture to onscreen depth buffer.\n"); @@ -5721,6 +5727,7 @@ void surface_modify_location(struct wined3d_surface *surface, DWORD location, BO surface, debug_surflocation(location), persistent); if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && surface_is_offscreen(surface) + && !(surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) && (location & SFLAG_INDRAWABLE)) ERR("Trying to invalidate the SFLAG_INDRAWABLE location of an offscreen surface.\n"); @@ -6112,7 +6119,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, c if (location == SFLAG_INTEXTURE) { struct wined3d_context *context = context_acquire(device, NULL); - surface_load_ds_location(surface, context, SFLAG_DS_OFFSCREEN); + surface_load_ds_location(surface, context, location); context_release(context); return WINED3D_OK; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 114e7061abf..e9c6233b408 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2153,8 +2153,6 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D #define SFLAG_INDRAWABLE 0x00100000 /* The GL drawable is current. */ #define SFLAG_INRB_MULTISAMPLE 0x00200000 /* The multisample renderbuffer is current. */ #define SFLAG_INRB_RESOLVED 0x00400000 /* The resolved renderbuffer is current. */ -#define SFLAG_DS_ONSCREEN 0x00800000 /* This is a depth / stencil surface, last modified onscreen. */ -#define SFLAG_DS_OFFSCREEN 0x01000000 /* This is a depth / stencil surface, last modified offscreen. */ #define SFLAG_PIN_SYSMEM 0x02000000 /* Keep the surface in sysmem, at the same address. */ /* In some conditions the surface memory must not be freed: @@ -2181,9 +2179,10 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D SFLAG_INRB_MULTISAMPLE | \ SFLAG_INRB_RESOLVED) -#define SFLAG_DS_LOCATIONS (SFLAG_DS_ONSCREEN | \ - SFLAG_DS_OFFSCREEN) -#define SFLAG_DS_DISCARDED SFLAG_DS_LOCATIONS +#define SFLAG_DS_DISCARDED (SFLAG_INTEXTURE | \ + SFLAG_INDRAWABLE | \ + SFLAG_INRB_MULTISAMPLE | \ + SFLAG_INRB_RESOLVED) typedef enum { NO_CONVERSION,