[PATCH 2/3] wined3d: Unload texture resources through texture ops.

Henri Verbeet hverbeet at codeweavers.com
Fri Dec 6 13:23:47 CST 2019


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/adapter_gl.c      |  57 +-----------
 dlls/wined3d/device.c          |   3 +-
 dlls/wined3d/texture.c         | 200 +++++++++++++++++++++++++----------------
 dlls/wined3d/wined3d_private.h |   3 +-
 4 files changed, 125 insertions(+), 138 deletions(-)

diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 3408439660f..a8a8e93c0b2 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4746,61 +4746,6 @@ static HRESULT adapter_gl_create_texture(struct wined3d_device *device,
     return hr;
 }
 
-static void wined3d_texture_gl_destroy_object(void *object)
-{
-    struct wined3d_renderbuffer_entry *entry, *entry2;
-    struct wined3d_texture_gl *texture_gl = object;
-    struct wined3d_context *context = NULL;
-    const struct wined3d_gl_info *gl_info;
-    struct wined3d_device *device;
-    unsigned int sub_count, i;
-    GLuint buffer_object;
-
-    TRACE("texture_gl %p.\n", texture_gl);
-
-    sub_count = texture_gl->t.level_count * texture_gl->t.layer_count;
-    for (i = 0; i < sub_count; ++i)
-    {
-        if (!(buffer_object = texture_gl->t.sub_resources[i].buffer_object))
-            continue;
-
-        TRACE("Deleting buffer object %u.\n", buffer_object);
-
-        if (!context)
-        {
-            context = context_acquire(texture_gl->t.resource.device, NULL, 0);
-            gl_info = wined3d_context_gl(context)->gl_info;
-        }
-
-        GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
-    }
-
-    if (!list_empty(&texture_gl->renderbuffers))
-    {
-        device = texture_gl->t.resource.device;
-        if (!context)
-        {
-            context = context_acquire(device, NULL, 0);
-            gl_info = wined3d_context_gl(context)->gl_info;
-        }
-
-        LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry)
-        {
-            TRACE("Deleting renderbuffer %u.\n", entry->id);
-            context_gl_resource_released(device, entry->id, TRUE);
-            gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
-            heap_free(entry);
-        }
-    }
-
-    if (context)
-        context_release(context);
-
-    wined3d_texture_gl_unload_texture(texture_gl);
-
-    heap_free(texture_gl);
-}
-
 static void adapter_gl_destroy_texture(struct wined3d_texture *texture)
 {
     struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture);
@@ -4820,7 +4765,7 @@ static void adapter_gl_destroy_texture(struct wined3d_texture *texture)
     texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
 
     wined3d_texture_cleanup(&texture_gl->t);
-    wined3d_cs_destroy_object(device->cs, wined3d_texture_gl_destroy_object, texture_gl);
+    wined3d_cs_destroy_object(device->cs, heap_free, texture_gl);
 
     if (swapchain_count)
         wined3d_device_decref(device);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 98559e4f6c6..90c08876505 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1146,6 +1146,7 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
     wine_rb_clear(&device->samplers, device_free_sampler, NULL);
 
     device->adapter->adapter_ops->adapter_uninit_3d(device);
+    device->d3d_initialized = FALSE;
 
     if ((view = device->fb.depth_stencil))
     {
@@ -1170,8 +1171,6 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
 
     heap_free(device->swapchains);
     device->swapchains = NULL;
-
-    device->d3d_initialized = FALSE;
 }
 
 /* Enables thread safety in the wined3d device and its resources. Called by DirectDraw
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 1c315a1dd77..7c9c8298519 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -636,51 +636,6 @@ static void wined3d_texture_gl_allocate_immutable_storage(struct wined3d_texture
     checkGLcall("allocate immutable storage");
 }
 
-void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl)
-{
-    struct wined3d_device *device = texture_gl->t.resource.device;
-    const struct wined3d_gl_info *gl_info = NULL;
-    struct wined3d_context *context = NULL;
-
-    if (texture_gl->t.resource.bind_count)
-        device_invalidate_state(device, STATE_SAMPLER(texture_gl->t.sampler));
-
-    if (texture_gl->texture_rgb.name || texture_gl->texture_srgb.name
-            || texture_gl->rb_multisample || texture_gl->rb_resolved)
-    {
-        context = context_acquire(device, NULL, 0);
-        gl_info = wined3d_context_gl(context)->gl_info;
-    }
-
-    if (texture_gl->texture_rgb.name)
-        gltexture_delete(device, gl_info, &texture_gl->texture_rgb);
-
-    if (texture_gl->texture_srgb.name)
-        gltexture_delete(device, gl_info, &texture_gl->texture_srgb);
-
-    if (texture_gl->rb_multisample)
-    {
-        TRACE("Deleting multisample renderbuffer %u.\n", texture_gl->rb_multisample);
-        context_gl_resource_released(device, texture_gl->rb_multisample, TRUE);
-        gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_multisample);
-        texture_gl->rb_multisample = 0;
-    }
-
-    if (texture_gl->rb_resolved)
-    {
-        TRACE("Deleting resolved renderbuffer %u.\n", texture_gl->rb_resolved);
-        context_gl_resource_released(device, texture_gl->rb_resolved, TRUE);
-        gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_resolved);
-        texture_gl->rb_resolved = 0;
-    }
-
-    if (context) context_release(context);
-
-    wined3d_texture_set_dirty(&texture_gl->t);
-
-    resource_unload(&texture_gl->t.resource);
-}
-
 void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture)
 {
     unsigned int sub_count = texture->level_count * texture->layer_count;
@@ -1119,12 +1074,14 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture)
 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))
@@ -1156,12 +1113,14 @@ static void wined3d_texture_destroy_object(void *object)
         }
         heap_free(texture->overlay_info);
     }
+
+    resource->resource_ops->resource_unload(resource);
 }
 
 void wined3d_texture_cleanup(struct wined3d_texture *texture)
 {
-    resource_cleanup(&texture->resource);
     wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture);
+    resource_cleanup(&texture->resource);
 }
 
 static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture)
@@ -1789,6 +1748,12 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture,
     return texture->texture_ops->texture_prepare_location(texture, sub_resource_idx, context, location);
 }
 
+static void wined3d_texture_unload_location(struct wined3d_texture *texture,
+        struct wined3d_context *context, unsigned int location)
+{
+    texture->texture_ops->texture_unload_location(texture, context, location);
+}
+
 static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct wined3d_texture *texture,
         unsigned int sub_resource_idx)
 {
@@ -2903,10 +2868,79 @@ static BOOL wined3d_texture_gl_load_location(struct wined3d_texture *texture,
     }
 }
 
+static void wined3d_texture_gl_unload_location(struct wined3d_texture *texture,
+        struct wined3d_context *context, unsigned int location)
+{
+    struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture);
+    struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+    struct wined3d_renderbuffer_entry *entry, *entry2;
+    unsigned int i, sub_count;
+
+    TRACE("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+
+    switch (location)
+    {
+        case WINED3D_LOCATION_BUFFER:
+            sub_count = texture->level_count * texture->layer_count;
+            for (i = 0; i < sub_count; ++i)
+            {
+                if (texture_gl->t.sub_resources[i].buffer_object)
+                    wined3d_texture_remove_buffer_object(&texture_gl->t, i, context_gl->gl_info);
+            }
+            break;
+
+        case WINED3D_LOCATION_TEXTURE_RGB:
+            if (texture_gl->texture_rgb.name)
+                gltexture_delete(texture_gl->t.resource.device, context_gl->gl_info, &texture_gl->texture_rgb);
+            break;
+
+        case WINED3D_LOCATION_TEXTURE_SRGB:
+            if (texture_gl->texture_srgb.name)
+                gltexture_delete(texture_gl->t.resource.device, context_gl->gl_info, &texture_gl->texture_srgb);
+            break;
+
+        case WINED3D_LOCATION_RB_MULTISAMPLE:
+            if (texture_gl->rb_multisample)
+            {
+                TRACE("Deleting multisample renderbuffer %u.\n", texture_gl->rb_multisample);
+                context_gl_resource_released(texture_gl->t.resource.device, texture_gl->rb_multisample, TRUE);
+                context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_multisample);
+                texture_gl->rb_multisample = 0;
+            }
+            break;
+
+        case WINED3D_LOCATION_RB_RESOLVED:
+            LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers,
+                    struct wined3d_renderbuffer_entry, entry)
+            {
+                context_gl_resource_released(texture_gl->t.resource.device, entry->id, TRUE);
+                context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+                list_remove(&entry->entry);
+                heap_free(entry);
+            }
+            list_init(&texture_gl->renderbuffers);
+            texture_gl->current_renderbuffer = NULL;
+
+            if (texture_gl->rb_resolved)
+            {
+                TRACE("Deleting resolved renderbuffer %u.\n", texture_gl->rb_resolved);
+                context_gl_resource_released(texture_gl->t.resource.device, texture_gl->rb_resolved, TRUE);
+                context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_resolved);
+                texture_gl->rb_resolved = 0;
+            }
+            break;
+
+        default:
+            ERR("Unhandled location %s.\n", wined3d_debug_location(location));
+            break;
+    }
+}
+
 static const struct wined3d_texture_ops texture_gl_ops =
 {
     wined3d_texture_gl_prepare_location,
     wined3d_texture_gl_load_location,
+    wined3d_texture_gl_unload_location,
     wined3d_texture_gl_upload_data,
     wined3d_texture_gl_download_data,
 };
@@ -2936,65 +2970,59 @@ static void texture_resource_preload(struct wined3d_resource *resource)
     context_release(context);
 }
 
-static void wined3d_texture_gl_unload(struct wined3d_resource *resource)
+static void texture_resource_unload(struct wined3d_resource *resource)
 {
-    struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource));
-    UINT sub_count = texture_gl->t.level_count * texture_gl->t.layer_count;
-    struct wined3d_renderbuffer_entry *entry, *entry2;
+    struct wined3d_texture *texture = texture_from_resource(resource);
     struct wined3d_device *device = resource->device;
     unsigned int location = resource->map_binding;
-    const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
-    UINT i;
+    unsigned int sub_count, i;
+
+    TRACE("resource %p.\n", resource);
 
-    TRACE("texture_gl %p.\n", texture_gl);
+    /* D3D is not initialised, so no GPU locations should currently exist.
+     * Moreover, we may not be able to acquire a valid context. */
+    if (!device->d3d_initialized)
+        return;
 
     context = context_acquire(device, NULL, 0);
-    gl_info = wined3d_context_gl(context)->gl_info;
 
     if (location == WINED3D_LOCATION_BUFFER)
         location = WINED3D_LOCATION_SYSMEM;
 
+    sub_count = texture->level_count * texture->layer_count;
     for (i = 0; i < sub_count; ++i)
     {
-        struct wined3d_texture_sub_resource *sub_resource = &texture_gl->t.sub_resources[i];
-
         if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
-                && wined3d_texture_load_location(&texture_gl->t, i, context, location))
+                && wined3d_texture_load_location(texture, i, context, location))
         {
-            wined3d_texture_invalidate_location(&texture_gl->t, i, ~location);
+            wined3d_texture_invalidate_location(texture, i, ~location);
         }
         else
         {
-            /* We should only get here on device reset/teardown for implicit
-             * resources. */
-            if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
-                    || resource->type != WINED3D_RTYPE_TEXTURE_2D)
+            if (resource->access & WINED3D_RESOURCE_ACCESS_CPU)
                 ERR("Discarding %s %p sub-resource %u with resource access %s.\n",
                         debug_d3dresourcetype(resource->type), resource, i,
                         wined3d_debug_resource_access(resource->access));
-            wined3d_texture_validate_location(&texture_gl->t, i, WINED3D_LOCATION_DISCARDED);
-            wined3d_texture_invalidate_location(&texture_gl->t, i, ~WINED3D_LOCATION_DISCARDED);
+            wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_DISCARDED);
+            wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED);
         }
-
-        if (sub_resource->buffer_object)
-            wined3d_texture_remove_buffer_object(&texture_gl->t, i, gl_info);
     }
 
-    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry)
-    {
-        context_gl_resource_released(device, entry->id, TRUE);
-        gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
-        list_remove(&entry->entry);
-        heap_free(entry);
-    }
-    list_init(&texture_gl->renderbuffers);
-    texture_gl->current_renderbuffer = NULL;
+    wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_BUFFER);
+    wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_TEXTURE_RGB);
+    wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_TEXTURE_SRGB);
+    wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_RB_MULTISAMPLE);
+    wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_RB_RESOLVED);
 
     context_release(context);
 
-    wined3d_texture_force_reload(&texture_gl->t);
-    wined3d_texture_gl_unload_texture(texture_gl);
+    wined3d_texture_force_reload(texture);
+    if (texture->resource.bind_count)
+        device_invalidate_state(device, STATE_SAMPLER(texture->sampler));
+    wined3d_texture_set_dirty(texture);
+
+    resource_unload(&texture->resource);
 }
 
 static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
@@ -3177,7 +3205,7 @@ static const struct wined3d_resource_ops texture_resource_ops =
     texture_resource_incref,
     texture_resource_decref,
     texture_resource_preload,
-    wined3d_texture_gl_unload,
+    texture_resource_unload,
     texture_resource_sub_resource_map,
     texture_resource_sub_resource_unmap,
 };
@@ -4088,10 +4116,17 @@ static BOOL wined3d_texture_no3d_load_location(struct wined3d_texture *texture,
     return FALSE;
 }
 
+static void wined3d_texture_no3d_unload_location(struct wined3d_texture *texture,
+        struct wined3d_context *context, unsigned int location)
+{
+    TRACE("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+}
+
 static const struct wined3d_texture_ops wined3d_texture_no3d_ops =
 {
     wined3d_texture_no3d_prepare_location,
     wined3d_texture_no3d_load_location,
+    wined3d_texture_no3d_unload_location,
     wined3d_texture_no3d_upload_data,
     wined3d_texture_no3d_download_data,
 };
@@ -4158,10 +4193,17 @@ static BOOL wined3d_texture_vk_load_location(struct wined3d_texture *texture,
     return FALSE;
 }
 
+static void wined3d_texture_vk_unload_location(struct wined3d_texture *texture,
+        struct wined3d_context *context, unsigned int location)
+{
+    FIXME("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+}
+
 static const struct wined3d_texture_ops wined3d_texture_vk_ops =
 {
     wined3d_texture_vk_prepare_location,
     wined3d_texture_vk_load_location,
+    wined3d_texture_vk_unload_location,
     wined3d_texture_vk_upload_data,
     wined3d_texture_vk_download_data,
 };
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7d3b709a974..8f9ad1ce856 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3470,6 +3470,8 @@ struct wined3d_texture_ops
             struct wined3d_context *context, unsigned int location);
     BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx,
             struct wined3d_context *context, unsigned int location);
+    void (*texture_unload_location)(struct wined3d_texture *texture,
+            struct wined3d_context *context, unsigned int location);
     void (*texture_upload_data)(struct wined3d_context *context, const struct wined3d_const_bo_address *src_bo_addr,
             const struct wined3d_format *src_format, const struct wined3d_box *src_box, unsigned int src_row_pitch,
             unsigned int src_slice_pitch, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
@@ -3745,7 +3747,6 @@ void wined3d_texture_gl_prepare_texture(struct wined3d_texture_gl *texture_gl,
 void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *texture_gl,
         struct wined3d_context_gl *context_gl, unsigned int level,
         const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
-void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl) DECLSPEC_HIDDEN;
 
 struct wined3d_texture_vk
 {
-- 
2.11.0




More information about the wine-devel mailing list