[PATCH 4/6] wined3d: Simplify FBO cleanup on resource destruction.

Stefan Dösinger stefan at codeweavers.com
Wed Oct 28 09:29:20 CDT 2015


We can tie it directly to the GL resource now. In theory we could just
remove this code, but then the GL texture won't go away until we happen
to reuse the FBO.

Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
---
 dlls/wined3d/context.c         | 53 +++++++++++++++++-------------------------
 dlls/wined3d/resource.c        |  3 ---
 dlls/wined3d/surface.c         |  9 ++++++-
 dlls/wined3d/texture.c         |  8 ++++---
 dlls/wined3d/wined3d_private.h |  4 ++--
 5 files changed, 36 insertions(+), 41 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 9c28453..24444b2 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -814,8 +814,8 @@ void context_free_timestamp_query(struct wined3d_timestamp_query *query)
 
 typedef void (context_fbo_entry_func_t)(struct wined3d_context *context, struct fbo_entry *entry);
 
-static void context_enum_surface_fbo_entries(const struct wined3d_device *device,
-        const struct wined3d_surface *surface, context_fbo_entry_func_t *callback)
+static void context_enum_fbo_entries(const struct wined3d_device *device,
+        GLuint name, BOOL rb_namespace, context_fbo_entry_func_t *callback)
 {
     UINT i;
 
@@ -825,21 +825,14 @@ static void context_enum_surface_fbo_entries(const struct wined3d_device *device
         const struct wined3d_gl_info *gl_info = context->gl_info;
         struct fbo_entry *entry, *entry2;
 
-        if (context->current_rt == surface) context->current_rt = NULL;
-
         LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
         {
             UINT j;
 
-            if (entry->d3d_depth_stencil == surface)
-            {
-                callback(context, entry);
-                continue;
-            }
-
-            for (j = 0; j < gl_info->limits.buffers; ++j)
+            for (j = 0; j < gl_info->limits.buffers + 1; ++j)
             {
-                if (entry->d3d_render_targets[j] == surface)
+                if (entry->key.objects[j].object == name
+                        && !(entry->key.rb_namespace & (1 << j)) == !rb_namespace)
                 {
                     callback(context, entry);
                     break;
@@ -858,13 +851,23 @@ static void context_queue_fbo_entry_destruction(struct wined3d_context *context,
 void context_resource_released(const struct wined3d_device *device,
         struct wined3d_resource *resource, enum wined3d_resource_type type)
 {
-    if (!device->d3d_initialized) return;
+    UINT i;
+    struct wined3d_surface *surface;
+
+    if (!device->d3d_initialized)
+        return;
 
     switch (type)
     {
         case WINED3D_RTYPE_SURFACE:
-            context_enum_surface_fbo_entries(device, surface_from_resource(resource),
-                    context_queue_fbo_entry_destruction);
+            surface = surface_from_resource(resource);
+
+            for (i = 0; i < device->context_count; ++i)
+            {
+                struct wined3d_context *context = device->contexts[i];
+                if (context->current_rt == surface)
+                    context->current_rt = NULL;
+            }
             break;
 
         default:
@@ -872,24 +875,10 @@ void context_resource_released(const struct wined3d_device *device,
     }
 }
 
-static void context_detach_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
-{
-    entry->attached = FALSE;
-}
-
-void context_resource_unloaded(const struct wined3d_device *device,
-        struct wined3d_resource *resource, enum wined3d_resource_type type)
+void context_gl_resource_released(struct wined3d_device *device,
+        GLuint name, BOOL rb_namespace)
 {
-    switch (type)
-    {
-        case WINED3D_RTYPE_SURFACE:
-            context_enum_surface_fbo_entries(device, surface_from_resource(resource),
-                    context_detach_fbo_entry);
-            break;
-
-        default:
-            break;
-    }
+    context_enum_fbo_entries(device, name, rb_namespace, context_queue_fbo_entry_destruction);
 }
 
 void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface)
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 1891165..93fab1b 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -244,9 +244,6 @@ void resource_unload(struct wined3d_resource *resource)
 {
     if (resource->map_count)
         ERR("Resource %p is being unloaded while mapped.\n", resource);
-
-    context_resource_unloaded(resource->device,
-            resource, resource->type);
 }
 
 DWORD CDECL wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index e1633fc..9a354e3 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -52,8 +52,9 @@ static void surface_cleanup(struct wined3d_surface *surface)
         struct wined3d_renderbuffer_entry *entry, *entry2;
         const struct wined3d_gl_info *gl_info;
         struct wined3d_context *context;
+        struct wined3d_device *device = surface->resource.device;
 
-        context = context_acquire(surface->resource.device, NULL);
+        context = context_acquire(device, NULL);
         gl_info = context->gl_info;
 
         if (surface->pbo)
@@ -65,18 +66,21 @@ static void surface_cleanup(struct wined3d_surface *surface)
         if (surface->rb_multisample)
         {
             TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample);
+            context_gl_resource_released(device, surface->rb_multisample, TRUE);
             gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample);
         }
 
         if (surface->rb_resolved)
         {
             TRACE("Deleting resolved renderbuffer %u.\n", surface->rb_resolved);
+            context_gl_resource_released(device, surface->rb_resolved, TRUE);
             gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_resolved);
         }
 
         LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->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);
             HeapFree(GetProcessHeap(), 0, entry);
         }
@@ -1177,6 +1181,7 @@ static void surface_unload(struct wined3d_resource *resource)
      */
     LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->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);
         HeapFree(GetProcessHeap(), 0, entry);
@@ -1186,11 +1191,13 @@ static void surface_unload(struct wined3d_resource *resource)
 
     if (surface->rb_multisample)
     {
+        context_gl_resource_released(device, surface->rb_multisample, TRUE);
         gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample);
         surface->rb_multisample = 0;
     }
     if (surface->rb_resolved)
     {
+        context_gl_resource_released(device, surface->rb_resolved, TRUE);
         gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_resolved);
         surface->rb_resolved = 0;
     }
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index a6d26ef..519b13d 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -83,8 +83,10 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
 }
 
 /* A GL context is provided by the caller */
-static void gltexture_delete(const struct wined3d_gl_info *gl_info, struct gl_texture *tex)
+static void gltexture_delete(struct wined3d_device *device, const struct wined3d_gl_info *gl_info,
+        struct gl_texture *tex)
 {
+    context_gl_resource_released(device, tex->name, FALSE);
     gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex->name);
     tex->name = 0;
 }
@@ -100,10 +102,10 @@ static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture)
     }
 
     if (texture->texture_rgb.name)
-        gltexture_delete(context->gl_info, &texture->texture_rgb);
+        gltexture_delete(device, context->gl_info, &texture->texture_rgb);
 
     if (texture->texture_srgb.name)
-        gltexture_delete(context->gl_info, &texture->texture_srgb);
+        gltexture_delete(device, context->gl_info, &texture->texture_srgb);
 
     if (context) context_release(context);
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 50952db..410b975 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1423,12 +1423,12 @@ void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN
 void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
 struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
 DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
+void context_gl_resource_released(struct wined3d_device *device,
+        GLuint name, BOOL rb_namespace) DECLSPEC_HIDDEN;
 void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
 void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN;
 void context_resource_released(const struct wined3d_device *device,
         struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN;
-void context_resource_unloaded(const struct wined3d_device *device,
-        struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN;
 void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) DECLSPEC_HIDDEN;
 BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
 void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN;
-- 
2.4.10




More information about the wine-patches mailing list