wined3d: Simplify FBO cleanup on resource destruction.

Signed-off-by: Stefan Dösinger <stefandoesinger@gmx.at>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Stefan Dösinger 2016-02-21 21:29:59 +00:00 committed by Alexandre Julliard
parent bcd9291615
commit 5dac6e49d8
5 changed files with 36 additions and 41 deletions

View File

@ -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)
for (j = 0; j < gl_info->limits.buffers + 1; ++j)
{
callback(context, entry);
continue;
}
for (j = 0; j < gl_info->limits.buffers; ++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)
void context_gl_resource_released(struct wined3d_device *device,
GLuint name, BOOL rb_namespace)
{
entry->attached = FALSE;
}
void context_resource_unloaded(const struct wined3d_device *device,
struct wined3d_resource *resource, enum wined3d_resource_type type)
{
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)

View File

@ -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)

View File

@ -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);
}
@ -1159,6 +1163,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);
@ -1168,11 +1173,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;
}

View File

@ -75,8 +75,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;
}
@ -92,10 +94,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);

View File

@ -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;