From 5ecdd7ba22945ce4e3a10b26c6f34a19eceeb289 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 2 Mar 2014 14:02:12 +0800 Subject: [PATCH] ilo: add support for PIPE_QUERY_PIPELINE_STATISTICS --- src/gallium/drivers/ilo/ilo_3d.c | 88 ++++++++++++++++++++++++++++ src/gallium/drivers/ilo/ilo_3d.h | 1 + src/gallium/drivers/ilo/ilo_query.c | 19 +++++- src/gallium/drivers/ilo/ilo_screen.c | 3 +- 4 files changed, 108 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_3d.c b/src/gallium/drivers/ilo/ilo_3d.c index 7615e7c62f8..90063761d16 100644 --- a/src/gallium/drivers/ilo/ilo_3d.c +++ b/src/gallium/drivers/ilo/ilo_3d.c @@ -100,6 +100,41 @@ process_query_for_time_elapsed(struct ilo_3d *hw3d, struct ilo_query *q) q->reg_read = 0; } +static void +process_query_for_pipeline_statistics(struct ilo_3d *hw3d, + struct ilo_query *q) +{ + const uint64_t *vals; + int i; + + assert(q->reg_read % 22 == 0); + + vals = intel_bo_map(q->bo, false); + + for (i = 0; i < q->reg_read; i += 22) { + struct pipe_query_data_pipeline_statistics *stats = + &q->data.pipeline_statistics; + const uint64_t *begin = vals + i; + const uint64_t *end = begin + 11; + + stats->ia_vertices += end[0] - begin[0]; + stats->ia_primitives += end[1] - begin[1]; + stats->vs_invocations += end[2] - begin[2]; + stats->gs_invocations += end[3] - begin[3]; + stats->gs_primitives += end[4] - begin[4]; + stats->c_invocations += end[5] - begin[5]; + stats->c_primitives += end[6] - begin[6]; + stats->ps_invocations += end[7] - begin[7]; + stats->hs_invocations += end[8] - begin[8]; + stats->ds_invocations += end[9] - begin[9]; + stats->cs_invocations += end[10] - begin[10]; + } + + intel_bo_unmap(q->bo); + + q->reg_read = 0; +} + static void ilo_3d_resume_queries(struct ilo_3d *hw3d) { @@ -124,6 +159,17 @@ ilo_3d_resume_queries(struct ilo_3d *hw3d) ilo_3d_pipeline_emit_write_timestamp(hw3d->pipeline, q->bo, q->reg_read++); } + + /* resume pipeline statistics queries */ + LIST_FOR_EACH_ENTRY(q, &hw3d->pipeline_statistics_queries, list) { + /* accumulate the result if the bo is alreay full */ + if (q->reg_read >= q->reg_total) + process_query_for_pipeline_statistics(hw3d, q); + + ilo_3d_pipeline_emit_write_statistics(hw3d->pipeline, + q->bo, q->reg_read); + q->reg_read += 11; + } } static void @@ -144,6 +190,14 @@ ilo_3d_pause_queries(struct ilo_3d *hw3d) ilo_3d_pipeline_emit_write_timestamp(hw3d->pipeline, q->bo, q->reg_read++); } + + /* pause pipeline statistics queries */ + LIST_FOR_EACH_ENTRY(q, &hw3d->pipeline_statistics_queries, list) { + assert(q->reg_read < q->reg_total); + ilo_3d_pipeline_emit_write_statistics(hw3d->pipeline, + q->bo, q->reg_read); + q->reg_read += 11; + } } static void @@ -219,6 +273,25 @@ ilo_3d_begin_query(struct ilo_context *ilo, struct ilo_query *q) q->data.u64 = 0; list_add(&q->list, &hw3d->prim_emitted_queries); break; + case PIPE_QUERY_PIPELINE_STATISTICS: + /* reserve some space for pausing the query */ + q->reg_cmd_size = ilo_3d_pipeline_estimate_size(hw3d->pipeline, + ILO_3D_PIPELINE_WRITE_STATISTICS, NULL); + hw3d->owner_reserve += q->reg_cmd_size; + ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve); + + memset(&q->data.pipeline_statistics, 0, + sizeof(q->data.pipeline_statistics)); + + if (ilo_query_alloc_bo(q, 11 * 2, -1, hw3d->cp->winsys)) { + /* XXX we should check the aperture size */ + ilo_3d_pipeline_emit_write_statistics(hw3d->pipeline, + q->bo, q->reg_read); + q->reg_read += 11; + + list_add(&q->list, &hw3d->pipeline_statistics_queries); + } + break; default: assert(!"unknown query type"); break; @@ -266,6 +339,16 @@ ilo_3d_end_query(struct ilo_context *ilo, struct ilo_query *q) case PIPE_QUERY_PRIMITIVES_EMITTED: list_del(&q->list); break; + case PIPE_QUERY_PIPELINE_STATISTICS: + list_del(&q->list); + + assert(q->reg_read + 11 <= q->reg_total); + hw3d->owner_reserve -= q->reg_cmd_size; + ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve); + ilo_3d_pipeline_emit_write_statistics(hw3d->pipeline, + q->bo, q->reg_read); + q->reg_read += 11; + break; default: assert(!"unknown query type"); break; @@ -296,6 +379,10 @@ ilo_3d_process_query(struct ilo_context *ilo, struct ilo_query *q) case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_EMITTED: break; + case PIPE_QUERY_PIPELINE_STATISTICS: + if (q->bo) + process_query_for_pipeline_statistics(hw3d, q); + break; default: assert(!"unknown query type"); break; @@ -341,6 +428,7 @@ ilo_3d_create(struct ilo_cp *cp, const struct ilo_dev_info *dev) list_inithead(&hw3d->time_elapsed_queries); list_inithead(&hw3d->prim_generated_queries); list_inithead(&hw3d->prim_emitted_queries); + list_inithead(&hw3d->pipeline_statistics_queries); hw3d->pipeline = ilo_3d_pipeline_create(cp, dev); if (!hw3d->pipeline) { diff --git a/src/gallium/drivers/ilo/ilo_3d.h b/src/gallium/drivers/ilo/ilo_3d.h index 694820d953f..369594affaa 100644 --- a/src/gallium/drivers/ilo/ilo_3d.h +++ b/src/gallium/drivers/ilo/ilo_3d.h @@ -60,6 +60,7 @@ struct ilo_3d { struct list_head time_elapsed_queries; struct list_head prim_generated_queries; struct list_head prim_emitted_queries; + struct list_head pipeline_statistics_queries; struct ilo_3d_pipeline *pipeline; }; diff --git a/src/gallium/drivers/ilo/ilo_query.c b/src/gallium/drivers/ilo/ilo_query.c index 6a7da7f2730..71bcc0f983f 100644 --- a/src/gallium/drivers/ilo/ilo_query.c +++ b/src/gallium/drivers/ilo/ilo_query.c @@ -57,7 +57,7 @@ static const struct { [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] = INFOX(ilo_3d, "pipeline statistics"), + [PIPE_QUERY_PIPELINE_STATISTICS] = INFO(ilo_3d, "pipeline statistics"), #undef INFO #undef INFOX @@ -80,6 +80,7 @@ ilo_create_query(struct pipe_context *pipe, unsigned query_type) case PIPE_QUERY_TIME_ELAPSED: case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_EMITTED: + case PIPE_QUERY_PIPELINE_STATISTICS: break; default: return NULL; @@ -151,6 +152,22 @@ serialize_query_data(unsigned type, const union pipe_query_result *data, r[0] = data->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; + } + break; default: memset(buf, 0, sizeof(union pipe_query_result)); break; diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c index 442e704615d..4a046628d62 100644 --- a/src/gallium/drivers/ilo/ilo_screen.c +++ b/src/gallium/drivers/ilo/ilo_screen.c @@ -419,9 +419,8 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TGSI_TEXCOORD: return false; case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: - return true; case PIPE_CAP_QUERY_PIPELINE_STATISTICS: - return false; /* TODO */ + return true; case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: return 0; case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: -- 2.30.2