[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