From patchwork Fri Dec 5 13:32:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 5443781 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4676E9F1D4 for ; Fri, 5 Dec 2014 13:28:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0A813201EC for ; Fri, 5 Dec 2014 13:28:45 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id AFA2C20155 for ; Fri, 5 Dec 2014 13:28:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 41A966E197; Fri, 5 Dec 2014 05:28:43 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTP id 817C46E197 for ; Fri, 5 Dec 2014 05:28:42 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP; 05 Dec 2014 05:26:59 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,522,1413270000"; d="scan'208";a="648871690" Received: from rosetta.fi.intel.com (HELO rosetta) ([10.237.72.102]) by orsmga002.jf.intel.com with ESMTP; 05 Dec 2014 05:28:40 -0800 Received: by rosetta (Postfix, from userid 1000) id 3150D80052; Fri, 5 Dec 2014 15:32:36 +0200 (EET) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Fri, 5 Dec 2014 15:32:30 +0200 Message-Id: <1417786350-27573-1-git-send-email-mika.kuoppala@intel.com> X-Mailer: git-send-email 1.9.1 Subject: [Intel-gfx] [PATCH] tests/gem_userptr_blits: add test to check blit aligns X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Copy a block into a destination object with varying base offset into the destination and source. Put guard area before and after the blit target to see that it didn't touch memory out of blit boundaries. References: https://bugs.freedesktop.org/show_bug.cgi?id=79053 Cc: Chris Wilson Signed-off-by: Mika Kuoppala --- tests/gem_userptr_blits.c | 275 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 268 insertions(+), 7 deletions(-) diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c index d641c12..b945b48 100644 --- a/tests/gem_userptr_blits.c +++ b/tests/gem_userptr_blits.c @@ -81,6 +81,7 @@ static uint32_t userptr_flags = LOCAL_I915_USERPTR_UNSYNCHRONIZED; #define HEIGHT 512 static uint32_t linear[WIDTH*HEIGHT]; +static uint32_t gen; static void gem_userptr_test_unsynchronized(void) { @@ -136,7 +137,7 @@ copy(int fd, uint32_t dst, uint32_t src, unsigned int error) batch[i++] = XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) + if (gen >= 8) batch[i - 1] |= 8; else batch[i - 1] |= 6; @@ -147,12 +148,12 @@ copy(int fd, uint32_t dst, uint32_t src, unsigned int error) batch[i++] = 0; /* dst x1,y1 */ batch[i++] = (HEIGHT << 16) | WIDTH; /* dst x2,y2 */ batch[i++] = 0; /* dst reloc */ - if (intel_gen(intel_get_drm_devid(fd)) >= 8) + if (gen >= 8) batch[i++] = 0; batch[i++] = 0; /* src x1,y1 */ batch[i++] = WIDTH*4; batch[i++] = 0; /* src reloc */ - if (intel_gen(intel_get_drm_devid(fd)) >= 8) + if (gen >= 8) batch[i++] = 0; batch[i++] = MI_BATCH_BUFFER_END; batch[i++] = MI_NOOP; @@ -170,7 +171,7 @@ copy(int fd, uint32_t dst, uint32_t src, unsigned int error) reloc[1].target_handle = src; reloc[1].delta = 0; reloc[1].offset = 7 * sizeof(batch[0]); - if (intel_gen(intel_get_drm_devid(fd)) >= 8) + if (gen >= 8) reloc[1].offset += sizeof(batch[0]); reloc[1].presumed_offset = 0; reloc[1].read_domains = I915_GEM_DOMAIN_RENDER; @@ -221,7 +222,7 @@ blit(int fd, uint32_t dst, uint32_t src, uint32_t *all_bo, int n_bo) batch[i++] = XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) + if (gen >= 8) batch[i - 1] |= 8; else batch[i - 1] |= 6; @@ -231,7 +232,7 @@ blit(int fd, uint32_t dst, uint32_t src, uint32_t *all_bo, int n_bo) batch[i++] = 0; /* dst x1,y1 */ batch[i++] = (HEIGHT << 16) | WIDTH; /* dst x2,y2 */ batch[i++] = 0; /* dst reloc */ - if (intel_gen(intel_get_drm_devid(fd)) >= 8) + if (gen >= 8) batch[i++] = 0; batch[i++] = 0; /* src x1,y1 */ batch[i++] = WIDTH*4; @@ -254,7 +255,7 @@ blit(int fd, uint32_t dst, uint32_t src, uint32_t *all_bo, int n_bo) reloc[1].target_handle = src; reloc[1].delta = 0; reloc[1].offset = 7 * sizeof(batch[0]); - if (intel_gen(intel_get_drm_devid(fd)) >= 8) + if (gen >= 8) reloc[1].offset += sizeof(batch[0]); reloc[1].presumed_offset = 0; reloc[1].read_domains = I915_GEM_DOMAIN_RENDER; @@ -972,6 +973,258 @@ static int test_coherency(int fd, int count) return 0; } +static uint32_t lb[12]; + +static void +copy_align(int fd, + uint32_t dst, uint32_t dst_offset, + uint32_t src, uint32_t src_offset, + uint32_t w, uint32_t h) +{ + uint32_t batch[12]; + struct drm_i915_gem_relocation_entry reloc[2]; + struct drm_i915_gem_exec_object2 obj[3]; + struct drm_i915_gem_execbuffer2 exec; + uint32_t handle; + int i=0; + + batch[i++] = XY_SRC_COPY_BLT_CMD | + XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB; + if (gen >= 8) + batch[i - 1] |= 8; + else + batch[i - 1] |= 6; + + batch[i++] = (3 << 24) | /* 32 bits */ + (0xcc << 16) | /* copy ROP */ + w * 4; + + batch[i++] = 0; /* dst, x1,y2 */ + batch[i++] = ((h) << 16) | (w); /* dst x2,y2 */ + batch[i++] = dst_offset * 4; /* dst reloc */ + if (gen >= 8) + batch[i++] = 0; + batch[i++] = 0; /* src x1,y1 */ + batch[i++] = w * 4; + + if ((w * 4) % 8) + igt_warn("src pitch NOT aligned to quad\n"); + + batch[i++] = src_offset * 4; /* src reloc */ + if (gen >= 8) + batch[i++] = 0; + batch[i++] = MI_BATCH_BUFFER_END; + batch[i++] = MI_NOOP; + + handle = gem_create(fd, 4096); + gem_write(fd, handle, 0, batch, sizeof(batch)); + + reloc[0].target_handle = dst; + reloc[0].delta = dst_offset * 4; + reloc[0].offset = 4 * sizeof(batch[0]); + reloc[0].presumed_offset = 0; + reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; + reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; + + reloc[1].target_handle = src; + reloc[1].delta = src_offset * 4; + reloc[1].offset = 7 * sizeof(batch[0]); + if (gen >= 8) + reloc[1].offset += sizeof(batch[0]); + reloc[1].presumed_offset = 0; + reloc[1].read_domains = I915_GEM_DOMAIN_RENDER; + reloc[1].write_domain = 0; + + memset(obj, 0, sizeof(obj)); + exec.buffer_count = 0; + obj[exec.buffer_count++].handle = dst; + if (src != dst) + obj[exec.buffer_count++].handle = src; + obj[exec.buffer_count].handle = handle; + obj[exec.buffer_count].relocation_count = 2; + obj[exec.buffer_count].relocs_ptr = (uintptr_t)reloc; + exec.buffer_count++; + exec.buffers_ptr = (uintptr_t)obj; + + exec.batch_start_offset = 0; + exec.batch_len = i * 4; + exec.DR1 = exec.DR4 = 0; + exec.num_cliprects = 0; + exec.cliprects_ptr = 0; + exec.flags = HAS_BLT_RING(intel_get_drm_devid(fd)) ? I915_EXEC_BLT : 0; + i915_execbuffer2_set_context_id(exec, 0); + exec.rsvd2 = 0; + + gem_execbuf(fd, &exec); + + memcpy(lb, batch, sizeof(batch)); + + gem_sync(fd, handle); + gem_close(fd, handle); +} + +static unsigned long verify_guard_area(uint32_t *p, + const int size, + const uint32_t sval) +{ + int i; + unsigned long count = 0; + + for (i = 0; i < size; i++) { + if (p[i] != i + sval) { + igt_warn("guard at index %d is 0x%08x, should be 0x%08x\n", + i, p[i], i + sval); + count++; + } + } + + return count; +} + +static unsigned long verify_destination_area(uint32_t *p, const int size, const int sval) +{ + int i; + unsigned long count = 0; + + for (i = 0; i < size; i++) { + if (p[i] != i + sval) { + igt_warn("dest data at index %d 0x%08x, should be 0x%08x\n", + i, p[i], i + sval); + count++; + } + } + + return count; +} + +static int +_test_destination_align(int fd, const uint32_t dst_align, + const uint32_t src_align, + const uint32_t w, + const uint32_t h, + const bool userptr) +{ + const uint32_t size = sizeof(linear) / 4; + const uint32_t guard_val = 0xdeadf00d; + uint32_t *p; + uint32_t h_dst; + uint32_t h_src; + int i, ret; + bool failed = false; + const int dwords = w*h; + + igt_assert(dwords < size); + + if (userptr) { + ret = posix_memalign((void **)&p, PAGE_SIZE, size * 4); + igt_assert(ret == 0 && p); + + ret = gem_userptr(fd, p, size * 4, 0, &h_dst); + igt_assert(ret == 0); + } else { + h_dst = gem_create(fd, size * 4); + p = linear; + } + + igt_assert(h_dst != 0); + + h_src = create_bo(fd, 0); + check_gpu(fd, h_src, 0); + + for (i = 0; i < size; i++) + p[i] = guard_val + i; + + if (!userptr) { + gem_write(fd, h_dst, 0, p, size * 4); + gem_read(fd, h_dst, 0, p, size * 4); + } + + igt_assert(verify_guard_area(p, size, guard_val) == 0); + + copy_align(fd, h_dst, dst_align, h_src, src_align, w, h); + + if (!userptr) + gem_read(fd, h_dst, 0, p, size * 4); + + if (verify_guard_area(p, dst_align, guard_val)) { + failed = true; + igt_warn("corrupted before blit target, align (%d:%d) dwords\n", + dst_align, src_align); + } + + if (verify_destination_area(p + dst_align, dwords, src_align)) { + failed = true; + igt_warn("blit src not copied correctly, align (%d:%d) dwords\n", + dst_align, src_align); + } + + if (verify_guard_area(p + dwords + dst_align, + size - dwords - dst_align, + guard_val + dwords + dst_align)) { + failed = true; + igt_warn("corrupted after blit target, align (%d:%d) dwords\n", + dst_align, src_align); + } + + gem_close(fd, h_src); + gem_close(fd, h_dst); + + if (userptr) + free(p); + + if (failed) { + igt_warn("failed batch:\n"); + for(i = 0; i < 12; i++) + igt_warn("0x%04x: 0x%08x\n", i, lb[i]); + } + + return failed ? 1 : 0; +} + +static bool assumed_fail(int dst_align, int w, int h) +{ + if (h == 1 || gen < 8) + return false; + + if ((w % 8) == 2 && h != 2) + return ((dst_align % 8) + (w % 8)) >= 4; + + return (dst_align % 8) + (w % 8) >= 8; +} + +static void test_destination_align(int fd, bool userptr, int dst_align, int src_align, int max_w, + int max_h) +{ + int i, j, w, h; + bool failed = false; + int res; + + for (i = 0; i <= src_align; i++) { + for (j = 0; j <= dst_align; j++) { + for (h = 2; h <= max_h; h += 2) { + for (w = 2; w <= max_w; w += 2) { + res = _test_destination_align(fd, j, i, w, h, userptr); + if (res) + igt_warn("BLT %s: from 0x%08x to 0x%08x %d:%d (%d) dwords\n", + res ? "FAIL" : "OK", + i * 4, j * 4, w, h, w * h); + + if (assumed_fail(j, w, h) != res) { + igt_warn("not expected dst blt result %s, %d:%d to 0x%08x, pitch 0x%08x\n", + res ? "FAIL" : "OK", w, h, j * 4, w * 4); + } + + if (res) + failed = true; + } + } + } + } + + igt_assert(failed == false); +} + static struct igt_eviction_test_ops fault_ops = { .create = create_userptr_bo, .flink = flink_userptr_bo, @@ -1248,6 +1501,8 @@ int main(int argc, char **argv) fd = drm_open_any(); igt_assert(fd >= 0); + gen = intel_gen(intel_get_drm_devid(fd)); + ret = has_userptr(fd); igt_skip_on_f(ret == 0, "No userptr support - %s (%d)\n", strerror(errno), ret); @@ -1457,5 +1712,11 @@ int main(int argc, char **argv) igt_subtest("access-control") test_access_control(fd); + igt_subtest("destination-bo-align") + test_destination_align(fd, false, 16, 0, 16, 16); + + igt_subtest("destination-userptr-align") + test_destination_align(fd, true, 16, 0, 16, 16); + igt_exit(); }