radeonsi: keep pipeline statistics disabled when they are not used
authorMarek Olšák <marek.olsak@amd.com>
Sat, 13 May 2023 03:10:21 +0000 (23:10 -0400)
committerMarge Bot <emma+marge@anholt.net>
Thu, 22 Jun 2023 08:35:54 +0000 (08:35 +0000)
so that we don't always disable/enable pipeline stats around blits
when there are no pipeline stat queries

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23517>

src/gallium/drivers/radeonsi/si_compute_blit.c
src/gallium/drivers/radeonsi/si_gfx_cs.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_query.c
src/gallium/drivers/radeonsi/si_state.c

index 983ceea..c661d93 100644 (file)
@@ -159,7 +159,8 @@ static void si_launch_grid_internal(struct si_context *sctx, const struct pipe_g
 
    /* Set settings for driver-internal compute dispatches. */
    sctx->flags &= ~SI_CONTEXT_START_PIPELINE_STATS;
-   sctx->flags |= SI_CONTEXT_STOP_PIPELINE_STATS;
+   if (sctx->num_hw_pipestat_streamout_queries)
+      sctx->flags |= SI_CONTEXT_STOP_PIPELINE_STATS;
 
    if (!(flags & SI_OP_CS_RENDER_COND_ENABLE))
       sctx->render_cond_enabled = false;
@@ -178,7 +179,9 @@ static void si_launch_grid_internal(struct si_context *sctx, const struct pipe_g
 
    /* Restore default settings. */
    sctx->flags &= ~SI_CONTEXT_STOP_PIPELINE_STATS;
-   sctx->flags |= SI_CONTEXT_START_PIPELINE_STATS;
+   if (sctx->num_hw_pipestat_streamout_queries)
+      sctx->flags |= SI_CONTEXT_START_PIPELINE_STATS;
+
    sctx->render_cond_enabled = sctx->render_cond;
    sctx->blitter_running = false;
 
index 8aa969d..eb09bb1 100644 (file)
@@ -377,11 +377,18 @@ void si_begin_new_gfx_cs(struct si_context *ctx, bool first_cs)
     *
     * TODO: Do we also need to invalidate CB & DB caches?
     */
-   ctx->flags |= SI_CONTEXT_INV_L2 | SI_CONTEXT_START_PIPELINE_STATS;
+   ctx->flags |= SI_CONTEXT_INV_L2;
    if (ctx->gfx_level < GFX10)
       ctx->flags |= SI_CONTEXT_INV_ICACHE | SI_CONTEXT_INV_SCACHE | SI_CONTEXT_INV_VCACHE;
 
-   ctx->pipeline_stats_enabled = -1;
+   /* Disable pipeline stats if there are no active queries. */
+   ctx->flags &= ~SI_CONTEXT_START_PIPELINE_STATS & ~SI_CONTEXT_STOP_PIPELINE_STATS;
+   if (ctx->num_hw_pipestat_streamout_queries)
+      ctx->flags |= SI_CONTEXT_START_PIPELINE_STATS;
+   else
+      ctx->flags |= SI_CONTEXT_STOP_PIPELINE_STATS;
+
+   ctx->pipeline_stats_enabled = -1; /* indicate that the current hw state is unknown */
 
    /* We don't know if the last draw used NGG because it can be a different process.
     * When switching NGG->legacy, we need to flush VGT for certain hw generations.
index 74eb42d..9c75d73 100644 (file)
@@ -1270,6 +1270,7 @@ struct si_context {
    int num_perfect_occlusion_queries;
    int num_pipeline_stat_queries;
    int num_pipeline_stat_emulated_queries;
+   int num_hw_pipestat_streamout_queries;
    struct list_head active_queries;
    unsigned num_cs_dw_queries_suspend;
    /* Shared buffer for pipeline stats queries implemented with an atomic op */
index 70339c7..212ad04 100644 (file)
@@ -872,6 +872,32 @@ static void si_query_hw_do_emit_start(struct si_context *sctx, struct si_query_h
                              RADEON_USAGE_WRITE | RADEON_PRIO_QUERY);
 }
 
+static void si_update_hw_pipeline_stats(struct si_context *sctx, unsigned type, int diff)
+{
+   if (type == PIPE_QUERY_PIPELINE_STATISTICS ||
+       /* All streamout queries: */
+       type == PIPE_QUERY_PRIMITIVES_GENERATED ||
+       type == PIPE_QUERY_PRIMITIVES_EMITTED ||
+       type == PIPE_QUERY_SO_STATISTICS ||
+       type == PIPE_QUERY_SO_OVERFLOW_PREDICATE ||
+       type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE) {
+      if (type == PIPE_QUERY_PIPELINE_STATISTICS)
+         sctx->num_pipeline_stat_queries += diff;
+
+      /* Increment for pipeline statistics and streamout queries. */
+      sctx->num_hw_pipestat_streamout_queries += diff;
+
+      /* Enable/disable pipeline stats if we have any queries. */
+      if (diff == 1 && sctx->num_hw_pipestat_streamout_queries == 1) {
+         sctx->flags &= ~SI_CONTEXT_STOP_PIPELINE_STATS;
+         sctx->flags |= SI_CONTEXT_START_PIPELINE_STATS;
+      } else if (diff == -1 && sctx->num_hw_pipestat_streamout_queries == 0) {
+         sctx->flags &= ~SI_CONTEXT_START_PIPELINE_STATS;
+         sctx->flags |= SI_CONTEXT_STOP_PIPELINE_STATS;
+      }
+   }
+}
+
 static void si_query_hw_emit_start(struct si_context *sctx, struct si_query_hw *query)
 {
    uint64_t va;
@@ -889,9 +915,7 @@ static void si_query_hw_emit_start(struct si_context *sctx, struct si_query_hw *
 
    si_update_occlusion_query_state(sctx, query->b.type, 1);
    si_update_prims_generated_query_state(sctx, query->b.type, 1);
-
-   if (query->b.type == PIPE_QUERY_PIPELINE_STATISTICS)
-      sctx->num_pipeline_stat_queries++;
+   si_update_hw_pipeline_stats(sctx, query->b.type, 1);
 
    si_need_gfx_cs_space(sctx, 0);
 
@@ -1010,9 +1034,7 @@ static void si_query_hw_emit_stop(struct si_context *sctx, struct si_query_hw *q
 
    si_update_occlusion_query_state(sctx, query->b.type, -1);
    si_update_prims_generated_query_state(sctx, query->b.type, -1);
-
-   if (query->b.type == PIPE_QUERY_PIPELINE_STATISTICS)
-      sctx->num_pipeline_stat_queries--;
+   si_update_hw_pipeline_stats(sctx, query->b.type, -1);
 }
 
 static void emit_set_predicate(struct si_context *ctx, struct si_resource *buf, uint64_t va,
index 2cd7607..8075ec1 100644 (file)
@@ -1489,11 +1489,16 @@ static void si_set_active_query_state(struct pipe_context *ctx, bool enable)
 
    /* Pipeline stat & streamout queries. */
    if (enable) {
-      sctx->flags &= ~SI_CONTEXT_STOP_PIPELINE_STATS;
-      sctx->flags |= SI_CONTEXT_START_PIPELINE_STATS;
+      /* Disable pipeline stats if there are no active queries. */
+      if (sctx->num_hw_pipestat_streamout_queries) {
+         sctx->flags &= ~SI_CONTEXT_STOP_PIPELINE_STATS;
+         sctx->flags |= SI_CONTEXT_START_PIPELINE_STATS;
+      }
    } else {
-      sctx->flags &= ~SI_CONTEXT_START_PIPELINE_STATS;
-      sctx->flags |= SI_CONTEXT_STOP_PIPELINE_STATS;
+      if (sctx->num_hw_pipestat_streamout_queries) {
+         sctx->flags &= ~SI_CONTEXT_START_PIPELINE_STATS;
+         sctx->flags |= SI_CONTEXT_STOP_PIPELINE_STATS;
+      }
    }
 
    /* Occlusion queries. */