From d9c4fcce5f925c4f9f1bce08ff25bfae9f3ee081 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 18 Jan 2024 21:01:04 -0400 Subject: [PATCH] asahi: log geometry shaders separate from xfb different perf issues. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/asahi/agx_state.c | 43 +++++++++++++++++---------- src/gallium/drivers/asahi/agx_state.h | 1 + 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 2c60cd2eef7..c9d74a67506 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -4165,7 +4165,10 @@ agx_launch_gs(struct agx_batch *batch, const struct pipe_draw_info *info, struct agx_device *dev = agx_device(ctx->base.screen); struct agx_compiled_shader *gs = ctx->gs; - perf_debug(dev, "Geometry shader or XFB"); + if (ctx->stage[PIPE_SHADER_GEOMETRY].shader->is_xfb_passthrough) + perf_debug(dev, "Transform feedbck"); + else + perf_debug(dev, "Geometry shader"); /* This is a graphics batch, so it may not have had a CDM encoder allocated * yet. Allocate that so we can start enqueueing compute work. @@ -4377,7 +4380,8 @@ agx_draw_without_restart(struct agx_batch *batch, static bool agx_needs_passthrough_gs(struct agx_context *ctx, const struct pipe_draw_info *info, - const struct pipe_draw_indirect_info *indirect) + const struct pipe_draw_indirect_info *indirect, + bool *xfb_only) { /* If there is already a geometry shader in the pipeline, we do not need to * apply a passthrough GS of our own. @@ -4426,16 +4430,11 @@ agx_needs_passthrough_gs(struct agx_context *ctx, return true; } - /* Transform feedback is layered on geometry shaders, so if transform - * feedback is used, we need a GS. - */ - if (ctx->stage[PIPE_SHADER_VERTEX].shader->has_xfb_info && - ctx->streamout.num_targets) - return true; - /* Edge flags are emulated with a geometry shader */ - if (has_edgeflags(ctx, info->mode)) + if (has_edgeflags(ctx, info->mode)) { + perf_debug_ctx(ctx, "Using passthrough GS due to edge flags"); return true; + } /* Various pipeline statistics are implemented in the pre-GS shader. */ if (ctx->pipeline_statistics[PIPE_STAT_QUERY_IA_PRIMITIVES] || @@ -4445,6 +4444,15 @@ agx_needs_passthrough_gs(struct agx_context *ctx, return true; } + /* Transform feedback is layered on geometry shaders, so if transform + * feedback is used, we need a GS. + */ + if (ctx->stage[PIPE_SHADER_VERTEX].shader->has_xfb_info && + ctx->streamout.num_targets) { + *xfb_only = true; + return true; + } + /* Otherwise, we don't need one */ return false; } @@ -4452,7 +4460,7 @@ agx_needs_passthrough_gs(struct agx_context *ctx, static struct agx_uncompiled_shader * agx_get_passthrough_gs(struct agx_context *ctx, struct agx_uncompiled_shader *prev_cso, - enum mesa_prim mode) + enum mesa_prim mode, bool xfb_passthrough) { bool edgeflags = has_edgeflags(ctx, mode); @@ -4480,6 +4488,7 @@ agx_get_passthrough_gs(struct agx_context *ctx, ralloc_free(prev); struct agx_uncompiled_shader *cso = pipe_shader_from_nir(&ctx->base, gs); + cso->is_xfb_passthrough = xfb_passthrough; prev_cso->passthrough_progs[mode][poly_mode][edgeflags] = cso; return cso; } @@ -4490,7 +4499,7 @@ agx_apply_passthrough_gs(struct agx_context *ctx, unsigned drawid_offset, const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count_bias *draws, - unsigned num_draws) + unsigned num_draws, bool xfb_passthrough) { enum pipe_shader_type prev_stage = ctx->stage[PIPE_SHADER_TESS_EVAL].shader ? PIPE_SHADER_TESS_EVAL @@ -4513,8 +4522,9 @@ agx_apply_passthrough_gs(struct agx_context *ctx, } /* Draw with passthrough */ - ctx->base.bind_gs_state(&ctx->base, - agx_get_passthrough_gs(ctx, prev_cso, info->mode)); + ctx->base.bind_gs_state( + &ctx->base, + agx_get_passthrough_gs(ctx, prev_cso, info->mode, xfb_passthrough)); ctx->base.draw_vbo(&ctx->base, info, drawid_offset, indirect, draws, num_draws); ctx->base.bind_gs_state(&ctx->base, NULL); @@ -4920,9 +4930,10 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, return; } - if (agx_needs_passthrough_gs(ctx, info, indirect)) { + bool xfb_passthrough = false; + if (agx_needs_passthrough_gs(ctx, info, indirect, &xfb_passthrough)) { agx_apply_passthrough_gs(ctx, info, drawid_offset, indirect, draws, - num_draws); + num_draws, xfb_passthrough); return; } diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 908bd81e3cd..96bf1d8cfd5 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -230,6 +230,7 @@ struct agx_uncompiled_shader { uint32_t xfb_strides[4]; bool has_xfb_info; + bool is_xfb_passthrough; /* Whether the shader accesses indexed samplers via the bindless heap */ bool uses_bindless_samplers;