diff --git a/src/gallium/drivers/d3d12/d3d12_batch.cpp b/src/gallium/drivers/d3d12/d3d12_batch.cpp index 6f578994ac6..50be53be027 100644 --- a/src/gallium/drivers/d3d12/d3d12_batch.cpp +++ b/src/gallium/drivers/d3d12/d3d12_batch.cpp @@ -67,6 +67,8 @@ d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) batch->objects = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); + batch->queries = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); if (!batch->bos || !batch->sampler_tables || !batch->sampler_views || !batch->surfaces || !batch->objects) return false; @@ -136,6 +138,14 @@ delete_object(set_entry *entry) object->Release(); } +static void +delete_query(set_entry *entry) +{ + struct d3d12_query *query = (struct d3d12_query *)entry->key; + if (pipe_reference(&query->reference, nullptr)) + d3d12_destroy_query(query); +} + bool d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t timeout_ns) { @@ -154,6 +164,7 @@ d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t _mesa_set_clear(batch->sampler_views, delete_sampler_view); _mesa_set_clear(batch->surfaces, delete_surface); _mesa_set_clear(batch->objects, delete_object); + _mesa_set_clear(batch->queries, delete_query); util_dynarray_foreach(&batch->local_bos, d3d12_bo*, bo) { @@ -190,6 +201,7 @@ d3d12_destroy_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) _mesa_set_destroy(batch->sampler_views, NULL); _mesa_set_destroy(batch->surfaces, NULL); _mesa_set_destroy(batch->objects, NULL); + _mesa_set_destroy(batch->queries, NULL); util_dynarray_fini(&batch->zombie_samplers); util_dynarray_fini(&batch->local_bos); } @@ -269,10 +281,13 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) batch->fence = d3d12_create_fence(screen); - util_dynarray_foreach(&ctx->ended_queries, struct d3d12_query*, query) { - (*query)->fence_value = screen->fence_value; + set_foreach_remove(batch->queries, entry) { + d3d12_query *query = (struct d3d12_query *)entry->key; + if (pipe_reference(&query->reference, nullptr)) + d3d12_destroy_query(query); + else + query->fence_value = screen->fence_value; } - util_dynarray_clear(&ctx->ended_queries); mtx_unlock(&screen->submit_mutex); } @@ -376,3 +391,14 @@ d3d12_batch_reference_object(struct d3d12_batch *batch, object->AddRef(); } } + +void +d3d12_batch_reference_query(struct d3d12_batch *batch, + struct d3d12_query *query) +{ + struct set_entry *entry = _mesa_set_search(batch->queries, query); + if (!entry) { + entry = _mesa_set_add(batch->queries, query); + pipe_reference(NULL, &query->reference); + } +} diff --git a/src/gallium/drivers/d3d12/d3d12_batch.h b/src/gallium/drivers/d3d12/d3d12_batch.h index 1c4af99ae77..61045531711 100644 --- a/src/gallium/drivers/d3d12/d3d12_batch.h +++ b/src/gallium/drivers/d3d12/d3d12_batch.h @@ -51,6 +51,7 @@ struct d3d12_batch { struct set *sampler_views; struct set *surfaces; struct set *objects; + struct set *queries; struct util_dynarray zombie_samplers; @@ -101,4 +102,8 @@ void d3d12_batch_reference_object(struct d3d12_batch *batch, ID3D12Object *object); +void +d3d12_batch_reference_query(struct d3d12_batch *batch, + struct d3d12_query *query); + #endif diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index 0006153415b..af16adf8622 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -114,7 +114,6 @@ d3d12_context_destroy(struct pipe_context *pctx) pipe_resource_reference(&ctx->pstipple.texture, nullptr); pipe_sampler_view_reference(&ctx->pstipple.sampler_view, nullptr); util_dynarray_fini(&ctx->recently_destroyed_bos); - util_dynarray_fini(&ctx->ended_queries); FREE(ctx->pstipple.sampler_cso); u_suballocator_destroy(&ctx->query_allocator); diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index 3f92670031d..2f201d7b2d5 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -261,7 +261,6 @@ struct d3d12_context { ID3D12GraphicsCommandList *state_fixup_cmdlist; struct list_head active_queries; - struct util_dynarray ended_queries; bool queries_disabled; struct d3d12_descriptor_pool *sampler_pool; diff --git a/src/gallium/drivers/d3d12/d3d12_query.cpp b/src/gallium/drivers/d3d12/d3d12_query.cpp index b84c56f334d..c596e0434d5 100644 --- a/src/gallium/drivers/d3d12/d3d12_query.cpp +++ b/src/gallium/drivers/d3d12/d3d12_query.cpp @@ -114,6 +114,7 @@ d3d12_create_query(struct pipe_context *pctx, if (!query) return NULL; + pipe_reference_init(&query->reference, 1); query->type = (pipe_query_type)query_type; for (unsigned i = 0; i < num_sub_queries(query_type); ++i) { assert(i < MAX_SUBQUERIES); @@ -160,11 +161,9 @@ d3d12_create_query(struct pipe_context *pctx, return (struct pipe_query *)query; } -static void -d3d12_destroy_query(struct pipe_context *pctx, - struct pipe_query *q) +void +d3d12_destroy_query(struct d3d12_query *query) { - struct d3d12_query *query = (struct d3d12_query *)q; pipe_resource *predicate = &query->predicate->base.b; pipe_resource_reference(&predicate, NULL); for (unsigned i = 0; i < num_sub_queries(query->type); ++i) { @@ -174,6 +173,16 @@ d3d12_destroy_query(struct pipe_context *pctx, FREE(query); } +static void +d3d12_release_query(struct pipe_context *pctx, + struct pipe_query *q) +{ + struct d3d12_query *query = (struct d3d12_query *)q; + if (pipe_reference(&query->reference, nullptr)) { + d3d12_destroy_query(query); + } +} + static bool accumulate_subresult(struct d3d12_context *ctx, struct d3d12_query *q_parent, unsigned sub_query, @@ -498,7 +507,7 @@ d3d12_end_query(struct pipe_context *pctx, // Assign the sentinel and track now that the query is ended query->fence_value = UINT64_MAX; - util_dynarray_append(&ctx->ended_queries, d3d12_query*, query); + d3d12_batch_reference_query(d3d12_current_batch(ctx), query); end_query(ctx, query); @@ -638,13 +647,12 @@ d3d12_context_query_init(struct pipe_context *pctx) { struct d3d12_context *ctx = d3d12_context(pctx); list_inithead(&ctx->active_queries); - util_dynarray_init(&ctx->ended_queries, NULL); u_suballocator_init(&ctx->query_allocator, &ctx->base, 4096, 0, PIPE_USAGE_STAGING, 0, true); pctx->create_query = d3d12_create_query; - pctx->destroy_query = d3d12_destroy_query; + pctx->destroy_query = d3d12_release_query; pctx->begin_query = d3d12_begin_query; pctx->end_query = d3d12_end_query; pctx->get_query_result = d3d12_get_query_result; diff --git a/src/gallium/drivers/d3d12/d3d12_query.h b/src/gallium/drivers/d3d12/d3d12_query.h index c180b4b8c4e..3915c342a05 100644 --- a/src/gallium/drivers/d3d12/d3d12_query.h +++ b/src/gallium/drivers/d3d12/d3d12_query.h @@ -58,6 +58,7 @@ struct d3d12_query_impl { struct d3d12_query { struct threaded_query base; + struct pipe_reference reference; enum pipe_query_type type; struct d3d12_query_impl subqueries[MAX_SUBQUERIES]; @@ -75,4 +76,7 @@ struct d3d12_query { uint64_t fence_value; }; +void +d3d12_destroy_query(d3d12_query *query); + #endif