[PATCH 2/5] wined3d: Use _SYSMEM map binding if user memory is not set for sub resource.

Paul Gofman pgofman at codeweavers.com
Sun Jun 14 13:16:35 CDT 2020


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
 dlls/wined3d/cs.c              | 16 +++++----
 dlls/wined3d/surface.c         | 27 ++++++++-------
 dlls/wined3d/texture.c         | 61 +++++++++++++++++++++-------------
 dlls/wined3d/wined3d_private.h |  8 +++++
 4 files changed, 71 insertions(+), 41 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index b87003c53b8..289420cd71f 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -2255,6 +2255,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
         unsigned int row_pitch, slice_pitch;
         struct wined3d_context *context;
         struct wined3d_bo_address addr;
+        unsigned int src_map_binding;
 
         if (op->flags & ~WINED3D_BLT_RAW)
         {
@@ -2287,11 +2288,12 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
 
         context = context_acquire(cs->device, NULL, 0);
 
+        src_map_binding = wined3d_texture_get_map_binding(src_texture, op->src_sub_resource_idx);
         if (!wined3d_texture_load_location(src_texture, op->src_sub_resource_idx,
-                context, src_texture->resource.map_binding))
+                context, src_map_binding))
         {
             ERR("Failed to load source sub-resource into %s.\n",
-                    wined3d_debug_location(src_texture->resource.map_binding));
+                    wined3d_debug_location(src_map_binding));
             context_release(context);
             goto error;
         }
@@ -2312,7 +2314,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
             goto error;
         }
 
-        wined3d_texture_get_memory(src_texture, op->src_sub_resource_idx, &addr, src_texture->resource.map_binding);
+        wined3d_texture_get_memory(src_texture, op->src_sub_resource_idx, &addr, src_map_binding);
         wined3d_texture_get_pitch(src_texture, op->src_sub_resource_idx % src_texture->level_count,
                 &row_pitch, &slice_pitch);
 
@@ -2458,15 +2460,17 @@ static void wined3d_cs_exec_add_dirty_texture_region(struct wined3d_cs *cs, cons
     struct wined3d_texture *texture = op->texture;
     unsigned int sub_resource_idx, i;
     struct wined3d_context *context;
+    unsigned int map_binding;
 
     context = context_acquire(cs->device, NULL, 0);
     sub_resource_idx = op->layer * texture->level_count;
+    map_binding = wined3d_texture_get_map_binding(texture, sub_resource_idx);
     for (i = 0; i < texture->level_count; ++i, ++sub_resource_idx)
     {
-        if (wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding))
-            wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
+        if (wined3d_texture_load_location(texture, sub_resource_idx, context, map_binding))
+            wined3d_texture_invalidate_location(texture, sub_resource_idx, ~map_binding);
         else
-            ERR("Failed to load location %s.\n", wined3d_debug_location(texture->resource.map_binding));
+            ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding));
     }
     context_release(context);
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 652f6070b93..d6e7c370d7e 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -352,7 +352,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr
 
     context = context_acquire(device, NULL, 0);
 
-    map_binding = src_texture->resource.map_binding;
+    map_binding = wined3d_texture_get_map_binding(src_texture, sub_resource_idx);
     if (!wined3d_texture_load_location(src_texture, sub_resource_idx, context, map_binding))
         ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding));
     wined3d_texture_get_pitch(src_texture, texture_level, &src_row_pitch, &src_slice_pitch);
@@ -366,7 +366,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr
         const BYTE *src;
         BYTE *dst;
 
-        map_binding = dst_texture->resource.map_binding;
+        map_binding = wined3d_texture_get_map_binding(dst_texture, 0);
         if (!wined3d_texture_load_location(dst_texture, 0, context, map_binding))
             ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding));
         wined3d_texture_get_pitch(dst_texture, 0, &dst_row_pitch, &dst_slice_pitch);
@@ -751,7 +751,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int
     {
         same_sub_resource = TRUE;
 
-        map_binding = dst_texture->resource.map_binding;
+        map_binding = wined3d_texture_get_map_binding(dst_texture, dst_sub_resource_idx);
         texture_level = dst_sub_resource_idx % dst_texture->level_count;
         if (!wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, map_binding))
             ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding));
@@ -789,7 +789,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int
             src_format = src_texture->resource.format;
         }
 
-        map_binding = src_texture->resource.map_binding;
+        map_binding = wined3d_texture_get_map_binding(src_texture, src_sub_resource_idx);
         texture_level = src_sub_resource_idx % src_texture->level_count;
         if (!wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, map_binding))
             ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding));
@@ -806,7 +806,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int
         }
         else
         {
-            map_binding = dst_texture->resource.map_binding;
+            map_binding = wined3d_texture_get_map_binding(dst_texture, dst_sub_resource_idx);
             texture_level = dst_sub_resource_idx % dst_texture->level_count;
             if (!wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, map_binding))
                 ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding));
@@ -1276,7 +1276,7 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view,
         d = min(box->back, d) - min(box->front, d);
     }
 
-    map_binding = texture->resource.map_binding;
+    map_binding = wined3d_texture_get_map_binding(texture, view->sub_resource_idx);
     if (!wined3d_texture_load_location(texture, view->sub_resource_idx, context, map_binding))
         ERR("Failed to load the sub-resource into %s.\n", wined3d_debug_location(map_binding));
     wined3d_texture_invalidate_location(texture, view->sub_resource_idx, ~map_binding);
@@ -1434,7 +1434,7 @@ static DWORD cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
     wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location);
 
     return dst_location | (dst_texture->sub_resources[dst_sub_resource_idx].locations
-            & dst_texture->resource.map_binding);
+            & wined3d_texture_get_map_binding(dst_texture, dst_sub_resource_idx));
 }
 
 static const struct wined3d_blitter_ops cpu_blitter_ops =
@@ -1486,6 +1486,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
     struct wined3d_context *context;
     enum wined3d_blit_op blit_op;
     BOOL scale, convert, resolve;
+    unsigned int dst_map_binding;
     RECT src_rect, dst_rect;
     bool src_ds, dst_ds;
 
@@ -1564,6 +1565,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
     dst_ds = dst_texture->resource.format->depth_size || dst_texture->resource.format->stencil_size;
     src_ds = src_texture->resource.format->depth_size || src_texture->resource.format->stencil_size;
 
+    dst_map_binding = wined3d_texture_get_map_binding(dst_texture, dst_sub_resource_idx);
+
     if (src_ds || dst_ds)
     {
         TRACE("Depth/stencil blit.\n");
@@ -1571,7 +1574,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
         if (dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)
             dst_location = dst_texture->resource.draw_binding;
         else
-            dst_location = dst_texture->resource.map_binding;
+            dst_location = dst_map_binding;
 
         if ((flags & WINED3D_BLT_RAW) || (!scale && !convert && !resolve))
             blit_op = WINED3D_BLIT_OP_RAW_BLIT;
@@ -1594,8 +1597,8 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
 
     /* In principle this would apply to depth blits as well, but we don't
      * implement those in the CPU blitter at the moment. */
-    if ((dst_sub_resource->locations & dst_texture->resource.map_binding)
-            && (src_sub_resource->locations & src_texture->resource.map_binding))
+    if ((dst_sub_resource->locations & dst_map_binding)
+            && (src_sub_resource->locations & wined3d_texture_get_map_binding(src_texture, src_sub_resource_idx)))
     {
         if (scale)
             TRACE("Not doing sysmem blit because of scaling.\n");
@@ -1646,7 +1649,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
         }
     }
     else if (!(src_sub_resource->locations & surface_simple_locations)
-            && (dst_sub_resource->locations & dst_texture->resource.map_binding)
+            && (dst_sub_resource->locations & dst_map_binding)
             && !(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
     {
         /* Download */
@@ -1706,7 +1709,7 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
         src_location = src_texture->resource.draw_binding;
 
     if (!(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU))
-        dst_location = dst_texture->resource.map_binding;
+        dst_location = dst_map_binding;
     else if (dst_texture->resource.multisample_type != WINED3D_MULTISAMPLE_NONE
             && (scale || convert || !wined3d_is_colour_blit(blit_op)))
         dst_location = WINED3D_LOCATION_RB_RESOLVED;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 5fa79691368..3db2b14988b 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -941,6 +941,7 @@ static void wined3d_texture_create_dc(void *object)
     struct wined3d_bo_address data;
     D3DKMT_CREATEDCFROMMEMORY desc;
     struct wined3d_device *device;
+    unsigned int map_binding;
     NTSTATUS status;
 
     TRACE("texture %p, sub_resource_idx %u.\n", idx->texture, idx->sub_resource_idx);
@@ -968,14 +969,15 @@ static void wined3d_texture_create_dc(void *object)
         }
     }
 
-    if (!(texture->sub_resources[sub_resource_idx].locations & texture->resource.map_binding))
+    map_binding = wined3d_texture_get_map_binding(texture, sub_resource_idx);
+    if (!(texture->sub_resources[sub_resource_idx].locations & map_binding))
     {
         context = context_acquire(device, NULL, 0);
-        wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
+        wined3d_texture_load_location(texture, sub_resource_idx, context, map_binding);
     }
-    wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
+    wined3d_texture_invalidate_location(texture, sub_resource_idx, ~map_binding);
     wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch);
-    wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
+    wined3d_texture_get_memory(texture, sub_resource_idx, &data, map_binding);
     if (data.buffer_object)
     {
         if (!context)
@@ -1046,7 +1048,8 @@ static void wined3d_texture_destroy_dc(void *object)
     dc_info->dc = NULL;
     dc_info->bitmap = NULL;
 
-    wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
+    wined3d_texture_get_memory(texture, sub_resource_idx, &data,
+            wined3d_texture_get_map_binding(texture, sub_resource_idx));
     if (data.buffer_object)
     {
         context = context_acquire(device, NULL, 0);
@@ -1486,15 +1489,18 @@ void wined3d_texture_load(struct wined3d_texture *texture,
             && !color_key_equal(&texture->async.gl_color_key, &texture->async.src_blt_color_key))))
     {
         unsigned int sub_count = texture->level_count * texture->layer_count;
+        unsigned int map_binding;
         unsigned int i;
 
         TRACE("Reloading because of color key value change.\n");
         for (i = 0; i < sub_count; i++)
         {
-            if (!wined3d_texture_load_location(texture, i, context, texture->resource.map_binding))
-                ERR("Failed to load location %s.\n", wined3d_debug_location(texture->resource.map_binding));
+            map_binding = wined3d_texture_get_map_binding(texture, i);
+
+            if (!wined3d_texture_load_location(texture, i, context, map_binding))
+                ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding));
             else
-                wined3d_texture_invalidate_location(texture, i, ~texture->resource.map_binding);
+                wined3d_texture_invalidate_location(texture, i, ~map_binding);
         }
 
         texture->async.gl_color_key = texture->async.src_blt_color_key;
@@ -2984,6 +2990,7 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g
     struct wined3d_bo_address data;
     BYTE *src_mem, *dst_mem = NULL;
     struct wined3d_box src_box;
+    unsigned int map_binding;
     DWORD dst_location;
     BOOL depth;
 
@@ -3041,27 +3048,27 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g
     }
 
     /* Upload from system memory */
-
+    map_binding = wined3d_texture_get_map_binding(&texture_gl->t, sub_resource_idx);
     if (srgb)
     {
         dst_location = WINED3D_LOCATION_TEXTURE_SRGB;
-        if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | texture_gl->t.resource.map_binding))
+        if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | map_binding))
                 == WINED3D_LOCATION_TEXTURE_RGB)
         {
             FIXME_(d3d_perf)("Downloading RGB texture %p, %u to reload it as sRGB.\n", texture_gl, sub_resource_idx);
             wined3d_texture_load_location(&texture_gl->t, sub_resource_idx,
-                    &context_gl->c, texture_gl->t.resource.map_binding);
+                    &context_gl->c, map_binding);
         }
     }
     else
     {
         dst_location = WINED3D_LOCATION_TEXTURE_RGB;
-        if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | texture_gl->t.resource.map_binding))
+        if ((sub_resource->locations & (WINED3D_LOCATION_TEXTURE_SRGB | map_binding))
                 == WINED3D_LOCATION_TEXTURE_SRGB)
         {
             FIXME_(d3d_perf)("Downloading sRGB texture %p, %u to reload it as RGB.\n", texture_gl, sub_resource_idx);
             wined3d_texture_load_location(&texture_gl->t, sub_resource_idx,
-                    &context_gl->c, texture_gl->t.resource.map_binding);
+                    &context_gl->c, map_binding);
         }
     }
 
@@ -3313,9 +3320,9 @@ static void texture_resource_unload(struct wined3d_resource *resource)
 {
     struct wined3d_texture *texture = texture_from_resource(resource);
     struct wined3d_device *device = resource->device;
-    unsigned int location = resource->map_binding;
     struct wined3d_context *context;
     unsigned int sub_count, i;
+    unsigned int location;
 
     TRACE("resource %p.\n", resource);
 
@@ -3332,6 +3339,8 @@ static void texture_resource_unload(struct wined3d_resource *resource)
     sub_count = texture->level_count * texture->layer_count;
     for (i = 0; i < sub_count; ++i)
     {
+        location = wined3d_texture_get_map_binding(texture, i);
+
         if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
                 && wined3d_texture_load_location(texture, i, context, location))
         {
@@ -3375,6 +3384,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
     struct wined3d_texture *texture;
     struct wined3d_bo_address data;
     unsigned int texture_level;
+    unsigned int map_binding;
     BYTE *base_memory;
     BOOL ret;
 
@@ -3408,18 +3418,20 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
 
     context = context_acquire(device, NULL, 0);
 
+    map_binding = wined3d_texture_get_map_binding(texture, sub_resource_idx);
+
     if (flags & WINED3D_MAP_DISCARD)
     {
         TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n",
-                wined3d_debug_location(resource->map_binding));
-        if ((ret = wined3d_texture_prepare_location(texture, sub_resource_idx, context, resource->map_binding)))
-            wined3d_texture_validate_location(texture, sub_resource_idx, resource->map_binding);
+                wined3d_debug_location(map_binding));
+        if ((ret = wined3d_texture_prepare_location(texture, sub_resource_idx, context, map_binding)))
+            wined3d_texture_validate_location(texture, sub_resource_idx, map_binding);
     }
     else
     {
         if (resource->usage & WINED3DUSAGE_DYNAMIC)
             WARN_(d3d_perf)("Mapping a dynamic texture without WINED3D_MAP_DISCARD.\n");
-        ret = wined3d_texture_load_location(texture, sub_resource_idx, context, resource->map_binding);
+        ret = wined3d_texture_load_location(texture, sub_resource_idx, context, map_binding);
     }
 
     if (!ret)
@@ -3436,9 +3448,9 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
 
     if (flags & WINED3D_MAP_WRITE
             && (!(flags & WINED3D_MAP_NO_DIRTY_UPDATE) || (resource->usage & WINED3DUSAGE_DYNAMIC)))
-        wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding);
+        wined3d_texture_invalidate_location(texture, sub_resource_idx, ~map_binding);
 
-    wined3d_texture_get_memory(texture, sub_resource_idx, &data, resource->map_binding);
+    wined3d_texture_get_memory(texture, sub_resource_idx, &data, map_binding);
     base_memory = wined3d_context_map_bo_address(context, &data, sub_resource->size, flags);
     sub_resource->map_flags = flags;
     TRACE("Base memory pointer %p.\n", base_memory);
@@ -3524,7 +3536,8 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso
 
     context = context_acquire(device, NULL, 0);
 
-    wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
+    wined3d_texture_get_memory(texture, sub_resource_idx, &data,
+            wined3d_texture_get_map_binding(texture, sub_resource_idx));
     range.offset = 0;
     range.size = sub_resource->size;
     wined3d_context_unmap_bo_address(context, &data, !!(sub_resource->map_flags & WINED3D_MAP_WRITE), &range);
@@ -4386,8 +4399,8 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un
 void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
         struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx)
 {
+    unsigned int dst_location = wined3d_texture_get_map_binding(dst_texture, dst_sub_resource_idx);
     unsigned int src_level, dst_level, dst_row_pitch, dst_slice_pitch;
-    unsigned int dst_location = dst_texture->resource.map_binding;
     struct wined3d_context *context;
     struct wined3d_bo_address data;
     struct wined3d_box src_box;
@@ -5520,6 +5533,7 @@ static bool blitter_use_cpu_clear(struct wined3d_rendertarget_view *view)
 {
     struct wined3d_resource *resource;
     struct wined3d_texture *texture;
+    unsigned int map_binding;
     DWORD locations;
 
     resource = view->resource;
@@ -5528,7 +5542,8 @@ static bool blitter_use_cpu_clear(struct wined3d_rendertarget_view *view)
 
     texture = texture_from_resource(resource);
     locations = texture->sub_resources[view->sub_resource_idx].locations;
-    if (locations & (resource->map_binding | WINED3D_LOCATION_DISCARDED))
+    map_binding = wined3d_texture_get_map_binding(texture, view->sub_resource_idx);
+    if (locations & (map_binding | WINED3D_LOCATION_DISCARDED))
         return !(resource->access & WINED3D_RESOURCE_ACCESS_GPU)
                 || (texture->flags & WINED3D_TEXTURE_PIN_SYSMEM);
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index dd4d34b08f7..b9f3c5e74d7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4185,6 +4185,14 @@ static inline bool wined3d_texture_is_full_rect(const struct wined3d_texture *te
     return true;
 }
 
+static inline unsigned int wined3d_texture_get_map_binding(const struct wined3d_texture *texture,
+        unsigned int sub_resource_idx)
+{
+    return texture->resource.map_binding == WINED3D_LOCATION_USER_MEMORY ?
+            (texture->sub_resources[sub_resource_idx].user_memory ? WINED3D_LOCATION_USER_MEMORY
+            : WINED3D_LOCATION_SYSMEM) : texture->resource.map_binding;
+}
+
 HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
         const struct wined3d_box *dst_box, struct wined3d_texture *src_texture,
         unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, DWORD flags,
-- 
2.26.2




More information about the wine-devel mailing list