[PATCH 8/8] wined3d: Give user memory its own location.

Stefan Dösinger stefan at codeweavers.com
Fri Jan 10 05:40:47 CST 2014


---
 dlls/wined3d/surface.c         | 64 ++++++++++++++++++++++++++----------------
 dlls/wined3d/utils.c           |  3 +-
 dlls/wined3d/wined3d_private.h | 14 +++++----
 3 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index bfde475..6eba8ab 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -514,21 +514,30 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
     return WINED3D_OK;
 }
 
-static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data)
+static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data,
+        DWORD location)
 {
-    if (surface->user_memory)
+    if (location & SFLAG_INUSERMEM)
     {
         data->addr = surface->user_memory;
         data->buffer_object = 0;
         return;
     }
-    if (surface->flags & SFLAG_PBO)
+    if (location & SFLAG_INSYSMEM)
     {
-        data->addr = NULL;
-        data->buffer_object = surface->pbo;
+        if (surface->flags & SFLAG_PBO)
+        {
+            data->addr = NULL;
+            data->buffer_object = surface->pbo;
+            return;
+        }
+        data->addr = surface->resource.allocatedMemory;
+        data->buffer_object = 0;
         return;
     }
-    data->addr = surface->resource.allocatedMemory;
+
+    ERR("Unexpected locations %s.\n", debug_surflocation(location));
+    data->addr = NULL;
     data->buffer_object = 0;
 }
 
@@ -551,7 +560,7 @@ static void surface_create_pbo(struct wined3d_surface *surface, const struct win
     struct wined3d_context *context;
     GLenum error;
     struct wined3d_bo_address data;
-    surface_get_memory(surface, &data);
+    surface_get_memory(surface, &data, SFLAG_INSYSMEM);
 
     context = context_acquire(surface->resource.device, NULL);
 
@@ -812,6 +821,9 @@ static BYTE *surface_map(struct wined3d_surface *surface, const RECT *rect, DWOR
 
     switch (surface->map_binding)
     {
+        case SFLAG_INUSERMEM:
+            return surface->user_memory;
+
         case SFLAG_INSYSMEM:
             if (surface->flags & SFLAG_PBO)
             {
@@ -837,9 +849,6 @@ static BYTE *surface_map(struct wined3d_surface *surface, const RECT *rect, DWOR
                 return ret;
             }
 
-            if (surface->user_memory)
-                return surface->user_memory;
-
             return surface->resource.allocatedMemory;
 
         default:
@@ -858,6 +867,9 @@ static void surface_unmap(struct wined3d_surface *surface)
 
     switch (surface->map_binding)
     {
+        case SFLAG_INUSERMEM:
+            break;
+
         case SFLAG_INSYSMEM:
             if (surface->flags & SFLAG_PBO)
             {
@@ -1515,10 +1527,10 @@ static BYTE *gdi_surface_map(struct wined3d_surface *surface, const RECT *rect,
 
     switch (surface->map_binding)
     {
-        case SFLAG_INSYSMEM:
-            if (surface->user_memory)
-                return surface->user_memory;
+        case SFLAG_INUSERMEM:
+            return surface->user_memory;
 
+        case SFLAG_INSYSMEM:
             return surface->resource.allocatedMemory;
 
         default:
@@ -1569,7 +1581,8 @@ void surface_set_texture_target(struct wined3d_surface *surface, GLenum target,
 /* This call just downloads data, the caller is responsible for binding the
  * correct texture. */
 /* Context activation is done by the caller. */
-static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
+static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
+        DWORD dst_location)
 {
     const struct wined3d_format *format = surface->resource.format;
     struct wined3d_bo_address data;
@@ -1581,7 +1594,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
         return;
     }
 
-    surface_get_memory(surface, &data);
+    surface_get_memory(surface, &data, dst_location);
 
     if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
     {
@@ -2084,7 +2097,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
         surface_load_location(dst_surface, SFLAG_INTEXTURE);
     wined3d_texture_bind(dst_surface->container, context, FALSE);
 
-    surface_get_memory(src_surface, &data);
+    surface_get_memory(src_surface, &data, src_surface->flags);
     src_pitch = wined3d_surface_get_pitch(src_surface);
 
     surface_upload_data(dst_surface, gl_info, src_format, src_rect, src_pitch, dst_point, FALSE, &data);
@@ -2767,6 +2780,8 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
         surface->flags &= ~SFLAG_NONPOW2;
 
     surface->user_memory = mem;
+    if (surface->user_memory)
+        surface->map_binding = SFLAG_INUSERMEM;
     surface->pitch = pitch;
     surface->resource.format = format;
     surface->resource.multisample_type = multisample_type;
@@ -2788,7 +2803,7 @@ HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
     else if (!surface_init_sysmem(surface))
         return E_OUTOFMEMORY;
 
-    surface_validate_location(surface, SFLAG_INSYSMEM);
+    surface_validate_location(surface, surface->map_binding);
 
     return WINED3D_OK;
 }
@@ -3332,7 +3347,7 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
     return WINED3D_OK;
 }
 
-static void read_from_framebuffer(struct wined3d_surface *surface)
+static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_location)
 {
     struct wined3d_device *device = surface->resource.device;
     const struct wined3d_gl_info *gl_info;
@@ -3347,7 +3362,7 @@ static void read_from_framebuffer(struct wined3d_surface *surface)
     struct wined3d_bo_address data;
     UINT pitch = wined3d_surface_get_pitch(surface);
 
-    surface_get_memory(surface, &data);
+    surface_get_memory(surface, &data, dst_location);
 
     context = context_acquire(device, surface);
     context_apply_blit_state(context, device);
@@ -4889,7 +4904,7 @@ static DWORD resource_access_from_location(DWORD location)
 }
 
 static void surface_load_sysmem(struct wined3d_surface *surface,
-        const struct wined3d_gl_info *gl_info)
+        const struct wined3d_gl_info *gl_info, DWORD dst_location)
 {
     surface_prepare_system_memory(surface);
 
@@ -4906,7 +4921,7 @@ static void surface_load_sysmem(struct wined3d_surface *surface,
         context = context_acquire(device, NULL);
 
         wined3d_texture_bind_and_dirtify(surface->container, context, !(surface->flags & SFLAG_INTEXTURE));
-        surface_download_data(surface, gl_info);
+        surface_download_data(surface, gl_info, dst_location);
 
         context_release(context);
 
@@ -4915,7 +4930,7 @@ static void surface_load_sysmem(struct wined3d_surface *surface,
 
     if (surface->flags & SFLAG_INDRAWABLE)
     {
-        read_from_framebuffer(surface);
+        read_from_framebuffer(surface, dst_location);
         return;
     }
 
@@ -5052,7 +5067,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
         surface_remove_pbo(surface, gl_info);
     }
 
-    surface_get_memory(surface, &data);
+    surface_get_memory(surface, &data, surface->flags);
     if (format.convert)
     {
         /* This code is entered for texture formats which need a fixup. */
@@ -5174,8 +5189,9 @@ HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location)
 
     switch (location)
     {
+        case SFLAG_INUSERMEM:
         case SFLAG_INSYSMEM:
-            surface_load_sysmem(surface, gl_info);
+            surface_load_sysmem(surface, gl_info, location);
             break;
 
         case SFLAG_INDRAWABLE:
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 5d0b428..54eb988 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[128];
+    char buf[140];
 
     buf[0] = 0;
     if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");                    /* 17 */
@@ -2804,6 +2804,7 @@ const char *debug_surflocation(DWORD flag) {
     if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");                  /* 18 */
     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 */
     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 ea0986b..7a09037 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2298,12 +2298,13 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
 #define SFLAG_SRGBALLOCATED     0x00001000 /* A sRGB GL texture is allocated for this surface. */
 #define SFLAG_PBO               0x00002000 /* The surface has a PBO. */
 #define SFLAG_INSYSMEM          0x00004000 /* The system memory copy is current. */
-#define SFLAG_INTEXTURE         0x00008000 /* The GL texture is current. */
-#define SFLAG_INSRGBTEX         0x00010000 /* The GL sRGB texture is current. */
-#define SFLAG_INDRAWABLE        0x00020000 /* The GL drawable is current. */
-#define SFLAG_INRB_MULTISAMPLE  0x00040000 /* The multisample renderbuffer is current. */
-#define SFLAG_INRB_RESOLVED     0x00080000 /* The resolved renderbuffer is current. */
-#define SFLAG_DISCARDED         0x00100000 /* Surface was discarded, allocating new location is enough. */
+#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. */
 
 /* In some conditions the surface memory must not be freed:
  * SFLAG_CONVERTED: Converting the data back would take too long
@@ -2320,6 +2321,7 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
                              SFLAG_PIN_SYSMEM)
 
 #define SFLAG_LOCATIONS     (SFLAG_INSYSMEM         | \
+                             SFLAG_INUSERMEM        | \
                              SFLAG_INTEXTURE        | \
                              SFLAG_INSRGBTEX        | \
                              SFLAG_INDRAWABLE       | \
-- 
1.8.3.2




More information about the wine-patches mailing list