}
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);
}
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