[PATCH 3/5] wined3d: Give the DIB section its own location.
Stefan Dösinger
stefan at codeweavers.com
Tue Jan 14 06:59:23 CST 2014
---
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 61f322e..ef91ebc 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 045ead6..d65de1f 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 54eb988..0afde9d 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 d4f0739..e795623 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 | \
--
1.8.3.2
More information about the wine-patches
mailing list