Signed-off-by: Jan Sikorski <jsikorski(a)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,
--
2.30.2