From patchwork Tue Dec 10 09:36:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: oscar.mateo@intel.com X-Patchwork-Id: 3316921 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 5DACF9F37C for ; Tue, 10 Dec 2013 09:42:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BBC8020220 for ; Tue, 10 Dec 2013 09:42:21 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 3DED720173 for ; Tue, 10 Dec 2013 09:42:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B6642FB215; Tue, 10 Dec 2013 01:42:18 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id E16DAFB215 for ; Tue, 10 Dec 2013 01:42:14 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 10 Dec 2013 01:42:14 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.93,864,1378882800"; d="scan'208";a="447553315" Received: from omateolo-haswell.isw.intel.com ([10.102.226.173]) by fmsmga002.fm.intel.com with ESMTP; 10 Dec 2013 01:42:13 -0800 From: oscar.mateo@intel.com To: intel-gfx@lists.freedesktop.org Date: Tue, 10 Dec 2013 09:36:23 +0000 Message-Id: <1386668183-19514-3-git-send-email-oscar.mateo@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1386668183-19514-1-git-send-email-oscar.mateo@intel.com> References: <1386668183-19514-1-git-send-email-oscar.mateo@intel.com> MIME-Version: 1.0 Cc: benjamin.widawsky@intel.com Subject: [Intel-gfx] =?utf-8?q?=5BPATCH_3/3=5D_tests/gem=5Fppgtt=3A_New_Fu?= =?utf-8?q?ll_PPGTT_set_of_tests?= X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 From: Oscar Mateo These tests cover some tricky corner cases found during the True-and-only Full PPGTT feature development. v2: Add pthread requirement to Makefile. v3: Added new "pinned" testcase. v4: Require Full PPGTT. Signed-off-by: Oscar Mateo --- tests/.gitignore | 1 + tests/Makefile.am | 1 + tests/Makefile.sources | 1 + tests/gem_full_ppgtt.c | 327 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 330 insertions(+) create mode 100644 tests/gem_full_ppgtt.c diff --git a/tests/.gitignore b/tests/.gitignore index 8a00364..a77b544 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -55,6 +55,7 @@ gem_partial_pwrite_pread gem_persistent_relocs gem_pin gem_pipe_control_store_loop +gem_full_ppgtt gem_pread gem_pread_after_blit gem_pwrite diff --git a/tests/Makefile.am b/tests/Makefile.am index b8cddd5..02e0796 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -32,6 +32,7 @@ LDADD = ../lib/libintel_tools.la $(PCIACCESS_LIBS) $(DRM_LIBS) LDADD += $(CAIRO_LIBS) $(LIBUDEV_LIBS) $(GLIB_LIBS) AM_CFLAGS += $(CAIRO_CFLAGS) $(LIBUDEV_CFLAGS) $(GLIB_CFLAGS) +gem_full_ppgtt_LDADD = $(LDADD) -lpthread gem_close_race_LDADD = $(LDADD) -lpthread gem_fence_thrash_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS) gem_fence_thrash_LDADD = $(LDADD) -lpthread diff --git a/tests/Makefile.sources b/tests/Makefile.sources index ca2b58c..c3c1852 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -36,6 +36,7 @@ TESTS_progs_M = \ gem_mmap_gtt \ gem_partial_pwrite_pread \ gem_persistent_relocs \ + gem_full_ppgtt \ gem_pread \ gem_pread_after_blit \ gem_pwrite \ diff --git a/tests/gem_full_ppgtt.c b/tests/gem_full_ppgtt.c new file mode 100644 index 0000000..f3c8576 --- /dev/null +++ b/tests/gem_full_ppgtt.c @@ -0,0 +1,327 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Oscar Mateo + * + */ + +/* + * This test covers some tricky corner cases found during + * True PPGTT development + */ + +#include +#include "rendercopy.h" +#include "igt_debugfs.h" + +#define WIDTH 512 +#define STRIDE (WIDTH*4) +#define HEIGHT 512 +#define SIZE (HEIGHT*STRIDE) + +/* options */ +int option_num_threads = 10; +int option_num_iter = 200; +bool option_tiled = false; + +/* globals */ +int global_fd; +int devid; +render_copyfunc_t rendercopy; + +static void init_buffer(drm_intel_bufmgr *bufmgr, + struct scratch_buf *buf, bool special) +{ + uint32_t tiling; + unsigned long pitch = STRIDE; + + if (option_tiled) + { + tiling = I915_TILING_X; + buf->bo = drm_intel_bo_alloc_tiled(bufmgr, "", + WIDTH, HEIGHT, 4, + &tiling, &pitch, 0); + } + else + { + tiling = I915_TILING_NONE; + buf->bo = drm_intel_bo_alloc(bufmgr, "", + special? 16*SIZE : SIZE, 4096); + } + + igt_assert(buf->bo); + buf->size = SIZE; + buf->tiling = tiling; + buf->stride = pitch; +} + +static bool check_buffer_contents(struct scratch_buf *buf, uint32_t val) +{ + uint32_t *ptr; + int i; + drm_intel_bo *bo = buf->bo; + + if (buf->tiling == I915_TILING_NONE) + do_or_die(drm_intel_bo_map(bo, 0)); + else + do_or_die(drm_intel_gem_bo_map_gtt(bo)); + + ptr = bo->virtual; + for (i = 0; i < WIDTH*HEIGHT; i++) { + if (ptr[i] != val) { + printf("Expected 0x%08x, found 0x%08x at offset 0x%08x\n", + val, ptr[i], i * 4); + return false; + } + val++; + } + + if (buf->tiling == I915_TILING_NONE) + drm_intel_bo_unmap(bo); + else + drm_intel_gem_bo_unmap_gtt(bo); + + return true; +} + +static void init_buffer_contents(struct scratch_buf *buf, uint32_t val) +{ + uint32_t *ptr; + int i; + drm_intel_bo *bo = buf->bo; + + if (buf->tiling == I915_TILING_NONE) + do_or_die(drm_intel_bo_map(bo, 1)); + else + do_or_die(drm_intel_gem_bo_map_gtt(bo)); + + ptr = bo->virtual; + for (i = 0; i < WIDTH*HEIGHT; i++) + ptr[i] = val++; + + if (buf->tiling == I915_TILING_NONE) + drm_intel_bo_unmap(bo); + else + drm_intel_gem_bo_unmap_gtt(bo); +} + +static void run(void) +{ + int fd; + drm_intel_bufmgr *bufmgr; + struct intel_batchbuffer *batch; + struct scratch_buf src, dst; + int i; + uint32_t start = 0; + + /* Initialize */ + igt_assert((fd = drm_open_any()) >= 0); + bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); + batch = intel_batchbuffer_alloc(bufmgr, devid); + init_buffer(bufmgr, &src, false); + init_buffer_contents(&src, start); + init_buffer(bufmgr, &dst, false); + + /* Work */ + for (i = 0; i < option_num_iter; i++) + rendercopy(batch, NULL, &src, 0, 0, WIDTH, HEIGHT, &dst, 0, 0); + igt_assert(check_buffer_contents(&dst, start)); + + /* Cleanup */ + drm_intel_bo_unreference(src.bo); + drm_intel_bo_unreference(dst.bo); + intel_batchbuffer_free(batch); + drm_intel_bufmgr_destroy(bufmgr); + close(fd); +} + +static void *work_multiple(void *arg) +{ + run(); + + pthread_exit(NULL); +} + +static void run_multiple(void) +{ + int i = 0; + void *retval; + pthread_t *threads = calloc(option_num_threads, sizeof(*threads)); + + for (i = 0; i < option_num_threads; i++) + pthread_create(&threads[i], NULL, work_multiple, &i); + + for (i = 0; i < option_num_threads; i++) + igt_assert(pthread_join(threads[i], &retval) == 0); + + free(threads); +} + +static void run_with_namedbo(uint32_t name) +{ + int fd; + drm_intel_bufmgr *bufmgr; + struct intel_batchbuffer *batch; + struct scratch_buf src, dst; + uint32_t start = 0; + int i; + + /* Initialize */ + igt_assert((fd = drm_open_any()) >= 0); + bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); + batch = intel_batchbuffer_alloc(bufmgr, devid); + init_buffer(bufmgr, &dst, false); + + /* Recover src */ + src.size = dst.size; + src.tiling = dst.tiling; + src.stride = dst.stride; + src.bo = drm_intel_bo_gem_create_from_name(bufmgr, "", name); + igt_assert(src.bo); + igt_assert(check_buffer_contents(&src, start)); + + /* Work */ + for (i = 0; i < option_num_iter; i++) + rendercopy(batch, NULL, &src, 0, 0, WIDTH, HEIGHT, &dst, 0, 0); + igt_assert(check_buffer_contents(&dst, start)); + + /* Cleanup */ + drm_intel_bo_unreference(src.bo); + drm_intel_bo_unreference(dst.bo); + intel_batchbuffer_free(batch); + drm_intel_bufmgr_destroy(bufmgr); + close(fd); +} + +static void *work_flinked(void *arg) +{ + uint32_t *name = (uint32_t *)arg; + + run_with_namedbo(*name); + + pthread_exit(NULL); +} + +static void run_flinked(void) +{ + drm_intel_bufmgr *bufmgr; + struct scratch_buf src; + uint32_t name; + uint32_t start = 0; + int i; + void *retval; + pthread_t *threads = calloc(option_num_threads, sizeof(*threads)); + + bufmgr = drm_intel_bufmgr_gem_init(global_fd, 4096); + init_buffer(bufmgr, &src, false); + init_buffer_contents(&src, start); + do_or_die(drm_intel_bo_flink(src.bo, &name)); + + for (i = 0; i < option_num_threads; i++) + pthread_create(&threads[i], NULL, work_flinked, &name); + + for (i = 0; i < option_num_threads; i++) + igt_assert(pthread_join(threads[i], &retval) == 0); + + free(threads); + drm_intel_bo_unreference(src.bo); + drm_intel_bufmgr_destroy(bufmgr); +} + +static void run_pinned(void) +{ + drm_intel_bufmgr *bufmgr; + struct scratch_buf src; + uint32_t name; + uint32_t val = 0; + + bufmgr = drm_intel_bufmgr_gem_init(global_fd, 4096); + init_buffer(bufmgr, &src, true); + init_buffer_contents(&src, val); + do_or_die(drm_intel_bo_flink(src.bo, &name)); + + /* Pin to GGTT */ + drm_intel_bo_pin(src.bo, 4096); + + /* Use the source bo in a different context (pin to a PPGTT) */ + run_with_namedbo(name); + + /* Make sure we switch the context in every ring so that the + * previous context finally dies */ + gem_quiescent_gpu(global_fd); + igt_drop_caches_set(DROP_RETIRE); + + drm_intel_bo_unpin(src.bo); + drm_intel_bo_unreference(src.bo); + drm_intel_bufmgr_destroy(bufmgr); +} + +static void do_tests(bool use_tiled, const char *suffix) +{ + option_tiled = use_tiled; + + /* One context, rendercopying in a loop */ + igt_subtest_f("single-ctx-%s", suffix) + run(); + + /* Multiple threads, each with its own context + * rendercopying in a loop */ + igt_subtest_f("multiple-ctx-%s", suffix) { + run_multiple(); + } + + /* Multiple threads, each with its own context + * rendercopying in a loop. The src bo is shared + * among them via flink */ + igt_subtest_f("multiple-ctx-flink-%s", suffix) { + run_flinked(); + } + + /* Pin object to GGTT, create a context, bind the + * object to the new PPGTT and then clean the context */ + igt_subtest_f("single-ctx-pinned-%s", suffix) { + run_pinned(); + } +} + +igt_main +{ + igt_fixture { + global_fd = drm_open_any(); + igt_require_f(gem_uses_full_ppgtt(global_fd), "Requires Full PPGTT\n"); + devid = intel_get_drm_devid(global_fd); + rendercopy = get_render_copyfunc(devid); + igt_require(rendercopy); + if (igt_run_in_simulation()) { + option_num_threads = 3; + option_num_iter = 10; + } + } + + do_tests(false, "linear"); + do_tests(true, "tiled"); + + igt_fixture + close(global_fd); +} +