From adf0ab2ad889c7c6bcda484edfde9a431f829b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 14 Jan 2014 13:59:23 +0100 Subject: [PATCH] wined3d: Give the DIB section its own location. --- dlls/wined3d/surface.c | 67 +++++++++++++++++++++++++++++++--- dlls/wined3d/swapchain.c | 4 +- dlls/wined3d/utils.c | 3 +- dlls/wined3d/wined3d_private.h | 15 ++++---- 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 61f322e3f8e..ef91ebc1ab0 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -511,6 +511,12 @@ static void surface_get_memory(const struct wined3d_surface *surface, struct win data->buffer_object = 0; return; } + if (location & SFLAG_INDIB) + { + data->addr = surface->dib.bitmap_data; + data->buffer_object = 0; + return; + } if (location & SFLAG_INSYSMEM) { if (surface->flags & SFLAG_PBO) @@ -605,6 +611,10 @@ void surface_prepare_map_memory(struct wined3d_surface *surface) ERR("Map binding is set to SFLAG_INUSERMEM but surface->user_memory is NULL.\n"); break; + case SFLAG_INDIB: + if (!surface->dib.bitmap_data) + ERR("Map binding is set to SFLAG_INDIB but surface->dib.bitmap_data is NULL.\n"); + case SFLAG_INSYSMEM: surface_prepare_system_memory(surface); break; @@ -3242,9 +3252,9 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) ERR("Map failed, hr %#x.\n", hr); return hr; } - surface->getdc_map_mem = map.data; - memcpy(surface->dib.bitmap_data, surface->getdc_map_mem, surface->resource.size); + surface_load_location(surface, SFLAG_INDIB); + surface_invalidate_location(surface, ~SFLAG_INDIB); if (surface->resource.format->id == WINED3DFMT_P8_UINT || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM) @@ -3305,14 +3315,13 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) return WINEDDERR_NODC; } - memcpy(surface->getdc_map_mem, surface->dib.bitmap_data, surface->resource.size); - - /* We locked first, so unlock now. */ - surface->getdc_map_mem = NULL; wined3d_surface_unmap(surface); surface->flags &= ~SFLAG_DCINUSE; + if (surface->map_binding == SFLAG_INUSERMEM) + surface_load_location(surface, SFLAG_INUSERMEM); + return WINED3D_OK; } @@ -4869,9 +4878,54 @@ static DWORD resource_access_from_location(DWORD location) } } +static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) +{ + struct wined3d_device *device = surface->resource.device; + struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + struct wined3d_bo_address dst, src; + UINT size = surface->resource.size; + + surface_get_memory(surface, &dst, location); + surface_get_memory(surface, &src, surface->flags); + + if (dst.buffer_object) + { + context = context_acquire(device, NULL); + gl_info = context->gl_info; + GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, dst.buffer_object)); + GL_EXTCALL(glBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, size, src.addr)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + checkGLcall("Upload PBO"); + context_release(context); + return; + } + if (src.buffer_object) + { + context = context_acquire(device, NULL); + gl_info = context->gl_info; + GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, src.buffer_object)); + GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_PACK_BUFFER_ARB, 0, size, dst.addr)); + GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); + checkGLcall("Download PBO"); + context_release(context); + return; + } + memcpy(dst.addr, src.addr, size); +} + static void surface_load_sysmem(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, DWORD dst_location) { + static const DWORD simple_locations = + SFLAG_INDIB | SFLAG_INUSERMEM | SFLAG_INSYSMEM; + + if (surface->flags & simple_locations) + { + surface_copy_simple_location(surface, dst_location); + return; + } + if (surface->flags & (SFLAG_INRB_MULTISAMPLE | SFLAG_INRB_RESOLVED)) surface_load_location(surface, SFLAG_INTEXTURE); @@ -5156,6 +5210,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location) switch (location) { + case SFLAG_INDIB: case SFLAG_INUSERMEM: case SFLAG_INSYSMEM: surface_load_sysmem(surface, gl_info, location); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 045ead65b23..d65de1f2c51 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -609,7 +609,7 @@ static const struct wined3d_swapchain_ops swapchain_gl_ops = /* Helper function that blits the front buffer contents to the target window. */ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) { - const struct wined3d_surface *front; + struct wined3d_surface *front; POINT offset = {0, 0}; HDC src_dc, dst_dc; RECT draw_rect; @@ -623,7 +623,7 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r TRACE("Copying surface %p to screen.\n", front); - memcpy(front->dib.bitmap_data, front->resource.heap_memory, front->resource.size); + surface_load_location(front, SFLAG_INDIB); src_dc = front->hDC; window = swapchain->win_handle; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index fa72a07288c..eb62455db47 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -2795,7 +2795,7 @@ void dump_color_fixup_desc(struct color_fixup_desc fixup) } const char *debug_surflocation(DWORD flag) { - char buf[140]; + char buf[152]; buf[0] = 0; if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */ @@ -2805,6 +2805,7 @@ const char *debug_surflocation(DWORD flag) { if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */ if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */ if (flag & SFLAG_INUSERMEM) strcat(buf, " | SFLAG_INUSERMEM"); /* 18 */ + if (flag & SFLAG_INDIB) strcat(buf, " | SFLAG_INDIB"); /* 14 */ return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0"); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d4f073956e0..e795623c2cd 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2217,7 +2217,6 @@ struct wined3d_surface /* For GetDC */ struct wined3d_surface_dib dib; HDC hDC; - void *getdc_map_mem; struct wined3d_color_key gl_color_key; @@ -2300,12 +2299,13 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D #define SFLAG_PBO 0x00002000 /* The surface has a PBO. */ #define SFLAG_INSYSMEM 0x00004000 /* The system memory copy is current. */ #define SFLAG_INUSERMEM 0x00008000 /* The user memory copy is current. */ -#define SFLAG_INTEXTURE 0x00010000 /* The GL texture is current. */ -#define SFLAG_INSRGBTEX 0x00020000 /* The GL sRGB texture is current. */ -#define SFLAG_INDRAWABLE 0x00040000 /* The GL drawable is current. */ -#define SFLAG_INRB_MULTISAMPLE 0x00080000 /* The multisample renderbuffer is current. */ -#define SFLAG_INRB_RESOLVED 0x00100000 /* The resolved renderbuffer is current. */ -#define SFLAG_DISCARDED 0x00200000 /* Surface was discarded, allocating new location is enough. */ +#define SFLAG_INDIB 0x00010000 /* The DIB copy is current. */ +#define SFLAG_INTEXTURE 0x00020000 /* The GL texture is current. */ +#define SFLAG_INSRGBTEX 0x00040000 /* The GL sRGB texture is current. */ +#define SFLAG_INDRAWABLE 0x00080000 /* The GL drawable is current. */ +#define SFLAG_INRB_MULTISAMPLE 0x00100000 /* The multisample renderbuffer is current. */ +#define SFLAG_INRB_RESOLVED 0x00200000 /* The resolved renderbuffer is current. */ +#define SFLAG_DISCARDED 0x00400000 /* Surface was discarded, allocating new location is enough. */ /* In some conditions the surface memory must not be freed: * SFLAG_CONVERTED: Converting the data back would take too long @@ -2321,6 +2321,7 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D #define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \ SFLAG_INUSERMEM | \ + SFLAG_INDIB | \ SFLAG_INTEXTURE | \ SFLAG_INSRGBTEX | \ SFLAG_INDRAWABLE | \