From: Paul Gofman Subject: [PATCH 2/5] wined3d: Use _SYSMEM map binding if user memory is not set for sub resource. Message-Id: <20200614181638.168694-2-pgofman@codeweavers.com> Date: Sun, 14 Jun 2020 21:16:35 +0300 In-Reply-To: <20200614181638.168694-1-pgofman@codeweavers.com> References: <20200614181638.168694-1-pgofman@codeweavers.com> Signed-off-by: Paul Gofman --- 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