iris: glGet timestamps, more correct timestamps
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 28 Sep 2018 13:42:51 +0000 (15:42 +0200)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:08 +0000 (10:26 -0800)
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_query.c
src/gallium/drivers/iris/iris_screen.c

index fdf531ef7e316a7e3deaac822b05fda145a4e7d0..a2704ab8b3b5773dc119a5ac4e4b3fb0588d146f 100644 (file)
@@ -539,6 +539,11 @@ bool iris_blorp_upload_shader(struct blorp_batch *blorp_batch,
                               uint32_t *kernel_out,
                               void *prog_data_out);
 
+/* iris_query.c */
+
+uint64_t iris_timebase_scale(const struct gen_device_info *devinfo,
+                             uint64_t gpu_timestamp);
+
 /* iris_resolve.c */
 
 void iris_predraw_resolve_inputs(struct iris_context *ice,
index 46006d493c787094d122691a60e93dae037481ad..15937a8be8d3943e11a9aad41e0861d7ef1853a7 100644 (file)
@@ -236,8 +236,27 @@ write_value(struct iris_context *ice, struct iris_query *q, unsigned offset)
    }
 }
 
+uint64_t
+iris_timebase_scale(const struct gen_device_info *devinfo,
+                    uint64_t gpu_timestamp)
+{
+   return (1000000000ull * gpu_timestamp) / devinfo->timestamp_frequency;
+}
+
+static uint64_t
+iris_raw_timestamp_delta(uint64_t time0, uint64_t time1)
+{
+   if (time0 > time1) {
+      return (1ULL << 36) + time1 - time0;
+   } else {
+      return time1 - time0;
+   }
+}
+
+
 static void
-calculate_result_on_cpu(struct iris_query *q)
+calculate_result_on_cpu(const struct gen_device_info *devinfo,
+                        struct iris_query *q)
 {
    switch (q->type) {
    case PIPE_QUERY_OCCLUSION_PREDICATE:
@@ -246,12 +265,16 @@ calculate_result_on_cpu(struct iris_query *q)
       break;
    case PIPE_QUERY_TIMESTAMP:
    case PIPE_QUERY_TIMESTAMP_DISJOINT:
-      /* The timestamp is the single ending snapshot. */
-      // XXX: timebase scale
-      q->result = q->map->end;
+      /* The timestamp is the single starting snapshot. */
+      q->result = iris_timebase_scale(devinfo, q->map->start);
+      // XXX: 36-bit overflow?
       break;
-   case PIPE_QUERY_OCCLUSION_COUNTER:
    case PIPE_QUERY_TIME_ELAPSED:
+      q->result = iris_raw_timestamp_delta(q->map->start, q->map->end);
+      q->result = iris_timebase_scale(devinfo, q->result);
+      q->result &= (1ull << 36) - 1;
+      break;
+   case PIPE_QUERY_OCCLUSION_COUNTER:
    case PIPE_QUERY_PRIMITIVES_GENERATED:
    case PIPE_QUERY_PRIMITIVES_EMITTED:
    case PIPE_QUERY_PIPELINE_STATISTICS:
@@ -397,6 +420,8 @@ iris_get_query_result(struct pipe_context *ctx,
 {
    struct iris_context *ice = (void *) ctx;
    struct iris_query *q = (void *) query;
+   struct iris_screen *screen = (void *) ctx->screen;
+   const struct gen_device_info *devinfo = &screen->devinfo;
 
    if (!q->ready) {
       if (iris_batch_references(&ice->render_batch, q->bo))
@@ -410,7 +435,7 @@ iris_get_query_result(struct pipe_context *ctx,
       }
 
       assert(q->map->snapshots_landed);
-      calculate_result_on_cpu(q);
+      calculate_result_on_cpu(devinfo, q);
    }
 
    assert(q->ready);
@@ -470,6 +495,7 @@ iris_get_query_result_resource(struct pipe_context *ctx,
    struct iris_context *ice = (void *) ctx;
    struct iris_query *q = (void *) query;
    struct iris_batch *batch = &ice->render_batch;
+   const struct gen_device_info *devinfo = &batch->screen->devinfo;
    unsigned snapshots_landed_offset =
       offsetof(struct iris_query_snapshots, snapshots_landed);
 
@@ -492,7 +518,7 @@ iris_get_query_result_resource(struct pipe_context *ctx,
       /* The final snapshots happen to have landed, so let's just compute
        * the result on the CPU now...
        */
-      calculate_result_on_cpu(q);
+      calculate_result_on_cpu(devinfo, q);
    }
 
    if (q->ready) {
index efc6a7045da34b0b2ffba29a7a72a5ca2eb49228..658ecc1f591efcfcab640f3caf7d694f14ca469e 100644 (file)
@@ -374,7 +374,16 @@ iris_get_compute_param(struct pipe_screen *pscreen,
 static uint64_t
 iris_get_timestamp(struct pipe_screen *pscreen)
 {
-   return 0;
+   struct iris_screen *screen = (struct iris_screen *) pscreen;
+   const unsigned TIMESTAMP = 0x2358;
+   uint64_t result;
+
+   iris_reg_read(screen->bufmgr, TIMESTAMP, &result);
+
+   result = iris_timebase_scale(&screen->devinfo, result);
+   result &= (1ull << 36) - 1;
+
+   return result;
 }
 
 static void