Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/wined3d/arb_program_shader.c | 2 +- dlls/wined3d/glsl_shader.c | 2 +- dlls/wined3d/surface.c | 2 +- dlls/wined3d/texture.c | 217 ++++++++++++++++-------------- dlls/wined3d/wined3d_private.h | 1 + 5 files changed, 117 insertions(+), 107 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index eeb51448b01..31ca3fca853 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -7947,7 +7947,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl context_gl->gl_info->gl_ops.gl.p_glFlush();
if (staging_texture) - wined3d_texture_decref(staging_texture); + wined3d_texture_destroy_temporary(staging_texture);
return dst_location; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index adfbf60e726..c38aadac39e 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -13276,7 +13276,7 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli gl_info->gl_ops.gl.p_glFlush();
if (staging_texture) - wined3d_texture_decref(staging_texture); + wined3d_texture_destroy_temporary(staging_texture);
return dst_location; } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 8a4ca4f5781..68238c7bed3 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1219,7 +1219,7 @@ release: dst_texture->swapchain->swapchain_ops->swapchain_frontbuffer_updated(dst_texture->swapchain); } if (converted_texture) - wined3d_texture_decref(converted_texture); + wined3d_texture_destroy_temporary(converted_texture); context_release(context);
return hr; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 339bf4e205a..608348a377a 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -332,6 +332,116 @@ static bool fbo_blitter_supported(enum wined3d_blit_op blit_op, const struct win return true; }
+static void wined3d_texture_destroy_dc(void *object) +{ + const struct wined3d_texture_idx *idx = object; + D3DKMT_DESTROYDCFROMMEMORY destroy_desc; + struct wined3d_context *context; + struct wined3d_texture *texture; + struct wined3d_dc_info *dc_info; + struct wined3d_bo_address data; + unsigned int sub_resource_idx; + struct wined3d_device *device; + struct wined3d_range range; + NTSTATUS status; + + TRACE("texture %p, sub_resource_idx %u.\n", idx->texture, idx->sub_resource_idx); + + texture = idx->texture; + sub_resource_idx = idx->sub_resource_idx; + device = texture->resource.device; + dc_info = &texture->dc_info[sub_resource_idx]; + + if (!dc_info->dc) + { + ERR("Sub-resource {%p, %u} has no DC.\n", texture, sub_resource_idx); + return; + } + + TRACE("dc %p, bitmap %p.\n", dc_info->dc, dc_info->bitmap); + + destroy_desc.hDc = dc_info->dc; + destroy_desc.hBitmap = dc_info->bitmap; + if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc))) + ERR("Failed to destroy dc, status %#x.\n", status); + dc_info->dc = NULL; + dc_info->bitmap = NULL; + + wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + if (data.buffer_object) + { + context = context_acquire(device, NULL, 0); + range.offset = 0; + range.size = texture->sub_resources[sub_resource_idx].size; + wined3d_context_unmap_bo_address(context, &data, 1, &range); + context_release(context); + } +} + +static void wined3d_texture_destroy_object(void *object) +{ + struct wined3d_texture *texture = object; + struct wined3d_resource *resource; + struct wined3d_dc_info *dc_info; + unsigned int sub_count; + unsigned int i; + + TRACE("texture %p.\n", texture); + + resource = &texture->resource; + sub_count = texture->level_count * texture->layer_count; + + if ((dc_info = texture->dc_info)) + { + for (i = 0; i < sub_count; ++i) + { + if (dc_info[i].dc) + { + struct wined3d_texture_idx texture_idx = {texture, i}; + + wined3d_texture_destroy_dc(&texture_idx); + } + } + heap_free(dc_info); + } + + if (texture->overlay_info) + { + for (i = 0; i < sub_count; ++i) + { + struct wined3d_overlay_info *info = &texture->overlay_info[i]; + struct wined3d_overlay_info *overlay, *cur; + + list_remove(&info->entry); + LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry) + { + list_remove(&overlay->entry); + } + } + heap_free(texture->overlay_info); + } + + if (texture->dirty_regions) + { + for (i = 0; i < texture->layer_count; ++i) + { + heap_free(texture->dirty_regions[i].boxes); + } + heap_free(texture->dirty_regions); + } + + resource->resource_ops->resource_unload(resource); +} + +void wined3d_texture_destroy_temporary(struct wined3d_texture *texture) +{ + assert(texture->resource.ref == 1); + wined3d_texture_destroy_object(texture); + wined3d_resource_free_sysmem(&texture->resource); + context_resource_released(texture->resource.device, &texture->resource); + heap_free(texture); +} + /* Blit between surface locations. Onscreen on different swapchains is not supported. * Depth / stencil is not supported. Context activation is done by the caller. */ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_context *context, @@ -571,10 +681,10 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont
done: if (dst_texture != dst_save_texture) - wined3d_texture_decref(dst_texture); + wined3d_texture_destroy_temporary(dst_texture);
if (src_staging_texture) - wined3d_texture_decref(src_staging_texture); + wined3d_texture_destroy_temporary(src_staging_texture);
if (restore_texture) context_restore(context, restore_texture, restore_idx); @@ -1118,52 +1228,6 @@ static void wined3d_texture_create_dc(void *object) TRACE("Created DC %p, bitmap %p for texture %p, %u.\n", dc_info->dc, dc_info->bitmap, texture, sub_resource_idx); }
-static void wined3d_texture_destroy_dc(void *object) -{ - const struct wined3d_texture_idx *idx = object; - D3DKMT_DESTROYDCFROMMEMORY destroy_desc; - struct wined3d_context *context; - struct wined3d_texture *texture; - struct wined3d_dc_info *dc_info; - struct wined3d_bo_address data; - unsigned int sub_resource_idx; - struct wined3d_device *device; - struct wined3d_range range; - NTSTATUS status; - - TRACE("texture %p, sub_resource_idx %u.\n", idx->texture, idx->sub_resource_idx); - - texture = idx->texture; - sub_resource_idx = idx->sub_resource_idx; - device = texture->resource.device; - dc_info = &texture->dc_info[sub_resource_idx]; - - if (!dc_info->dc) - { - ERR("Sub-resource {%p, %u} has no DC.\n", texture, sub_resource_idx); - return; - } - - TRACE("dc %p, bitmap %p.\n", dc_info->dc, dc_info->bitmap); - - destroy_desc.hDc = dc_info->dc; - destroy_desc.hBitmap = dc_info->bitmap; - if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc))) - ERR("Failed to destroy dc, status %#x.\n", status); - dc_info->dc = NULL; - dc_info->bitmap = NULL; - - wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); - if (data.buffer_object) - { - context = context_acquire(device, NULL, 0); - range.offset = 0; - range.size = texture->sub_resources[sub_resource_idx].size; - wined3d_context_unmap_bo_address(context, &data, 1, &range); - context_release(context); - } -} - void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) { texture->swapchain = swapchain; @@ -1453,61 +1517,6 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture) return refcount; }
-static void wined3d_texture_destroy_object(void *object) -{ - struct wined3d_texture *texture = object; - struct wined3d_resource *resource; - struct wined3d_dc_info *dc_info; - unsigned int sub_count; - unsigned int i; - - TRACE("texture %p.\n", texture); - - resource = &texture->resource; - sub_count = texture->level_count * texture->layer_count; - - if ((dc_info = texture->dc_info)) - { - for (i = 0; i < sub_count; ++i) - { - if (dc_info[i].dc) - { - struct wined3d_texture_idx texture_idx = {texture, i}; - - wined3d_texture_destroy_dc(&texture_idx); - } - } - heap_free(dc_info); - } - - if (texture->overlay_info) - { - for (i = 0; i < sub_count; ++i) - { - struct wined3d_overlay_info *info = &texture->overlay_info[i]; - struct wined3d_overlay_info *overlay, *cur; - - list_remove(&info->entry); - LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry) - { - list_remove(&overlay->entry); - } - } - heap_free(texture->overlay_info); - } - - if (texture->dirty_regions) - { - for (i = 0; i < texture->layer_count; ++i) - { - heap_free(texture->dirty_regions[i].boxes); - } - heap_free(texture->dirty_regions); - } - - resource->resource_ops->resource_unload(resource); -} - void wined3d_texture_cleanup(struct wined3d_texture *texture) { wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture); @@ -5961,7 +5970,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit (old_colour_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL);
if (staging_texture) - wined3d_texture_decref(staging_texture); + wined3d_texture_destroy_temporary(staging_texture);
return dst_location; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0c169ec344b..fe7a8dff55e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4462,6 +4462,7 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un void wined3d_texture_validate_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN; void wined3d_texture_clear_dirty_regions(struct wined3d_texture *texture) DECLSPEC_HIDDEN; +void wined3d_texture_destroy_temporary(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
HRESULT wined3d_texture_no3d_init(struct wined3d_texture *texture_no3d, struct wined3d_device *device, const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,