summaryrefslogtreecommitdiff
path: root/tests/perf.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-12-08 15:14:15 +0000
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>2017-12-08 17:22:38 +0000
commit4dce16890fd3c9894f8b855a85fd169bf7faead2 (patch)
treef9746d3178042f61d958ccd549737e0d9df52db6 /tests/perf.c
parentd56a18576ee471a0e7bb065b3c109556f80d8d3e (diff)
igt/perf: Read RCS0 timestamp directly
On Haswell, at least, MI_REPORT_PERF_COUNT is not flushed by the PIPECONTROL surrounding the batch. (In theory, before the breadcrumb is updated the CPU's view of memory is coherent with the GPU, i.e. all writes have landed and are visible to userspace. This does not appear to be the case for MI_REPORT_PERF_COUNT.) This makes it an unreliable method for querying the timestamp, so use MI_STORE_REGISTER_MEM instead. Testcase: igt/perf/oa-exponents Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Diffstat (limited to 'tests/perf.c')
-rw-r--r--tests/perf.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/tests/perf.c b/tests/perf.c
index 394663e8..969b8c74 100644
--- a/tests/perf.c
+++ b/tests/perf.c
@@ -559,47 +559,46 @@ emit_report_perf_count(struct intel_batchbuffer *batch,
}
static uint32_t
-i915_get_one_gpu_timestamp(uint32_t *context_id)
+i915_get_one_gpu_timestamp(void)
{
- drm_intel_bufmgr *bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
- drm_intel_context *mi_rpc_ctx = drm_intel_gem_context_create(bufmgr);
- drm_intel_bo *mi_rpc_bo = drm_intel_bo_alloc(bufmgr, "mi_rpc dest bo", 4096, 64);
- struct intel_batchbuffer *mi_rpc_batch = intel_batchbuffer_alloc(bufmgr, devid);
- int ret;
+ const bool r64b = intel_gen(devid) >= 8;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_exec_object2 obj[2];
+ struct drm_i915_gem_relocation_entry reloc;
+ uint32_t batch[16];
uint32_t timestamp;
+ int i;
- drm_intel_bufmgr_gem_enable_reuse(bufmgr);
-
- if (context_id) {
- ret = drm_intel_gem_context_get_id(mi_rpc_ctx, context_id);
- igt_assert_eq(ret, 0);
- }
-
- igt_assert(mi_rpc_ctx);
- igt_assert(mi_rpc_bo);
- igt_assert(mi_rpc_batch);
-
- ret = drm_intel_bo_map(mi_rpc_bo, true);
- igt_assert_eq(ret, 0);
- memset(mi_rpc_bo->virtual, 0x80, 4096);
- drm_intel_bo_unmap(mi_rpc_bo);
-
- emit_report_perf_count(mi_rpc_batch,
- mi_rpc_bo, /* dst */
- 0, /* dst offset in bytes */
- 0xdeadbeef); /* report ID */
-
- intel_batchbuffer_flush_with_context(mi_rpc_batch, mi_rpc_ctx);
-
- ret = drm_intel_bo_map(mi_rpc_bo, false /* write enable */);
- igt_assert_eq(ret, 0);
- timestamp = ((uint32_t *)mi_rpc_bo->virtual)[1];
- drm_intel_bo_unmap(mi_rpc_bo);
+ memset(obj, 0, sizeof(obj));
+ obj[0].handle = gem_create(drm_fd, 4096);
+ obj[1].handle = gem_create(drm_fd, 4096);
+ obj[1].relocs_ptr = to_user_pointer(&reloc);
+ obj[1].relocation_count = 1;
- drm_intel_bo_unreference(mi_rpc_bo);
- intel_batchbuffer_free(mi_rpc_batch);
- drm_intel_gem_context_destroy(mi_rpc_ctx);
- drm_intel_bufmgr_destroy(bufmgr);
+ i = 0;
+ batch[i++] = 0x24 << 23 | (1 + r64b); /* SRM */
+ batch[i++] = 0x2358; /* RCS0 timestamp */
+ reloc.target_handle = obj[0].handle;
+ reloc.presumed_offset = obj[0].offset;
+ reloc.offset = i * sizeof(batch[0]);
+ reloc.delta = 0;
+ reloc.read_domains = I915_GEM_DOMAIN_RENDER;
+ reloc.write_domain = I915_GEM_DOMAIN_RENDER;
+ batch[i++] = reloc.delta;
+ if (r64b)
+ batch[i++] = 0;
+ batch[i] = MI_BATCH_BUFFER_END;
+ gem_write(drm_fd, obj[1].handle, 0, batch, sizeof(batch));
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(obj);
+ execbuf.buffer_count = 2;
+ execbuf.batch_len = 4096;
+ gem_execbuf(drm_fd, &execbuf);
+ gem_close(drm_fd, obj[1].handle);
+
+ gem_read(drm_fd, obj[0].handle, 0, &timestamp, sizeof(timestamp));
+ gem_close(drm_fd, obj[0].handle);
return timestamp;
}
@@ -1792,7 +1791,6 @@ test_oa_exponents(void)
uint32_t n_reports = 0;
uint32_t n_idle_reports = 0;
uint32_t n_reads = 0;
- uint32_t context_id;
uint64_t first_timestamp = 0;
bool check_first_timestamp = true;
struct drm_i915_perf_record_header *header;
@@ -1821,7 +1819,7 @@ test_oa_exponents(void)
* first timestamp as way to filter previously
* scheduled work that would have configured
* the OA unit at a different period. */
- first_timestamp = i915_get_one_gpu_timestamp(&context_id);
+ first_timestamp = i915_get_one_gpu_timestamp();
while (n_reads < ARRAY_SIZE(reads) &&
n_reports < ARRAY_SIZE(reports)) {
@@ -1947,8 +1945,8 @@ test_oa_exponents(void)
uint32_t *rpt = NULL, *last = NULL, *last_periodic = NULL;
igt_debug(" > More than 5%% error: avg_ts_delta = %"PRIu64", delta_delta = %"PRIu64", "
- "expected_delta = %"PRIu64", first_timestamp = %"PRIu64" ctx_id=%"PRIu32"\n",
- average_timestamp_delta, delta_delta, expected_timestamp_delta, first_timestamp, context_id);
+ "expected_delta = %"PRIu64", first_timestamp = %"PRIu64"\n",
+ average_timestamp_delta, delta_delta, expected_timestamp_delta, first_timestamp);
for (int i = 0; i < (n_reports - 1); i++) {
/* XXX: calculating with u32 arithmetic to account for overflow */
uint32_t u32_delta =