Module: wine Branch: master Commit: b28511f73b04d54dfdc4f31e31e4606e7e0e5b0e URL: http://source.winehq.org/git/wine.git/?a=commit;h=b28511f73b04d54dfdc4f31e31...
Author: Stefan Dösinger stefan@codeweavers.com Date: Mon Oct 12 22:34:39 2015 +0200
wined3d: Pass a context to read_from_framebuffer.
Signed-off-by: Stefan Dösinger stefan@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wined3d/context.c | 14 ++++++++++++++ dlls/wined3d/surface.c | 18 +++++++++++++----- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 3e2a804..dc4199a 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1194,6 +1194,20 @@ void context_release(struct wined3d_context *context) } }
+/* This is used when a context for render target A is active, but a separate context is + * needed to access the WGL framebuffer for render target B. Re-acquire a context for rt + * A to avoid breaking caller code. */ +void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) +{ + if (context->current_rt != restore) + { + context_release(context); + context = context_acquire(restore->resource.device, restore); + } + + context_release(context); +} + static void context_enter(struct wined3d_context *context) { TRACE("Entering context %p, level %u.\n", context, context->level + 1); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index c911d35..7101bc4 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -2681,11 +2681,13 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) return WINED3D_OK; }
-static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_location) +static void read_from_framebuffer(struct wined3d_surface *surface, + struct wined3d_context *old_ctx, DWORD dst_location) { struct wined3d_device *device = surface->resource.device; const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; + struct wined3d_context *context = old_ctx; + struct wined3d_surface *restore_rt = NULL; BYTE *mem; BYTE *row, *top, *bottom; int i; @@ -2694,7 +2696,12 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
surface_get_memory(surface, &data, dst_location);
- context = context_acquire(device, surface); + if (surface != old_ctx->current_rt) + { + restore_rt = old_ctx->current_rt; + context = context_acquire(device, surface); + } + context_apply_blit_state(context, device); gl_info = context->gl_info;
@@ -2781,7 +2788,8 @@ error: checkGLcall("glBindBuffer"); }
- context_release(context); + if (restore_rt) + context_restore(context, restore_rt); }
/* Read the framebuffer contents into a texture. Note that this function @@ -3824,7 +3832,7 @@ static void surface_load_sysmem(struct wined3d_surface *surface,
if (surface->locations & WINED3D_LOCATION_DRAWABLE) { - read_from_framebuffer(surface, dst_location); + read_from_framebuffer(surface, context, dst_location); return; }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 70a8db8..75c16ef 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1423,6 +1423,7 @@ void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN; void context_resource_unloaded(const struct wined3d_device *device, struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN; +void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) DECLSPEC_HIDDEN; BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN; void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN; void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;