ilo: add support for PIPE_QUERY_PIPELINE_STATISTICS

This commit is contained in:
Chia-I Wu
2014-03-02 14:02:12 +08:00
parent 8fc2f0c874
commit 5ecdd7ba22
4 changed files with 108 additions and 3 deletions

View File

@@ -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) {

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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: