static bool
accumulate_subresult(struct d3d12_context *ctx, struct d3d12_query *q_parent,
unsigned sub_query,
- union pipe_query_result *result, bool write, bool wait)
+ union pipe_query_result *result, bool write)
{
struct pipe_transfer *transfer = NULL;
struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);
if (write)
access |= PIPE_MAP_WRITE;
- if (!wait)
- access |= PIPE_MAP_DONTBLOCK;
+ access |= PIPE_MAP_UNSYNCHRONIZED;
+
results = pipe_buffer_map_range(&ctx->base, q->buffer, q->buffer_offset,
q->num_queries * q->query_size,
access, &transfer);
static bool
accumulate_result(struct d3d12_context *ctx, struct d3d12_query *q,
- union pipe_query_result *result, bool write, bool wait)
+ union pipe_query_result *result, bool write)
{
union pipe_query_result local_result;
switch (q->type) {
case PIPE_QUERY_PRIMITIVES_GENERATED:
- if (!accumulate_subresult(ctx, q, 0, &local_result, write, wait))
+ if (!accumulate_subresult(ctx, q, 0, &local_result, write))
return false;
result->u64 = local_result.so_statistics.primitives_storage_needed;
- if (!accumulate_subresult(ctx, q, 1, &local_result, write, wait))
+ if (!accumulate_subresult(ctx, q, 1, &local_result, write))
return false;
result->u64 += local_result.pipeline_statistics.gs_primitives;
- if (!accumulate_subresult(ctx, q, 2, &local_result, write, wait))
+ if (!accumulate_subresult(ctx, q, 2, &local_result, write))
return false;
result->u64 += local_result.pipeline_statistics.ia_primitives;
return true;
case PIPE_QUERY_PRIMITIVES_EMITTED:
- if (!accumulate_subresult(ctx, q, 0, &local_result, write, wait))
+ if (!accumulate_subresult(ctx, q, 0, &local_result, write))
return false;
result->u64 = local_result.so_statistics.num_primitives_written;
return true;
default:
assert(num_sub_queries(q->type) == 1);
- return accumulate_subresult(ctx, q, 0, result, write, wait);
+ return accumulate_subresult(ctx, q, 0, result, write);
}
}
}
}
+static bool
+query_ensure_ready(struct d3d12_screen* screen, struct d3d12_context* ctx, struct d3d12_query* query, bool wait)
+{
+ // If the query is not flushed, it won't have
+ // been submitted yet, and won't have a waitable
+ // fence value
+ if (query->fence_value == UINT64_MAX) {
+ d3d12_flush_cmdlist(ctx);
+ }
+
+ if (screen->fence->GetCompletedValue() < query->fence_value){
+ if (!wait)
+ return false;
+
+ screen->fence->SetEventOnCompletion(query->fence_value, NULL);
+ }
+
+ return true;
+}
+
static void
begin_subquery(struct d3d12_context *ctx, struct d3d12_query *q_parent, unsigned sub_query)
{
union pipe_query_result result;
/* Accumulate current results and store in first slot */
- accumulate_subresult(ctx, q_parent, sub_query, &result, true, true);
+ accumulate_subresult(ctx, q_parent, sub_query, &result, true);
q->curr_query = 1;
}
/* Accumulate current results and store in first slot */
d3d12_flush_cmdlist_and_wait(ctx);
- accumulate_subresult(ctx, q_parent, 0, &result, true, true);
+ accumulate_subresult(ctx, q_parent, 0, &result, true);
q->curr_query = 2;
}
struct d3d12_context *ctx = d3d12_context(pctx);
struct d3d12_query *query = (struct d3d12_query *)q;
+ // 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);
+
end_query(ctx, query);
if (query->type != PIPE_QUERY_TIMESTAMP &&
union pipe_query_result *result)
{
struct d3d12_context *ctx = d3d12_context(pctx);
+ struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);
struct d3d12_query *query = (struct d3d12_query *)q;
- return accumulate_result(ctx, query, result, false, wait);
+ if (!query_ensure_ready(screen, ctx, query, wait))
+ return false;
+
+ return accumulate_result(ctx, query, result, false);
}
void
if (mode == PIPE_RENDER_COND_WAIT) {
d3d12_flush_cmdlist_and_wait(ctx);
union pipe_query_result result;
- accumulate_result(ctx, (d3d12_query *)pquery, &result, true, true);
+ accumulate_result(ctx, (d3d12_query *)pquery, &result, true);
}
struct d3d12_resource *res = (struct d3d12_resource *)query->subqueries[0].buffer;
{
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);