diff options
author | Chia-I Wu <[email protected]> | 2014-09-20 13:23:01 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2014-09-21 23:31:10 +0800 |
commit | 9c873816a8ba0fe19fe6d38839078c1b75957953 (patch) | |
tree | dc27349e98a257792d818eeeb686704a4d7c4898 /src/gallium/drivers/ilo/ilo_query.c | |
parent | 26fefae9a715b5498b5ffcd835556b02e4f0c68b (diff) |
ilo: rework query support
This fixes some corner cases, but more importantly, the new code should be
easier to reason about.
Signed-off-by: Chia-I Wu <[email protected]>
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_query.c')
-rw-r--r-- | src/gallium/drivers/ilo/ilo_query.c | 172 |
1 files changed, 73 insertions, 99 deletions
diff --git a/src/gallium/drivers/ilo/ilo_query.c b/src/gallium/drivers/ilo/ilo_query.c index 812e056996e..e0cd4ee7554 100644 --- a/src/gallium/drivers/ilo/ilo_query.c +++ b/src/gallium/drivers/ilo/ilo_query.c @@ -33,31 +33,30 @@ #include "ilo_query.h" static const struct { - const char *name; - - void (*begin)(struct ilo_context *ilo, struct ilo_query *q); - void (*end)(struct ilo_context *ilo, struct ilo_query *q); - void (*process)(struct ilo_context *ilo, struct ilo_query *q); -} query_info[PIPE_QUERY_TYPES] = { -#define INFO(prefix, desc) { \ - .name = desc, \ - .begin = prefix ## _begin_query, \ - .end = prefix ## _end_query, \ - .process = prefix ## _process_query, \ + bool (*init)(struct pipe_context *pipe, struct ilo_query *q); + void (*begin)(struct pipe_context *pipe, struct ilo_query *q); + void (*end)(struct pipe_context *pipe, struct ilo_query *q); + void (*process)(struct pipe_context *pipe, struct ilo_query *q); +} ilo_query_table[PIPE_QUERY_TYPES] = { +#define INFO(prefix) { \ + .init = prefix ## _init_query, \ + .begin = prefix ## _begin_query, \ + .end = prefix ## _end_query, \ + .process = prefix ## _process_query, \ } -#define INFOX(prefix, desc) { desc, NULL, NULL, NULL, } - - [PIPE_QUERY_OCCLUSION_COUNTER] = INFO(ilo_3d, "occlusion counter"), - [PIPE_QUERY_OCCLUSION_PREDICATE] = INFOX(ilo_3d, "occlusion pred."), - [PIPE_QUERY_TIMESTAMP] = INFO(ilo_3d, "timestamp"), - [PIPE_QUERY_TIMESTAMP_DISJOINT] = INFOX(ilo_3d, "timestamp disjoint"), - [PIPE_QUERY_TIME_ELAPSED] = INFO(ilo_3d, "time elapsed"), - [PIPE_QUERY_PRIMITIVES_GENERATED] = INFO(ilo_3d, "primitives generated"), - [PIPE_QUERY_PRIMITIVES_EMITTED] = INFO(ilo_3d, "primitives emitted"), - [PIPE_QUERY_SO_STATISTICS] = INFOX(ilo_3d, "so statistics"), - [PIPE_QUERY_SO_OVERFLOW_PREDICATE] = INFOX(ilo_3d, "so overflow pred."), - [PIPE_QUERY_GPU_FINISHED] = INFOX(ilo_3d, "gpu finished"), - [PIPE_QUERY_PIPELINE_STATISTICS] = INFO(ilo_3d, "pipeline statistics"), +#define INFOX(prefix) { NULL, NULL, NULL, NULL, } + + [PIPE_QUERY_OCCLUSION_COUNTER] = INFO(ilo_3d), + [PIPE_QUERY_OCCLUSION_PREDICATE] = INFOX(ilo_3d), + [PIPE_QUERY_TIMESTAMP] = INFO(ilo_3d), + [PIPE_QUERY_TIMESTAMP_DISJOINT] = INFOX(ilo_3d), + [PIPE_QUERY_TIME_ELAPSED] = INFO(ilo_3d), + [PIPE_QUERY_PRIMITIVES_GENERATED] = INFO(ilo_3d), + [PIPE_QUERY_PRIMITIVES_EMITTED] = INFO(ilo_3d), + [PIPE_QUERY_SO_STATISTICS] = INFOX(ilo_3d), + [PIPE_QUERY_SO_OVERFLOW_PREDICATE] = INFOX(ilo_3d), + [PIPE_QUERY_GPU_FINISHED] = INFOX(ilo_3d), + [PIPE_QUERY_PIPELINE_STATISTICS] = INFO(ilo_3d), #undef INFO #undef INFOX @@ -91,8 +90,15 @@ ilo_create_query(struct pipe_context *pipe, unsigned query_type, unsigned index) return NULL; q->type = query_type; + q->index = index; + list_inithead(&q->list); + if (!ilo_query_table[q->type].init(pipe, q)) { + FREE(q); + return NULL; + } + return (struct pipe_query *) q; } @@ -110,62 +116,71 @@ ilo_destroy_query(struct pipe_context *pipe, struct pipe_query *query) static void ilo_begin_query(struct pipe_context *pipe, struct pipe_query *query) { - struct ilo_context *ilo = ilo_context(pipe); struct ilo_query *q = ilo_query(query); + if (q->active) + return; + + util_query_clear_result(&q->result, q->type); + q->used = 0; q->active = true; - query_info[q->type].begin(ilo, q); + ilo_query_table[q->type].begin(pipe, q); } static void ilo_end_query(struct pipe_context *pipe, struct pipe_query *query) { - struct ilo_context *ilo = ilo_context(pipe); struct ilo_query *q = ilo_query(query); - query_info[q->type].end(ilo, q); + if (!q->active) { + /* require ilo_begin_query() first */ + if (q->in_pairs) + return; + + ilo_begin_query(pipe, query); + } - /* - * some queries such as timestamp query does not require a call to - * begin_query() so q->active is always false - */ q->active = false; + + ilo_query_table[q->type].end(pipe, q); } /** - * The type (union pipe_query_result) indicates only the size of the buffer. - * Callers expect the result to be "serialized". + * Serialize the result. The size of \p buf is + * sizeof(union pipe_query_result). */ static void -serialize_query_data(unsigned type, const union pipe_query_result *data, - void *buf) +query_serialize(const struct ilo_query *q, void *buf) { - switch (type) { + switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_TIMESTAMP: case PIPE_QUERY_TIME_ELAPSED: case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_EMITTED: { - uint64_t *r = buf; - r[0] = data->u64; + uint64_t *dst = buf; + dst[0] = q->result.u64; } break; case PIPE_QUERY_PIPELINE_STATISTICS: { - uint64_t *r = buf; - r[0] = data->pipeline_statistics.ia_vertices; - r[1] = data->pipeline_statistics.ia_primitives; - r[2] = data->pipeline_statistics.vs_invocations; - r[3] = data->pipeline_statistics.gs_invocations; - r[4] = data->pipeline_statistics.gs_primitives; - r[5] = data->pipeline_statistics.c_invocations; - r[6] = data->pipeline_statistics.c_primitives; - r[7] = data->pipeline_statistics.ps_invocations; - r[8] = data->pipeline_statistics.hs_invocations; - r[9] = data->pipeline_statistics.ds_invocations; - r[10] = data->pipeline_statistics.cs_invocations; + const struct pipe_query_data_pipeline_statistics *stats = + &q->result.pipeline_statistics; + uint64_t *dst = buf; + + dst[0] = stats->ia_vertices; + dst[1] = stats->ia_primitives; + dst[2] = stats->vs_invocations; + dst[3] = stats->gs_invocations; + dst[4] = stats->gs_primitives; + dst[5] = stats->c_invocations; + dst[6] = stats->c_primitives; + dst[7] = stats->ps_invocations; + dst[8] = stats->hs_invocations; + dst[9] = stats->ds_invocations; + dst[10] = stats->cs_invocations; } break; default: @@ -178,71 +193,30 @@ static boolean ilo_get_query_result(struct pipe_context *pipe, struct pipe_query *query, boolean wait, union pipe_query_result *result) { - struct ilo_context *ilo = ilo_context(pipe); struct ilo_query *q = ilo_query(query); if (q->active) return false; if (q->bo) { - if (ilo_builder_has_reloc(&ilo->cp->builder, q->bo)) - ilo_cp_submit(ilo->cp, "syncing for queries"); + struct ilo_cp *cp = ilo_context(pipe)->cp; + + if (ilo_builder_has_reloc(&cp->builder, q->bo)) + ilo_cp_submit(cp, "syncing for queries"); if (!wait && intel_bo_is_busy(q->bo)) return false; - - query_info[q->type].process(ilo, q); } + ilo_query_table[q->type].process(pipe, q); + if (result) - serialize_query_data(q->type, &q->data, (void *) result); + query_serialize(q, (void *) result); return true; } /** - * Allocate a query bo for reading hardware statistics. - * - * \param reg_count specifies how many registers need to be read. - * \param repeat_count specifies how many times the registers are read. If - * zero or negative, a 4KB bo is allocated. - */ -bool -ilo_query_alloc_bo(struct ilo_query *q, int reg_count, int repeat_count, - struct intel_winsys *winsys) -{ - const char *name; - int reg_total; - - name = query_info[q->type].name; - - reg_total = reg_count * repeat_count; - if (reg_total <= 0) - reg_total = 4096 / sizeof(uint64_t); - - /* (re-)allocate the bo */ - if (q->reg_total < reg_total) { - /* registers are 64-bit */ - const int size = reg_total * sizeof(uint64_t); - - if (q->bo) - intel_bo_unreference(q->bo); - - q->bo = intel_winsys_alloc_buffer(winsys, - name, size, false); - q->reg_total = (q->bo) ? reg_total : 0; - } - - /* avoid partial reads */ - if (reg_count) - q->reg_total -= q->reg_total % reg_count; - - q->reg_read = 0; - - return (q->bo != NULL); -} - -/** * Initialize query-related functions. */ void |