Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/wined3d/texture.c | 19 +++++++++++++------ dlls/wined3d/wined3d_private.h | 3 ++- 2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 84020f17c95..5fa79691368 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -735,7 +735,7 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su } if (locations & WINED3D_LOCATION_USER_MEMORY) { - data->addr = texture->user_memory; + data->addr = texture->sub_resources[sub_resource_idx].user_memory; data->buffer_object = 0; return; } @@ -1416,6 +1416,7 @@ static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture)
ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) { + unsigned int i, sub_resource_count; ULONG refcount;
TRACE("texture %p, swapchain %p.\n", texture, texture->swapchain); @@ -1432,8 +1433,14 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) * since the application is allowed to free that memory once the * texture is destroyed. Note that this implies that * the destroy handler can't access that memory either. */ - if (texture->user_memory) + sub_resource_count = texture->layer_count * texture->level_count; + for (i = 0; i < sub_resource_count; ++i) + if (texture->sub_resources[i].user_memory) + break; + + if (i < sub_resource_count) wined3d_resource_wait_idle(&texture->resource); + texture->resource.device->adapter->adapter_ops->adapter_destroy_texture(texture); }
@@ -1872,7 +1879,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT } }
- if ((texture->user_memory = mem)) + if ((texture->sub_resources[0].user_memory = mem)) { texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; valid_location = WINED3D_LOCATION_USER_MEMORY; @@ -3126,7 +3133,7 @@ static BOOL wined3d_texture_gl_prepare_location(struct wined3d_texture *texture, return wined3d_resource_prepare_sysmem(&texture->resource);
case WINED3D_LOCATION_USER_MEMORY: - if (!texture->user_memory) + if (!texture->sub_resources[sub_resource_idx].user_memory) ERR("Preparing WINED3D_LOCATION_USER_MEMORY, but texture->user_memory is NULL.\n"); return TRUE;
@@ -4437,7 +4444,7 @@ static BOOL wined3d_texture_no3d_prepare_location(struct wined3d_texture *textur return wined3d_resource_prepare_sysmem(&texture->resource);
case WINED3D_LOCATION_USER_MEMORY: - if (!texture->user_memory) + if (!texture->sub_resources[sub_resource_idx].user_memory) ERR("Preparing WINED3D_LOCATION_USER_MEMORY, but texture->user_memory is NULL.\n"); return TRUE;
@@ -5081,7 +5088,7 @@ static BOOL wined3d_texture_vk_prepare_location(struct wined3d_texture *texture, return wined3d_resource_prepare_sysmem(&texture->resource);
case WINED3D_LOCATION_USER_MEMORY: - if (!texture->user_memory) + if (!texture->sub_resources[sub_resource_idx].user_memory) ERR("Preparing WINED3D_LOCATION_USER_MEMORY, but texture->user_memory is NULL.\n"); return TRUE;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 17acd4be4d5..dd4d34b08f7 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4060,7 +4060,6 @@ struct wined3d_texture DWORD flags; DWORD update_map_binding;
- void *user_memory; unsigned int row_pitch; unsigned int slice_pitch;
@@ -4113,6 +4112,8 @@ struct wined3d_texture uint32_t map_flags; DWORD locations; struct wined3d_bo_gl bo; + + void *user_memory; } *sub_resources; };
Signed-off-by: Paul Gofman pgofman@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,
On Sun, 14 Jun 2020 at 22:47, Paul Gofman pgofman@codeweavers.com wrote:
+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;
+}
I don't particularly like this. Perhaps in the end it can't be avoided, but superficially it seems like it may be nicer to just merge WINED3D_LOCATION_USER_MEMORY into WINED3D_LOCATION_SYSMEM instead, and then check sub_resource->user_memory in wined3d_texture_get_memory() instead.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- I was previously testing creating mipmaps with DDSD_LPSURFACE and that never succeeded for me. However, it appears possible to set user memory pointer with _SetSurfaceDesc for mipmaps, as well as change texture dimensions along with that, including those for attached surfaces.
dlls/ddraw/tests/ddraw7.c | 87 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index c85f0201118..42262ce9ac7 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -7147,6 +7147,93 @@ static void test_set_surface_desc(void) * parameters. */ hr = IDirectDrawSurface7_SetSurfaceDesc(surface, &ddsd, 0); ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x.\n", hr); + + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_LPSURFACE; + ddsd.lpSurface = data; + hr = IDirectDrawSurface7_SetSurfaceDesc(surface, &ddsd, 0); + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface7_Release(surface); + } + + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_MIPMAPCOUNT; + ddsd.dwWidth = 8; + ddsd.dwHeight = 8; + U2(ddsd).dwMipMapCount = 3; + ddsd.lpSurface = data; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; + + hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &surface, NULL); + ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWHW || hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr); + + if (hr == DD_OK) + { + static DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, {0}}; + void *surface2_system_mem; + IDirectDrawSurface7 *surface2; + + hr = IDirectDrawSurface7_GetAttachedSurface(surface, &caps, &surface2); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + reset_ddsd(&ddsd); + hr = IDirectDrawSurface7_GetSurfaceDesc(surface2, &ddsd); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + ok(ddsd.dwWidth == 4, "Got unexpected dwWidth %u.\n", ddsd.dwWidth); + + hr = IDirectDrawSurface7_Lock(surface2, NULL, &ddsd, 0, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + surface2_system_mem = ddsd.lpSurface; + IDirectDrawSurface7_Unlock(surface2, NULL); + + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE; + ddsd.dwWidth = 16; + ddsd.dwHeight = 16; + U1(ddsd).lPitch = 16 * 4; + ddsd.lpSurface = data; + hr = IDirectDrawSurface7_SetSurfaceDesc(surface, &ddsd, 0); + todo_wine ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE; + ddsd.dwWidth = 8; + ddsd.dwHeight = 8; + U1(ddsd).lPitch = 8 * 4; + ddsd.lpSurface = data; + hr = IDirectDrawSurface7_SetSurfaceDesc(surface, &ddsd, 0); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + reset_ddsd(&ddsd); + hr = IDirectDrawSurface7_Lock(surface2, NULL, &ddsd, 0, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + todo_wine ok(ddsd.lpSurface == surface2_system_mem, "Got unexpected lpSurface %p.\n", ddsd.lpSurface); + IDirectDrawSurface7_Unlock(surface2, NULL); + + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE; + ddsd.dwWidth = 4; + ddsd.dwHeight = 4; + U1(ddsd).lPitch = 4 * 4; + ddsd.lpSurface = data; + hr = IDirectDrawSurface7_SetSurfaceDesc(surface2, &ddsd, 0); + todo_wine ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + reset_ddsd(&ddsd); + hr = IDirectDrawSurface7_Lock(surface2, NULL, &ddsd, 0, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + todo_wine ok(ddsd.lpSurface == data, "Got unexpected lpSurface %p.\n", ddsd.lpSurface); + IDirectDrawSurface7_Unlock(surface2, NULL); + + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE; + ddsd.dwWidth = 16; + ddsd.dwHeight = 16; + U1(ddsd).lPitch = 16 * 4; + ddsd.lpSurface = data; + hr = IDirectDrawSurface7_SetSurfaceDesc(surface2, &ddsd, 0); + todo_wine ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + IDirectDrawSurface7_Release(surface2); IDirectDrawSurface7_Release(surface); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=73371
Your paranoid android.
=== w1064v1809_2scr (32 bit report) ===
ddraw: ddraw7.c:15431: Test failed: Expected 22 surfaces, got 18.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49375 Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ddraw/tests/ddraw7.c | 2 +- dlls/wined3d/texture.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 42262ce9ac7..89b5157f4dc 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -7206,7 +7206,7 @@ static void test_set_surface_desc(void) reset_ddsd(&ddsd); hr = IDirectDrawSurface7_Lock(surface2, NULL, &ddsd, 0, NULL); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - todo_wine ok(ddsd.lpSurface == surface2_system_mem, "Got unexpected lpSurface %p.\n", ddsd.lpSurface); + ok(ddsd.lpSurface == surface2_system_mem, "Got unexpected lpSurface %p.\n", ddsd.lpSurface); IDirectDrawSurface7_Unlock(surface2, NULL);
reset_ddsd(&ddsd); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 3db2b14988b..76291368558 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1833,7 +1833,8 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT create_dib = true; }
- wined3d_resource_free_sysmem(&texture->resource); + if (!update_memory_only || texture->level_count * texture->layer_count == 1) + wined3d_resource_free_sysmem(&texture->resource);
if (!update_memory_only) {
On Sun, 14 Jun 2020 at 22:47, Paul Gofman pgofman@codeweavers.com wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49375 Signed-off-by: Paul Gofman pgofman@codeweavers.com
dlls/ddraw/tests/ddraw7.c | 2 +- dlls/wined3d/texture.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
I think we would like to free that memory eventually though, if we can. Perhaps we could do something similar to what wined3d_texture_update_map_binding() does for PBOs?
On 6/15/20 19:06, Henri Verbeet wrote:
On Sun, 14 Jun 2020 at 22:47, Paul Gofman pgofman@codeweavers.com wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49375 Signed-off-by: Paul Gofman pgofman@codeweavers.com
dlls/ddraw/tests/ddraw7.c | 2 +- dlls/wined3d/texture.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
I think we would like to free that memory eventually though, if we can. Perhaps we could do something similar to what wined3d_texture_update_map_binding() does for PBOs?
I suppose we can check if there are any NULL user_memory left when setting the pointer, and free system memory if there are none.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43232 Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/d3d9/device.c | 4 +- dlls/ddraw/surface.c | 80 ++++++++++++++++++++++----------------- dlls/ddraw/tests/ddraw7.c | 4 +- dlls/wined3d/swapchain.c | 4 +- dlls/wined3d/texture.c | 28 ++++++++------ dlls/wined3d/wined3d.spec | 2 +- include/wine/wined3d.h | 2 +- 7 files changed, 70 insertions(+), 54 deletions(-)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 2ee582b4c54..9e0ed51894e 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1341,7 +1341,7 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, if (set_mem) wined3d_texture_update_desc(object->wined3d_texture, width, height, wined3dformat_from_d3dformat(format), WINED3D_MULTISAMPLE_NONE, 0, - *shared_handle, 0); + *shared_handle, 0, 0);
TRACE("Created texture %p.\n", object); *texture = (IDirect3DTexture9 *)&object->IDirect3DBaseTexture9_iface; @@ -1578,7 +1578,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, unsigned i
if (user_mem) wined3d_texture_update_desc(texture, width, height, desc.format, - multisample_type, multisample_quality, user_mem, 0); + multisample_type, multisample_quality, user_mem, 0, 0);
wined3d_texture_decref(texture);
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index ba56fad9644..899bc77d1b9 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -4605,7 +4605,7 @@ static HRESULT WINAPI ddraw_surface1_SetClipper(IDirectDrawSurface *iface, IDire *****************************************************************************/ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, DDSURFACEDESC2 *DDSD, DWORD Flags) { - struct ddraw_surface *This = impl_from_IDirectDrawSurface7(iface); + struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); HRESULT hr; const DWORD allowed_flags = DDSD_LPSURFACE | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_CAPS; @@ -4624,9 +4624,9 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, WARN("Flags is %x, returning DDERR_INVALIDPARAMS\n", Flags); return DDERR_INVALIDPARAMS; } - if (!(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) - || This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE - || This->surface_desc.ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE)) + if (!(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) + || surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE + || surface->surface_desc.ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE)) { WARN("Surface is not in system memory, returning DDERR_INVALIDSURFACETYPE.\n"); return DDERR_INVALIDSURFACETYPE; @@ -4662,10 +4662,10 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, DDSD->u1.lPitch, DDSD->dwWidth); return DDERR_INVALIDPARAMS; } - if (DDSD->dwWidth != This->surface_desc.dwWidth) - TRACE("Surface width changed from %u to %u.\n", This->surface_desc.dwWidth, DDSD->dwWidth); - if (DDSD->u1.lPitch != This->surface_desc.u1.lPitch) - TRACE("Surface pitch changed from %u to %u.\n", This->surface_desc.u1.lPitch, DDSD->u1.lPitch); + if (DDSD->dwWidth != surface->surface_desc.dwWidth) + TRACE("Surface width changed from %u to %u.\n", surface->surface_desc.dwWidth, DDSD->dwWidth); + if (DDSD->u1.lPitch != surface->surface_desc.u1.lPitch) + TRACE("Surface pitch changed from %u to %u.\n", surface->surface_desc.u1.lPitch, DDSD->u1.lPitch); pitch = DDSD->u1.lPitch; width = DDSD->dwWidth; } @@ -4676,8 +4676,8 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, } else { - pitch = This->surface_desc.u1.lPitch; - width = This->surface_desc.dwWidth; + pitch = surface->surface_desc.u1.lPitch; + width = surface->surface_desc.dwWidth; }
if (DDSD->dwFlags & DDSD_HEIGHT) @@ -4687,13 +4687,13 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, WARN("Height is 0, returning DDERR_INVALIDPARAMS.\n"); return DDERR_INVALIDPARAMS; } - if (DDSD->dwHeight != This->surface_desc.dwHeight) - TRACE("Surface height changed from %u to %u.\n", This->surface_desc.dwHeight, DDSD->dwHeight); + if (DDSD->dwHeight != surface->surface_desc.dwHeight) + TRACE("Surface height changed from %u to %u.\n", surface->surface_desc.dwHeight, DDSD->dwHeight); height = DDSD->dwHeight; } else { - height = This->surface_desc.dwHeight; + height = surface->surface_desc.dwHeight; }
wined3d_mutex_lock(); @@ -4708,17 +4708,17 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, wined3d_mutex_unlock(); return DDERR_INVALIDPARAMS; } - current_format_id = wined3dformat_from_ddrawformat(&This->surface_desc.u4.ddpfPixelFormat); + current_format_id = wined3dformat_from_ddrawformat(&surface->surface_desc.u4.ddpfPixelFormat); if (format_id != current_format_id) TRACE("Surface format changed from %#x to %#x.\n", current_format_id, format_id); } else { - format_id = wined3dformat_from_ddrawformat(&This->surface_desc.u4.ddpfPixelFormat); + format_id = wined3dformat_from_ddrawformat(&surface->surface_desc.u4.ddpfPixelFormat); }
- if (FAILED(hr = wined3d_texture_update_desc(This->wined3d_texture, width, height, - format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch))) + if (FAILED(hr = wined3d_texture_update_desc(surface->wined3d_texture, width, height, + format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch, surface->sub_resource_idx))) { WARN("Failed to update surface desc, hr %#x.\n", hr); wined3d_mutex_unlock(); @@ -4726,13 +4726,13 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, }
if (DDSD->dwFlags & DDSD_WIDTH) - This->surface_desc.dwWidth = width; + surface->surface_desc.dwWidth = width; if (DDSD->dwFlags & DDSD_PITCH) - This->surface_desc.u1.lPitch = DDSD->u1.lPitch; + surface->surface_desc.u1.lPitch = DDSD->u1.lPitch; if (DDSD->dwFlags & DDSD_HEIGHT) - This->surface_desc.dwHeight = height; + surface->surface_desc.dwHeight = height; if (DDSD->dwFlags & DDSD_PIXELFORMAT) - This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat; + surface->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat;
wined3d_mutex_unlock();
@@ -5854,28 +5854,40 @@ static HRESULT ddraw_surface_reserve_memory(struct wined3d_texture *wined3d_text static const unsigned int extra_size = 0x10000;
struct ddraw_texture *texture = wined3d_texture_get_parent(wined3d_texture); - struct wined3d_resource_desc desc; + struct wined3d_resource_desc resource_desc; + struct wined3d_sub_resource_desc desc; unsigned int pitch, slice_pitch; - HRESULT hr; + unsigned int sub_resource_idx; + HRESULT hr = WINED3D_OK; + unsigned int offset;
- wined3d_resource_get_desc(wined3d_texture_get_resource(wined3d_texture), &desc); - if (!(texture->texture_memory = heap_alloc_zero(desc.size + extra_size))) + wined3d_resource_get_desc(wined3d_texture_get_resource(wined3d_texture), &resource_desc); + if (!(texture->texture_memory = heap_alloc_zero(resource_desc.size + extra_size))) { ERR("Out of memory.\n"); return E_OUTOFMEMORY; } TRACE("texture->texture_memory %p.\n", texture->texture_memory);
- wined3d_texture_get_pitch(wined3d_texture, 0, &pitch, &slice_pitch); - - if (FAILED(hr = wined3d_texture_update_desc(wined3d_texture, - desc.width, desc.height, desc.format, - WINED3D_MULTISAMPLE_NONE, 0, texture->texture_memory, pitch))) + offset = 0; + sub_resource_idx = 0; + while (wined3d_texture_get_sub_resource_desc(wined3d_texture, sub_resource_idx, &desc) + == WINED3D_OK) { - heap_free(texture->texture_memory); - texture->texture_memory = NULL; - } + wined3d_texture_get_pitch(wined3d_texture, sub_resource_idx, &pitch, &slice_pitch);
+ if (FAILED(hr = wined3d_texture_update_desc(wined3d_texture, + desc.width, desc.height, resource_desc.format, + desc.multisample_type, desc.multisample_quality, + (BYTE *)texture->texture_memory + offset, pitch, sub_resource_idx))) + { + heap_free(texture->texture_memory); + texture->texture_memory = NULL; + break; + } + ++sub_resource_idx; + offset += desc.size; + } return hr; }
@@ -6474,7 +6486,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
if ((desc->dwFlags & DDSD_LPSURFACE) && FAILED(hr = wined3d_texture_update_desc(wined3d_texture, wined3d_desc.width, wined3d_desc.height, wined3d_desc.format, - WINED3D_MULTISAMPLE_NONE, 0, desc->lpSurface, pitch))) + WINED3D_MULTISAMPLE_NONE, 0, desc->lpSurface, pitch, 0))) { ERR("Failed to set surface memory, hr %#x.\n", hr); goto fail; diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 89b5157f4dc..15f552f88e5 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -7216,12 +7216,12 @@ static void test_set_surface_desc(void) U1(ddsd).lPitch = 4 * 4; ddsd.lpSurface = data; hr = IDirectDrawSurface7_SetSurfaceDesc(surface2, &ddsd, 0); - todo_wine ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
reset_ddsd(&ddsd); hr = IDirectDrawSurface7_Lock(surface2, NULL, &ddsd, 0, NULL); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - todo_wine ok(ddsd.lpSurface == data, "Got unexpected lpSurface %p.\n", ddsd.lpSurface); + ok(ddsd.lpSurface == data, "Got unexpected lpSurface %p.\n", ddsd.lpSurface); IDirectDrawSurface7_Unlock(surface2, NULL);
reset_ddsd(&ddsd); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index e034bdf6241..be658cdf907 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1927,14 +1927,14 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha
if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, desc->backbuffer_width, desc->backbuffer_height, desc->backbuffer_format, - desc->multisample_type, desc->multisample_quality, NULL, 0))) + desc->multisample_type, desc->multisample_quality, NULL, 0, 0))) return hr;
for (i = 0; i < desc->backbuffer_count; ++i) { if (FAILED(hr = wined3d_texture_update_desc(swapchain->back_buffers[i], desc->backbuffer_width, desc->backbuffer_height, desc->backbuffer_format, - desc->multisample_type, desc->multisample_quality, NULL, 0))) + desc->multisample_type, desc->multisample_quality, NULL, 0, 0))) return hr; } } diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 76291368558..a740645d46c 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1744,7 +1744,7 @@ void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *t
HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, - UINT multisample_quality, void *mem, UINT pitch) + UINT multisample_quality, void *mem, UINT pitch, unsigned int sub_resource_idx) { struct wined3d_texture_sub_resource *sub_resource; const struct wined3d_d3d_info *d3d_info; @@ -1757,10 +1757,12 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT DWORD valid_location = 0; bool update_memory_only; bool create_dib = false; + unsigned int level;
TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, " - "mem %p, pitch %u.\n", - texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_quality, mem, pitch); + "mem %p, pitch %u, sub_resource_idx %u.\n", + texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_quality, mem, pitch, + sub_resource_idx);
device = texture->resource.device; d3d = device->wined3d; @@ -1768,8 +1770,10 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT d3d_info = &device->adapter->d3d_info; format = wined3d_get_format(device->adapter, format_id, texture->resource.bind_flags); resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1); + level = sub_resource_idx % texture->level_count;
- update_memory_only = width == texture->resource.width && height == texture->resource.height + update_memory_only = width == wined3d_texture_get_level_width(texture, level) + && height == wined3d_texture_get_level_height(texture, level) && format_id == texture->resource.format->id && multisample_type == texture->resource.multisample_type && multisample_quality == texture->resource.multisample_quality;
@@ -1782,7 +1786,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT { unsigned int current_row_pitch, current_slice_pitch;
- wined3d_texture_get_pitch(texture, 0, ¤t_row_pitch, ¤t_slice_pitch); + wined3d_texture_get_pitch(texture, level, ¤t_row_pitch, ¤t_slice_pitch); update_memory_only = pitch == current_row_pitch && slice_pitch == current_slice_pitch; }
@@ -1791,7 +1795,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
if (texture->level_count * texture->layer_count > 1 && !update_memory_only) { - WARN("Texture has multiple sub-resources, not supported.\n"); + FIXME("Texture has multiple sub-resources, not supported.\n"); return WINED3DERR_INVALIDCALL; }
@@ -1826,7 +1830,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
if (texture->dc_info && texture->dc_info[0].dc) { - struct wined3d_texture_idx texture_idx = {texture, 0}; + struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx};
wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx); wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); @@ -1838,7 +1842,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
if (!update_memory_only) { - sub_resource = &texture->sub_resources[0]; + sub_resource = &texture->sub_resources[sub_resource_idx];
texture->row_pitch = pitch; texture->slice_pitch = slice_pitch; @@ -1886,7 +1890,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT } }
- if ((texture->sub_resources[0].user_memory = mem)) + if ((texture->sub_resources[sub_resource_idx].user_memory = mem)) { texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; valid_location = WINED3D_LOCATION_USER_MEMORY; @@ -1905,12 +1909,12 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info)) texture->resource.map_binding = WINED3D_LOCATION_SYSMEM;
- wined3d_texture_validate_location(texture, 0, valid_location); - wined3d_texture_invalidate_location(texture, 0, ~valid_location); + wined3d_texture_validate_location(texture, sub_resource_idx, valid_location); + wined3d_texture_invalidate_location(texture, sub_resource_idx, ~valid_location);
if (create_dib) { - struct wined3d_texture_idx texture_idx = {texture, 0}; + struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx};
wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx); wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index f4a648cac8b..75ce68119d7 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -307,7 +307,7 @@ @ cdecl wined3d_texture_set_lod(ptr long) @ cdecl wined3d_texture_set_overlay_position(ptr long long long) @ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr) -@ cdecl wined3d_texture_update_desc(ptr long long long long long ptr long) +@ cdecl wined3d_texture_update_desc(ptr long long long long long ptr long long) @ cdecl wined3d_texture_update_overlay(ptr long ptr ptr long ptr long)
@ cdecl wined3d_unordered_access_view_create(ptr ptr ptr ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 5450b4d2117..07e6833402a 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2811,7 +2811,7 @@ void __cdecl wined3d_texture_set_sub_resource_parent(struct wined3d_texture *tex HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, UINT multisample_quality, - void *mem, UINT pitch); + void *mem, UINT pitch, unsigned int sub_resource_idx); HRESULT __cdecl wined3d_texture_update_overlay(struct wined3d_texture *texture, unsigned int sub_resource_idx, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, DWORD flags);
On Sun, 14 Jun 2020 at 22:48, Paul Gofman pgofman@codeweavers.com wrote:
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 5450b4d2117..07e6833402a 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2811,7 +2811,7 @@ void __cdecl wined3d_texture_set_sub_resource_parent(struct wined3d_texture *tex HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, UINT multisample_quality,
void *mem, UINT pitch);
void *mem, UINT pitch, unsigned int sub_resource_idx);
By convention, "sub_resource_idx" is the first argument after "texture".
On Sun, 14 Jun 2020 at 22:47, Paul Gofman pgofman@codeweavers.com wrote:
@@ -1432,8 +1433,14 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) * since the application is allowed to free that memory once the * texture is destroyed. Note that this implies that * the destroy handler can't access that memory either. */
if (texture->user_memory)
sub_resource_count = texture->layer_count * texture->level_count;
for (i = 0; i < sub_resource_count; ++i)
if (texture->sub_resources[i].user_memory)
break;
if (i < sub_resource_count) wined3d_resource_wait_idle(&texture->resource);
Why not simply call wined3d_resource_wait_idle() inside the loop?
@@ -1872,7 +1879,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT } }
- if ((texture->user_memory = mem))
- if ((texture->sub_resources[0].user_memory = mem)) {
That breaks ddraw_surface_reserve_memory() for mip-mapped textures. It turns out those were slightly broken already (i.e., see wined3d_texture_get_memory()), but no need to make it worse.
On 6/15/20 19:06, Henri Verbeet wrote:
@@ -1872,7 +1879,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT } }
- if ((texture->user_memory = mem))
- if ((texture->sub_resources[0].user_memory = mem)) {
That breaks ddraw_surface_reserve_memory() for mip-mapped textures. It turns out those were slightly broken already (i.e., see wined3d_texture_get_memory()), but no need to make it worse.
Will it make sense if I merge this patch with the last one (which adds sub_resource_idx parameter here and fixes the memory setting for mipmaps in ddraw_surface_reserve_memory()? That would avoid adding some temporary code here which would be then deleted in the later patch.
On Mon, 15 Jun 2020 at 22:31, Paul Gofman pgofman@codeweavers.com wrote:
Will it make sense if I merge this patch with the last one (which adds sub_resource_idx parameter here and fixes the memory setting for mipmaps in ddraw_surface_reserve_memory()? That would avoid adding some temporary code here which would be then deleted in the later patch.
I'd expect that to work, yes.