From ca0c3f770ae4fe4d535f59f2d54b4c0a531e800f Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 6 Dec 2019 22:53:47 +0330 Subject: [PATCH] wined3d: Unload texture resources through texture ops. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- 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.4.GIT