wined3d: Unload texture resources through texture ops.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3bc8bde91b
commit
ca0c3f770a
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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("texture_gl %p.\n", texture_gl);
|
||||
TRACE("resource %p.\n", resource);
|
||||
|
||||
/* 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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue