From 13a0cf4480b908aafa337c121cbdfc338318f088 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 9 May 2014 17:33:19 -0400 Subject: freedreno/query: allow multiple query implementations Split out fd_query into an abstract base class, to allow multiple implementations. The current sw based queries are moved into fd_sw_query. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/Makefile.sources | 1 + src/gallium/drivers/freedreno/freedreno_context.h | 4 + src/gallium/drivers/freedreno/freedreno_query.c | 118 ++------------- src/gallium/drivers/freedreno/freedreno_query.h | 33 ++++- src/gallium/drivers/freedreno/freedreno_query_sw.c | 165 +++++++++++++++++++++ src/gallium/drivers/freedreno/freedreno_query_sw.h | 55 +++++++ 6 files changed, 269 insertions(+), 107 deletions(-) create mode 100644 src/gallium/drivers/freedreno/freedreno_query_sw.c create mode 100644 src/gallium/drivers/freedreno/freedreno_query_sw.h (limited to 'src/gallium/drivers/freedreno') diff --git a/src/gallium/drivers/freedreno/Makefile.sources b/src/gallium/drivers/freedreno/Makefile.sources index 311b0b6a205..3621abddb28 100644 --- a/src/gallium/drivers/freedreno/Makefile.sources +++ b/src/gallium/drivers/freedreno/Makefile.sources @@ -3,6 +3,7 @@ C_SOURCES := \ freedreno_lowering.c \ freedreno_program.c \ freedreno_query.c \ + freedreno_query_sw.c \ freedreno_fence.c \ freedreno_resource.c \ freedreno_surface.c \ diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index a50e6236903..2e7fdedd9ae 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -258,6 +258,10 @@ struct fd_context { void (*draw)(struct fd_context *pctx, const struct pipe_draw_info *info); void (*clear)(struct fd_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil); + + /* queries: */ + struct fd_query * (*create_query)(struct fd_context *ctx, + unsigned query_type); }; static INLINE struct fd_context * diff --git a/src/gallium/drivers/freedreno/freedreno_query.c b/src/gallium/drivers/freedreno/freedreno_query.c index 3913896bf56..fb9908b39ee 100644 --- a/src/gallium/drivers/freedreno/freedreno_query.c +++ b/src/gallium/drivers/freedreno/freedreno_query.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; ttxab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark + * Copyright (C) 2013 Rob Clark * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -27,63 +27,26 @@ */ #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_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) { + 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 (ctx->create_query && !q) + q = ctx->create_query(ctx, query_type); return (struct pipe_query *) q; } @@ -92,64 +55,21 @@ static void fd_destroy_query(struct pipe_context *pctx, struct pipe_query *pq) { struct fd_query *q = fd_query(pq); - free(q); -} - -static uint64_t -read_counter(struct pipe_context *pctx, int type) -{ - 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; -} - -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: - return false; - } + q->funcs->destroy_query(fd_context(pctx), q); } 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(); + q->funcs->begin_query(fd_context(pctx), q); } static void fd_end_query(struct pipe_context *pctx, struct pipe_query *pq) { struct fd_query *q = fd_query(pq); - q->active = false; - q->end_value = read_counter(pctx, q->type); - if (is_rate_query(q)) - q->end_time = os_time_get(); + q->funcs->end_query(fd_context(pctx), q); } static boolean @@ -157,21 +77,7 @@ fd_get_query_result(struct pipe_context *pctx, struct pipe_query *pq, boolean wait, union pipe_query_result *result) { struct fd_query *q = fd_query(pq); - - if (q->active) - return false; - - 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 true; + return q->funcs->get_query_result(fd_context(pctx), q, wait, result); } static int diff --git a/src/gallium/drivers/freedreno/freedreno_query.h b/src/gallium/drivers/freedreno/freedreno_query.h index 8bcbba2fdc9..bc9a7a20559 100644 --- a/src/gallium/drivers/freedreno/freedreno_query.h +++ b/src/gallium/drivers/freedreno/freedreno_query.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ /* - * Copyright (C) 2012 Rob Clark + * Copyright (C) 2013 Rob Clark * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -31,6 +31,37 @@ #include "pipe/p_context.h" +struct fd_context; +struct fd_query; + +struct fd_query_funcs { + void (*destroy_query)(struct fd_context *ctx, + struct fd_query *q); + void (*begin_query)(struct fd_context *ctx, struct fd_query *q); + void (*end_query)(struct fd_context *ctx, struct fd_query *q); + boolean (*get_query_result)(struct fd_context *ctx, + struct fd_query *q, boolean wait, + union pipe_query_result *result); +}; + +struct fd_query { + const struct fd_query_funcs *funcs; + bool active; + int type; +}; + +static inline struct fd_query * +fd_query(struct pipe_query *pq) +{ + return (struct fd_query *)pq; +} + +#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 */ + void fd_query_screen_init(struct pipe_screen *pscreen); void fd_query_context_init(struct pipe_context *pctx); diff --git a/src/gallium/drivers/freedreno/freedreno_query_sw.c b/src/gallium/drivers/freedreno/freedreno_query_sw.c new file mode 100644 index 00000000000..8d81698f31d --- /dev/null +++ b/src/gallium/drivers/freedreno/freedreno_query_sw.c @@ -0,0 +1,165 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2014 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Rob Clark + */ + +#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_sw.h" +#include "freedreno_context.h" +#include "freedreno_util.h" + +/* + * SW Queries: + * + * In the core, we have some support for basic sw counters + */ + +static void +fd_sw_destroy_query(struct fd_context *ctx, struct fd_query *q) +{ + struct fd_sw_query *sq = fd_sw_query(q); + free(sq); +} + +static uint64_t +read_counter(struct fd_context *ctx, int type) +{ + 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; +} + +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: + return false; + } +} + +static void +fd_sw_begin_query(struct fd_context *ctx, struct fd_query *q) +{ + struct fd_sw_query *sq = fd_sw_query(q); + q->active = true; + sq->begin_value = read_counter(ctx, q->type); + if (is_rate_query(q)) + sq->begin_time = os_time_get(); +} + +static void +fd_sw_end_query(struct fd_context *ctx, struct fd_query *q) +{ + struct fd_sw_query *sq = fd_sw_query(q); + q->active = false; + sq->end_value = read_counter(ctx, q->type); + if (is_rate_query(q)) + sq->end_time = os_time_get(); +} + +static boolean +fd_sw_get_query_result(struct fd_context *ctx, struct fd_query *q, + boolean wait, union pipe_query_result *result) +{ + struct fd_sw_query *sq = fd_sw_query(q); + + if (q->active) + return false; + + util_query_clear_result(result, q->type); + + result->u64 = sq->end_value - sq->begin_value; + + if (is_rate_query(q)) { + double fps = (result->u64 * 1000000) / + (double)(sq->end_time - sq->begin_time); + result->u64 = (uint64_t)fps; + } + + return true; +} + +static const struct fd_query_funcs sw_query_funcs = { + .destroy_query = fd_sw_destroy_query, + .begin_query = fd_sw_begin_query, + .end_query = fd_sw_end_query, + .get_query_result = fd_sw_get_query_result, +}; + +struct fd_query * +fd_sw_create_query(struct fd_context *ctx, unsigned query_type) +{ + struct fd_sw_query *sq; + 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; + } + + sq = CALLOC_STRUCT(fd_sw_query); + if (!sq) + return NULL; + + q = &sq->base; + q->funcs = &sw_query_funcs; + q->type = query_type; + + return q; +} diff --git a/src/gallium/drivers/freedreno/freedreno_query_sw.h b/src/gallium/drivers/freedreno/freedreno_query_sw.h new file mode 100644 index 00000000000..3446474d0bd --- /dev/null +++ b/src/gallium/drivers/freedreno/freedreno_query_sw.h @@ -0,0 +1,55 @@ +/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ + +/* + * Copyright (C) 2014 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Rob Clark + */ + +#ifndef FREEDRENO_QUERY_SW_H_ +#define FREEDRENO_QUERY_SW_H_ + +#include "freedreno_query.h" + +/* + * SW Queries: + * + * In the core, we have some support for basic sw counters + */ + +struct fd_sw_query { + struct fd_query base; + uint64_t begin_value, end_value; + uint64_t begin_time, end_time; +}; + +static inline struct fd_sw_query * +fd_sw_query(struct fd_query *q) +{ + return (struct fd_sw_query *)q; +} + +struct fd_query * fd_sw_create_query(struct fd_context *ctx, + unsigned query_type); + +#endif /* FREEDRENO_QUERY_SW_H_ */ -- cgit v1.2.3