/* -*- mode: C; c-file-style: "k&r"; ttxab-width 4; indent-tabs-mode: t; -*- */
/*
- * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
+ * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
*/
#include "pipe/p_state.h"
-#include "util/u_string.h"
#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "os/os_time.h"
#include "freedreno_query.h"
+#include "freedreno_query_sw.h"
+#include "freedreno_query_hw.h"
#include "freedreno_context.h"
#include "freedreno_util.h"
-#define FD_QUERY_DRAW_CALLS (PIPE_QUERY_DRIVER_SPECIFIC + 0)
-#define FD_QUERY_BATCH_TOTAL (PIPE_QUERY_DRIVER_SPECIFIC + 1) /* total # of batches (submits) */
-#define FD_QUERY_BATCH_SYSMEM (PIPE_QUERY_DRIVER_SPECIFIC + 2) /* batches using system memory (GMEM bypass) */
-#define FD_QUERY_BATCH_GMEM (PIPE_QUERY_DRIVER_SPECIFIC + 3) /* batches using GMEM */
-#define FD_QUERY_BATCH_RESTORE (PIPE_QUERY_DRIVER_SPECIFIC + 4) /* batches requiring GMEM restore */
-
-/* Currently just simple cpu query's supported.. probably need
- * to refactor this a bit when I'm eventually ready to add gpu
- * queries:
+/*
+ * Pipe Query interface:
*/
-struct fd_query {
- int type;
- /* storage for the collected data */
- union pipe_query_result data;
- bool active;
- uint64_t begin_value, end_value;
- uint64_t begin_time, end_time;
-};
-
-static inline struct fd_query *
-fd_query(struct pipe_query *pq)
-{
- return (struct fd_query *)pq;
-}
static struct pipe_query *
-fd_create_query(struct pipe_context *pctx, unsigned query_type)
+fd_create_query(struct pipe_context *pctx, unsigned query_type, unsigned index)
{
+ struct fd_context *ctx = fd_context(pctx);
struct fd_query *q;
- switch (query_type) {
- case PIPE_QUERY_PRIMITIVES_GENERATED:
- case PIPE_QUERY_PRIMITIVES_EMITTED:
- case FD_QUERY_DRAW_CALLS:
- case FD_QUERY_BATCH_TOTAL:
- case FD_QUERY_BATCH_SYSMEM:
- case FD_QUERY_BATCH_GMEM:
- case FD_QUERY_BATCH_RESTORE:
- break;
- default:
- return NULL;
- }
-
- q = CALLOC_STRUCT(fd_query);
- if (!q)
- return NULL;
-
- q->type = query_type;
+ q = fd_sw_create_query(ctx, query_type);
+ if (!q && ctx->create_query)
+ q = ctx->create_query(ctx, query_type);
return (struct pipe_query *) q;
}
fd_destroy_query(struct pipe_context *pctx, struct pipe_query *pq)
{
struct fd_query *q = fd_query(pq);
- free(q);
+ q->funcs->destroy_query(fd_context(pctx), q);
}
-static uint64_t
-read_counter(struct pipe_context *pctx, int type)
+static boolean
+fd_begin_query(struct pipe_context *pctx, struct pipe_query *pq)
{
- struct fd_context *ctx = fd_context(pctx);
- switch (type) {
- case PIPE_QUERY_PRIMITIVES_GENERATED:
- /* for now same thing as _PRIMITIVES_EMITTED */
- case PIPE_QUERY_PRIMITIVES_EMITTED:
- return ctx->stats.prims_emitted;
- case FD_QUERY_DRAW_CALLS:
- return ctx->stats.draw_calls;
- case FD_QUERY_BATCH_TOTAL:
- return ctx->stats.batch_total;
- case FD_QUERY_BATCH_SYSMEM:
- return ctx->stats.batch_sysmem;
- case FD_QUERY_BATCH_GMEM:
- return ctx->stats.batch_gmem;
- case FD_QUERY_BATCH_RESTORE:
- return ctx->stats.batch_restore;
- }
- return 0;
-}
+ struct fd_query *q = fd_query(pq);
+ boolean ret;
-static bool
-is_rate_query(struct fd_query *q)
-{
- switch (q->type) {
- case FD_QUERY_BATCH_TOTAL:
- case FD_QUERY_BATCH_SYSMEM:
- case FD_QUERY_BATCH_GMEM:
- case FD_QUERY_BATCH_RESTORE:
- return true;
- default:
+ if (q->active)
return false;
- }
-}
-static void
-fd_begin_query(struct pipe_context *pctx, struct pipe_query *pq)
-{
- struct fd_query *q = fd_query(pq);
- q->active = true;
- q->begin_value = read_counter(pctx, q->type);
- if (is_rate_query(q))
- q->begin_time = os_time_get();
+ ret = q->funcs->begin_query(fd_context(pctx), q);
+ q->active = ret;
+
+ return ret;
}
-static void
+static bool
fd_end_query(struct pipe_context *pctx, struct pipe_query *pq)
{
struct fd_query *q = fd_query(pq);
+
+ /* there are a couple special cases, which don't have
+ * a matching ->begin_query():
+ */
+ if (skip_begin_query(q->type) && !q->active)
+ fd_begin_query(pctx, pq);
+
+ if (!q->active)
+ return false;
+
+ q->funcs->end_query(fd_context(pctx), q);
q->active = false;
- q->end_value = read_counter(pctx, q->type);
- if (is_rate_query(q))
- q->end_time = os_time_get();
+
+ return true;
}
static boolean
util_query_clear_result(result, q->type);
- result->u64 = q->end_value - q->begin_value;
-
- if (is_rate_query(q)) {
- double fps = (result->u64 * 1000000) /
- (double)(q->end_time - q->begin_time);
- result->u64 = (uint64_t)fps;
- }
+ return q->funcs->get_query_result(fd_context(pctx), q, wait, result);
+}
- return true;
+static void
+fd_render_condition(struct pipe_context *pctx, struct pipe_query *pq,
+ boolean condition, enum pipe_render_cond_flag mode)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ ctx->cond_query = pq;
+ ctx->cond_cond = condition;
+ ctx->cond_mode = mode;
}
static int
unsigned index, struct pipe_driver_query_info *info)
{
struct pipe_driver_query_info list[] = {
- {"draw-calls", FD_QUERY_DRAW_CALLS, 0},
- {"batches", FD_QUERY_BATCH_TOTAL, 0},
- {"batches-sysmem", FD_QUERY_BATCH_SYSMEM, 0},
- {"batches-gmem", FD_QUERY_BATCH_GMEM, 0},
- {"restores", FD_QUERY_BATCH_RESTORE, 0},
+ {"draw-calls", FD_QUERY_DRAW_CALLS, {0}},
+ {"batches", FD_QUERY_BATCH_TOTAL, {0}},
+ {"batches-sysmem", FD_QUERY_BATCH_SYSMEM, {0}},
+ {"batches-gmem", FD_QUERY_BATCH_GMEM, {0}},
+ {"restores", FD_QUERY_BATCH_RESTORE, {0}},
+ {"prims-emitted", PIPE_QUERY_PRIMITIVES_EMITTED, {0}},
};
if (!info)
return 1;
}
+static void
+fd_set_active_query_state(struct pipe_context *pipe, boolean enable)
+{
+}
+
void
fd_query_screen_init(struct pipe_screen *pscreen)
{
pctx->begin_query = fd_begin_query;
pctx->end_query = fd_end_query;
pctx->get_query_result = fd_get_query_result;
+ pctx->set_active_query_state = fd_set_active_query_state;
+ pctx->render_condition = fd_render_condition;
}