[PATCH 1/7] wined3d: Don't call wined3d_texture_decref() in the CS thread.

Jan Sikorski jsikorski at codeweavers.com
Thu Oct 7 05:57:24 CDT 2021


Signed-off-by: Jan Sikorski <jsikorski at 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




More information about the wine-devel mailing list