diff options
author | Danylo Piliaiev <[email protected]> | 2020-05-18 20:44:58 +0300 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-05-25 12:32:16 +0000 |
commit | 045267d1e6238e45eb98f286332ee233dec53312 (patch) | |
tree | 47bd336e95ed4ee17bb0c9fc0cae2d6bd4e74125 /src/mesa | |
parent | a51ab5f95624d1c29d9592aa2212f80dead8ecdf (diff) |
st/mesa: Clear texture's views when texture is removed from Shared->TexObjects
If texture is shared between several contexts, calling glDeleteTextures
will remove it from ctx->Shared->TexObjects - which makes impossible for
contexts, when destroyed, to release their views to this texture. Which
leaves dangling pointers to destroyed contexts.
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2960
Signed-off-by: Danylo Piliaiev <[email protected]>
Reviewed-by: Tapani Pälli <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5106>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/main/dd.h | 6 | ||||
-rw-r--r-- | src/mesa/main/texobj.c | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 17 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_sampler_view.c | 2 |
4 files changed, 28 insertions, 1 deletions
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 4a7d775db45..a4d1d5bdaa0 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -371,6 +371,12 @@ struct dd_function_table { void (*DeleteTexture)(struct gl_context *ctx, struct gl_texture_object *texObj); + /** + * Called to notify that texture is removed from ctx->Shared->TexObjects + */ + void (*TextureRemovedFromShared)(struct gl_context *ctx, + struct gl_texture_object *texObj); + /** Called to allocate a new texture image object. */ struct gl_texture_image * (*NewTextureImage)(struct gl_context *ctx); diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 8bd9cee4615..3e058975db8 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -1514,6 +1514,10 @@ delete_textures(struct gl_context *ctx, GLsizei n, const GLuint *textures) */ _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); + if (ctx->Driver.TextureRemovedFromShared) { + ctx->Driver.TextureRemovedFromShared(ctx, delObj); + } + /* Unreference the texobj. If refcount hits zero, the texture * will be deleted. */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 1cb85b8b406..32e390c53d6 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -195,6 +195,22 @@ st_DeleteTextureObject(struct gl_context *ctx, _mesa_delete_texture_object(ctx, texObj); } +/** + * Called via ctx->Driver.TextureRemovedFromShared() + * When texture is removed from ctx->Shared->TexObjects we lose + * the ability to clean up views on context destruction, which may + * lead to dangling pointers to destroyed contexts. + * Release the views to prevent this. + */ +static void +st_TextureReleaseAllSamplerViews(struct gl_context *ctx, + struct gl_texture_object *texObj) +{ + struct st_context *st = st_context(ctx); + struct st_texture_object *stObj = st_texture_object(texObj); + + st_texture_release_all_sampler_views(st, stObj); +} /** called via ctx->Driver.FreeTextureImageBuffer() */ static void @@ -3355,6 +3371,7 @@ st_init_texture_functions(struct dd_function_table *functions) functions->NewTextureImage = st_NewTextureImage; functions->DeleteTextureImage = st_DeleteTextureImage; functions->DeleteTexture = st_DeleteTextureObject; + functions->TextureRemovedFromShared = st_TextureReleaseAllSamplerViews; functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer; functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer; functions->MapTextureImage = st_MapTextureImage; diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 102908e1029..a31e573c01a 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -226,7 +226,7 @@ st_texture_release_all_sampler_views(struct st_context *st, for (unsigned i = 0; i < views->count; ++i) { struct st_sampler_view *stsv = &views->views[i]; if (stsv->view) { - if (stsv->st != st) { + if (stsv->st && stsv->st != st) { /* Transfer this reference to the zombie list. It will * likely be freed when the zombie list is freed. */ |