asahi: implement xfb stream queries

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26614>
This commit is contained in:
Alyssa Rosenzweig 2023-11-20 13:10:39 -04:00
parent 0099315edf
commit 79e37f7581
4 changed files with 28 additions and 23 deletions

View file

@ -68,11 +68,11 @@ agx_begin_query(struct pipe_context *pctx, struct pipe_query *pquery)
break;
case PIPE_QUERY_PRIMITIVES_GENERATED:
ctx->prims_generated = query;
ctx->prims_generated[query->index] = query;
break;
case PIPE_QUERY_PRIMITIVES_EMITTED:
ctx->tf_prims_generated = query;
ctx->tf_prims_generated[query->index] = query;
break;
case PIPE_QUERY_TIME_ELAPSED:
@ -119,10 +119,10 @@ agx_end_query(struct pipe_context *pctx, struct pipe_query *pquery)
ctx->occlusion_query = NULL;
return true;
case PIPE_QUERY_PRIMITIVES_GENERATED:
ctx->prims_generated = NULL;
ctx->prims_generated[query->index] = NULL;
return true;
case PIPE_QUERY_PRIMITIVES_EMITTED:
ctx->tf_prims_generated = NULL;
ctx->tf_prims_generated[query->index] = NULL;
return true;
case PIPE_QUERY_TIME_ELAPSED:
ctx->time_elapsed = NULL;

View file

@ -3423,16 +3423,18 @@ agx_batch_geometry_params(struct agx_batch *batch, uint64_t input_index_buffer,
}
}
/* TODO: Multiple streams! */
if (batch->ctx->prims_generated) {
params.prims_generated_counter[0] =
agx_get_query_address(batch, batch->ctx->prims_generated);
for (unsigned i = 0; i < ARRAY_SIZE(batch->ctx->prims_generated); ++i) {
if (batch->ctx->prims_generated[i]) {
params.prims_generated_counter[i] =
agx_get_query_address(batch, batch->ctx->prims_generated[i]);
}
}
/* TODO: Multiple streams! */
if (batch->ctx->tf_prims_generated) {
params.xfb_prims_generated_counter[0] =
agx_get_query_address(batch, batch->ctx->tf_prims_generated);
for (unsigned i = 0; i < ARRAY_SIZE(batch->ctx->tf_prims_generated); ++i) {
if (batch->ctx->tf_prims_generated[i]) {
params.xfb_prims_generated_counter[i] =
agx_get_query_address(batch, batch->ctx->tf_prims_generated[i]);
}
}
/* Calculate input primitive count for direct draws, and allocate the count
@ -3562,11 +3564,12 @@ agx_launch_gs(struct agx_batch *batch, const struct pipe_draw_info *info,
/* Run a GS-less draw consuming those results */
void *vs_cso = ctx->stage[PIPE_SHADER_VERTEX].shader;
void *gs_cso = ctx->stage[PIPE_SHADER_GEOMETRY].shader;
struct agx_query *prim_query = ctx->prims_generated;
struct agx_query *prim_queries[ARRAY_SIZE(ctx->prims_generated)];
memcpy(prim_queries, ctx->prims_generated, sizeof(prim_queries));
ctx->base.bind_vs_state(&ctx->base, gs->gs_copy);
ctx->base.bind_gs_state(&ctx->base, NULL);
ctx->prims_generated = NULL;
memset(ctx->prims_generated, 0, sizeof(ctx->prims_generated));
bool indexed = gs->gs_output_mode != MESA_PRIM_POINTS;
@ -3593,7 +3596,7 @@ agx_launch_gs(struct agx_batch *batch, const struct pipe_draw_info *info,
/* Restore state */
ctx->base.bind_vs_state(&ctx->base, vs_cso);
ctx->base.bind_gs_state(&ctx->base, gs_cso);
ctx->prims_generated = prim_query;
memcpy(ctx->prims_generated, prim_queries, sizeof(prim_queries));
}
static bool
@ -3690,11 +3693,12 @@ agx_apply_passthrough_gs(struct agx_context *ctx,
/* Draw without XFB */
if (split_xfb) {
unsigned saved_targets = ctx->streamout.num_targets;
struct agx_query *saved_prims_generated = ctx->prims_generated;
struct agx_query *prim_queries[ARRAY_SIZE(ctx->prims_generated)];
memcpy(prim_queries, ctx->prims_generated, sizeof(prim_queries));
ctx->base.bind_rasterizer_state(&ctx->base, saved_rast);
ctx->streamout.num_targets = 0;
ctx->prims_generated = NULL;
memset(ctx->prims_generated, 0, sizeof(ctx->prims_generated));
if (!saved_rast->base.rasterizer_discard) {
ctx->base.draw_vbo(&ctx->base, info, drawid_offset, indirect, draws,
@ -3702,7 +3706,7 @@ agx_apply_passthrough_gs(struct agx_context *ctx,
}
ctx->streamout.num_targets = saved_targets;
ctx->prims_generated = saved_prims_generated;
memcpy(ctx->prims_generated, prim_queries, sizeof(prim_queries));
}
}
@ -3733,7 +3737,8 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
return;
}
bool uses_prims_generated = ctx->active_queries && ctx->prims_generated;
/* Only the rasterization stream counts */
bool uses_prims_generated = ctx->active_queries && ctx->prims_generated[0];
bool uses_gs = ctx->stage[PIPE_SHADER_GEOMETRY].shader;
if (indirect && (uses_prims_generated)) {

View file

@ -481,8 +481,8 @@ struct agx_context {
enum pipe_render_cond_flag cond_mode;
struct agx_query *occlusion_query;
struct agx_query *prims_generated;
struct agx_query *tf_prims_generated;
struct agx_query *prims_generated[4];
struct agx_query *tf_prims_generated[4];
struct agx_query *time_elapsed;
bool active_queries;

View file

@ -160,11 +160,11 @@ agx_primitives_update_direct(struct agx_context *ctx,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count_bias *draw)
{
assert(ctx->active_queries && ctx->prims_generated && "precondition");
assert(ctx->active_queries && ctx->prims_generated[0] && "precondition");
assert(!ctx->stage[PIPE_SHADER_GEOMETRY].shader &&
"Geometry shaders use their own counting");
ctx->prims_generated->value +=
ctx->prims_generated[0]->value +=
xfb_prims_for_vertices(info->mode, draw->count);
}