summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/ilo/ilo_query.c
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2014-09-20 13:23:01 +0800
committerChia-I Wu <[email protected]>2014-09-21 23:31:10 +0800
commit9c873816a8ba0fe19fe6d38839078c1b75957953 (patch)
treedc27349e98a257792d818eeeb686704a4d7c4898 /src/gallium/drivers/ilo/ilo_query.c
parent26fefae9a715b5498b5ffcd835556b02e4f0c68b (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.c172
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