freedreno/query: add optional enable hook
authorRob Clark <robclark@freedesktop.org>
Wed, 10 Feb 2016 19:31:59 +0000 (14:31 -0500)
committerRob Clark <robclark@freedesktop.org>
Wed, 17 Feb 2016 15:41:55 +0000 (10:41 -0500)
Add enable hook for hw query providers.  Some will need to configure
perfctr selector registers, which we want to do at the start of the
submit.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a4xx/fd4_emit.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_query_hw.c
src/gallium/drivers/freedreno/freedreno_query_hw.h

index 811f58bbba2b24e96af86a17015be3e6cd9fcbb6..8c37992e17de1d1b8f2ba53c7a712864830eab04 100644 (file)
@@ -33,6 +33,7 @@
 #include "util/u_format.h"
 
 #include "freedreno_resource.h"
+#include "freedreno_query_hw.h"
 
 #include "fd3_emit.h"
 #include "fd3_blend.h"
@@ -888,6 +889,8 @@ fd3_emit_restore(struct fd_context *ctx)
 
        fd_wfi(ctx, ring);
 
+       fd_hw_query_enable(ctx, ring);
+
        ctx->needs_rb_fbd = true;
 }
 
index 4a3f1da30ed6594010bb2b6a4e7205246dde9314..72154bf286a1786f25a9a1c8d24f4b87cd81814a 100644 (file)
@@ -33,6 +33,7 @@
 #include "util/u_format.h"
 
 #include "freedreno_resource.h"
+#include "freedreno_query_hw.h"
 
 #include "fd4_emit.h"
 #include "fd4_blend.h"
@@ -882,6 +883,8 @@ fd4_emit_restore(struct fd_context *ctx)
        OUT_PKT0(ring, REG_A4XX_GRAS_ALPHA_CONTROL, 1);
        OUT_RING(ring, 0x0);
 
+       fd_hw_query_enable(ctx, ring);
+
        ctx->needs_rb_fbd = true;
 }
 
index 9e7130ab91536328ca9f9108e0b7410544b82a43..85ce97c16b79c377c64e3d5b3396364155c28b20 100644 (file)
@@ -164,6 +164,9 @@ struct fd_context {
         */
        struct fd_hw_sample *sample_cache[MAX_HW_SAMPLE_PROVIDERS];
 
+       /* which sample providers were active in the current batch: */
+       uint32_t active_providers;
+
        /* tracking for current stage, to know when to start/stop
         * any active queries:
         */
index 027fdc9de23936793a7a0fb9c4d27f7df1a70226..7e99c35d132900f3b1daf33f1342ac5d34352aa3 100644 (file)
@@ -89,7 +89,9 @@ static void
 resume_query(struct fd_context *ctx, struct fd_hw_query *hq,
                struct fd_ringbuffer *ring)
 {
+       int idx = pidx(hq->provider->query_type);
        assert(!hq->period);
+       ctx->active_providers |= (1 << idx);
        hq->period = util_slab_alloc(&ctx->sample_period_pool);
        list_inithead(&hq->period->list);
        hq->period->start = get_sample(ctx, ring, hq->base.type);
@@ -101,7 +103,9 @@ static void
 pause_query(struct fd_context *ctx, struct fd_hw_query *hq,
                struct fd_ringbuffer *ring)
 {
+       int idx = pidx(hq->provider->query_type);
        assert(hq->period && !hq->period->end);
+       assert(ctx->active_providers & (1 << idx));
        hq->period->end = get_sample(ctx, ring, hq->base.type);
        list_addtail(&hq->period->list, &hq->current_periods);
        hq->period = NULL;
@@ -431,6 +435,23 @@ fd_hw_query_set_stage(struct fd_context *ctx, struct fd_ringbuffer *ring,
        ctx->stage = stage;
 }
 
+/* call the provider->enable() for all the hw queries that were active
+ * in the current batch.  This sets up perfctr selector regs statically
+ * for the duration of the batch.
+ */
+void
+fd_hw_query_enable(struct fd_context *ctx, struct fd_ringbuffer *ring)
+{
+       for (int idx = 0; idx < MAX_HW_SAMPLE_PROVIDERS; idx++) {
+               if (ctx->active_providers & (1 << idx)) {
+                       assert(ctx->sample_providers[idx]);
+                       if (ctx->sample_providers[idx]->enable)
+                               ctx->sample_providers[idx]->enable(ctx, ring);
+               }
+       }
+       ctx->active_providers = 0;  /* clear it for next frame */
+}
+
 void
 fd_hw_query_register_provider(struct pipe_context *pctx,
                const struct fd_hw_sample_provider *provider)
index 8f4b1f58ee53beb37a3a48a4e9b3768923d1e374..8a5d114d806150c6a14b10b013269b0d8bddbf15 100644 (file)
@@ -76,6 +76,11 @@ struct fd_hw_sample_provider {
        /* stages applicable to the query type: */
        enum fd_render_stage active;
 
+       /* Optional hook for enabling a counter.  Guaranteed to happen
+        * at least once before the first ->get_sample() in a batch.
+        */
+       void (*enable)(struct fd_context *ctx, struct fd_ringbuffer *ring);
+
        /* when a new sample is required, emit appropriate cmdstream
         * and return a sample object:
         */
@@ -144,6 +149,7 @@ void fd_hw_query_prepare_tile(struct fd_context *ctx, uint32_t n,
                struct fd_ringbuffer *ring);
 void fd_hw_query_set_stage(struct fd_context *ctx,
                struct fd_ringbuffer *ring, enum fd_render_stage stage);
+void fd_hw_query_enable(struct fd_context *ctx, struct fd_ringbuffer *ring);
 void fd_hw_query_register_provider(struct pipe_context *pctx,
                const struct fd_hw_sample_provider *provider);
 void fd_hw_query_init(struct pipe_context *pctx);