Mesa (master): ilo: add support for PIPE_QUERY_PIPELINE_STATISTICS

Chia-I Wu olv at kemper.freedesktop.org
Mon Mar 10 08:46:19 UTC 2014


Module: Mesa
Branch: master
Commit: 5ecdd7ba22945ce4e3a10b26c6f34a19eceeb289
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5ecdd7ba22945ce4e3a10b26c6f34a19eceeb289

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Sun Mar  2 14:02:12 2014 +0800

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 7615e7c..9006376 100644
--- a/src/gallium/drivers/ilo/ilo_3d.c
+++ b/src/gallium/drivers/ilo/ilo_3d.c
@@ -101,6 +101,41 @@ process_query_for_time_elapsed(struct ilo_3d *hw3d, struct ilo_query *q)
 }
 
 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)
 {
    struct ilo_query *q;
@@ -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 694820d..369594a 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 6a7da7f..71bcc0f 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 442e704..4a04662 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:




More information about the mesa-commit mailing list