diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-02-16 14:42:04 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-02-18 09:46:02 +0000 |
commit | 3990dd87b60bf8092671cb3c536666936b460b0c (patch) | |
tree | 6cc74f7134f210057fe63fdd12a5a548d139fad0 | |
parent | 3b12d9e6dc115939ddd110c7a7f7ad319b731524 (diff) |
igt/gem_ctx_thrash: Combine context thrashing with a render test
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | tests/gem_ctx_thrash.c | 138 | ||||
-rw-r--r-- | tests/gem_wait.c | 7 |
2 files changed, 138 insertions, 7 deletions
diff --git a/tests/gem_ctx_thrash.c b/tests/gem_ctx_thrash.c index 7feedf6f0..129cf4572 100644 --- a/tests/gem_ctx_thrash.c +++ b/tests/gem_ctx_thrash.c @@ -63,7 +63,7 @@ static unsigned get_num_contexts(int fd) return count; } -static int has_engine(int fd, const struct intel_execution_engine *e) +static int has_engine(int fd, const struct intel_execution_engine *e, uint32_t ctx) { uint32_t bbe = MI_BATCH_BUFFER_END; struct drm_i915_gem_execbuffer2 execbuf; @@ -78,10 +78,137 @@ static int has_engine(int fd, const struct intel_execution_engine *e) execbuf.buffers_ptr = (uintptr_t)&exec; execbuf.buffer_count = 1; execbuf.flags = e->exec_id | e->flags; + execbuf.rsvd1 = ctx; ret = __gem_execbuf(fd, &execbuf); gem_close(fd, exec.handle); - return ret == 0; + return ret; +} + +static void single(const char *name, bool all_engines) +{ + struct drm_i915_gem_exec_object2 *obj; + struct drm_i915_gem_relocation_entry *reloc; + const struct intel_execution_engine *e; + unsigned engines[16]; + uint64_t size; + uint32_t *ctx, *map, scratch; + unsigned num_ctx; + int fd, gen, num_engines; +#define MAX_LOOP 16 + + fd = drm_open_driver_master(DRIVER_INTEL); + gen = intel_gen(intel_get_drm_devid(fd)); + num_ctx = get_num_contexts(fd); + + num_engines = 0; + if (all_engines) { + for (e = intel_execution_engines; e->name; e++) { + if (e->exec_id == 0) + continue; + + if (has_engine(fd, e, 0)) + continue; + + if (e->exec_id == I915_EXEC_BSD) { + int is_bsd2 = e->flags != 0; + if (gem_has_bsd2(fd) != is_bsd2) + continue; + } + + igt_require(has_engine(fd, e, 1) == -ENOENT); + + engines[num_engines++] = e->exec_id | e->flags; + if (num_engines == ARRAY_SIZE(engines)) + break; + } + } else + engines[num_engines++] = 0; + + size = ALIGN(num_ctx * sizeof(uint32_t), 4096); + scratch = gem_create(fd, ALIGN(num_ctx * sizeof(uint32_t), 4096)); + gem_set_caching(fd, scratch, I915_CACHING_CACHED); + obj = calloc(num_ctx, 2 * sizeof(*obj)); + reloc = calloc(num_ctx, sizeof(*reloc)); + + ctx = malloc(num_ctx * sizeof(uint32_t)); + igt_assert(ctx); + for (unsigned n = 0; n < num_ctx; n++) { + ctx[n] = gem_context_create(fd); + obj[2*n + 0].handle = scratch; + + reloc[n].target_handle = scratch; + reloc[n].presumed_offset = 0; + reloc[n].offset = sizeof(uint32_t); + reloc[n].delta = n * sizeof(uint32_t); + reloc[n].read_domains = I915_GEM_DOMAIN_INSTRUCTION; + reloc[n].write_domain = 0; /* lies! */ + if (gen >= 4 && gen < 8) + reloc[n].offset += sizeof(uint32_t); + + obj[2*n + 1].relocs_ptr = (uintptr_t)&reloc[n]; + obj[2*n + 1].relocation_count = 1; + } + + map = gem_mmap__cpu(fd, scratch, 0, size, PROT_WRITE); + for (unsigned loop = 1; loop <= MAX_LOOP; loop <<= 1) { + unsigned count = loop * num_ctx; + uint32_t *all; + + all = malloc(count * sizeof(uint32_t)); + for (unsigned n = 0; n < count; n++) + all[n] = ctx[n % num_ctx]; + igt_permute_array(all, count, xchg_int); + for (unsigned n = 0; n < count; n++) { + struct drm_i915_gem_execbuffer2 execbuf; + unsigned r = n % num_ctx; + uint64_t offset = reloc[r].presumed_offset + reloc[r].delta; + uint32_t handle = gem_create(fd, 4096); + uint32_t buf[16]; + int i; + + buf[i = 0] = MI_STORE_DWORD_IMM; + if (gen >= 8) { + buf[++i] = offset; + buf[++i] = offset >> 32; + } else if (gen >= 4) { + if (gen < 6) + buf[i] |= 1 << 22; + buf[++i] = 0; + buf[++i] = offset; + } else { + buf[i]--; + buf[++i] = offset; + } + buf[++i] = all[n]; + buf[++i] = MI_BATCH_BUFFER_END; + gem_write(fd, handle, 0, buf, sizeof(buf)); + obj[2*r + 1].handle = handle; + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = (uintptr_t)&obj[2*r]; + execbuf.buffer_count = 2; + execbuf.flags = engines[n % num_engines]; + execbuf.rsvd1 = all[n]; + gem_execbuf(fd, &execbuf); + gem_close(fd, handle); + } + + /* Note we lied about the write-domain when writing from the + * GPU (in order to avoid inter-ring synchronisation), so now + * we have to force the synchronisation here. + */ + gem_set_domain(fd, scratch, + I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); + for (unsigned n = count - num_ctx; n < count; n++) + igt_assert_eq(map[n % num_ctx], all[n]); + free(all); + igt_progress(name, loop, MAX_LOOP); + } + munmap(map, size); + + free(ctx); + close(fd); } static void processes(void) @@ -102,7 +229,7 @@ static void processes(void) if (e->exec_id == 0) continue; - if (!has_engine(fd, e)) + if (has_engine(fd, e, 0)) continue; if (e->exec_id == I915_EXEC_BSD) { @@ -235,6 +362,11 @@ igt_main { igt_skip_on_simulation(); + igt_subtest("single") + single("single", false); + igt_subtest("engines") + single("engines", true); + igt_subtest("processes") processes(); diff --git a/tests/gem_wait.c b/tests/gem_wait.c index e1c174b3d..ecf0dcf3d 100644 --- a/tests/gem_wait.c +++ b/tests/gem_wait.c @@ -155,7 +155,7 @@ static void render_timeout(int fd) igt_assert_lt(iter, 1000000); - igt_info("%d iters is enough work\n", iter); + igt_debug("%d iters is enough work\n", iter); gem_quiescent_gpu(fd); if (do_signals) igt_fork_signal_helper(); @@ -174,9 +174,8 @@ static void render_timeout(int fd) igt_assert_neq(timeout, 0); if (timeout == (ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC)) igt_info("Buffer was already done!\n"); - else { - igt_info("Finished with %" PRIu64 " time remaining\n", timeout); - } + else + igt_info("Finished with %fs remaining\n", timeout*1e-9); /* check that polling with timeout=0 works. */ timeout = 0; |