freedreno/query: add optional enable hook

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>
This commit is contained in:
Rob Clark 2016-02-10 14:31:59 -05:00
parent 45ab5b1c34
commit 8529e210ec
5 changed files with 36 additions and 0 deletions

View 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;
}

View 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;
}

View 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:
*/

View 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)

View 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);