asahi: Fix occlusion query lifetime
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sat, 11 Mar 2023 21:19:43 +0000 (16:19 -0500)
committerMarge Bot <emma+marge@anholt.net>
Wed, 15 Mar 2023 08:46:09 +0000 (08:46 +0000)
Theoretical lifetime issue, now easy to hit with the batch sync changes. Fixes
memory badness.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21857>

src/gallium/drivers/asahi/agx_query.c

index 44df4d1..a0ff593 100644 (file)
@@ -17,8 +17,19 @@ agx_create_query(struct pipe_context *ctx, unsigned query_type, unsigned index)
 }
 
 static void
-agx_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
+agx_destroy_query(struct pipe_context *ctx, struct pipe_query *pquery)
 {
+   struct agx_query *query = (struct agx_query *)pquery;
+
+   /* It is legal for the query to be destroyed before its value is read,
+    * particularly during application teardown. In this case, don't leave a
+    * dangling reference to the query.
+    */
+   if (query->writer) {
+      *util_dynarray_element(&query->writer->occlusion_queries,
+                             struct agx_query *, query->writer_index) = NULL;
+   }
+
    free(query);
 }
 
@@ -154,6 +165,11 @@ agx_finish_batch_occlusion_queries(struct agx_batch *batch)
 
    util_dynarray_foreach(&batch->occlusion_queries, struct agx_query *, it) {
       struct agx_query *query = *it;
+
+      /* Skip queries that have since been destroyed */
+      if (query == NULL)
+         continue;
+
       assert(query->writer == batch);
 
       /* Get the result for this batch. If results is NULL, it means that no