diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 3cd37827a8f..469a4932174 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -996,19 +996,6 @@ static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DW return WINED3D_OK; } -/* Context activation is done by the caller. */ -static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) -{ - GLuint *buffer_object; - - buffer_object = &surface->container->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object; - GL_EXTCALL(glDeleteBuffers(1, buffer_object)); - checkGLcall("glDeleteBuffers(1, buffer_object)"); - - *buffer_object = 0; - surface_invalidate_location(surface, WINED3D_LOCATION_BUFFER); -} - static ULONG surface_resource_incref(struct wined3d_resource *resource) { struct wined3d_surface *surface = surface_from_resource(resource); @@ -1071,10 +1058,6 @@ static void surface_unload(struct wined3d_resource *resource) surface_invalidate_location(surface, ~surface->resource.map_binding); } - /* Destroy PBOs, but load them into real sysmem before */ - if (surface->container->sub_resources[surface_get_sub_resource_idx(surface)].buffer_object) - surface_remove_pbo(surface, gl_info); - /* Destroy fbo render buffers. This is needed for implicit render targets, for * all application-created targets the application has to release the surface * before calling _Reset @@ -3681,7 +3664,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, surface_prepare_map_memory(surface); surface_load_location(surface, context, surface->resource.map_binding); - surface_remove_pbo(surface, gl_info); + wined3d_texture_remove_buffer_object(texture, surface_get_sub_resource_idx(surface), gl_info); } surface_get_memory(surface, &data, surface->locations); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 9846f073724..90a397828a1 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -74,6 +74,23 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc return WINED3D_OK; } +/* Context activation is done by the caller. */ +void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture, + unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) +{ + GLuint *buffer_object; + + buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object; + GL_EXTCALL(glDeleteBuffers(1, buffer_object)); + checkGLcall("glDeleteBuffers"); + texture->texture_ops->texture_sub_resource_invalidate_location( + texture->sub_resources[sub_resource_idx].resource, WINED3D_LOCATION_BUFFER); + *buffer_object = 0; + + TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n", + *buffer_object, texture, sub_resource_idx); +} + /* A GL context is provided by the caller */ static void gltexture_delete(struct wined3d_device *device, const struct wined3d_gl_info *gl_info, struct gl_texture *tex) @@ -979,6 +996,7 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) { struct wined3d_texture *texture = wined3d_texture_from_resource(resource); UINT sub_count = texture->level_count * texture->layer_count; + struct wined3d_context *context = NULL; UINT i; TRACE("texture %p.\n", texture); @@ -988,7 +1006,16 @@ static void wined3d_texture_unload(struct wined3d_resource *resource) struct wined3d_resource *sub_resource = texture->sub_resources[i].resource; sub_resource->resource_ops->resource_unload(sub_resource); + + if (texture->sub_resources[i].buffer_object) + { + if (!context) + context = context_acquire(texture->resource.device, NULL); + wined3d_texture_remove_buffer_object(texture, i, context->gl_info); + } } + if (context) + context_release(context); wined3d_texture_force_reload(texture); wined3d_texture_unload_gl_texture(texture); diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index fcadd395c28..2d88af6bfc4 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -362,19 +362,6 @@ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context * srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); } -static void wined3d_volume_free_pbo(struct wined3d_volume *volume) -{ - GLuint *buffer_object = &volume->container->sub_resources[volume->texture_level].buffer_object; - struct wined3d_context *context = context_acquire(volume->resource.device, NULL); - const struct wined3d_gl_info *gl_info = context->gl_info; - - TRACE("Deleting PBO %u belonging to volume %p.\n", *buffer_object, volume); - GL_EXTCALL(glDeleteBuffers(1, buffer_object)); - checkGLcall("glDeleteBuffers"); - *buffer_object = 0; - context_release(context); -} - void wined3d_volume_cleanup(struct wined3d_volume *volume) { TRACE("volume %p.\n", volume); @@ -407,15 +394,6 @@ static void volume_unload(struct wined3d_resource *resource) wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_DISCARDED); } - if (volume->container->sub_resources[volume->texture_level].buffer_object) - { - /* Should not happen because only dynamic default pool volumes - * have a buffer, and those are not evicted by device_evit_managed_resources - * and must be freed before a non-ex device reset. */ - ERR("Unloading a volume with a buffer\n"); - wined3d_volume_free_pbo(volume); - } - /* The texture name is managed by the container. */ resource_unload(resource); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 28121b75b7a..da3698588f7 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2424,6 +2424,8 @@ void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; +void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture, + unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;