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

Stefan Dösinger stefandoesinger at gmx.at
Sun Feb 14 14:33:55 CST 2016


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.
---
 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 6fc3a6c..fc6a0a0 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -812,8 +812,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;
 
@@ -823,21 +823,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;
@@ -856,13 +849,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:
@@ -870,24 +873,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 a4936cf..423d162 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -254,9 +254,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 459cbdc..a8c52ba 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);
         }
@@ -1180,6 +1184,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);
@@ -1189,11 +1194,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 b4c8bb2..4111a82 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 a62d9a0..33f6a23 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1508,12 +1508,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