static void store_dword_loop(int fd) { int i; int num_rings = gem_get_num_rings(fd); srandom(0xdeadbeef); for (i = 0; i < SLOW_QUICK(0x100000, 10); i++) { int ring = random() % num_rings + 1; if (ring == I915_EXEC_RENDER) { BEGIN_BATCH(4, 1); OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE); OUT_BATCH(0xffffffff); /* compare dword */ OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(MI_NOOP); ADVANCE_BATCH(); } else { BEGIN_BATCH(4, 1); OUT_BATCH(MI_FLUSH_DW | 1); OUT_BATCH(0); /* reserved */ OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(MI_NOOP | (1<<22) | (0xf)); ADVANCE_BATCH(); } intel_batchbuffer_flush_on_ring(batch, ring); } drm_intel_bo_map(target_buffer, 0); // map to force waiting on rendering drm_intel_bo_unmap(target_buffer); }
int main(int argc, char **argv) { uint32_t batch[2] = {MI_BATCH_BUFFER_END}; uint32_t handle; int fd, i; fd = drm_open_any(); handle = gem_create(fd, 4096); gem_write(fd, handle, 0, batch, sizeof(batch)); do_or_die(exec(fd, handle, NORMAL)); fail(exec(fd, handle, BROKEN)); if (exec(fd, handle, USE_LUT)) return 77; do_or_die(exec(fd, handle, USE_LUT)); fail(exec(fd, handle, USE_LUT | BROKEN)); for (i = 2; i <= SLOW_QUICK(65536, 8); i *= 2) { if (many_exec(fd, handle, i+1, i+1, NORMAL) == -1 && errno == ENOSPC) break; pass(many_exec(fd, handle, i-1, i-1, NORMAL)); pass(many_exec(fd, handle, i-1, i, NORMAL)); pass(many_exec(fd, handle, i-1, i+1, NORMAL)); pass(many_exec(fd, handle, i, i-1, NORMAL)); pass(many_exec(fd, handle, i, i, NORMAL)); pass(many_exec(fd, handle, i, i+1, NORMAL)); pass(many_exec(fd, handle, i+1, i-1, NORMAL)); pass(many_exec(fd, handle, i+1, i, NORMAL)); pass(many_exec(fd, handle, i+1, i+1, NORMAL)); fail(many_exec(fd, handle, i-1, i-1, NORMAL | BROKEN)); fail(many_exec(fd, handle, i-1, i, NORMAL | BROKEN)); fail(many_exec(fd, handle, i-1, i+1, NORMAL | BROKEN)); fail(many_exec(fd, handle, i, i-1, NORMAL | BROKEN)); fail(many_exec(fd, handle, i, i, NORMAL | BROKEN)); fail(many_exec(fd, handle, i, i+1, NORMAL | BROKEN)); fail(many_exec(fd, handle, i+1, i-1, NORMAL | BROKEN)); fail(many_exec(fd, handle, i+1, i, NORMAL | BROKEN)); fail(many_exec(fd, handle, i+1, i+1, NORMAL | BROKEN)); pass(many_exec(fd, handle, i-1, i-1, USE_LUT)); pass(many_exec(fd, handle, i-1, i, USE_LUT)); pass(many_exec(fd, handle, i-1, i+1, USE_LUT)); pass(many_exec(fd, handle, i, i-1, USE_LUT)); pass(many_exec(fd, handle, i, i, USE_LUT)); pass(many_exec(fd, handle, i, i+1, USE_LUT)); pass(many_exec(fd, handle, i+1, i-1, USE_LUT)); pass(many_exec(fd, handle, i+1, i, USE_LUT)); pass(many_exec(fd, handle, i+1, i+1, USE_LUT)); fail(many_exec(fd, handle, i-1, i-1, USE_LUT | BROKEN)); fail(many_exec(fd, handle, i-1, i, USE_LUT | BROKEN)); fail(many_exec(fd, handle, i-1, i+1, USE_LUT | BROKEN)); fail(many_exec(fd, handle, i, i-1, USE_LUT | BROKEN)); fail(many_exec(fd, handle, i, i, USE_LUT | BROKEN)); fail(many_exec(fd, handle, i, i+1, USE_LUT | BROKEN)); fail(many_exec(fd, handle, i+1, i-1, USE_LUT | BROKEN)); fail(many_exec(fd, handle, i+1, i, USE_LUT | BROKEN)); fail(many_exec(fd, handle, i+1, i+1, USE_LUT | BROKEN)); } return 0; }
static void store_dword_loop(int fd, int ring, int count, int divider) { int i, val = 0; struct drm_i915_gem_execbuffer2 execbuf; struct drm_i915_gem_exec_object2 obj[2]; struct drm_i915_gem_relocation_entry reloc[divider]; uint32_t handle[divider]; uint32_t *batch[divider]; uint32_t *target; int gen = intel_gen(devid); memset(obj, 0, sizeof(obj)); obj[0].handle = gem_create(fd, 4096); target = mmap_coherent(fd, obj[0].handle, 4096); memset(reloc, 0, sizeof(reloc)); for (i = 0; i < divider; i++) { uint32_t *b; handle[i] = gem_create(fd, 4096); batch[i] = mmap_coherent(fd, handle[i], 4096); gem_set_domain(fd, handle[i], coherent_domain, coherent_domain); b = batch[i]; *b++ = MI_STORE_DWORD_IMM; *b++ = 0; *b++ = 0; *b++ = 0; *b++ = MI_BATCH_BUFFER_END; reloc[i].target_handle = obj[0].handle; reloc[i].offset = 4; if (gen < 8) reloc[i].offset += 4; reloc[i].read_domains = I915_GEM_DOMAIN_INSTRUCTION; reloc[i].write_domain = I915_GEM_DOMAIN_INSTRUCTION; obj[1].relocation_count = 1; } memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffers_ptr = (uintptr_t)obj; execbuf.buffer_count = 2; execbuf.flags = ring; igt_info("running storedw loop on render with stall every %i batch\n", divider); for (i = 0; i < SLOW_QUICK(0x2000, 0x10); i++) { int j = i % divider; gem_set_domain(fd, handle[j], coherent_domain, coherent_domain); batch[j][3] = val; obj[1].handle = handle[j]; obj[1].relocs_ptr = (uintptr_t)&reloc[j]; gem_execbuf(fd, &execbuf); if (j == 0) { gem_set_domain(fd, obj[0].handle, coherent_domain, 0); igt_assert_f(*target == val, "%d: value mismatch: stored 0x%08x, expected 0x%08x\n", i, *target, val); } val++; } gem_set_domain(fd, obj[0].handle, coherent_domain, 0); igt_info("completed %d writes successfully, current value: 0x%08x\n", i, target[0]); munmap(target, 4096); gem_close(fd, obj[0].handle); for (i = 0; i < divider; ++i) { munmap(batch[i], 4096); gem_close(fd, handle[i]); } }