st/mesa: Clear texture's views when texture is removed from Shared->TexObjects
authorDanylo Piliaiev <danylo.piliaiev@globallogic.com>
Mon, 18 May 2020 17:44:58 +0000 (20:44 +0300)
committerMarge Bot <eric+marge@anholt.net>
Mon, 25 May 2020 12:32:16 +0000 (12:32 +0000)
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 <danylo.piliaiev@globallogic.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5106>

src/mesa/main/dd.h
src/mesa/main/texobj.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_sampler_view.c

index 4a7d775db459c5dc8f000c0110ff3b6247446b66..a4d1d5bdaa0ec1987adae6090a20457115eeb5ef 100644 (file)
@@ -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);
 
index 8bd9cee46154de1f7da67bd3cfecf59a6bc8c7b4..3e058975db86c50a044248502559f344d17bda5a 100644 (file)
@@ -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.
              */
index 1cb85b8b4062b6b11d700a8308f98d76e44903ae..32e390c53d64f576aa24755760ae6ca5c187412e 100644 (file)
@@ -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;
index 102908e102922b4ce5ce0dff9506491fa26cbdae..a31e573c01a3dec0371ddcbbf94d306c3ccbc6b5 100644 (file)
@@ -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.
              */