diff options
author | Yi Sun <yi.sun@intel.com> | 2015-03-05 10:27:31 +0800 |
---|---|---|
committer | Yi Sun <yi.sun@intel.com> | 2015-03-05 10:27:31 +0800 |
commit | 744f273c2f0069cdb49cb9ca007108aa36f832d3 (patch) | |
tree | 9fc898d018e44e2011f23cfc7179a211e22d5e84 | |
parent | 33ce0061d1856ede097e5855d4732bb518dfbb7c (diff) |
Remove all test cases.
Signed-off-by: Yi Sun <yi.sun@intel.com>
162 files changed, 0 insertions, 43255 deletions
diff --git a/tests/Android.mk b/tests/Android.mk deleted file mode 100644 index 814b8462..00000000 --- a/tests/Android.mk +++ /dev/null @@ -1,88 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(LOCAL_PATH)/Makefile.sources - -#================# -# each igt test is a separate executable. define a function to build one of these tests -define add_test - include $(CLEAR_VARS) - - # specific to this test - LOCAL_SRC_FILES := $1.c - LOCAL_MODULE := $1 - - # common to all tests - LOCAL_CFLAGS += ${IGT_LOCAL_CFLAGS} - LOCAL_C_INCLUDES = ${IGT_LOCAL_C_INCLUDES} - LOCAL_STATIC_LIBRARIES := ${IGT_LOCAL_STATIC_LIBRARIES} - LOCAL_SHARED_LIBRARIES := ${IGT_LOCAL_SHARED_LIBRARIES} - - LOCAL_MODULE_TAGS := optional - # ask linker to define a specific symbol; we use this to identify IGT tests - LOCAL_LDFLAGS := -Wl,--defsym=$2=0 - LOCAL_MODULE_PATH := $(ANDROID_PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR)/intel/validation/core/igt - - include $(BUILD_EXECUTABLE) -endef - - -# some tests still do not build under android -skip_tests_list := -skip_tests_list += testdisplay # needs glib.h -skip_tests_list += pm_rpm - -# set local compilation flags for IGT tests -IGT_LOCAL_CFLAGS += -DHAVE_STRUCT_SYSINFO_TOTALRAM -DANDROID -UNDEBUG -IGT_LOCAL_CFLAGS += -include "check-ndebug.h" -std=gnu99 -# FIXME: drop once Bionic correctly annotates "noreturn" on pthread_exit -IGT_LOCAL_CFLAGS += -Wno-error=return-type -# Excessive complaining for established cases. Rely on the Linux version warnings. -IGT_LOCAL_CFLAGS += -Wno-sign-compare - -# set local includes -IGT_LOCAL_C_INCLUDES = $(LOCAL_PATH)/../lib -IGT_LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/PRIVATE/drm/include/drm - -# set local libraries -IGT_LOCAL_STATIC_LIBRARIES := libintel_gpu_tools -IGT_LOCAL_SHARED_LIBRARIES := libpciaccess libdrm libdrm_intel - -# handle cairo requirements if it is enabled -ifeq ("${ANDROID_HAS_CAIRO}", "1") - IGT_LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/cairo-1.12.16/src - IGT_LOCAL_SHARED_LIBRARIES += libcairo - IGT_LOCAL_CFLAGS += -DANDROID_HAS_CAIRO=1 -else -# the following tests depend on cairo, so skip them - skip_tests_list += \ - kms_3d \ - kms_plane \ - kms_addfb \ - kms_cursor_crc \ - kms_flip \ - kms_flip_tiling \ - kms_pipe_crc_basic \ - kms_psr_sink_crc \ - kms_fbc_crc \ - kms_setmode \ - kms_sink_crc_basic \ - gem_render_copy \ - pm_lpsp \ - kms_fence_pin_leak \ - kms_mmio_vs_cs_flip \ - kms_render \ - kms_universal_plane \ - kms_rotation_crc \ - kms_force_connector \ - kms_flip_event_leak \ - kms_pwrite_crc - IGT_LOCAL_CFLAGS += -DANDROID_HAS_CAIRO=0 -endif - -# create two test lists, one for simple single tests, one for tests that have subtests -tests_list := $(filter-out $(skip_tests_list),$(TESTS_progs) $(HANG) $(TESTS_testsuite)) -tests_list_M := $(filter-out $(skip_tests_list),$(TESTS_progs_M)) - -$(foreach item,$(tests_list),$(eval $(call add_test,$(item),"IGT_SINGLE_TEST"))) -$(foreach item,$(tests_list_M),$(eval $(call add_test,$(item),"IGT_MULTI_TEST"))) - diff --git a/tests/ZZ_check_dmesg b/tests/ZZ_check_dmesg deleted file mode 100755 index e28ba35f..00000000 --- a/tests/ZZ_check_dmesg +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -if dmesg | grep '\*ERROR\*' > /dev/null ; then - echo "DRM_ERROR dirt in dmesg" - exit 1 -fi - -if dmesg | grep -- '------\[ cut here \]----' > /dev/null ; then - echo "found a backtrace in dmesg" - exit 1 -fi diff --git a/tests/check_drm_clients b/tests/check_drm_clients deleted file mode 100755 index eb12416a..00000000 --- a/tests/check_drm_clients +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -exit 0 diff --git a/tests/core_get_client_auth.c b/tests/core_get_client_auth.c deleted file mode 100644 index bbfdddf4..00000000 --- a/tests/core_get_client_auth.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright © 2012,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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - * Based upon code from libva/va/drm/va_drm_auth.c: - */ - -/* - * Testcase: Check that the hollowed-out get_client ioctl still works for libva - * - * Oh dear, libva, why do you do such funny things? - */ - -#define _GNU_SOURCE -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#ifdef __linux__ -# include <sys/syscall.h> -#else -# include <pthread.h> -#endif - -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -/* Checks whether the thread id is the current thread */ -static bool -is_local_tid(pid_t tid) -{ -#ifndef __linux__ - return pthread_self() == tid; -#elif !defined(ANDROID) - /* On Linux systems, drmGetClient() would return the thread ID - instead of the actual process ID */ - return syscall(SYS_gettid) == tid; -#else - return gettid() == tid; -#endif -} - - -static bool check_auth(int fd) -{ - pid_t client_pid; - int i, auth, pid, uid; - unsigned long magic, iocs; - bool is_authenticated = false; - - client_pid = getpid(); - for (i = 0; !is_authenticated; i++) { - if (drmGetClient(fd, i, &auth, &pid, &uid, &magic, &iocs) != 0) - break; - is_authenticated = auth && (pid == client_pid || is_local_tid(pid)); - } - return is_authenticated; -} - - -igt_main -{ - /* root (which we run igt as) should always be authenticated */ - igt_subtest("simple") { - int fd = drm_open_any(); - - igt_assert(check_auth(fd) == true); - - close(fd); - } - - igt_subtest("master-drop") { - int fd = drm_open_any(); - int fd2 = drm_open_any(); - - igt_assert(check_auth(fd2) == true); - - close(fd); - - igt_assert(check_auth(fd2) == true); - - close(fd2); - } -} diff --git a/tests/core_getclient.c b/tests/core_getclient.c deleted file mode 100644 index 7598e0ff..00000000 --- a/tests/core_getclient.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright © 2007 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: - * Eric Anholt <eric@anholt.net> - * - */ - -#include <limits.h> -#include <sys/ioctl.h> -#include <stdlib.h> -#include <errno.h> - -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Tests the DRM_IOCTL_GET_CLIENT ioctl."); - -igt_simple_main -{ - int fd, ret; - drm_client_t client; - - fd = drm_open_any(); - - /* Look for client index 0. This should exist whether we're operating - * on an otherwise unused drm device, or the X Server is running on - * the device. - */ - client.idx = 0; - ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client); - igt_assert(ret == 0); - - /* Look for some absurd client index and make sure it's invalid. - * The DRM drivers currently always return data, so the user has - * no real way to detect when the list has terminated. That's bad, - * and this test is XFAIL as a result. - */ - client.idx = 0x7fffffff; - ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client); - igt_assert(ret == -1 && errno == EINVAL); - - close(fd); -} diff --git a/tests/core_getstats.c b/tests/core_getstats.c deleted file mode 100644 index 52a2d204..00000000 --- a/tests/core_getstats.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright © 2007 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: - * Eric Anholt <eric@anholt.net> - * - */ - -#include <limits.h> -#include <sys/ioctl.h> -#include <sys/types.h> - -#include <drm.h> - -#include "igt_core.h" -#include "drmtest.h" - -/** - * Checks DRM_IOCTL_GET_STATS. - * - * I don't care too much about the actual contents, just that the kernel - * doesn't crash. - */ - -IGT_TEST_DESCRIPTION("Tests the DRM_IOCTL_GET_STATS ioctl."); - -igt_simple_main -{ - int fd, ret; - drm_stats_t stats; - - fd = drm_open_any(); - - ret = ioctl(fd, DRM_IOCTL_GET_STATS, &stats); - igt_assert(ret == 0); - - close(fd); -} diff --git a/tests/core_getversion.c b/tests/core_getversion.c deleted file mode 100644 index 30132e44..00000000 --- a/tests/core_getversion.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2007 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: - * Eric Anholt <eric@anholt.net> - * - */ - -#include <string.h> -#include <sys/ioctl.h> -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Tests the DRM_IOCTL_GET_VERSION ioctl and libdrm's " - "drmGetVersion() interface to it."); - -igt_simple_main -{ - int fd; - drmVersionPtr v; - - fd = drm_open_any(); - v = drmGetVersion(fd); - igt_assert(strlen(v->name) != 0); - igt_assert(strlen(v->date) != 0); - igt_assert(strlen(v->desc) != 0); - igt_assert(v->version_major >= 1); - drmFree(v); - close(fd); -} diff --git a/tests/ddx_intel_after_fbdev b/tests/ddx_intel_after_fbdev deleted file mode 100755 index bcd2c29d..00000000 --- a/tests/ddx_intel_after_fbdev +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -# -# Testcase: Load Intel DDX after fbdev was loaded -# - -whoami | grep -q root || { - echo "ERROR: not running as root" - exit 1 -} - -# no other X session should be running -find /tmp/ -name .X*lock 2>/dev/null | grep -q X && { - echo "ERROR: X session already running" - exit 1 -} - -TMPDIR=$(mktemp -d /tmp/igt.XXXX) || { - echo "ERROR: Failed to create temp dir" - exit 1 -} - -cat > $TMPDIR/xorg.conf.fbdev << EOF -Section "Device" - Driver "fbdev" - Identifier "Device[fbdev]" -EndSection -EOF - -cat > $TMPDIR/xorg.conf.intel << EOF -Section "Device" - Driver "intel" - Identifier "Device[intel]" -EndSection -EOF - -# log before fbdev -dmesg -c > $TMPDIR/dmesg.1.before.fbdev -cp /var/log/Xorg.0.log $TMPDIR/Xorg.0.log.1.before.fbdev - -# run fbdev -xinit -- /usr/bin/X -config $TMPDIR/xorg.conf.fbdev & -sleep 5 -if [ -f `which intel_reg_dumper` ]; then -`which intel_reg_dumper` > $TMPDIR/intel_reg_dumped.1.fbdev -fi -killall X - -# log after fbdev & before intel -dmesg -c > $TMPDIR/dmesg.2.after.fbdev.before.intel -cp /var/log/Xorg.0.log $TMPDIR/Xorg.0.log.2.after.fbdev.before.intel - -sleep 5 - -# run intel -xinit -- /usr/bin/X -config $TMPDIR/xorg.conf.intel & -sleep 5 -if [ -f `which intel_reg_dumper` ]; then -`which intel_reg_dumper` > $TMPDIR/intel_reg_dumped.2.intel -fi -killall X - -# log after intel -dmesg -c > $TMPDIR/dmesg.3.after.intel -cp /var/log/Xorg.0.log $TMPDIR/Xorg.0.log.3.after.intel - -cp $0 $TMPDIR/ - -tar czf $TMPDIR.tar.gz $TMPDIR/* -if [ -f $TMPDIR.tar.gz ]; then - echo $TMPDIR.tar.gz contains this script, all configs and logs generated on this tests -fi - -exit 0 diff --git a/tests/debugfs_emon_crash b/tests/debugfs_emon_crash deleted file mode 100755 index 809bfab3..00000000 --- a/tests/debugfs_emon_crash +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# -# This check if we can crash the kernel with segmentation-fault -# by reading /sys/kernel/debug/dri/0/i915_emon_status too quickly -# - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -for z in $(seq 1 1000); do - cat $i915_dfs_path/i915_emon_status > /dev/null 2&>1 -done - -# If we got here, we haven't crashed - -exit 0 diff --git a/tests/debugfs_wedged b/tests/debugfs_wedged deleted file mode 100755 index 903a0a20..00000000 --- a/tests/debugfs_wedged +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -# Testcase: wedge the hw to check the error_state reading -# -# Unfortunately wedged is permanent, so this test is not run by default -echo 1 > ${i915_dfs_path}/i915_wedged -cat $i915_dfs_path/i915_error_state > /dev/null 2>&1 diff --git a/tests/drm_import_export.c b/tests/drm_import_export.c deleted file mode 100644 index 57b13ddb..00000000 --- a/tests/drm_import_export.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright © 2014 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <libdrm/drm.h> -#include <libdrm/i915_drm.h> -#include <xf86drm.h> -#include <intel_bufmgr.h> -#include <errno.h> -#include <pthread.h> -#include <unistd.h> -#include <sys/syscall.h> - -#include "igt_core.h" -#include "drmtest.h" - -int fd; -drm_intel_bufmgr *bufmgr; -int fd1; -drm_intel_bufmgr *bufmgr1; - -bool use_flink; - -static void new_buffers(void) -{ - unsigned int *buf1; - drm_intel_bo *bo1, *bo2; - - - bo1 = drm_intel_bo_alloc(bufmgr, "buf1",16384, 4096); - igt_assert(bo1); - drm_intel_bo_map(bo1, 1); - bo2 = drm_intel_bo_alloc(bufmgr, "buf2", 16384, 4096); - igt_assert(bo2); - drm_intel_bo_map(bo2, 1); - - buf1 = (unsigned int *)bo1->virtual; - igt_assert(buf1); - memset(buf1, 0, 16384); - buf1[4000]=0x05000000; - - drm_intel_bo_exec(bo1, 16384, NULL, 0,0); - drm_intel_bo_wait_rendering(bo1); - - drm_intel_bo_unmap( bo1 ); - drm_intel_bo_unreference(bo1); - - drm_intel_bo_unmap( bo2 ); - drm_intel_bo_unreference(bo2); -} - -static void test_surfaces(drm_intel_bo *bo_shared) -{ - drm_intel_bo * bo; - int loop=2; - - while(loop--) { - if (use_flink) { - uint32_t name; - drm_intel_bo_flink(bo_shared, &name); - bo = drm_intel_bo_gem_create_from_name(bufmgr, - "shared resource", - name); - } else { - int prime_fd; - - drm_intel_bo_gem_export_to_prime(bo_shared, &prime_fd); - bo = drm_intel_bo_gem_create_from_prime(bufmgr, - prime_fd, 4096); - close(prime_fd); - } - - igt_assert(bo); - new_buffers(); - drm_intel_bo_unreference(bo); - } -} - -static void start_test(void) -{ - int i; - - for (i=0; i < 16384; i++) - { - drm_intel_bo * bo_shared; - - bo_shared = drm_intel_bo_alloc(bufmgr1, "buf-shared",16384, 4096); - test_surfaces(bo_shared); - drm_intel_bo_unreference(bo_shared); - } -} - -static void * test_thread(void * par) -{ -#ifdef __linux__ - igt_debug("start %ld\n", syscall(SYS_gettid)); -#else - igt_debug("start %ld\n", (long) pthread_self()); -#endif - start_test(); - - return NULL; -} - -pthread_t test_thread_id1; -pthread_t test_thread_id2; -pthread_t test_thread_id3; -pthread_t test_thread_id4; - -igt_main { - igt_fixture { - fd1 = drm_open_any(); - igt_assert(fd1 >= 0); - bufmgr1 = drm_intel_bufmgr_gem_init(fd1, 8 *1024); - igt_assert(bufmgr1); - - drm_intel_bufmgr_gem_enable_reuse(bufmgr1); - - fd = drm_open_any(); - igt_assert(fd >= 0); - bufmgr = drm_intel_bufmgr_gem_init(fd, 8 *1024); - igt_assert(bufmgr); - - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - } - - igt_subtest("flink") { - use_flink = true; - - pthread_create(&test_thread_id1, NULL, test_thread, NULL); - pthread_create(&test_thread_id2, NULL, test_thread, NULL); - pthread_create(&test_thread_id3, NULL, test_thread, NULL); - pthread_create(&test_thread_id4, NULL, test_thread, NULL); - - pthread_join(test_thread_id1, NULL); - pthread_join(test_thread_id2, NULL); - pthread_join(test_thread_id3, NULL); - pthread_join(test_thread_id4, NULL); - } - - igt_subtest("prime") { - use_flink = false; - - pthread_create(&test_thread_id1, NULL, test_thread, NULL); - pthread_create(&test_thread_id2, NULL, test_thread, NULL); - pthread_create(&test_thread_id3, NULL, test_thread, NULL); - pthread_create(&test_thread_id4, NULL, test_thread, NULL); - - pthread_join(test_thread_id1, NULL); - pthread_join(test_thread_id2, NULL); - pthread_join(test_thread_id3, NULL); - pthread_join(test_thread_id4, NULL); - } -} diff --git a/tests/drm_lib.sh b/tests/drm_lib.sh deleted file mode 100755 index c50664c7..00000000 --- a/tests/drm_lib.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/sh - -# hacked-up long option parsing -for arg in $@ ; do - case $arg in - --list-subtests) - exit 79 - ;; - --run-subtest) - exit 79 - ;; - --debug) - IGT_LOG_LEVEL=debug - ;; - --help-description) - echo $IGT_TEST_DESCRIPTION - exit 0 - ;; - --help) - echo "Usage: `basename $0` [OPTIONS]" - echo " --list-subtests" - echo " --run-subtest <pattern>" - echo " --debug" - echo " --help-description" - echo " --help" - exit 0 - ;; - esac -done - -die() { - echo "$@" - exit 1 -} - -do_or_die() { - $@ > /dev/null 2>&1 || (echo "FAIL: $@ ($?)" && exit -1) -} - -if [ -d /debug/dri ] ; then - debugfs_path=/debug/dri -fi - -if [ -d /sys/kernel/debug/dri ] ; then - debugfs_path=/sys/kernel/debug/dri -fi - -i915_dfs_path=x -for minor in `seq 0 16`; do - if [ -f $debugfs_path/$minor/i915_error_state ] ; then - i915_dfs_path=$debugfs_path/$minor - break - fi -done - -if [ $i915_dfs_path = "x" ] ; then - die " i915 debugfs path not found." -fi - -# read everything we can -if [ `cat $i915_dfs_path/clients | wc -l` -gt "2" ] ; then - [ -n "$DRM_LIB_ALLOW_NO_MASTER" ] || \ - die "ERROR: other drm clients running" -fi - -whoami | grep -q root || ( echo ERROR: not running as root; exit 1 ) - -i915_sfs_path= -if [ -d /sys/class/drm ] ; then - sysfs_path=/sys/class/drm - if [ -f $sysfs_path/card$minor/error ] ; then - i915_sfs_path="$sysfs_path/card$minor" - fi -fi -# sysfs may not exist as the 'error' is a new interface in 3.11 - -function drmtest_skip_on_simulation() -{ - [ -n "$INTEL_SIMULATION" ] && exit 77 -} - -drmtest_skip_on_simulation diff --git a/tests/drm_read.c b/tests/drm_read.c deleted file mode 100644 index 334f26a7..00000000 --- a/tests/drm_read.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright © 2014 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/* - * Testcase: boundary testing of read(drm_fd) - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <signal.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <sys/poll.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Call read(drm) and see if it behaves."); - -static void sighandler(int sig) -{ -} - -static void assert_empty(int fd) -{ - struct pollfd pfd = {fd, POLLIN}; - do_or_die(poll(&pfd, 1, 0)); -} - -static void generate_event(int fd) -{ - union drm_wait_vblank vbl; - - /* We require that pipe 0 is running */ - - vbl.request.type = - DRM_VBLANK_RELATIVE | - DRM_VBLANK_EVENT; - vbl.request.sequence = 0; - - do_ioctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl); -} - -static void wait_for_event(int fd) -{ - struct pollfd pfd = {fd, POLLIN}; - igt_assert(poll(&pfd, 1, -1) == 1); -} - -static int setup(int in, int nonblock) -{ - int fd; - - alarm(0); - - fd = dup(in); - if (nonblock) { - int ret = -1; - if (fd != -1) - ret = fcntl(fd, F_GETFL); - if (ret != -1) { - ret |= O_NONBLOCK; - ret = fcntl(fd, F_SETFL, ret); - } - igt_require(ret != -1); - } - - assert_empty(fd); - return fd; -} - -static void teardown(int fd) -{ - alarm(0); - assert_empty(fd); - close(fd); - errno = 0; -} - -static void test_invalid_buffer(int in) -{ - int fd = setup(in, 0); - - alarm(1); - - igt_assert_eq(read(fd, (void *)-1, 4096), -1); - igt_assert_eq(errno, EFAULT); - - teardown(fd); -} - -static void test_empty(int in, int nonblock, int expected) -{ - char buffer[1024]; - int fd = setup(in, nonblock); - - alarm(1); - igt_assert_eq(read(fd, buffer, sizeof(buffer)), -1); - igt_assert_eq(errno, expected); - - teardown(fd); -} - -static void test_short_buffer(int in, int nonblock) -{ - char buffer[1024]; /* events are typically 32 bytes */ - int fd = setup(in, nonblock); - - generate_event(fd); - generate_event(fd); - - wait_for_event(fd); - - alarm(3); - - igt_assert_eq(read(fd, buffer, 4), 0); - igt_assert(read(fd, buffer, 40) > 0); - igt_assert(read(fd, buffer, 40) > 0); - - teardown(fd); -} - -static int pipe0_enabled(int fd) -{ - struct drm_mode_card_res res; - uint32_t crtcs[32]; - int i; - - /* We assume we can generate events on pipe 0. So we have better - * make sure that is running! - */ - - memset(&res, 0, sizeof(res)); - res.count_crtcs = 32; - res.crtc_id_ptr = (uintptr_t)crtcs; - - if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) - return 0; - - if (res.count_crtcs > 32) - return 0; - - for (i = 0; i < res.count_crtcs; i++) { - struct drm_i915_get_pipe_from_crtc_id get_pipe; - struct drm_mode_crtc mode; - - memset(&get_pipe, 0, sizeof(get_pipe)); - memset(&mode, 0, sizeof(mode)); - - mode.crtc_id = crtcs[i]; - - get_pipe.pipe = -1; - get_pipe.crtc_id = mode.crtc_id; - drmIoctl(fd, DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID, &get_pipe); - if (get_pipe.pipe) - continue; - - drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &mode); - return mode.mode_valid && mode.mode.clock; - } - - return 0; -} - -igt_main -{ - int fd; - - signal(SIGALRM, sighandler); - siginterrupt(SIGALRM, 1); - - igt_fixture { - fd = drm_open_any_master(); - igt_require(pipe0_enabled(fd)); - } - - igt_subtest("invalid-buffer") - test_invalid_buffer(fd); - - igt_subtest("empty-block") - test_empty(fd, 0, EINTR); - - igt_subtest("empty-nonblock") - test_empty(fd, 1, EAGAIN); - - igt_subtest("short-buffer-block") - test_short_buffer(fd, 0); - - igt_subtest("short-buffer-nonblock") - test_short_buffer(fd, 1); -} diff --git a/tests/drm_vma_limiter.c b/tests/drm_vma_limiter.c deleted file mode 100644 index bb7102f1..00000000 --- a/tests/drm_vma_limiter.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -/* Testcase: check whether the libdrm vma limiter works - * - * We've had reports of the X server exhausting the default rlimit of 64k vma's - * in the kernel. libdrm has grown facilities to limit the vma caching since, - * this checks whether they actually work. - */ - -IGT_TEST_DESCRIPTION("Check whether the libdrm vma limiter works."); - -/* we do both cpu and gtt maps, so only need half of 64k to exhaust */ -#define BO_ARRAY_SIZE 35000 -drm_intel_bo *bos[BO_ARRAY_SIZE]; - -igt_simple_main -{ - int fd; - int i; - char *ptr; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - drm_intel_bufmgr_gem_set_vma_cache_size(bufmgr, 500); - - for (i = 0; i < BO_ARRAY_SIZE; i++) { - bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096); - igt_assert(bos[i]); - - drm_intel_bo_map(bos[i], 1); - ptr = bos[i]->virtual; - igt_assert(ptr); - *ptr = 'c'; - drm_intel_bo_unmap(bos[i]); - - drm_intel_gem_bo_map_gtt(bos[i]); - ptr = bos[i]->virtual; - igt_assert(ptr); - *ptr = 'c'; - drm_intel_gem_bo_unmap_gtt(bos[i]); - } - - /* and recheck whether a second map of the same still works */ - for (i = 0; i < BO_ARRAY_SIZE; i++) { - bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096); - igt_assert(bos[i]); - - drm_intel_bo_map(bos[i], 1); - ptr = bos[i]->virtual; - igt_assert(*ptr = 'c'); - drm_intel_bo_unmap(bos[i]); - - drm_intel_gem_bo_map_gtt(bos[i]); - ptr = bos[i]->virtual; - igt_assert(*ptr = 'c'); - drm_intel_gem_bo_unmap_gtt(bos[i]); - } - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/drm_vma_limiter_cached.c b/tests/drm_vma_limiter_cached.c deleted file mode 100644 index 74d0c1a0..00000000 --- a/tests/drm_vma_limiter_cached.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -/* Testcase: check whether the libdrm vma limiter works - * - * We've had reports of the X server exhausting the default rlimit of 64k vma's - * in the kernel. libdrm has grown facilities to limit the vma caching since, - * this checks whether they actually work. - * - * This one checks whether mmaps of unused cached bos are also properly reaped. - */ - -/* we do both cpu and gtt maps, so only need half of 64k to exhaust */ - -igt_simple_main -{ - int fd; - int i; - char *ptr; - drm_intel_bo *load_bo; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - load_bo = drm_intel_bo_alloc(bufmgr, "target bo", 1024*4096, 4096); - igt_assert(load_bo); - - drm_intel_bufmgr_gem_set_vma_cache_size(bufmgr, 500); - - /* IMPORTANT: we need to enable buffer reuse, otherwise we won't test - * the libdrm bo cache! */ - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - /* put some load onto the gpu to keep the light buffers active for long - * enough */ - for (i = 0; i < 10000; i++) { - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 4096); - OUT_BATCH(0); /* dst x1,y1 */ - OUT_BATCH((1024 << 16) | 512); - OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH((0 << 16) | 512); /* src x1, y1 */ - OUT_BATCH(4096); - OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - } - -#define GROUP_SZ 100 - for (i = 0; i < 68000; ) { - int j; - drm_intel_bo *bo[GROUP_SZ]; - - for (j = 0; j < GROUP_SZ; j++, i++) { - bo[j] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096); - igt_assert(bo[j]); - - drm_intel_gem_bo_map_gtt(bo[j]); - ptr = bo[j]->virtual; - igt_assert(ptr); - *ptr = 'c'; - drm_intel_gem_bo_unmap_gtt(bo[j]); - - /* put it onto the active list ... */ - COLOR_BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - 128); - OUT_BATCH(0); /* dst x1,y1 */ - OUT_BATCH((1 << 16) | 1); - OUT_RELOC(bo[j], I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0xffffffff); /* color */ - ADVANCE_BATCH(); - } - intel_batchbuffer_flush(batch); - - for (j = 0; j < GROUP_SZ; j++) - drm_intel_bo_unreference(bo[j]); - } - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/drm_vma_limiter_cpu.c b/tests/drm_vma_limiter_cpu.c deleted file mode 100644 index e17a679d..00000000 --- a/tests/drm_vma_limiter_cpu.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -/* Testcase: check whether the libdrm vma limiter works - * - * We've had reports of the X server exhausting the default rlimit of 64k vma's - * in the kernel. libdrm has grown facilities to limit the vma caching since, - * this checks whether they actually work. - * - * This one checks cpu mmaps only. - */ - -#define BO_ARRAY_SIZE 68000 -drm_intel_bo *bos[BO_ARRAY_SIZE]; - -igt_simple_main -{ - int fd; - int i; - char *ptr; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - drm_intel_bufmgr_gem_set_vma_cache_size(bufmgr, 500); - - for (i = 0; i < BO_ARRAY_SIZE; i++) { - bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096); - igt_assert(bos[i]); - - drm_intel_bo_map(bos[i], 1); - ptr = bos[i]->virtual; - igt_assert(ptr); - *ptr = 'c'; - drm_intel_bo_unmap(bos[i]); - } - - /* and recheck whether a second map of the same still works */ - for (i = 0; i < BO_ARRAY_SIZE; i++) { - bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096); - igt_assert(bos[i]); - - drm_intel_bo_map(bos[i], 1); - ptr = bos[i]->virtual; - igt_assert(*ptr = 'c'); - drm_intel_bo_unmap(bos[i]); - } - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/drm_vma_limiter_gtt.c b/tests/drm_vma_limiter_gtt.c deleted file mode 100644 index 303e86da..00000000 --- a/tests/drm_vma_limiter_gtt.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -/* Testcase: check whether the libdrm vma limiter works - * - * We've had reports of the X server exhausting the default rlimit of 64k vma's - * in the kernel. libdrm has grown facilities to limit the vma caching since, - * this checks whether they actually work. - * - * This one checks cpu mmaps only. - */ - -/* we do both cpu and gtt maps, so only need half of 64k to exhaust */ -#define BO_ARRAY_SIZE 68000 -drm_intel_bo *bos[BO_ARRAY_SIZE]; - -igt_simple_main -{ - int fd; - int i; - char *ptr; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - drm_intel_bufmgr_gem_set_vma_cache_size(bufmgr, 500); - - for (i = 0; i < BO_ARRAY_SIZE; i++) { - bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096); - igt_assert(bos[i]); - - drm_intel_gem_bo_map_gtt(bos[i]); - ptr = bos[i]->virtual; - igt_assert(ptr); - *ptr = 'c'; - drm_intel_gem_bo_unmap_gtt(bos[i]); - } - - /* and recheck whether a second map of the same still works */ - for (i = 0; i < BO_ARRAY_SIZE; i++) { - bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096); - igt_assert(bos[i]); - - drm_intel_gem_bo_map_gtt(bos[i]); - ptr = bos[i]->virtual; - igt_assert(*ptr = 'c'); - drm_intel_gem_bo_unmap_gtt(bos[i]); - } - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/drv_debugfs_reader b/tests/drv_debugfs_reader deleted file mode 100755 index 9e2845eb..00000000 --- a/tests/drv_debugfs_reader +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -# read everything we can -cat $i915_dfs_path/* > /dev/null 2>&1 - -exit 0 diff --git a/tests/drv_hangman.c b/tests/drv_hangman.c deleted file mode 100644 index a882822b..00000000 --- a/tests/drv_hangman.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright © 2014 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: - * Mika Kuoppala <mika.kuoppala@intel.com> - * Oscar Mateo <oscar.mateo@intel.com> - * - */ - -#include <limits.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include "intel_chipset.h" -#include "drmtest.h" -#include "igt_aux.h" -#include "igt_gt.h" -#include "ioctl_wrappers.h" - -#ifndef I915_PARAM_CMD_PARSER_VERSION -#define I915_PARAM_CMD_PARSER_VERSION 28 -#endif - -static int _read_sysfs(void *dst, int maxlen, - const char* path, - const char *fname) -{ - int fd; - char full[PATH_MAX]; - int r, e; - - igt_assert(snprintf(full, PATH_MAX, "%s/%s", path, fname) < PATH_MAX); - - fd = open(full, O_RDONLY); - if (fd == -1) - return -errno; - - r = read(fd, dst, maxlen); - e = errno; - close(fd); - - if (r < 0) - return -e; - - return r; -} - -static int read_sysfs(void *dst, int maxlen, const char *fname) -{ - char path[PATH_MAX]; - - igt_assert(snprintf(path, PATH_MAX, "/sys/class/drm/card%d", - drm_get_card()) < PATH_MAX); - - return _read_sysfs(dst, maxlen, path, fname); -} - -static void test_sysfs_error_exists(void) -{ - char tmp[1024]; - - igt_assert(read_sysfs(tmp, sizeof(tmp), "error") > 0); -} - -static void test_debugfs_error_state_exists(void) -{ - int fd; - - igt_assert((fd = igt_debugfs_open("i915_error_state", O_RDONLY)) >= 0); - - close (fd); -} - -static void test_debugfs_ring_stop_exists(void) -{ - int fd; - - igt_assert((fd = igt_debugfs_open("i915_ring_stop", O_RDONLY)) >= 0); - - close(fd); -} - -static void read_dfs(const char *fname, char *d, int maxlen) -{ - int fd; - int l; - - igt_assert((fd = igt_debugfs_open(fname, O_RDONLY)) >= 0); - - igt_assert((l = read(fd, d, maxlen-1)) > 0); - igt_assert(l < maxlen); - d[l] = 0; - close(fd); - - igt_debug("dfs entry %s read '%s'\n", fname, d); -} - -static void _assert_dfs_entry(const char *fname, const char *s, bool inverse) -{ - char tmp[1024]; - const int l = min(strlen(s), sizeof(tmp)); - - read_dfs(fname, tmp, l + 1); - if (!inverse) { - igt_fail_on_f(strncmp(tmp, s, l) != 0, - "contents of %s: '%s' (expected '%s')\n", fname, tmp, s); - } else { - igt_fail_on_f(strncmp(tmp, s, l) == 0, - "contents of %s: '%s' (expected not '%s'\n", fname, tmp, s); - } -} - -static void assert_dfs_entry(const char *fname, const char *s) -{ - _assert_dfs_entry(fname, s, false); -} - -static void assert_dfs_entry_not(const char *fname, const char *s) -{ - _assert_dfs_entry(fname, s, true); -} - -static void assert_error_state_clear(void) -{ - assert_dfs_entry("i915_error_state", "no error state collected"); -} - -static void assert_error_state_collected(void) -{ - assert_dfs_entry_not("i915_error_state", "no error state collected"); -} - -#define MAGIC_NUMBER 0x10001 -const uint32_t batch[] = { MI_NOOP, - MI_BATCH_BUFFER_END, - MAGIC_NUMBER, - MAGIC_NUMBER }; - -static uint64_t submit_batch(int fd, unsigned ring_id, bool stop_ring) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec; - uint64_t presumed_offset; - - gem_require_ring(fd, ring_id); - - exec.handle = gem_create(fd, 4096); - gem_write(fd, exec.handle, 0, batch, sizeof(batch)); - exec.relocation_count = 0; - exec.relocs_ptr = 0; - exec.alignment = 0; - exec.offset = 0; - exec.flags = 0; - exec.rsvd1 = 0; - exec.rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)&exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = sizeof(batch); - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring_id; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - gem_execbuf(fd, &execbuf); - gem_sync(fd, exec.handle); - presumed_offset = exec.offset; - - if (stop_ring) { - igt_set_stop_rings(igt_to_stop_ring_flag(ring_id)); - - gem_execbuf(fd, &execbuf); - gem_sync(fd, exec.handle); - - igt_assert(igt_get_stop_rings() == STOP_RING_NONE); - igt_assert(presumed_offset == exec.offset); - } - - gem_close(fd, exec.handle); - - return exec.offset; -} - -static void clear_error_state(void) -{ - int fd; - const char *b = "1"; - - igt_assert((fd = igt_debugfs_open("i915_error_state", O_WRONLY)) >= 0); - igt_assert(write(fd, b, 1) == 1); - close(fd); -} - -static void test_error_state_basic(void) -{ - int fd; - - clear_error_state(); - assert_error_state_clear(); - - fd = drm_open_any(); - submit_batch(fd, I915_EXEC_RENDER, true); - close(fd); - - assert_error_state_collected(); - clear_error_state(); - assert_error_state_clear(); -} - -static void check_error_state(const int gen, - const bool uses_cmd_parser, - const char *expected_ring_name, - uint64_t expected_offset) -{ - FILE *file; - int debug_fd; - char *line = NULL; - size_t line_size = 0; - char *ring_name = NULL; - bool bb_ok = false, req_ok = false, ringbuf_ok = false; - - debug_fd = igt_debugfs_open("i915_error_state", O_RDONLY); - igt_assert(debug_fd >= 0); - file = fdopen(debug_fd, "r"); - - while (getline(&line, &line_size, file) > 0) { - char *dashes = NULL; - int bb_matched = 0; - uint32_t gtt_offset; - int req_matched = 0; - int requests; - uint32_t tail; - int ringbuf_matched = 0; - int i, items; - - dashes = strstr(line, "---"); - if (!dashes) - continue; - - ring_name = realloc(ring_name, dashes - line); - strncpy(ring_name, line, dashes - line); - ring_name[dashes - line - 1] = '\0'; - - bb_matched = sscanf(dashes, "--- gtt_offset = 0x%08x\n", - >t_offset); - if (bb_matched == 1) { - char expected_line[32]; - - igt_assert(strstr(ring_name, expected_ring_name)); - if (!uses_cmd_parser) - igt_assert(gtt_offset == expected_offset); - - for (i = 0; i < sizeof(batch) / 4; i++) { - igt_assert(getline(&line, &line_size, file) > 0); - snprintf(expected_line, sizeof(expected_line), "%08x : %08x", - 4*i, batch[i]); - igt_assert(strstr(line, expected_line)); - } - bb_ok = true; - continue; - } - - req_matched = sscanf(dashes, "--- %d requests\n", &requests); - if (req_matched == 1) { - igt_assert(strstr(ring_name, expected_ring_name)); - igt_assert(requests > 0); - - for (i = 0; i < requests; i++) { - uint32_t seqno; - long jiffies; - - igt_assert(getline(&line, &line_size, file) > 0); - items = sscanf(line, " seqno 0x%08x, emitted %ld, tail 0x%08x\n", - &seqno, &jiffies, &tail); - igt_assert(items == 3); - } - req_ok = true; - continue; - } - - ringbuf_matched = sscanf(dashes, "--- ringbuffer = 0x%08x\n", - >t_offset); - if (ringbuf_matched == 1) { - unsigned int offset, command, expected_addr = 0; - - if (!strstr(ring_name, expected_ring_name)) - continue; - igt_assert(req_ok); - - for (i = 0; i < tail / 4; i++) { - igt_assert(getline(&line, &line_size, file) > 0); - items = sscanf(line, "%08x : %08x\n", - &offset, &command); - igt_assert(items == 2); - if ((command & 0x1F800000) == MI_BATCH_BUFFER_START) { - igt_assert(getline(&line, &line_size, file) > 0); - items = sscanf(line, "%08x : %08x\n", - &offset, &expected_addr); - igt_assert(items == 2); - i++; - } - } - if (!uses_cmd_parser) { - if (gen >= 4) - igt_assert(expected_addr == expected_offset); - else - igt_assert((expected_addr & ~0x1) == expected_offset); - } - ringbuf_ok = true; - continue; - } - - if (bb_ok && req_ok && ringbuf_ok) - break; - } - igt_assert(bb_ok && req_ok && ringbuf_ok); - - free(line); - free(ring_name); - close(debug_fd); -} - -static bool uses_cmd_parser(int fd, int gen) -{ - int parser_version = 0; - drm_i915_getparam_t gp; - int rc; - - gp.param = I915_PARAM_CMD_PARSER_VERSION; - gp.value = &parser_version; - rc = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); - if (rc || parser_version == 0) - return false; - - if (!gem_uses_aliasing_ppgtt(fd)) - return false; - - if (gen != 7) - return false; - - return true; -} - -static void test_error_state_capture(unsigned ring_id, - const char *ring_name) -{ - int fd, gen; - uint64_t offset; - bool cmd_parser; - - clear_error_state(); - - fd = drm_open_any(); - gen = intel_gen(intel_get_drm_devid(fd)); - cmd_parser = uses_cmd_parser(fd, gen); - - offset = submit_batch(fd, ring_id, true); - close(fd); - - check_error_state(gen, cmd_parser, ring_name, offset); -} - -static const struct target_ring { - const int id; - const char *short_name; - const char *full_name; -} rings[] = { - { I915_EXEC_RENDER, "render", "render ring" }, - { I915_EXEC_BSD, "bsd", "bsd ring" }, - { I915_EXEC_BLT, "blt", "blitter ring" }, - { I915_EXEC_VEBOX, "vebox", "video enhancement ring" }, -}; - -igt_main -{ - igt_skip_on_simulation(); - - igt_subtest("error-state-debugfs-entry") - test_debugfs_error_state_exists(); - - igt_subtest("error-state-sysfs-entry") - test_sysfs_error_exists(); - - igt_subtest("ring-stop-sysfs-entry") - test_debugfs_ring_stop_exists(); - - igt_subtest("error-state-basic") - test_error_state_basic(); - - for (int i = 0; i < sizeof(rings)/sizeof(rings[0]); i++) { - igt_subtest_f("error-state-capture-%s", rings[i].short_name) - test_error_state_capture(rings[i].id, rings[i].full_name); - } -} diff --git a/tests/drv_missed_irq_hang b/tests/drv_missed_irq_hang deleted file mode 100755 index 6e8cfc27..00000000 --- a/tests/drv_missed_irq_hang +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -# -# Testcase: Simulate missed breadcrumb interrupts -# - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -oldpath=`pwd` - -cd $i915_dfs_path - -function blt_wait { - (cd $oldpath; $SOURCE_DIR/gem_exec_blt 16384) > /dev/null - (cd $oldpath; $SOURCE_DIR/gem_exec_blt 65536) > /dev/null - (cd $oldpath; $SOURCE_DIR/gem_exec_blt 262144) > /dev/null -} - -function check_for_missed_irq { - if test `cat i915_ring_missed_irq` = 0x00000000; then - echo "missed interrupts undetected" - exit 1 - fi -} - -function check_for_hang { - if cat i915_error_state | grep -v "no error state collected" > /dev/null ; then - echo "gpu hang reported" - exit 2 - fi -} - -if [ ! -f i915_ring_missed_irq ] ; then - echo "kernel doesn't support interrupt masking" - exit 77 -fi - -# clear error state first -echo > i915_error_state -check_for_hang - -echo 0xf > i915_ring_test_irq -echo "Interrupts masked" -if test `cat i915_ring_test_irq` != 0x0000000f; then - echo "Failed to set interrupt mask" - exit 3 -fi - -blt_wait -check_for_missed_irq -check_for_hang - -blt_wait -check_for_hang - -echo 0 > i915_ring_test_irq -echo "Interrupts unmasked" -if test `cat i915_ring_test_irq` != 0x00000000; then - echo "Failed to clear interrupt mask" - exit 3 -fi - -blt_wait -check_for_hang - -echo 0 > i915_ring_missed_irq -echo "Cleared missed interrupts" -if test `cat i915_ring_missed_irq` != 0x00000000; then - echo "Failed to clear missed interrupts" - exit 3 -fi - -exit 0 diff --git a/tests/drv_module_reload b/tests/drv_module_reload deleted file mode 100755 index bb29a64f..00000000 --- a/tests/drv_module_reload +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# -# Testcase: Reload the drm module -# -# ... we've broken this way too often :( -# - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -# no other drm service should be running, so we can just unbind - -# we must kick away fbcon (but only fbcon) -for vtcon in /sys/class/vtconsole/vtcon*/ ; do - if grep "frame buffer device" $vtcon/name > /dev/null ; then - echo unbinding $vtcon: `cat $vtcon/name` - echo 0 > $vtcon/bind - fi -done - -# The sound driver uses our power well -pkill alsactl -rmmod snd_hda_intel &> /dev/null - -#ignore errors in ips - gen5 only -rmmod intel_ips &> /dev/null -rmmod i915 -#ignore errors in intel-gtt, often built-in -rmmod intel-gtt &> /dev/null -# drm may be used by other devices (nouveau, radeon, udl, etc) -rmmod drm_kms_helper &> /dev/null -rmmod drm &> /dev/null - -if lsmod | grep i915 &> /dev/null ; then - echo WARNING: i915.ko still loaded! - exit 1 -else - echo module successfully unloaded -fi - -modprobe i915 -echo 1 > /sys/class/vtconsole/vtcon1/bind - -modprobe snd_hda_intel - -# does the device exist? -if $SOURCE_DIR/gem_alive > /dev/null ; then - echo "module successfully loaded again" -else - echo "failed to reload module successfully" - exit 2 -fi - -# then try to run something -if ! $SOURCE_DIR/gem_exec_nop > /dev/null ; then - echo "failed to execute a simple batch after reload" - exit 3 -fi - -exit 0 diff --git a/tests/drv_suspend.c b/tests/drv_suspend.c deleted file mode 100644 index 955c294c..00000000 --- a/tests/drv_suspend.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright © 2013, 2015 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * David Weinehall <david.weinehall@intel.com> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_gt.h" -#include "igt_aux.h" - -#define OBJECT_SIZE (16*1024*1024) - -static void -test_fence_restore(int fd, bool tiled2untiled, bool hibernate) -{ - uint32_t handle1, handle2, handle_tiled; - uint32_t *ptr1, *ptr2, *ptr_tiled; - int i; - - /* We wall the tiled object with untiled canary objects to make sure - * that we detect tile leaking in both directions. */ - handle1 = gem_create(fd, OBJECT_SIZE); - handle2 = gem_create(fd, OBJECT_SIZE); - handle_tiled = gem_create(fd, OBJECT_SIZE); - - /* Access the buffer objects in the order we want to have the laid out. */ - ptr1 = gem_mmap(fd, handle1, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr1 != MAP_FAILED); - for (i = 0; i < OBJECT_SIZE/sizeof(uint32_t); i++) - ptr1[i] = i; - - ptr_tiled = gem_mmap(fd, handle_tiled, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr_tiled != MAP_FAILED); - if (tiled2untiled) - gem_set_tiling(fd, handle_tiled, I915_TILING_X, 2048); - for (i = 0; i < OBJECT_SIZE/sizeof(uint32_t); i++) - ptr_tiled[i] = i; - - ptr2 = gem_mmap(fd, handle2, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr2 != MAP_FAILED); - for (i = 0; i < OBJECT_SIZE/sizeof(uint32_t); i++) - ptr2[i] = i; - - if (tiled2untiled) - gem_set_tiling(fd, handle_tiled, I915_TILING_NONE, 2048); - else - gem_set_tiling(fd, handle_tiled, I915_TILING_X, 2048); - - if (hibernate) - igt_system_hibernate_autoresume(); - else - igt_system_suspend_autoresume(); - - igt_info("checking the first canary object\n"); - for (i = 0; i < OBJECT_SIZE/sizeof(uint32_t); i++) - igt_assert(ptr1[i] == i); - - igt_info("checking the second canary object\n"); - for (i = 0; i < OBJECT_SIZE/sizeof(uint32_t); i++) - igt_assert(ptr2[i] == i); - - gem_close(fd, handle1); - gem_close(fd, handle2); - gem_close(fd, handle_tiled); - - munmap(ptr1, OBJECT_SIZE); - munmap(ptr2, OBJECT_SIZE); - munmap(ptr_tiled, OBJECT_SIZE); -} - -static void -test_debugfs_reader(bool hibernate) -{ - struct igt_helper_process reader = {}; - reader.use_SIGKILL = true; - - igt_fork_helper(&reader) { - static const char dfs_base[] = "/sys/kernel/debug/dri"; - static char tmp[1024]; - - snprintf(tmp, sizeof(tmp) - 1, - "while true; do find %s/%i/ -type f | xargs cat > /dev/null 2>&1; done", - dfs_base, drm_get_card()); - igt_assert(execl("/bin/sh", "sh", "-c", tmp, (char *) NULL) != -1); - } - - sleep(1); - - if (hibernate) - igt_system_hibernate_autoresume(); - else - igt_system_suspend_autoresume(); - - sleep(1); - - igt_stop_helper(&reader); -} - -static void -test_sysfs_reader(bool hibernate) -{ - struct igt_helper_process reader = {}; - reader.use_SIGKILL = true; - - igt_fork_helper(&reader) { - static const char dfs_base[] = "/sys/class/drm/card"; - static char tmp[1024]; - - snprintf(tmp, sizeof(tmp) - 1, - "while true; do find %s%i*/ -type f | xargs cat > /dev/null 2>&1; done", - dfs_base, drm_get_card()); - igt_assert(execl("/bin/sh", "sh", "-c", tmp, (char *) NULL) != -1); - } - - sleep(1); - - if (hibernate) - igt_system_hibernate_autoresume(); - else - igt_system_suspend_autoresume(); - - sleep(1); - - igt_stop_helper(&reader); -} - -static void -test_forcewake(bool hibernate) -{ - int fw_fd; - - fw_fd = igt_open_forcewake_handle(); - igt_assert(fw_fd >= 0); - - if (hibernate) - igt_system_hibernate_autoresume(); - else - igt_system_suspend_autoresume(); - - close (fw_fd); -} - -int fd; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture - fd = drm_open_any(); - - igt_subtest("fence-restore-tiled2untiled") - test_fence_restore(fd, true, false); - - igt_subtest("fence-restore-untiled") - test_fence_restore(fd, false, false); - - igt_subtest("debugfs-reader") - test_debugfs_reader(false); - - igt_subtest("sysfs-reader") - test_sysfs_reader(false); - - igt_subtest("forcewake") - test_forcewake(false); - - igt_subtest("fence-restore-tiled2untiled-hibernate") - test_fence_restore(fd, true, true); - - igt_subtest("fence-restore-untiled-hibernate") - test_fence_restore(fd, false, true); - - igt_subtest("debugfs-reader-hibernate") - test_debugfs_reader(true); - - igt_subtest("sysfs-reader-hibernate") - test_sysfs_reader(true); - - igt_subtest("forcewake-hibernate") - test_forcewake(true); - - igt_fixture - close(fd); -} diff --git a/tests/eviction_common.c b/tests/eviction_common.c deleted file mode 100644 index b18c2a73..00000000 --- a/tests/eviction_common.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright © 2007, 2011, 2013, 2014 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: - * Eric Anholt <eric@anholt.net> - * Daniel Vetter <daniel.vetter@ffwll.ch> - * Tvrtko Ursulin <tvrtko.ursulin@intel.com> - * - */ - -#include <stdlib.h> - -#include "drmtest.h" -#include "igt_aux.h" - -struct igt_eviction_test_ops -{ - uint32_t (*create)(int fd, int size); - void (*flink)(uint32_t old_handle, uint32_t new_handle); - void (*close)(int fd, uint32_t bo); - int (*copy)(int fd, uint32_t dst, uint32_t src, - uint32_t *all_bo, int nr_bos); - void (*clear)(int fd, uint32_t bo, int size); -}; - -#define FORKING_EVICTIONS_INTERRUPTIBLE (1 << 0) -#define FORKING_EVICTIONS_SWAPPING (1 << 1) -#define FORKING_EVICTIONS_DUP_DRMFD (1 << 2) -#define FORKING_EVICTIONS_MEMORY_PRESSURE (1 << 3) -#define ALL_FORKING_EVICTIONS (FORKING_EVICTIONS_INTERRUPTIBLE | \ - FORKING_EVICTIONS_SWAPPING | \ - FORKING_EVICTIONS_DUP_DRMFD | \ - FORKING_EVICTIONS_MEMORY_PRESSURE) - -static void exchange_uint32_t(void *array, unsigned i, unsigned j) -{ - uint32_t *i_arr = array; - - igt_swap(i_arr[i], i_arr[j]); -} - -static int minor_evictions(int fd, struct igt_eviction_test_ops *ops, - int surface_size, int nr_surfaces) -{ - uint32_t *bo, *sel; - int n, m, pass, fail; - int total_surfaces; - - /* Make sure nr_surfaces is not divisible by seven - * to avoid duplicates in the selection loop below. - */ - nr_surfaces /= 7; - nr_surfaces *= 7; - nr_surfaces += 3; - - total_surfaces = gem_aperture_size(fd) / surface_size + 1; - igt_require(nr_surfaces < total_surfaces); - intel_require_memory(total_surfaces, surface_size, CHECK_RAM); - - bo = malloc((nr_surfaces + total_surfaces)*sizeof(*bo)); - igt_assert(bo); - - for (n = 0; n < total_surfaces; n++) - bo[n] = ops->create(fd, surface_size); - - sel = bo + n; - for (fail = 0, m = 0; fail < 10; fail++) { - int ret; - for (pass = 0; pass < 100; pass++) { - for (n = 0; n < nr_surfaces; n++, m += 7) - sel[n] = bo[m%total_surfaces]; - ret = ops->copy(fd, sel[0], sel[1], sel, nr_surfaces); - igt_assert(ret == 0); - } - ret = ops->copy(fd, bo[0], bo[0], bo, total_surfaces); - igt_assert(ret == ENOSPC); - } - - for (n = 0; n < total_surfaces; n++) - ops->close(fd, bo[n]); - free(bo); - - return 0; -} - -static int major_evictions(int fd, struct igt_eviction_test_ops *ops, - int surface_size, int nr_surfaces) -{ - int n, m, loop; - uint32_t *bo; - int ret; - - intel_require_memory(nr_surfaces, surface_size, CHECK_RAM); - - bo = malloc(nr_surfaces*sizeof(*bo)); - igt_assert(bo); - - for (n = 0; n < nr_surfaces; n++) - bo[n] = ops->create(fd, surface_size); - - for (loop = 0, m = 0; loop < 100; loop++, m += 17) { - n = m % nr_surfaces; - ret = ops->copy(fd, bo[n], bo[n], &bo[n], 1); - igt_assert(ret == 0); - } - - for (n = 0; n < nr_surfaces; n++) - ops->close(fd, bo[n]); - free(bo); - - return 0; -} - -static int swapping_evictions(int fd, struct igt_eviction_test_ops *ops, - int surface_size, - int working_surfaces, - int trash_surfaces) -{ - uint32_t *bo; - int i, n, pass, ret; - - intel_require_memory(working_surfaces, surface_size, CHECK_RAM); - - if (trash_surfaces < working_surfaces) - trash_surfaces = working_surfaces; - - intel_require_memory(trash_surfaces, surface_size, CHECK_RAM | CHECK_SWAP); - - bo = malloc(trash_surfaces*sizeof(*bo)); - igt_assert(bo); - - for (n = 0; n < trash_surfaces; n++) - bo[n] = ops->create(fd, surface_size); - - for (i = 0; i < trash_surfaces/32; i++) { - igt_permute_array(bo, trash_surfaces, exchange_uint32_t); - - for (pass = 0; pass < 100; pass++) { - ret = ops->copy(fd, bo[0], bo[1], bo, working_surfaces); - igt_assert(ret == 0); - } - } - - for (n = 0; n < trash_surfaces; n++) - ops->close(fd, bo[n]); - free(bo); - - return 0; -} - -static int forking_evictions(int fd, struct igt_eviction_test_ops *ops, - int surface_size, int working_surfaces, - int trash_surfaces, unsigned flags) -{ - uint32_t *bo; - int n, pass, l, ret; - int num_threads = sysconf(_SC_NPROCESSORS_ONLN); - int bo_count; - - intel_require_memory(working_surfaces, surface_size, CHECK_RAM); - - if (flags & FORKING_EVICTIONS_SWAPPING) { - bo_count = trash_surfaces; - if (bo_count < working_surfaces) - bo_count = working_surfaces; - - } else - bo_count = working_surfaces; - - igt_assert(working_surfaces <= bo_count); - intel_require_memory(bo_count, surface_size, CHECK_RAM | CHECK_SWAP); - - bo = malloc(bo_count*sizeof(*bo)); - igt_assert(bo); - - for (n = 0; n < bo_count; n++) - bo[n] = ops->create(fd, surface_size); - - igt_fork(i, min(num_threads * 4, 12)) { - int realfd = fd; - int num_passes = flags & FORKING_EVICTIONS_SWAPPING ? 10 : 100; - - /* Every fork should have a different permutation! */ - srand(i * 63); - - if (flags & FORKING_EVICTIONS_INTERRUPTIBLE) - igt_fork_signal_helper(); - - igt_permute_array(bo, bo_count, exchange_uint32_t); - - if (flags & FORKING_EVICTIONS_DUP_DRMFD) { - realfd = drm_open_any(); - - /* We can overwrite the bo array since we're forked. */ - for (l = 0; l < bo_count; l++) { - uint32_t handle = bo[l]; - uint32_t flink = gem_flink(fd, bo[l]); - - bo[l] = gem_open(realfd, flink); - if (ops->flink) - ops->flink(handle, bo[l]); - } - } - - for (pass = 0; pass < num_passes; pass++) { - ret = ops->copy(realfd, bo[0], bo[1], bo, working_surfaces); - igt_assert(ret == 0); - - for (l = 0; l < working_surfaces && - (flags & FORKING_EVICTIONS_MEMORY_PRESSURE); - l++) { - ops->clear(realfd, bo[l], surface_size); - } - } - - if (flags & FORKING_EVICTIONS_INTERRUPTIBLE) - igt_stop_signal_helper(); - - /* drmfd closing will take care of additional bo refs */ - if (flags & FORKING_EVICTIONS_DUP_DRMFD) - close(realfd); - } - - igt_waitchildren(); - - for (n = 0; n < bo_count; n++) - ops->close(fd, bo[n]); - free(bo); - - return 0; -} diff --git a/tests/gem_alive.c b/tests/gem_alive.c deleted file mode 100644 index 390a54fa..00000000 --- a/tests/gem_alive.c +++ /dev/null @@ -1,35 +0,0 @@ -#include <sys/ioctl.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <signal.h> -#include <i915_drm.h> - -#include "drmtest.h" - -int main(void) -{ - struct drm_i915_gem_sw_finish arg = { 0 }; - int fd; - - signal(SIGALRM, SIG_IGN); - - fd = __drm_open_any(); - if (fd < 0) - return IGT_EXIT_SKIP; - - alarm(1); - if (ioctl(fd, DRM_IOCTL_I915_GEM_SW_FINISH, &arg) == 0) - return IGT_EXIT_SKIP; - - switch (errno) { - case ENOENT: - return 0; - case EIO: - return 1; - case EINTR: - return 2; - default: - return 3; - } -} diff --git a/tests/gem_bad_address.c b/tests/gem_bad_address.c deleted file mode 100644 index 4a4a5703..00000000 --- a/tests/gem_bad_address.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * Jesse Barnes <jbarnes@virtuousgeek.org> (based on gem_bad_blit.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_chipset.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -#define BAD_GTT_DEST ((512*1024*1024)) /* past end of aperture */ - -static void -bad_store(void) -{ - BEGIN_BATCH(4, 0); - OUT_BATCH(MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL | 1 << 21); - OUT_BATCH(0); - OUT_BATCH(BAD_GTT_DEST); - OUT_BATCH(0xdeadbeef); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -igt_simple_main -{ - int fd; - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - bad_store(); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_bad_batch.c b/tests/gem_bad_batch.c deleted file mode 100644 index e3de3b6d..00000000 --- a/tests/gem_bad_batch.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * Jesse Barnes <jbarnes@virtuousgeek.org> (based on gem_bad_blit.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "intel_io.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -static void -bad_batch(void) -{ - BEGIN_BATCH(2, 0); - OUT_BATCH(MI_BATCH_BUFFER_START); - OUT_BATCH(0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -igt_simple_main -{ - int fd; - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - bad_batch(); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_bad_blit.c b/tests/gem_bad_blit.c deleted file mode 100644 index 593167c2..00000000 --- a/tests/gem_bad_blit.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * - */ - -/** @file gem_tiled_blits.c - * - * This is a test of doing many tiled blits, with a working set - * larger than the aperture size. - * - * The goal is to catch a couple types of failure; - * - Fence management problems on pre-965. - * - A17 or L-shaped memory tiling workaround problems in acceleration. - * - * The model is to fill a collection of 1MB objects in a way that can't trip - * over A6 swizzling -- upload data to a non-tiled object, blit to the tiled - * object. Then, copy the 1MB objects randomly between each other for a while. - * Finally, download their data through linear objects again and see what - * resulted. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "intel_io.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -#define BAD_GTT_DEST ((256*1024*1024)) /* past end of aperture */ - -static void -bad_blit(drm_intel_bo *src_bo, uint32_t devid) -{ - uint32_t src_pitch = 512, dst_pitch = 512; - uint32_t cmd_bits = 0; - - if (IS_965(devid)) { - src_pitch /= 4; - cmd_bits |= XY_SRC_COPY_BLT_SRC_TILED; - } - - if (IS_965(devid)) { - dst_pitch /= 4; - cmd_bits |= XY_SRC_COPY_BLT_DST_TILED; - } - - BLIT_COPY_BATCH_START(cmd_bits); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - dst_pitch); - OUT_BATCH(0); /* dst x1,y1 */ - OUT_BATCH((64 << 16) | 64); /* 64x64 blit */ - OUT_BATCH(BAD_GTT_DEST); - if (batch->gen >= 8) - OUT_BATCH(BAD_GTT_DEST >> 32); /* Upper 16 bits */ - OUT_BATCH(0); /* src x1,y1 */ - OUT_BATCH(src_pitch); - OUT_RELOC_FENCED(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -igt_simple_main -{ - drm_intel_bo *src; - int fd; - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - src = drm_intel_bo_alloc(bufmgr, "src", 128 * 128, 4096); - - bad_blit(src, batch->devid); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_bad_length.c b/tests/gem_bad_length.c deleted file mode 100644 index 29b39253..00000000 --- a/tests/gem_bad_length.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Test minimal bo_create and batchbuffer exec."); - -/* - * Testcase: Minimal bo_create and batchbuffer exec - * - * Originally this caught an kernel oops due to the unchecked assumption that - * objects have size > 0. - */ - -static uint32_t do_gem_create(int fd, int size, int *retval) -{ - struct drm_i915_gem_create create; - int ret; - - create.handle = 0; - create.size = (size + 4095) & -4096; - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); - igt_assert(retval || ret == 0); - if (retval) - *retval = errno; - - return create.handle; -} - -#if 0 -static int gem_exec(int fd, struct drm_i915_gem_execbuffer2 *execbuf) -{ - return drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf); -} -#endif - -static void create0(int fd) -{ - int retval = 0; - igt_info("trying to create a zero-length gem object\n"); - do_gem_create(fd, 0, &retval); - igt_assert(retval == EINVAL); -} - -#if 0 -static void exec0(int fd) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec[1]; - uint32_t buf[2] = { MI_BATCH_BUFFER_END, 0 }; - - /* Just try executing with a zero-length bo. - * We expect the kernel to either accept the nop batch, or reject it - * for the zero-length buffer, but never crash. - */ - - exec[0].handle = gem_create(fd, 4096); - gem_write(fd, exec[0].handle, 0, buf, sizeof(buf)); - exec[0].relocation_count = 0; - exec[0].relocs_ptr = 0; - exec[0].alignment = 0; - exec[0].offset = 0; - exec[0].flags = 0; - exec[0].rsvd1 = 0; - exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = sizeof(buf); - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = 0; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - igt_info("trying to run an empty batchbuffer\n"); - gem_exec(fd, &execbuf); - - gem_close(fd, exec[0].handle); -} -#endif - -igt_simple_main -{ - int fd; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - create0(fd); - - //exec0(fd); - - close(fd); -} diff --git a/tests/gem_bad_reloc.c b/tests/gem_bad_reloc.c deleted file mode 100644 index 36d8c09a..00000000 --- a/tests/gem_bad_reloc.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright © 2014 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Simulates SNA behaviour using negative self-relocations" - " for STATE_BASE_ADDRESS command packets."); - -#define USE_LUT (1 << 12) - -/* Simulates SNA behaviour using negative self-relocations for - * STATE_BASE_ADDRESS command packets. If they wrap around (to values greater - * than the total size of the GTT), the GPU will hang. - * See https://bugs.freedesktop.org/show_bug.cgi?id=78533 - */ -static int negative_reloc(int fd, unsigned flags) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[2]; - struct drm_i915_gem_relocation_entry gem_reloc[1000]; - uint64_t gtt_max = gem_aperture_size(fd); - uint32_t buf[1024] = {MI_BATCH_BUFFER_END}; - int i; - -#define BIAS (256*1024) - - igt_require(intel_gen(intel_get_drm_devid(fd)) >= 7); - - memset(gem_exec, 0, sizeof(gem_exec)); - gem_exec[0].handle = gem_create(fd, 4096); - gem_write(fd, gem_exec[0].handle, 0, buf, 8); - - gem_reloc[0].offset = 1024; - gem_reloc[0].delta = 0; - gem_reloc[0].target_handle = gem_exec[0].handle; - gem_reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND; - - gem_exec[1].handle = gem_create(fd, 4096); - gem_write(fd, gem_exec[1].handle, 0, buf, 8); - gem_exec[1].relocation_count = 1; - gem_exec[1].relocs_ptr = (uintptr_t)gem_reloc; - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 2; - execbuf.batch_len = 8; - - do_or_die(drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf)); - gem_close(fd, gem_exec[1].handle); - - igt_info("Found offset %ld for 4k batch\n", (long)gem_exec[0].offset); - /* - * Ideally we'd like to be able to control where the kernel is going to - * place the buffer. We don't SKIP here because it causes the test - * to "randomly" flip-flop between the SKIP and PASS states. - */ - if (gem_exec[0].offset < BIAS) { - igt_info("Offset is below BIAS, not testing anything\n"); - return 0; - } - - memset(gem_reloc, 0, sizeof(gem_reloc)); - for (i = 0; i < sizeof(gem_reloc)/sizeof(gem_reloc[0]); i++) { - gem_reloc[i].offset = 8 + 4*i; - gem_reloc[i].delta = -BIAS*i/1024; - gem_reloc[i].target_handle = flags & USE_LUT ? 0 : gem_exec[0].handle; - gem_reloc[i].read_domains = I915_GEM_DOMAIN_COMMAND; - } - - gem_exec[0].relocation_count = sizeof(gem_reloc)/sizeof(gem_reloc[0]); - gem_exec[0].relocs_ptr = (uintptr_t)gem_reloc; - - execbuf.buffer_count = 1; - execbuf.flags = flags & USE_LUT; - do_or_die(drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf)); - - igt_info("Batch is now at offset %ld\n", (long)gem_exec[0].offset); - - gem_read(fd, gem_exec[0].handle, 0, buf, sizeof(buf)); - gem_close(fd, gem_exec[0].handle); - - for (i = 0; i < sizeof(gem_reloc)/sizeof(gem_reloc[0]); i++) - igt_assert(buf[2 + i] < gtt_max); - - return 0; -} - -static int negative_reloc_blt(int fd) -{ - const int gen = intel_gen(intel_get_drm_devid(fd)); - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[1024][2]; - struct drm_i915_gem_relocation_entry gem_reloc; - uint32_t buf[1024], *b; - int i; - - memset(&gem_reloc, 0, sizeof(gem_reloc)); - gem_reloc.offset = 4 * sizeof(uint32_t); - gem_reloc.presumed_offset = ~0ULL; - gem_reloc.delta = -4096; - gem_reloc.target_handle = 0; - gem_reloc.read_domains = I915_GEM_DOMAIN_RENDER; - gem_reloc.write_domain = I915_GEM_DOMAIN_RENDER; - - for (i = 0; i < 1024; i++) { - memset(gem_exec[i], 0, sizeof(gem_exec[i])); - - gem_exec[i][0].handle = gem_create(fd, 4096); - gem_exec[i][0].flags = EXEC_OBJECT_NEEDS_FENCE; - - b = buf; - *b++ = XY_COLOR_BLT_CMD_NOLEN | - ((gen >= 8) ? 5 : 4) | - COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; - *b++ = 0xf0 << 16 | 1 << 25 | 1 << 24 | 4096; - *b++ = 1 << 16 | 0; - *b++ = 2 << 16 | 1024; - *b++ = ~0; - if (gen >= 8) - *b++ = ~0; - *b++ = 0xc0ffee ^ i; - *b++ = MI_BATCH_BUFFER_END; - if ((b - buf) & 1) - *b++ = 0; - - gem_exec[i][1].handle = gem_create(fd, 4096); - gem_write(fd, gem_exec[i][1].handle, 0, buf, (b - buf) * sizeof(uint32_t)); - gem_exec[i][1].relocation_count = 1; - gem_exec[i][1].relocs_ptr = (uintptr_t)&gem_reloc; - } - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffer_count = 2; - execbuf.batch_len = (b - buf) * sizeof(uint32_t); - execbuf.flags = USE_LUT; - if (gen >= 6) - execbuf.flags |= I915_EXEC_BLT; - - for (i = 0; i < 1024; i++) { - execbuf.buffers_ptr = (uintptr_t)gem_exec[i]; - gem_execbuf(fd, &execbuf); - } - - for (i = 1024; i--;) { - gem_read(fd, gem_exec[i][0].handle, - i*sizeof(uint32_t), buf + i, sizeof(uint32_t)); - gem_close(fd, gem_exec[i][0].handle); - gem_close(fd, gem_exec[i][1].handle); - } - - if (0) { - for (i = 0; i < 1024; i += 8) - igt_info("%08x %08x %08x %08x %08x %08x %08x %08x\n", - buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], - buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); - } - for (i = 0; i < 1024; i++) - igt_assert_eq(buf[i], 0xc0ffee ^ i); - - return 0; -} - -int fd; - -igt_main -{ - igt_fixture { - fd = drm_open_any(); - } - - igt_subtest("negative-reloc") - negative_reloc(fd, 0); - - igt_subtest("negative-reloc-lut") - negative_reloc(fd, USE_LUT); - - igt_subtest("negative-reloc-blt") - negative_reloc_blt(fd); - - igt_fixture { - close(fd); - } -} diff --git a/tests/gem_basic.c b/tests/gem_basic.c deleted file mode 100644 index f79b0669..00000000 --- a/tests/gem_basic.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright © 2008 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: - * Eric Anholt <eric@anholt.net> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -static void -test_bad_close(int fd) -{ - struct drm_gem_close close_bo; - int ret; - - igt_info("Testing error return on bad close ioctl.\n"); - - close_bo.handle = 0x10101010; - ret = ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo); - - igt_assert(ret == -1 && errno == EINVAL); -} - -static void -test_create_close(int fd) -{ - uint32_t handle; - - igt_info("Testing creating and closing an object.\n"); - - handle = gem_create(fd, 16*1024); - - gem_close(fd, handle); -} - -static void -test_create_fd_close(int fd) -{ - igt_info("Testing closing with an object allocated.\n"); - - gem_create(fd, 16*1024); - /* leak it */ - - close(fd); -} - -int fd; - -igt_main -{ - igt_fixture - fd = drm_open_any(); - - igt_subtest("bad-close") - test_bad_close(fd); - igt_subtest("create-close") - test_create_close(fd); - igt_subtest("create-fd-close") - test_create_fd_close(fd); -} diff --git a/tests/gem_caching.c b/tests/gem_caching.c deleted file mode 100644 index 2fad0ec9..00000000 --- a/tests/gem_caching.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright © 2012 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test snoop consistency when touching partial" - " cachelines."); - -/* - * Testcase: snoop consistency when touching partial cachelines - * - */ - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -drm_intel_bo *scratch_bo; -drm_intel_bo *staging_bo; -#define BO_SIZE (4*4096) -uint32_t devid; -uint64_t mappable_gtt_limit; -int fd; - -static void -copy_bo(drm_intel_bo *src, drm_intel_bo *dst) -{ - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 4096); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH((BO_SIZE/4096) << 16 | 1024); - OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(4096); - OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -static void -blt_bo_fill(drm_intel_bo *tmp_bo, drm_intel_bo *bo, uint8_t val) -{ - uint8_t *gtt_ptr; - int i; - - do_or_die(drm_intel_gem_bo_map_gtt(tmp_bo)); - gtt_ptr = tmp_bo->virtual; - - for (i = 0; i < BO_SIZE; i++) - gtt_ptr[i] = val; - - drm_intel_gem_bo_unmap_gtt(tmp_bo); - - if (bo->offset < mappable_gtt_limit && - (IS_G33(devid) || intel_gen(devid) >= 4)) - igt_trash_aperture(); - - copy_bo(tmp_bo, bo); -} - -#define MAX_BLT_SIZE 128 -#define ROUNDS 1000 -#define TEST_READ 0x1 -#define TEST_WRITE 0x2 -#define TEST_BOTH (TEST_READ | TEST_WRITE) -igt_main -{ - unsigned flags = TEST_BOTH; - int i, j; - uint8_t *cpu_ptr; - uint8_t *gtt_ptr; - - igt_skip_on_simulation(); - - igt_fixture { - srandom(0xdeadbeef); - - fd = drm_open_any(); - - gem_require_caching(fd); - - devid = intel_get_drm_devid(fd); - if (IS_GEN2(devid)) /* chipset only handles cached -> uncached */ - flags &= ~TEST_READ; - if (IS_BROADWATER(devid) || IS_CRESTLINE(devid)) { - /* chipset is completely fubar */ - igt_info("coherency broken on i965g/gm\n"); - flags = 0; - } - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - /* overallocate the buffers we're actually using because */ - scratch_bo = drm_intel_bo_alloc(bufmgr, "scratch bo", BO_SIZE, 4096); - gem_set_caching(fd, scratch_bo->handle, 1); - - staging_bo = drm_intel_bo_alloc(bufmgr, "staging bo", BO_SIZE, 4096); - - igt_init_aperture_trashers(bufmgr); - mappable_gtt_limit = gem_mappable_aperture_size(); - } - - igt_subtest("reads") { - igt_require(flags & TEST_READ); - - igt_info("checking partial reads\n"); - - for (i = 0; i < ROUNDS; i++) { - uint8_t val0 = i; - int start, len; - - blt_bo_fill(staging_bo, scratch_bo, i); - - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - drm_intel_bo_map(scratch_bo, false); - cpu_ptr = scratch_bo->virtual; - for (j = 0; j < len; j++) { - igt_assert_f(cpu_ptr[j] == val0, - "mismatch at %i, got: %i, expected: %i\n", - j, cpu_ptr[j], val0); - } - drm_intel_bo_unmap(scratch_bo); - - igt_progress("partial reads test: ", i, ROUNDS); - } - } - - igt_subtest("writes") { - igt_require(flags & TEST_WRITE); - - igt_info("checking partial writes\n"); - - for (i = 0; i < ROUNDS; i++) { - uint8_t val0 = i, val1; - int start, len; - - blt_bo_fill(staging_bo, scratch_bo, val0); - - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - val1 = val0 + 63; - drm_intel_bo_map(scratch_bo, true); - cpu_ptr = scratch_bo->virtual; - memset(cpu_ptr + start, val1, len); - drm_intel_bo_unmap(scratch_bo); - - copy_bo(scratch_bo, staging_bo); - do_or_die(drm_intel_gem_bo_map_gtt(staging_bo)); - gtt_ptr = staging_bo->virtual; - - for (j = 0; j < start; j++) { - igt_assert_f(gtt_ptr[j] == val0, - "mismatch at %i, partial=[%d+%d] got: %i, expected: %i\n", - j, start, len, gtt_ptr[j], val0); - } - for (; j < start + len; j++) { - igt_assert_f(gtt_ptr[j] == val1, - "mismatch at %i, partial=[%d+%d] got: %i, expected: %i\n", - j, start, len, gtt_ptr[j], val1); - } - for (; j < BO_SIZE; j++) { - igt_assert_f(gtt_ptr[j] == val0, - "mismatch at %i, partial=[%d+%d] got: %i, expected: %i\n", - j, start, len, gtt_ptr[j], val0); - } - drm_intel_gem_bo_unmap_gtt(staging_bo); - - igt_progress("partial writes test: ", i, ROUNDS); - } - } - - igt_subtest("read-writes") { - igt_require((flags & TEST_BOTH) == TEST_BOTH); - - igt_info("checking partial writes after partial reads\n"); - - for (i = 0; i < ROUNDS; i++) { - uint8_t val0 = i, val1, val2; - int start, len; - - blt_bo_fill(staging_bo, scratch_bo, val0); - - /* partial read */ - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - do_or_die(drm_intel_bo_map(scratch_bo, false)); - cpu_ptr = scratch_bo->virtual; - for (j = 0; j < len; j++) { - igt_assert_f(cpu_ptr[j] == val0, - "mismatch in read at %i, got: %i, expected: %i\n", - j, cpu_ptr[j], val0); - } - drm_intel_bo_unmap(scratch_bo); - - /* Change contents through gtt to make the pread cachelines - * stale. */ - val1 = i + 17; - blt_bo_fill(staging_bo, scratch_bo, val1); - - /* partial write */ - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - val2 = i + 63; - do_or_die(drm_intel_bo_map(scratch_bo, false)); - cpu_ptr = scratch_bo->virtual; - memset(cpu_ptr + start, val2, len); - - copy_bo(scratch_bo, staging_bo); - do_or_die(drm_intel_gem_bo_map_gtt(staging_bo)); - gtt_ptr = staging_bo->virtual; - - for (j = 0; j < start; j++) { - igt_assert_f(gtt_ptr[j] == val1, - "mismatch at %i, partial=[%d+%d] got: %i, expected: %i\n", - j, start, len, gtt_ptr[j], val1); - } - for (; j < start + len; j++) { - igt_assert_f(gtt_ptr[j] == val2, - "mismatch at %i, partial=[%d+%d] got: %i, expected: %i\n", - j, start, len, gtt_ptr[j], val2); - } - for (; j < BO_SIZE; j++) { - igt_assert_f(gtt_ptr[j] == val1, - "mismatch at %i, partial=[%d+%d] got: %i, expected: %i\n", - j, start, len, gtt_ptr[j], val1); - } - drm_intel_gem_bo_unmap_gtt(staging_bo); - drm_intel_bo_unmap(scratch_bo); - - igt_progress("partial read/writes test: ", i, ROUNDS); - } - } - - igt_fixture { - igt_cleanup_aperture_trashers(); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_close_race.c b/tests/gem_close_race.c deleted file mode 100644 index c9128f2f..00000000 --- a/tests/gem_close_race.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <pthread.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" - -#define OBJECT_SIZE (256 * 1024) - -#define COPY_BLT_CMD (2<<29|0x53<<22|0x6) -#define BLT_WRITE_ALPHA (1<<21) -#define BLT_WRITE_RGB (1<<20) - -static char device[80]; -static uint32_t devid; -static bool has_64bit_relocations; - -static void selfcopy(int fd, uint32_t handle, int loops) -{ - struct drm_i915_gem_relocation_entry reloc[2]; - struct drm_i915_gem_exec_object2 gem_exec[2]; - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_pwrite gem_pwrite; - struct drm_i915_gem_create create; - uint32_t buf[12], *b = buf; - - memset(reloc, 0, sizeof(reloc)); - memset(gem_exec, 0, sizeof(gem_exec)); - memset(&execbuf, 0, sizeof(execbuf)); - - *b = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB; - if (has_64bit_relocations) - *b += 2; - b++; - *b++ = 0xcc << 16 | 1 << 25 | 1 << 24 | (4*1024); - *b++ = 0; - *b++ = 1 << 16 | 1024; - - reloc[0].offset = (b - buf) * sizeof(*b); - reloc[0].target_handle = handle; - reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; - *b++ = 0; - if (has_64bit_relocations) - *b++ = 0; - - *b++ = 512 << 16; - *b++ = 4*1024; - - reloc[1].offset = (b - buf) * sizeof(*b); - reloc[1].target_handle = handle; - reloc[1].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[1].write_domain = 0; - *b++ = 0; - if (has_64bit_relocations) - *b++ = 0; - - *b++ = MI_BATCH_BUFFER_END; - *b++ = 0; - - gem_exec[0].handle = handle; - - create.handle = 0; - create.size = 4096; - drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); - gem_exec[1].handle = create.handle; - gem_exec[1].relocation_count = 2; - gem_exec[1].relocs_ptr = (uintptr_t)reloc; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 2; - execbuf.batch_len = (b - buf) * sizeof(*b); - if (HAS_BLT_RING(devid)) - execbuf.flags |= I915_EXEC_BLT; - - gem_pwrite.handle = gem_exec[1].handle; - gem_pwrite.offset = 0; - gem_pwrite.size = execbuf.batch_len; - gem_pwrite.data_ptr = (uintptr_t)buf; - if (drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &gem_pwrite) == 0) { - while (loops--) - drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - } - - drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create.handle); -} - -static uint32_t load(int fd) -{ - uint32_t handle; - - handle = gem_create(fd, OBJECT_SIZE); - if (handle == 0) - return 0; - - selfcopy(fd, handle, 100); - return handle; -} - -static void run(int child) -{ - uint32_t handle; - int fd; - - fd = open(device, O_RDWR); - igt_assert(fd != -1); - - handle = load(fd); - if ((child & 63) == 63) - gem_read(fd, handle, 0, &handle, sizeof(handle)); -} - -#define NUM_FD 768 - -struct thread { - pthread_mutex_t mutex; - int device; - int fds[NUM_FD]; - int done; -}; - -static void *thread_run(void *_data) -{ - struct thread *t = _data; - uint32_t handle = gem_create(t->device, OBJECT_SIZE); - struct drm_gem_open arg = { gem_flink(t->device, handle) }; - - pthread_mutex_lock(&t->mutex); - while (!t->done) { - pthread_mutex_unlock(&t->mutex); - - for (int n = 0; n < NUM_FD; n++) { - int fd = t->fds[n]; - - arg.handle = 0; - drmIoctl(fd, DRM_IOCTL_GEM_OPEN, &arg); - if (arg.handle == 0) - continue; - - selfcopy(fd, arg.handle, 100); - - drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &arg.handle); - } - - pthread_mutex_lock(&t->mutex); - } - pthread_mutex_unlock(&t->mutex); - - gem_close(t->device, handle); - return 0; -} - -static void *thread_busy(void *_data) -{ - struct thread *t = _data; - uint32_t handle = gem_create(t->device, OBJECT_SIZE); - struct drm_gem_open arg = { gem_flink(t->device, handle) }; - - pthread_mutex_lock(&t->mutex); - while (!t->done) { - struct drm_i915_gem_busy busy; - int fd = t->fds[rand() % NUM_FD]; - - pthread_mutex_unlock(&t->mutex); - - arg.handle = 0; - drmIoctl(fd, DRM_IOCTL_GEM_OPEN, &arg); - if (arg.handle == 0) - continue; - - selfcopy(fd, arg.handle, 10); - - busy.handle = arg.handle; - drmIoctl(fd, DRM_IOCTL_I915_GEM_BUSY, &busy); - - drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &arg.handle); - - usleep(10*1000); - - pthread_mutex_lock(&t->mutex); - } - pthread_mutex_unlock(&t->mutex); - - gem_close(t->device, handle); - return 0; -} - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - int fd; - - sprintf(device, "/dev/dri/card%d", drm_get_card()); - fd = open(device, O_RDWR); - - igt_assert(fd != -1); - devid = intel_get_drm_devid(fd); - has_64bit_relocations = intel_gen(devid) >= 8; - close(fd); - } - - igt_subtest("process-exit") { - igt_fork(child, NUM_FD) - run(child); - igt_waitchildren(); - } - - igt_subtest("gem-close-race") { - pthread_t thread[2]; - struct thread *data = calloc(1, sizeof(struct thread)); - int n; - - igt_assert(data); - - pthread_mutex_init(&data->mutex, NULL); - data->device = open(device, O_RDWR); - for (n = 0; n < NUM_FD; n++) - data->fds[n] = open(device, O_RDWR); - - pthread_create(&thread[0], NULL, thread_run, data); - pthread_create(&thread[1], NULL, thread_busy, data); - - for (n = 0; n < 1000*NUM_FD; n++) { - int i = rand() % NUM_FD; - if (data->fds[i] == -1) { - data->fds[i] = open(device, O_RDWR); - } else{ - close(data->fds[i]); - data->fds[i] = -1; - } - } - - pthread_mutex_lock(&data->mutex); - data->done = 1; - pthread_mutex_unlock(&data->mutex); - - pthread_join(thread[1], NULL); - pthread_join(thread[0], NULL); - - for (n = 0; n < NUM_FD; n++) - close(data->fds[n]); - close(data->device); - free(data); - } -} diff --git a/tests/gem_concurrent_blit.c b/tests/gem_concurrent_blit.c deleted file mode 100644 index e1693ba7..00000000 --- a/tests/gem_concurrent_blit.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Copyright © 2009,2012,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: - * Eric Anholt <eric@anholt.net> - * Chris Wilson <chris@chris-wilson.co.uk> - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/** @file gem_concurrent_blit.c - * - * This is a test of pread/pwrite behavior when writing to active - * buffers. - * - * Based on gem_gtt_concurrent_blt. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/wait.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_aux.h" -#include "igt_core.h" -#include "igt_gt.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Test of pread/pwrite behavior when writing to active" - " buffers."); - -int fd, devid, gen; -struct intel_batchbuffer *batch; - -static void -nop_release_bo(drm_intel_bo *bo) -{ - drm_intel_bo_unreference(bo); -} - -static void -prw_set_bo(drm_intel_bo *bo, uint32_t val, int width, int height) -{ - int size = width * height, i; - uint32_t *tmp; - - tmp = malloc(4*size); - if (tmp) { - for (i = 0; i < size; i++) - tmp[i] = val; - drm_intel_bo_subdata(bo, 0, 4*size, tmp); - free(tmp); - } else { - for (i = 0; i < size; i++) - drm_intel_bo_subdata(bo, 4*i, 4, &val); - } -} - -static void -prw_cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height, drm_intel_bo *tmp) -{ - int size = width * height, i; - uint32_t *vaddr; - - do_or_die(drm_intel_bo_map(tmp, true)); - do_or_die(drm_intel_bo_get_subdata(bo, 0, 4*size, tmp->virtual)); - vaddr = tmp->virtual; - for (i = 0; i < size; i++) - igt_assert_eq_u32(vaddr[i], val); - drm_intel_bo_unmap(tmp); -} - -static drm_intel_bo * -unmapped_create_bo(drm_intel_bufmgr *bufmgr, int width, int height) -{ - drm_intel_bo *bo; - - bo = drm_intel_bo_alloc(bufmgr, "bo", 4*width*height, 0); - igt_assert(bo); - - return bo; -} - -static void -gtt_set_bo(drm_intel_bo *bo, uint32_t val, int width, int height) -{ - uint32_t *vaddr = bo->virtual; - int size = width * height; - - drm_intel_gem_bo_start_gtt_access(bo, true); - while (size--) - *vaddr++ = val; -} - -static void -gtt_cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height, drm_intel_bo *tmp) -{ - uint32_t *vaddr = bo->virtual; - int y; - - /* GTT access is slow. So we just compare a few points */ - drm_intel_gem_bo_start_gtt_access(bo, false); - for (y = 0; y < height; y++) - igt_assert_eq_u32(vaddr[y*width+y], val); -} - -static drm_intel_bo * -map_bo(drm_intel_bo *bo) -{ - /* gtt map doesn't have a write parameter, so just keep the mapping - * around (to avoid the set_domain with the gtt write domain set) and - * manually tell the kernel when we start access the gtt. */ - do_or_die(drm_intel_gem_bo_map_gtt(bo)); - - return bo; -} - -static drm_intel_bo * -tile_bo(drm_intel_bo *bo, int width) -{ - uint32_t tiling = I915_TILING_X; - uint32_t stride = width * 4; - - do_or_die(drm_intel_bo_set_tiling(bo, &tiling, stride)); - - return bo; -} - -static drm_intel_bo * -gtt_create_bo(drm_intel_bufmgr *bufmgr, int width, int height) -{ - return map_bo(unmapped_create_bo(bufmgr, width, height)); -} - -static drm_intel_bo * -gttX_create_bo(drm_intel_bufmgr *bufmgr, int width, int height) -{ - return tile_bo(gtt_create_bo(bufmgr, width, height), width); -} - -static drm_intel_bo * -wc_create_bo(drm_intel_bufmgr *bufmgr, int width, int height) -{ - drm_intel_bo *bo; - - gem_require_mmap_wc(fd); - - bo = unmapped_create_bo(bufmgr, width, height); - bo->virtual = gem_mmap__wc(fd, bo->handle, 0, bo->size, PROT_READ | PROT_WRITE); - return bo; -} - -static void -wc_release_bo(drm_intel_bo *bo) -{ - munmap(bo->virtual, bo->size); - bo->virtual = NULL; - - nop_release_bo(bo); -} - -static drm_intel_bo * -gpu_create_bo(drm_intel_bufmgr *bufmgr, int width, int height) -{ - return unmapped_create_bo(bufmgr, width, height); -} - - -static drm_intel_bo * -gpuX_create_bo(drm_intel_bufmgr *bufmgr, int width, int height) -{ - return tile_bo(gpu_create_bo(bufmgr, width, height), width); -} - -static void -cpu_set_bo(drm_intel_bo *bo, uint32_t val, int width, int height) -{ - int size = width * height; - uint32_t *vaddr; - - do_or_die(drm_intel_bo_map(bo, true)); - vaddr = bo->virtual; - while (size--) - *vaddr++ = val; - drm_intel_bo_unmap(bo); -} - -static void -cpu_cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height, drm_intel_bo *tmp) -{ - int size = width * height; - uint32_t *vaddr; - - do_or_die(drm_intel_bo_map(bo, false)); - vaddr = bo->virtual; - while (size--) - igt_assert_eq_u32(*vaddr++, val); - drm_intel_bo_unmap(bo); -} - -static void -gpu_set_bo(drm_intel_bo *bo, uint32_t val, int width, int height) -{ - struct drm_i915_gem_relocation_entry reloc[1]; - struct drm_i915_gem_exec_object2 gem_exec[2]; - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_pwrite gem_pwrite; - struct drm_i915_gem_create create; - uint32_t buf[10], *b; - uint32_t tiling, swizzle; - - drm_intel_bo_get_tiling(bo, &tiling, &swizzle); - - memset(reloc, 0, sizeof(reloc)); - memset(gem_exec, 0, sizeof(gem_exec)); - memset(&execbuf, 0, sizeof(execbuf)); - - b = buf; - *b++ = XY_COLOR_BLT_CMD_NOLEN | - ((gen >= 8) ? 5 : 4) | - COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; - if (gen >= 4 && tiling) { - b[-1] |= XY_COLOR_BLT_TILED; - *b = width; - } else - *b = width << 2; - *b++ |= 0xf0 << 16 | 1 << 25 | 1 << 24; - *b++ = 0; - *b++ = height << 16 | width; - reloc[0].offset = (b - buf) * sizeof(uint32_t); - reloc[0].target_handle = bo->handle; - reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; - *b++ = 0; - if (gen >= 8) - *b++ = 0; - *b++ = val; - *b++ = MI_BATCH_BUFFER_END; - if ((b - buf) & 1) - *b++ = 0; - - gem_exec[0].handle = bo->handle; - gem_exec[0].flags = EXEC_OBJECT_NEEDS_FENCE; - - create.handle = 0; - create.size = 4096; - drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); - gem_exec[1].handle = create.handle; - gem_exec[1].relocation_count = 1; - gem_exec[1].relocs_ptr = (uintptr_t)reloc; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 2; - execbuf.batch_len = (b - buf) * sizeof(buf[0]); - if (gen >= 6) - execbuf.flags = I915_EXEC_BLT; - - gem_pwrite.handle = gem_exec[1].handle; - gem_pwrite.offset = 0; - gem_pwrite.size = execbuf.batch_len; - gem_pwrite.data_ptr = (uintptr_t)buf; - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &gem_pwrite)); - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - - drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create.handle); -} - -static void -gpu_cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height, drm_intel_bo *tmp) -{ - intel_copy_bo(batch, tmp, bo, width*height*4); - cpu_cmp_bo(tmp, val, width, height, NULL); -} - -const struct access_mode { - const char *name; - void (*set_bo)(drm_intel_bo *bo, uint32_t val, int w, int h); - void (*cmp_bo)(drm_intel_bo *bo, uint32_t val, int w, int h, drm_intel_bo *tmp); - drm_intel_bo *(*create_bo)(drm_intel_bufmgr *bufmgr, int width, int height); - void (*release_bo)(drm_intel_bo *bo); -} access_modes[] = { - { - .name = "prw", - .set_bo = prw_set_bo, - .cmp_bo = prw_cmp_bo, - .create_bo = unmapped_create_bo, - .release_bo = nop_release_bo, - }, - { - .name = "cpu", - .set_bo = cpu_set_bo, - .cmp_bo = cpu_cmp_bo, - .create_bo = unmapped_create_bo, - .release_bo = nop_release_bo, - }, - { - .name = "gtt", - .set_bo = gtt_set_bo, - .cmp_bo = gtt_cmp_bo, - .create_bo = gtt_create_bo, - .release_bo = nop_release_bo, - }, - { - .name = "gttX", - .set_bo = gtt_set_bo, - .cmp_bo = gtt_cmp_bo, - .create_bo = gttX_create_bo, - .release_bo = nop_release_bo, - }, - { - .name = "wc", - .set_bo = gtt_set_bo, - .cmp_bo = gtt_cmp_bo, - .create_bo = wc_create_bo, - .release_bo = wc_release_bo, - }, - { - .name = "gpu", - .set_bo = gpu_set_bo, - .cmp_bo = gpu_cmp_bo, - .create_bo = gpu_create_bo, - .release_bo = nop_release_bo, - }, - { - .name = "gpuX", - .set_bo = gpu_set_bo, - .cmp_bo = gpu_cmp_bo, - .create_bo = gpuX_create_bo, - .release_bo = nop_release_bo, - }, -}; - -#define MAX_NUM_BUFFERS 1024 -int num_buffers = MAX_NUM_BUFFERS; -const int width = 512, height = 512; -igt_render_copyfunc_t rendercopy; - -typedef void (*do_copy)(drm_intel_bo *dst, drm_intel_bo *src); -typedef struct igt_hang_ring (*do_hang)(void); - -static void render_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) -{ - struct igt_buf d = { - .bo = dst, - .size = width * height * 4, - .num_tiles = width * height * 4, - .stride = width * 4, - }, s = { - .bo = src, - .size = width * height * 4, - .num_tiles = width * height * 4, - .stride = width * 4, - }; - uint32_t swizzle; - - drm_intel_bo_get_tiling(dst, &d.tiling, &swizzle); - drm_intel_bo_get_tiling(src, &s.tiling, &swizzle); - - rendercopy(batch, NULL, - &s, 0, 0, - width, height, - &d, 0, 0); -} - -static void blt_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) -{ - intel_blt_copy(batch, - src, 0, 0, 4*width, - dst, 0, 0, 4*width, - width, height, 32); -} - -static void cpu_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) -{ - const int size = width * height * sizeof(uint32_t); - void *d, *s; - - gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_CPU, 0); - gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); - s = gem_mmap__cpu(fd, src->handle, 0, size, PROT_READ); - igt_assert(s != NULL); - d = gem_mmap__cpu(fd, dst->handle, 0, size, PROT_WRITE); - igt_assert(d != NULL); - - memcpy(d, s, size); - - munmap(d, size); - munmap(s, size); -} - -static void gtt_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) -{ - const int size = width * height * sizeof(uint32_t); - void *d, *s; - - gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_GTT, 0); - gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - - s = gem_mmap__gtt(fd, src->handle, size, PROT_READ); - igt_assert(s != NULL); - d = gem_mmap__gtt(fd, dst->handle, size, PROT_WRITE); - igt_assert(d != NULL); - - memcpy(d, s, size); - - munmap(d, size); - munmap(s, size); -} - -static void wc_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) -{ - const int size = width * height * sizeof(uint32_t); - void *d, *s; - - gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_GTT, 0); - gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - - s = gem_mmap__wc(fd, src->handle, 0, size, PROT_READ); - igt_assert(s != NULL); - d = gem_mmap__wc(fd, dst->handle, 0, size, PROT_WRITE); - igt_assert(d != NULL); - - memcpy(d, s, size); - - munmap(d, size); - munmap(s, size); -} - -static struct igt_hang_ring no_hang(void) -{ - return (struct igt_hang_ring){0, 0}; -} - -static struct igt_hang_ring bcs_hang(void) -{ - return igt_hang_ring(fd, I915_EXEC_BLT); -} - -static struct igt_hang_ring rcs_hang(void) -{ - return igt_hang_ring(fd, I915_EXEC_RENDER); -} - -static void hang_require(void) -{ - igt_require_hang_ring(fd, -1); -} - -static void do_overwrite_source(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_copy do_copy_func, - do_hang do_hang_func) -{ - struct igt_hang_ring hang; - int i; - - gem_quiescent_gpu(fd); - for (i = 0; i < num_buffers; i++) { - mode->set_bo(src[i], i, width, height); - mode->set_bo(dst[i], ~i, width, height); - } - for (i = 0; i < num_buffers; i++) - do_copy_func(dst[i], src[i]); - hang = do_hang_func(); - for (i = num_buffers; i--; ) - mode->set_bo(src[i], 0xdeadbeef, width, height); - for (i = 0; i < num_buffers; i++) - mode->cmp_bo(dst[i], i, width, height, dummy); - igt_post_hang_ring(fd, hang); -} - -static void do_overwrite_source__rev(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_copy do_copy_func, - do_hang do_hang_func) -{ - struct igt_hang_ring hang; - int i; - - gem_quiescent_gpu(fd); - for (i = 0; i < num_buffers; i++) { - mode->set_bo(src[i], i, width, height); - mode->set_bo(dst[i], ~i, width, height); - } - for (i = 0; i < num_buffers; i++) - do_copy_func(dst[i], src[i]); - hang = do_hang_func(); - for (i = 0; i < num_buffers; i++) - mode->set_bo(src[i], 0xdeadbeef, width, height); - for (i = num_buffers; i--; ) - mode->cmp_bo(dst[i], i, width, height, dummy); - igt_post_hang_ring(fd, hang); -} - -static void do_overwrite_source__one(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_copy do_copy_func, - do_hang do_hang_func) -{ - struct igt_hang_ring hang; - - gem_quiescent_gpu(fd); - mode->set_bo(src[0], 0, width, height); - mode->set_bo(dst[0], ~0, width, height); - do_copy_func(dst[0], src[0]); - hang = do_hang_func(); - mode->set_bo(src[0], 0xdeadbeef, width, height); - mode->cmp_bo(dst[0], 0, width, height, dummy); - igt_post_hang_ring(fd, hang); -} - -static void do_early_read(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_copy do_copy_func, - do_hang do_hang_func) -{ - struct igt_hang_ring hang; - int i; - - gem_quiescent_gpu(fd); - for (i = num_buffers; i--; ) - mode->set_bo(src[i], 0xdeadbeef, width, height); - for (i = 0; i < num_buffers; i++) - do_copy_func(dst[i], src[i]); - hang = do_hang_func(); - for (i = num_buffers; i--; ) - mode->cmp_bo(dst[i], 0xdeadbeef, width, height, dummy); - igt_post_hang_ring(fd, hang); -} - -static void do_gpu_read_after_write(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_copy do_copy_func, - do_hang do_hang_func) -{ - struct igt_hang_ring hang; - int i; - - gem_quiescent_gpu(fd); - for (i = num_buffers; i--; ) - mode->set_bo(src[i], 0xabcdabcd, width, height); - for (i = 0; i < num_buffers; i++) - do_copy_func(dst[i], src[i]); - for (i = num_buffers; i--; ) - do_copy_func(dummy, dst[i]); - hang = do_hang_func(); - for (i = num_buffers; i--; ) - mode->cmp_bo(dst[i], 0xabcdabcd, width, height, dummy); - igt_post_hang_ring(fd, hang); -} - -typedef void (*do_test)(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_copy do_copy_func, - do_hang do_hang_func); - -typedef void (*run_wrap)(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_test do_test_func, - do_copy do_copy_func, - do_hang do_hang_func); - -static void run_single(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_test do_test_func, - do_copy do_copy_func, - do_hang do_hang_func) -{ - do_test_func(mode, src, dst, dummy, do_copy_func, do_hang_func); -} - -static void run_interruptible(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_test do_test_func, - do_copy do_copy_func, - do_hang do_hang_func) -{ - int loop; - - for (loop = 0; loop < 10; loop++) - do_test_func(mode, src, dst, dummy, do_copy_func, do_hang_func); -} - -static void run_forked(const struct access_mode *mode, - drm_intel_bo **src, drm_intel_bo **dst, - drm_intel_bo *dummy, - do_test do_test_func, - do_copy do_copy_func, - do_hang do_hang_func) -{ - const int old_num_buffers = num_buffers; - - num_buffers /= 16; - num_buffers += 2; - - igt_fork(child, 16) { - drm_intel_bufmgr *bufmgr; - - /* recreate process local variables */ - fd = drm_open_any(); - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, devid); - - for (int i = 0; i < num_buffers; i++) { - src[i] = mode->create_bo(bufmgr, width, height); - dst[i] = mode->create_bo(bufmgr, width, height); - } - dummy = mode->create_bo(bufmgr, width, height); - - for (int loop = 0; loop < 10; loop++) - do_test_func(mode, src, dst, dummy, - do_copy_func, do_hang_func); - - for (int i = 0; i < num_buffers; i++) { - mode->release_bo(src[i]); - mode->release_bo(dst[i]); - } - mode->release_bo(dummy); - } - - igt_waitchildren(); - - num_buffers = old_num_buffers; -} - -static void bit17_require(void) -{ - struct drm_i915_gem_get_tiling2 { - uint32_t handle; - uint32_t tiling_mode; - uint32_t swizzle_mode; - uint32_t phys_swizzle_mode; - } arg; -#define DRM_IOCTL_I915_GEM_GET_TILING2 DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling2) - - memset(&arg, 0, sizeof(arg)); - arg.handle = gem_create(fd, 4096); - gem_set_tiling(fd, arg.handle, I915_TILING_X, 512); - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING2, &arg)); - gem_close(fd, arg.handle); - igt_require(arg.phys_swizzle_mode == arg.swizzle_mode); -} - -static void cpu_require(void) -{ - bit17_require(); -} - -static void gtt_require(void) -{ -} - -static void wc_require(void) -{ - bit17_require(); - gem_require_mmap_wc(fd); -} - -static void bcs_require(void) -{ -} - -static void rcs_require(void) -{ - igt_require(rendercopy); -} - -static void no_require(void) -{ -} - -static void -run_basic_modes(const struct access_mode *mode, - const char *suffix, - run_wrap run_wrap_func) -{ - const struct { - const char *prefix; - do_copy copy; - void (*require)(void); - } pipelines[] = { - { "cpu", cpu_copy_bo, cpu_require }, - { "gtt", gtt_copy_bo, gtt_require }, - { "wc", wc_copy_bo, wc_require }, - { "blt", blt_copy_bo, bcs_require }, - { "render", render_copy_bo, rcs_require }, - { NULL, NULL } - }, *p; - const struct { - const char *suffix; - do_hang hang; - void (*require)(void); - } hangs[] = { - { "", no_hang, no_require }, - { "-hang-blt", bcs_hang, hang_require }, - { "-hang-render", rcs_hang, hang_require }, - { NULL, NULL }, - }, *h; - drm_intel_bo *src[MAX_NUM_BUFFERS], *dst[MAX_NUM_BUFFERS], *dummy = NULL; - drm_intel_bufmgr *bufmgr; - - - for (h = hangs; h->suffix; h++) { - for (p = pipelines; p->prefix; p++) { - igt_fixture { - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - for (int i = 0; i < num_buffers; i++) { - src[i] = mode->create_bo(bufmgr, width, height); - dst[i] = mode->create_bo(bufmgr, width, height); - } - dummy = mode->create_bo(bufmgr, width, height); - } - - /* try to overwrite the source values */ - igt_subtest_f("%s-%s-overwrite-source-one%s%s", mode->name, p->prefix, suffix, h->suffix) { - h->require(); - p->require(); - run_wrap_func(mode, src, dst, dummy, - do_overwrite_source__one, - p->copy, h->hang); - } - - igt_subtest_f("%s-%s-overwrite-source%s%s", mode->name, p->prefix, suffix, h->suffix) { - h->require(); - p->require(); - run_wrap_func(mode, src, dst, dummy, - do_overwrite_source, - p->copy, h->hang); - } - igt_subtest_f("%s-%s-overwrite-source-rev%s%s", mode->name, p->prefix, suffix, h->suffix) { - h->require(); - p->require(); - run_wrap_func(mode, src, dst, dummy, - do_overwrite_source__rev, - p->copy, h->hang); - } - - /* try to read the results before the copy completes */ - igt_subtest_f("%s-%s-early-read%s%s", mode->name, p->prefix, suffix, h->suffix) { - h->require(); - p->require(); - run_wrap_func(mode, src, dst, dummy, - do_early_read, - p->copy, h->hang); - } - - /* and finally try to trick the kernel into loosing the pending write */ - igt_subtest_f("%s-%s-gpu-read-after-write%s%s", mode->name, p->prefix, suffix, h->suffix) { - h->require(); - p->require(); - run_wrap_func(mode, src, dst, dummy, - do_gpu_read_after_write, - p->copy, h->hang); - } - - igt_fixture { - for (int i = 0; i < num_buffers; i++) { - mode->release_bo(src[i]); - mode->release_bo(dst[i]); - } - mode->release_bo(dummy); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - } - } - } -} - -static void -run_modes(const struct access_mode *mode) -{ - run_basic_modes(mode, "", run_single); - - igt_fork_signal_helper(); - run_basic_modes(mode, "-interruptible", run_interruptible); - igt_stop_signal_helper(); - - igt_fork_signal_helper(); - run_basic_modes(mode, "-forked", run_forked); - igt_stop_signal_helper(); -} - -igt_main -{ - int max, i; - - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - gen = intel_gen(devid); - rendercopy = igt_get_render_copyfunc(devid); - - max = gem_aperture_size (fd) / (1024 * 1024) / 2; - if (num_buffers > max) - num_buffers = max; - - max = intel_get_total_ram_mb() * 3 / 4; - if (num_buffers > max) - num_buffers = max; - num_buffers /= 2; - igt_info("using 2x%d buffers, each 1MiB\n", num_buffers); - } - - for (i = 0; i < ARRAY_SIZE(access_modes); i++) - run_modes(&access_modes[i]); -} diff --git a/tests/gem_cpu_reloc.c b/tests/gem_cpu_reloc.c deleted file mode 100644 index c67907ad..00000000 --- a/tests/gem_cpu_reloc.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright © 2012 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/* - * Testcase: Test the relocations through the CPU domain - * - * Attempt to stress test performing relocations whilst the batch is in the - * CPU domain. - * - * A freshly allocated buffer starts in the CPU domain, and the pwrite - * should also be performed whilst in the CPU domain and so we should - * execute the relocations within the CPU domain. If for any reason one of - * those steps should land it in the GTT domain, we take the secondary - * precaution of filling the mappable portion of the GATT. - * - * In order to detect whether a relocation fails, we first fill a target - * buffer with a sequence of invalid commands that would cause the GPU to - * immediate hang, and then attempt to overwrite them with a legal, if - * short, batchbuffer using a BLT. Then we come to execute the bo, if the - * relocation fail and we either copy across all zeros or garbage, then the - * GPU will hang. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test the relocations through the CPU domain."); - -static uint32_t use_blt; - -static void copy(int fd, uint32_t batch, uint32_t src, uint32_t dst) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_relocation_entry gem_reloc[2]; - struct drm_i915_gem_exec_object2 gem_exec[3]; - - gem_reloc[0].offset = 4 * sizeof(uint32_t); - gem_reloc[0].delta = 0; - gem_reloc[0].target_handle = dst; - gem_reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - gem_reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; - gem_reloc[0].presumed_offset = 0; - - gem_reloc[1].offset = 7 * sizeof(uint32_t); - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - gem_reloc[1].offset += sizeof(uint32_t); - gem_reloc[1].delta = 0; - gem_reloc[1].target_handle = src; - gem_reloc[1].read_domains = I915_GEM_DOMAIN_RENDER; - gem_reloc[1].write_domain = 0; - gem_reloc[1].presumed_offset = 0; - - memset(gem_exec, 0, sizeof(gem_exec)); - gem_exec[0].handle = src; - gem_exec[1].handle = dst; - gem_exec[2].handle = batch; - gem_exec[2].relocation_count = 2; - gem_exec[2].relocs_ptr = (uintptr_t)gem_reloc; - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 3; - execbuf.batch_len = 4096; - execbuf.flags = use_blt; - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); -} - -static void exec(int fd, uint32_t handle) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec; - - memset(&gem_exec, 0, sizeof(gem_exec)); - gem_exec.handle = handle; - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)&gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_len = 4096; - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); -} - -uint32_t gen6_batch[] = { - (XY_SRC_COPY_BLT_CMD | 6 | - XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB), - (3 << 24 | /* 32 bits */ - 0xcc << 16 | /* copy ROP */ - 4096), - 0 << 16 | 0, /* dst x1, y1 */ - 1 << 16 | 2, - 0, /* dst relocation */ - 0 << 16 | 0, /* src x1, y1 */ - 4096, - 0, /* src relocation */ - MI_BATCH_BUFFER_END, -}; - -uint32_t gen8_batch[] = { - (XY_SRC_COPY_BLT_CMD | 8 | - XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB), - (3 << 24 | /* 32 bits */ - 0xcc << 16 | /* copy ROP */ - 4096), - 0 << 16 | 0, /* dst x1, y1 */ - 1 << 16 | 2, - 0, /* dst relocation */ - 0, /* FIXME */ - 0 << 16 | 0, /* src x1, y1 */ - 4096, - 0, /* src relocation */ - 0, /* FIXME */ - MI_BATCH_BUFFER_END, -}; - -uint32_t *batch = gen6_batch; -uint32_t batch_size = sizeof(gen6_batch); - -igt_simple_main -{ - const uint32_t hang[] = {-1, -1, -1, -1}; - const uint32_t end[] = {MI_BATCH_BUFFER_END, 0}; - uint64_t aper_size; - uint32_t noop; - uint32_t *handles; - int fd, i, count; - - fd = drm_open_any(); - noop = intel_get_drm_devid(fd); - - use_blt = 0; - if (intel_gen(noop) >= 6) - use_blt = I915_EXEC_BLT; - - if (intel_gen(noop) >= 8) { - batch = gen8_batch; - batch_size += 2 * 4; - } - - aper_size = gem_mappable_aperture_size(); - count = aper_size / 4096 * 2; - if (igt_run_in_simulation()) - count = 10; - - intel_require_memory(1+count, 4096, CHECK_RAM); - - handles = malloc (count * sizeof(uint32_t)); - igt_assert(handles); - - noop = gem_create(fd, 4096); - gem_write(fd, noop, 0, end, sizeof(end)); - - /* fill the entire gart with batches and run them */ - for (i = 0; i < count; i++) { - uint32_t bad; - - handles[i] = gem_create(fd, 4096); - gem_write(fd, handles[i], 0, batch, batch_size); - - bad = gem_create(fd, 4096); - gem_write(fd, bad, 0, hang, sizeof(hang)); - gem_write(fd, bad, 4096-sizeof(end), end, sizeof(end)); - - /* launch the newly created batch */ - copy(fd, handles[i], noop, bad); - exec(fd, bad); - gem_close(fd, bad); - - igt_progress("gem_cpu_reloc: ", i, 2*count); - } - - /* And again in reverse to try and catch the relocation code out */ - for (i = 0; i < count; i++) { - uint32_t bad; - - bad = gem_create(fd, 4096); - gem_write(fd, bad, 0, hang, sizeof(hang)); - gem_write(fd, bad, 4096-sizeof(end), end, sizeof(end)); - - /* launch the newly created batch */ - copy(fd, handles[count-i-1], noop, bad); - exec(fd, bad); - gem_close(fd, bad); - - igt_progress("gem_cpu_reloc: ", count+i, 3*count); - } - - /* Third time lucky? */ - for (i = 0; i < count; i++) { - uint32_t bad; - - bad = gem_create(fd, 4096); - gem_write(fd, bad, 0, hang, sizeof(hang)); - gem_write(fd, bad, 4096-sizeof(end), end, sizeof(end)); - - /* launch the newly created batch */ - gem_set_domain(fd, handles[i], - I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); - copy(fd, handles[i], noop, bad); - exec(fd, bad); - gem_close(fd, bad); - - igt_progress("gem_cpu_reloc: ", 2*count+i, 3*count); - } - - igt_info("Test suceeded, cleanup up - this might take a while.\n"); - close(fd); -} diff --git a/tests/gem_cs_prefetch.c b/tests/gem_cs_prefetch.c deleted file mode 100644 index 700883c8..00000000 --- a/tests/gem_cs_prefetch.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/* - * Testcase: Test the CS prefetch behaviour on batches - * - * Historically the batch prefetcher doesn't check whether it's crossing page - * boundaries and likes to throw up when it gets a pagefault in return for his - * over-eager behaviour. Check for this. - * - * This test for a bug where we've failed to plug a scratch pte entry into the - * very last gtt pte. - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test the CS prefetch behaviour on batches."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -static void exec(int fd, uint32_t handle) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[1]; - int ret = 0; - - gem_exec[0].handle = handle; - gem_exec[0].relocation_count = 0; - gem_exec[0].relocs_ptr = 0; - gem_exec[0].alignment = 0; - gem_exec[0].offset = 0; - gem_exec[0].flags = 0; - gem_exec[0].rsvd1 = 0; - gem_exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 4096; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = 0; - execbuf.rsvd1 = 0; - execbuf.rsvd2 = 0; - - ret = drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - gem_sync(fd, handle); - igt_assert(ret == 0); -} - -igt_simple_main -{ - uint32_t batch_end[4] = {MI_BATCH_BUFFER_END, 0, 0, 0}; - int fd, i, ret; - uint64_t aper_size; - int count; - drm_intel_bo *sample_batch_bo; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - aper_size = gem_aperture_size(fd); - - /* presume a big per-bo overhead */ - igt_skip_on_f(intel_get_total_ram_mb() < (aper_size / (1024*1024)) * 3 / 2, - "not enough mem to run test\n"); - - count = aper_size / 4096; - - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - igt_assert(batch); - - sample_batch_bo = drm_intel_bo_alloc(bufmgr, "", 4096, 4096); - igt_assert(sample_batch_bo); - ret = drm_intel_bo_subdata(sample_batch_bo, 4096-sizeof(batch_end), - sizeof(batch_end), batch_end); - igt_assert(ret == 0); - - /* fill the entire gart with batches and run them */ - for (i = 0; i < count; i++) { - drm_intel_bo *batch_bo; - - batch_bo = drm_intel_bo_alloc(bufmgr, "", 4096, 4096); - igt_assert(batch_bo); - - /* copy the sample batch with the gpu to the new one, so that we - * also test the unmappable part of the gtt. */ - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 4096); - OUT_BATCH(0); /* dst y1,x1 */ - OUT_BATCH((1 << 16) | 1024); - OUT_RELOC_FENCED(batch_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH((0 << 16) | 0); /* src x1, y1 */ - OUT_BATCH(4096); - OUT_RELOC_FENCED(sample_batch_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); - if (i % 100 == 0) - gem_sync(fd, batch_bo->handle); - - drm_intel_bo_disable_reuse(batch_bo); - - /* launch the newly created batch */ - exec(fd, batch_bo->handle); - - // leak buffers - //drm_intel_bo_unreference(batch_bo); - igt_progress("gem_cs_prefetch: ", i, count); - } - - igt_info("Test suceeded, cleanup up - this might take a while.\n"); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_cs_tlb.c b/tests/gem_cs_tlb.c deleted file mode 100644 index 5b8b993c..00000000 --- a/tests/gem_cs_tlb.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright © 2011,2012 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/* - * Testcase: Check whether we correctly invalidate the cs tlb - * - * Motivated by a strange bug on launchpad where *acth != ipehr, on snb notably - * where everything should be coherent by default. - * - * https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1063252 - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Check whether we correctly invalidate the cs tlb."); - -#define LOCAL_I915_EXEC_VEBOX (4<<0) -#define BATCH_SIZE (1024*1024) - -static int exec(int fd, uint32_t handle, int split, - uint64_t *gtt_ofs, unsigned ring_id) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[1]; - int ret = 0; - - gem_exec[0].handle = handle; - gem_exec[0].relocation_count = 0; - gem_exec[0].relocs_ptr = 0; - gem_exec[0].alignment = 0; - gem_exec[0].offset = 0x00100000; - gem_exec[0].flags = 0; - gem_exec[0].rsvd1 = 0; - gem_exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8*(split+1); - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring_id; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - ret = drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - - *gtt_ofs = gem_exec[0].offset; - - return ret; -} - -static void run_on_ring(int fd, unsigned ring_id, const char *ring_name) -{ - uint32_t handle, handle_new; - uint64_t gtt_offset, gtt_offset_new; - uint32_t *batch_ptr, *batch_ptr_old; - unsigned split; - char buf[100]; - int i; - - gem_require_ring(fd, ring_id); - - sprintf(buf, "testing %s cs tlb coherency: ", ring_name); - - /* Shut up gcc, too stupid. */ - batch_ptr_old = NULL; - handle = 0; - gtt_offset = 0; - - for (split = 0; split < BATCH_SIZE/8 - 1; split += 2) { - igt_progress(buf, split, BATCH_SIZE/8 - 1); - - handle_new = gem_create(fd, BATCH_SIZE); - batch_ptr = gem_mmap__cpu(fd, handle_new, 0, BATCH_SIZE, - PROT_READ | PROT_WRITE); - batch_ptr[split*2] = MI_BATCH_BUFFER_END; - - for (i = split*2 + 2; i < BATCH_SIZE/8; i++) - batch_ptr[i] = 0xffffffff; - - if (split > 0) { - gem_sync(fd, handle); - gem_close(fd, handle); - } - - igt_assert(exec(fd, handle_new, split, >t_offset_new, 0) == 0); - - if (split > 0) { - /* Check that we've managed to collide in the tlb. */ - igt_assert(gtt_offset == gtt_offset_new); - - /* We hang onto the storage of the old batch by keeping - * the cpu mmap around. */ - munmap(batch_ptr_old, BATCH_SIZE); - } - - handle = handle_new; - gtt_offset = gtt_offset_new; - batch_ptr_old = batch_ptr; - } - -} - -int fd; - -igt_main -{ - - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - - /* This test is very sensitive to residual gtt_mm noise from previous - * tests. Try to quiet thing down first. */ - gem_quiescent_gpu(fd); - sleep(5); /* needs more serious ducttape */ - } - - igt_subtest("render") - run_on_ring(fd, I915_EXEC_RENDER, "render"); - - igt_subtest("bsd") - run_on_ring(fd, I915_EXEC_BSD, "bsd"); - - igt_subtest("blt") - run_on_ring(fd, I915_EXEC_BLT, "blt"); - - igt_subtest("vebox") - run_on_ring(fd, LOCAL_I915_EXEC_VEBOX, "vebox"); - - igt_fixture - close(fd); -} diff --git a/tests/gem_ctx_bad_destroy.c b/tests/gem_ctx_bad_destroy.c deleted file mode 100644 index ee897638..00000000 --- a/tests/gem_ctx_bad_destroy.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright © 2012 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: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -/* - * Negative test cases for destroy contexts - */ - -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Negative test cases for destroy contexts."); - -uint32_t ctx_id; -int fd; - -igt_main -{ - igt_fixture { - fd = drm_open_any_render(); - - ctx_id = gem_context_create(fd); - /* Make sure a proper destroy works first */ - gem_context_destroy(fd, ctx_id); - } - - /* try double destroy */ - igt_subtest("double-destroy") { - ctx_id = gem_context_create(fd); - gem_context_destroy(fd, ctx_id); - igt_assert(__gem_context_destroy(fd, ctx_id) == -ENOENT); - } - - igt_subtest("invalid-ctx") - igt_assert(__gem_context_destroy(fd, 2) == -ENOENT); - - igt_subtest("invalid-default-ctx") - igt_assert(__gem_context_destroy(fd, 0) == -ENOENT); - - igt_subtest("invalid-pad") { - struct drm_i915_gem_context_destroy destroy; - - ctx_id = gem_context_create(fd); - - memset(&destroy, 0, sizeof(destroy)); - destroy.ctx_id = ctx_id; - destroy.pad = 1; - - igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy) < 0 && - errno == EINVAL); - gem_context_destroy(fd, ctx_id); - } - - igt_fixture - close(fd); -} diff --git a/tests/gem_ctx_bad_exec.c b/tests/gem_ctx_bad_exec.c deleted file mode 100644 index 36afd7d8..00000000 --- a/tests/gem_ctx_bad_exec.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright © 2012 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: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -/* - * Negative test cases: - * test we can't submit contexts to unsupported rings - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Test that context cannot be submitted to unsupported" - " rings."); - -/* Copied from gem_exec_nop.c */ -static int exec(int fd, uint32_t handle, int ring, int ctx_id) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec; - int ret = 0; - - gem_exec.handle = handle; - gem_exec.relocation_count = 0; - gem_exec.relocs_ptr = 0; - gem_exec.alignment = 0; - gem_exec.offset = 0; - gem_exec.flags = 0; - gem_exec.rsvd1 = 0; - gem_exec.rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)&gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, ctx_id); - execbuf.rsvd2 = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - gem_sync(fd, handle); - - return ret; -} - -uint32_t handle; -uint32_t batch[2] = {MI_BATCH_BUFFER_END}; -uint32_t ctx_id; -int fd; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any_render(); - - ctx_id = gem_context_create(fd); - - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, sizeof(batch)); - } - - igt_subtest("render") - igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0); - igt_subtest("bsd") - igt_assert(exec(fd, handle, I915_EXEC_BSD, ctx_id) != 0); - igt_subtest("blt") - igt_assert(exec(fd, handle, I915_EXEC_BLT, ctx_id) != 0); -#ifdef I915_EXEC_VEBOX - igt_fixture - igt_require(gem_has_vebox(fd)); - igt_subtest("vebox") - igt_assert(exec(fd, handle, I915_EXEC_VEBOX, ctx_id) != 0); -#endif -} diff --git a/tests/gem_ctx_basic.c b/tests/gem_ctx_basic.c deleted file mode 100644 index 4301b34e..00000000 --- a/tests/gem_ctx_basic.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright © 2011 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: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -/* - * This test is useful for finding memory and refcount leaks. - */ - -#include <pthread.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Basic test for memory and refcount leaks."); - -/* options */ -int num_contexts = 10; -int uncontexted = 0; /* test only context create/destroy */ -int multiple_fds = 1; -int iter = 10000; - -/* globals */ -pthread_t *threads; -int devid; -int fd; - -static void init_buffer(drm_intel_bufmgr *bufmgr, - struct igt_buf *buf, - uint32_t size) -{ - buf->bo = drm_intel_bo_alloc(bufmgr, "", size, 4096); - buf->size = size; - igt_assert(buf->bo); - buf->tiling = I915_TILING_NONE; - buf->stride = 4096; -} - -static void *work(void *arg) -{ - struct intel_batchbuffer *batch; - igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(devid); - drm_intel_context *context; - drm_intel_bufmgr *bufmgr; - int td_fd; - int i; - - if (multiple_fds) - td_fd = fd = drm_open_any_render(); - else - td_fd = fd; - - igt_assert(td_fd >= 0); - - bufmgr = drm_intel_bufmgr_gem_init(td_fd, 4096); - batch = intel_batchbuffer_alloc(bufmgr, devid); - context = drm_intel_gem_context_create(bufmgr); - igt_require(context); - - for (i = 0; i < iter; i++) { - struct igt_buf src, dst; - - init_buffer(bufmgr, &src, 4096); - init_buffer(bufmgr, &dst, 4096); - - - if (uncontexted) { - igt_assert(rendercopy); - rendercopy(batch, NULL, &src, 0, 0, 0, 0, &dst, 0, 0); - } else { - int ret; - ret = drm_intel_bo_subdata(batch->bo, 0, 4096, batch->buffer); - igt_assert(ret == 0); - intel_batchbuffer_flush_with_context(batch, context); - } - } - - drm_intel_gem_context_destroy(context); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - if (multiple_fds) - close(td_fd); - - pthread_exit(NULL); -} - -static int opt_handler(int opt, int opt_index) -{ - switch (opt) { - case 'i': - iter = atoi(optarg); - break; - case 'c': - num_contexts = atoi(optarg); - break; - case 'm': - multiple_fds = 1; - break; - case 'u': - uncontexted = 1; - break; - } - - return 0; -} - -int main(int argc, char *argv[]) -{ - int i; - - igt_simple_init_parse_opts(&argc, argv, "i:c:n:mu", NULL, NULL, - opt_handler); - - fd = drm_open_any_render(); - devid = intel_get_drm_devid(fd); - - if (igt_run_in_simulation()) { - num_contexts = 2; - iter = 4; - } - - threads = calloc(num_contexts, sizeof(*threads)); - - for (i = 0; i < num_contexts; i++) - pthread_create(&threads[i], NULL, work, &i); - - for (i = 0; i < num_contexts; i++) { - void *retval; - igt_assert(pthread_join(threads[i], &retval) == 0); - } - - free(threads); - close(fd); - - igt_exit(); -} diff --git a/tests/gem_ctx_create.c b/tests/gem_ctx_create.c deleted file mode 100644 index 046c974d..00000000 --- a/tests/gem_ctx_create.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright © 2012 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: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" - -int ret, fd; -struct drm_i915_gem_context_create create; - -igt_main -{ - igt_fixture - fd = drm_open_any_render(); - - igt_subtest("basic") { - create.ctx_id = rand(); - create.pad = 0; - - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create); - igt_skip_on(ret != 0 && (errno == ENODEV || errno == EINVAL)); - igt_assert(ret == 0); - igt_assert(create.ctx_id != 0); - } - - igt_subtest("invalid-pad") { - create.ctx_id = rand(); - create.pad = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create); - igt_skip_on(ret != 0 && (errno == ENODEV || errno == EINVAL)); - igt_assert(ret == 0); - igt_assert(create.ctx_id != 0); - - create.pad = 1; - - igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create) < 0 && - errno == EINVAL); - } - - igt_fixture - close(fd); -} diff --git a/tests/gem_ctx_exec.c b/tests/gem_ctx_exec.c deleted file mode 100644 index 43b38a2f..00000000 --- a/tests/gem_ctx_exec.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright © 2012 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: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -/* - * This test covers basic context switch functionality - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_aux.h" -#include "igt_gt.h" - -IGT_TEST_DESCRIPTION("Test basic context switch functionality."); - -/* Copied from gem_exec_nop.c */ -static int exec(int fd, uint32_t handle, int ring, int ctx_id) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec; - int ret = 0; - - gem_exec.handle = handle; - gem_exec.relocation_count = 0; - gem_exec.relocs_ptr = 0; - gem_exec.alignment = 0; - gem_exec.offset = 0; - gem_exec.flags = 0; - gem_exec.rsvd1 = 0; - gem_exec.rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)&gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, ctx_id); - execbuf.rsvd2 = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - - return ret; -} - -static void big_exec(int fd, uint32_t handle, int ring) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 *gem_exec; - uint32_t ctx_id1, ctx_id2; - int num_buffers = gem_available_aperture_size(fd) / 4096; - int i; - - /* Make sure we only fill half of RAM with gem objects. */ - igt_require(intel_get_total_ram_mb() * 1024 / 2 > num_buffers * 4); - - gem_exec = calloc(num_buffers + 1, sizeof(*gem_exec)); - igt_assert(gem_exec); - memset(gem_exec, 0, (num_buffers + 1) * sizeof(*gem_exec)); - - - ctx_id1 = gem_context_create(fd); - ctx_id2 = gem_context_create(fd); - - gem_exec[0].handle = handle; - - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = num_buffers + 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - execbuf.rsvd2 = 0; - - execbuf.buffer_count = 1; - i915_execbuffer2_set_context_id(execbuf, ctx_id1); - igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf) == 0); - - for (i = 0; i < num_buffers; i++) { - uint32_t tmp_handle = gem_create(fd, 4096); - - gem_exec[i].handle = tmp_handle; - } - gem_exec[i].handle = handle; - execbuf.buffer_count = i + 1; - - /* figure out how many buffers we can exactly fit */ - while (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf) != 0) { - i--; - gem_close(fd, gem_exec[i].handle); - gem_exec[i].handle = handle; - execbuf.buffer_count--; - igt_info("trying buffer count %i\n", i - 1); - } - - igt_info("reduced buffer count to %i from %i\n", - i - 1, num_buffers); - - /* double check that it works */ - igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf) == 0); - - i915_execbuffer2_set_context_id(execbuf, ctx_id2); - igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf) == 0); - gem_sync(fd, handle); -} - -uint32_t handle; -uint32_t batch[2] = {0, MI_BATCH_BUFFER_END}; -uint32_t ctx_id; -int fd; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any_render(); - - handle = gem_create(fd, 4096); - - /* check that we can create contexts. */ - ctx_id = gem_context_create(fd); - gem_context_destroy(fd, ctx_id); - gem_write(fd, handle, 0, batch, sizeof(batch)); - } - - igt_subtest("basic") { - ctx_id = gem_context_create(fd); - igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0); - gem_sync(fd, handle); - gem_context_destroy(fd, ctx_id); - - ctx_id = gem_context_create(fd); - igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0); - gem_sync(fd, handle); - gem_context_destroy(fd, ctx_id); - - igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) < 0); - gem_sync(fd, handle); - } - - igt_subtest("eviction") - big_exec(fd, handle, I915_EXEC_RENDER); - - igt_subtest("reset-pin-leak") { - int i; - - /* - * Use an explicit context to isolate the test from - * any major code changes related to the per-file - * default context (eg. if they would be eliminated). - */ - ctx_id = gem_context_create(fd); - - /* - * Iterate enough times that the kernel will - * become unhappy if the ggtt pin count for - * the last context is leaked at every reset. - */ - for (i = 0; i < 20; i++) { - igt_set_stop_rings(STOP_RING_DEFAULTS); - igt_assert(exec(fd, handle, I915_EXEC_RENDER, 0) == 0); - igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0); - gem_sync(fd, handle); - } - - gem_context_destroy(fd, ctx_id); - } -} diff --git a/tests/gem_ctx_param_basic.c b/tests/gem_ctx_param_basic.c deleted file mode 100644 index b44b37cf..00000000 --- a/tests/gem_ctx_param_basic.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright © 2015 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - */ - -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Basic test for context set/get param input validation."); - -int fd; -int32_t ctx; - -#define LOCAL_I915_GEM_CONTEXT_GETPARAM 0x34 -#define LOCAL_I915_GEM_CONTEXT_SETPARAM 0x35 -#define LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_CONTEXT_GETPARAM, struct local_i915_gem_context_param) -#define LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_CONTEXT_SETPARAM, struct local_i915_gem_context_param) - -#define TEST_SUCCESS(ioc) \ - igt_assert(drmIoctl(fd, (ioc), &ctx_param) == 0); -#define TEST_FAIL(ioc, exp_errno) \ - igt_assert(drmIoctl(fd, (ioc), &ctx_param) < 0 && errno == exp_errno); - -igt_main -{ - struct local_i915_gem_context_param ctx_param; - - memset(&ctx_param, 0, sizeof(ctx_param)); - - igt_fixture { - fd = drm_open_any_render(); - ctx = gem_context_create(fd); - } - - ctx_param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD; - - igt_subtest("basic") { - ctx_param.context = ctx; - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM); - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM); - } - - igt_subtest("basic-default") { - ctx_param.context = 0; - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM); - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM); - } - - igt_subtest("invalid-ctx-get") { - ctx_param.context = 2; - TEST_FAIL(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM, ENOENT); - } - - igt_subtest("invalid-ctx-set") { - ctx_param.context = ctx; - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM); - ctx_param.context = 2; - TEST_FAIL(LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM, ENOENT); - } - - igt_subtest("invalid-size-get") { - ctx_param.context = ctx; - ctx_param.size = 8; - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM); - igt_assert(ctx_param.size == 0); - } - - igt_subtest("invalid-size-set") { - ctx_param.context = ctx; - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM); - ctx_param.size = 8; - TEST_FAIL(LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM, EINVAL); - ctx_param.size = 0; - } - - ctx_param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD + 1; - - igt_subtest("invalid-param-get") { - ctx_param.context = ctx; - TEST_FAIL(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM, EINVAL); - } - - igt_subtest("invalid-param-set") { - ctx_param.context = ctx; - TEST_FAIL(LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM, EINVAL); - } - - ctx_param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD; - - igt_subtest("non-root-set") { - igt_fork(child, 1) { - igt_drop_root(); - - ctx_param.context = ctx; - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM); - ctx_param.value--; - TEST_FAIL(LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM, EPERM); - } - - igt_waitchildren(); - } - - igt_subtest("root-set") { - ctx_param.context = ctx; - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM); - ctx_param.value--; - TEST_SUCCESS(LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM); - } - - igt_fixture - close(fd); -} diff --git a/tests/gem_ctx_thrash.c b/tests/gem_ctx_thrash.c deleted file mode 100644 index b4818f4e..00000000 --- a/tests/gem_ctx_thrash.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright © 2014 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. - * - */ - -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <pthread.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/resource.h> - -#include "ioctl_wrappers.h" -#include "igt_aux.h" -#include "intel_chipset.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Fill the Gobal GTT with context objects and VMs\n"); - -#define OBJECT_SIZE (1024 * 1024) -#define NUM_THREADS 8 - -static int fd; -static unsigned devid; -static igt_render_copyfunc_t render_copy; - -static dri_bo **all_bo; -static int num_bo; -static int bo_per_ctx; - -static drm_intel_context **all_ctx; -static int num_ctx; -static int ctx_per_thread; - -static void xchg_ptr(void *array, unsigned i, unsigned j) -{ - void **A = array; - igt_swap(A[i], A[j]); -} - -static void xchg_int(void *array, unsigned i, unsigned j) -{ - int *A = array; - igt_swap(A[i], A[j]); -} - -static int reopen(int _fd) -{ - struct stat st; - char name[128]; - - igt_assert(fstat(_fd, &st) == 0); - - sprintf(name, "/dev/dri/card%u", (unsigned)(st.st_rdev & 0x7f)); - return open(name, O_RDWR); -} - -static void *thread(void *bufmgr) -{ - struct intel_batchbuffer *batch; - dri_bo **bo; - drm_intel_context **ctx; - int c, b; - - batch = intel_batchbuffer_alloc(bufmgr, devid); - - bo = malloc(num_bo * sizeof(dri_bo *)); - igt_assert(bo); - memcpy(bo, all_bo, num_bo * sizeof(dri_bo *)); - - ctx = malloc(num_ctx * sizeof(drm_intel_context *)); - igt_assert(ctx); - memcpy(ctx, all_ctx, num_ctx * sizeof(drm_intel_context *)); - igt_permute_array(ctx, num_ctx, xchg_ptr); - - for (c = 0; c < ctx_per_thread; c++) { - igt_permute_array(bo, num_bo, xchg_ptr); - for (b = 0; b < bo_per_ctx; b++) { - struct igt_buf src, dst; - - src.bo = bo[b % num_bo]; - src.stride = 64; - src.size = OBJECT_SIZE; - src.tiling = I915_TILING_NONE; - - dst.bo = bo[(b+1) % num_bo]; - dst.stride = 64; - dst.size = OBJECT_SIZE; - dst.tiling = I915_TILING_NONE; - - render_copy(batch, ctx[c % num_ctx], - &src, 0, 0, 16, 16, &dst, 0, 0); - } - } - - free(ctx); - free(bo); - intel_batchbuffer_free(batch); - - return NULL; -} - -static int uses_ppgtt(int _fd) -{ - struct drm_i915_getparam gp; - int val = 0; - - memset(&gp, 0, sizeof(gp)); - gp.param = 18; /* HAS_ALIASING_PPGTT */ - gp.value = &val; - - if (drmIoctl(_fd, DRM_IOCTL_I915_GETPARAM, &gp)) - return 0; - - errno = 0; - return val; -} - -static void -processes(void) -{ - int *all_fds; - uint64_t aperture; - struct rlimit rlim; - int ppgtt_mode; - int ctx_size; - int obj_size; - int n; - - igt_skip_on_simulation(); - - fd = drm_open_any_render(); - devid = intel_get_drm_devid(fd); - aperture = gem_aperture_size(fd); - - ppgtt_mode = uses_ppgtt(fd); - igt_require(ppgtt_mode); - - render_copy = igt_get_render_copyfunc(devid); - igt_require_f(render_copy, "no render-copy function\n"); - - if (ppgtt_mode > 1) - ctx_size = aperture >> 10; /* Assume full-ppgtt of maximum size */ - else - ctx_size = 64 << 10; /* Most gen require at least 64k for ctx */ - num_ctx = 3 * (aperture / ctx_size) / 2; - igt_info("Creating %d contexts (assuming of size %d)\n", - num_ctx, ctx_size); - intel_require_memory(num_ctx, ctx_size, CHECK_RAM | CHECK_SWAP); - - /* tweak rlimits to allow us to create this many files */ - igt_assert(getrlimit(RLIMIT_NOFILE, &rlim) == 0); - if (rlim.rlim_cur < ALIGN(num_ctx + 1024, 1024)) { - rlim.rlim_cur = ALIGN(num_ctx + 1024, 1024); - if (rlim.rlim_cur > rlim.rlim_max) - rlim.rlim_max = rlim.rlim_cur; - igt_assert(setrlimit(RLIMIT_NOFILE, &rlim) == 0); - } - - all_fds = malloc(num_ctx * sizeof(int)); - igt_assert(all_fds); - for (n = 0; n < num_ctx; n++) { - all_fds[n] = reopen(fd); - if (all_fds[n] == -1) { - int err = errno; - for (int i = n; i--; ) - close(all_fds[i]); - free(all_fds); - errno = err; - igt_assert_f(0, "failed to create context %d/%d\n", n, num_ctx); - } - } - - num_bo = 2 * num_ctx; - obj_size = (2 * aperture / num_bo + 4095) & -4096; - igt_info("Creating %d surfaces (of size %d)\n", num_bo, obj_size); - intel_require_memory(num_bo, obj_size, CHECK_RAM); - - igt_fork(child, NUM_THREADS) { - drm_intel_bufmgr *bufmgr; - struct intel_batchbuffer *batch; - int c; - - igt_permute_array(all_fds, num_ctx, xchg_int); - - for (c = 0; c < num_ctx; c++) { - struct igt_buf src, dst; - - bufmgr = drm_intel_bufmgr_gem_init(all_fds[c], 4096); - igt_assert(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - src.bo = drm_intel_bo_alloc(bufmgr, "", obj_size, 0); - igt_assert(src.bo); - src.stride = 64; - src.size = obj_size; - src.tiling = I915_TILING_NONE; - - dst.bo = drm_intel_bo_alloc(bufmgr, "", obj_size, 0); - igt_assert(dst.bo); - dst.stride = 64; - dst.size = obj_size; - dst.tiling = I915_TILING_NONE; - - render_copy(batch, NULL, - &src, 0, 0, 16, 16, &dst, 0, 0); - - intel_batchbuffer_free(batch); - drm_intel_bo_unreference(src.bo); - drm_intel_bo_unreference(dst.bo); - drm_intel_bufmgr_destroy(bufmgr); - } - } - igt_waitchildren(); - - for (n = 0; n < num_ctx; n++) - close(all_fds[n]); - free(all_fds); - close(fd); -} - -static void -threads(void) -{ - pthread_t threads[NUM_THREADS]; - drm_intel_bufmgr *bufmgr; - uint64_t aperture; - int ppgtt_mode; - int ctx_size; - int n; - - igt_skip_on_simulation(); - - fd = drm_open_any_render(); - devid = intel_get_drm_devid(fd); - aperture = gem_aperture_size(fd); - - ppgtt_mode = uses_ppgtt(fd); - igt_require(ppgtt_mode); - - render_copy = igt_get_render_copyfunc(devid); - igt_require_f(render_copy, "no render-copy function\n"); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - if (ppgtt_mode > 1) - ctx_size = aperture >> 10; /* Assume full-ppgtt of maximum size */ - else - ctx_size = 64 << 10; /* Most gen require at least 64k for ctx */ - num_ctx = 3 * (aperture / ctx_size) / 2; - igt_info("Creating %d contexts (assuming of size %d)\n", - num_ctx, ctx_size); - intel_require_memory(num_ctx, ctx_size, CHECK_RAM | CHECK_SWAP); - all_ctx = malloc(num_ctx * sizeof(drm_intel_context *)); - igt_assert(all_ctx); - for (n = 0; n < num_ctx; n++) { - all_ctx[n] = drm_intel_gem_context_create(bufmgr); - igt_assert(all_ctx[n]); - } - - num_bo = 3 * (aperture / OBJECT_SIZE) / 2; - igt_info("Creating %d surfaces (of size %d)\n", num_bo, OBJECT_SIZE); - intel_require_memory(num_bo, OBJECT_SIZE, CHECK_RAM); - all_bo = malloc(num_bo * sizeof(dri_bo *)); - igt_assert(all_bo); - for (n = 0; n < num_bo; n++) { - all_bo[n] = drm_intel_bo_alloc(bufmgr, "", OBJECT_SIZE, 0); - igt_assert(all_bo[n]); - } - - ctx_per_thread = 3 * num_ctx / NUM_THREADS / 2; - bo_per_ctx = 3 * num_bo / NUM_THREADS / 2; - - for (n = 0; n < NUM_THREADS; n++) - pthread_create(&threads[n], NULL, thread, bufmgr); - - for (n = 0; n < NUM_THREADS; n++) - pthread_join(threads[n], NULL); - - drm_intel_bufmgr_destroy(bufmgr); - close(fd); -} - -igt_main -{ - igt_subtest("processes") - processes(); - - igt_subtest("threads") - threads(); -} diff --git a/tests/gem_double_irq_loop.c b/tests/gem_double_irq_loop.c deleted file mode 100644 index a43fd1a9..00000000 --- a/tests/gem_double_irq_loop.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> (based on gem_storedw_*.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "i830_reg.h" -#include "intel_chipset.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *target_buffer, *blt_bo; - -/* - * Testcase: Basic check for missed irqs on blt - * - * Execs one large and then immediately a tiny batch on the blt ring. Then waits - * on the second batch. This hopefully catches races in our irq acknowledgement. - */ - -IGT_TEST_DESCRIPTION("Basic check for missed IRQs on blt ring."); - - -#define MI_COND_BATCH_BUFFER_END (0x36<<23 | 1) -#define MI_DO_COMPARE (1<<21) -static void -dummy_reloc_loop(void) -{ - int i; - - for (i = 0; i < 0x800; i++) { - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 4*4096); - OUT_BATCH(2048 << 16 | 0); - OUT_BATCH((4096) << 16 | (2048)); - OUT_RELOC_FENCED(blt_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(4*4096); - OUT_RELOC_FENCED(blt_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - intel_batchbuffer_flush(batch); - - 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(batch); - - drm_intel_bo_map(target_buffer, 0); - // map to force completion - drm_intel_bo_unmap(target_buffer); - } -} - -igt_simple_main -{ - int fd; - int devid; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - igt_require_f(HAS_BLT_RING(devid), - "not (yet) implemented for pre-snb\n"); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - - target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_buffer); - - blt_bo = drm_intel_bo_alloc(bufmgr, "target bo", 4*4096*4096, 4096); - igt_assert(blt_bo); - - dummy_reloc_loop(); - - drm_intel_bo_unreference(target_buffer); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_dummy_reloc_loop.c b/tests/gem_dummy_reloc_loop.c deleted file mode 100644 index 5e0a10a5..00000000 --- a/tests/gem_dummy_reloc_loop.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> (based on gem_storedw_*.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "i830_reg.h" -#include "intel_chipset.h" - -#define LOCAL_I915_EXEC_VEBOX (4<<0) -#define LOCAL_I915_EXEC_BSD_RING1 (1<<13) -#define LOCAL_I915_EXEC_BSD_RING2 (2<<13) - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *target_buffer; - -#define NUM_FD 50 - -static int mfd[NUM_FD]; -static drm_intel_bufmgr *mbufmgr[NUM_FD]; -static struct intel_batchbuffer *mbatch[NUM_FD]; -static drm_intel_bo *mbuffer[NUM_FD]; - -/* - * Testcase: Basic check of ring<->cpu sync using a dummy reloc - * - * The last test (that randomly switches the ring) seems to be pretty effective - * at hitting the missed irq bug that's worked around with the HWSTAM irq write. - */ - -IGT_TEST_DESCRIPTION("Check ring<->cpu sync using a dummy reloc."); - -#define MI_COND_BATCH_BUFFER_END (0x36<<23 | 1) -#define MI_DO_COMPARE (1<<21) -static void -dummy_reloc_loop(int ring) -{ - int i; - - for (i = 0; i < 0x100000; i++) { - BEGIN_BATCH(4, 1); - if (ring == I915_EXEC_RENDER) { - 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); - } else { - 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 completion - drm_intel_bo_unmap(target_buffer); - } -} - -static void -dummy_reloc_loop_random_ring(int num_rings) -{ - int i; - - srandom(0xdeadbeef); - - for (i = 0; i < 0x100000; i++) { - int ring = random() % num_rings + 1; - - BEGIN_BATCH(4, 1); - if (ring == I915_EXEC_RENDER) { - 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); - } else { - 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); - } -} - -static void -dummy_reloc_loop_random_ring_multi_fd(int num_rings) -{ - int i; - struct intel_batchbuffer *saved_batch; - - saved_batch = batch; - - srandom(0xdeadbeef); - - for (i = 0; i < 0x100000; i++) { - int mindex; - int ring = random() % num_rings + 1; - - mindex = random() % NUM_FD; - batch = mbatch[mindex]; - - BEGIN_BATCH(4, 1); - if (ring == I915_EXEC_RENDER) { - OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE); - OUT_BATCH(0xffffffff); /* compare dword */ - OUT_RELOC(mbuffer[mindex], I915_GEM_DOMAIN_RENDER, - I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(MI_NOOP); - } else { - OUT_BATCH(MI_FLUSH_DW | 1); - OUT_BATCH(0); /* reserved */ - OUT_RELOC(mbuffer[mindex], 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); - } - - batch = saved_batch; -} - -int fd; -int devid; -int num_rings; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - int i; - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - num_rings = gem_get_num_rings(fd); - /* Not yet implemented on pre-snb. */ - igt_require(HAS_BLT_RING(devid)); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - - target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_buffer); - - /* Create multi drm_fd and map one gem object to multi gem_contexts */ - { - unsigned int target_flink; - char buffer_name[32]; - igt_assert(dri_bo_flink(target_buffer, &target_flink) == 0); - - for (i = 0; i < NUM_FD; i++) { - sprintf(buffer_name, "Target buffer %d\n", i); - mfd[i] = drm_open_any(); - mbufmgr[i] = drm_intel_bufmgr_gem_init(mfd[i], 4096); - igt_assert_f(mbufmgr[i], - "fail to initialize buf manager " - "for drm_fd %d\n", - mfd[i]); - drm_intel_bufmgr_gem_enable_reuse(mbufmgr[i]); - mbatch[i] = intel_batchbuffer_alloc(mbufmgr[i], devid); - igt_assert_f(mbatch[i], - "fail to create batchbuffer " - "for drm_fd %d\n", - mfd[i]); - mbuffer[i] = intel_bo_gem_create_from_name( - mbufmgr[i], - buffer_name, - target_flink); - igt_assert_f(mbuffer[i], - "fail to create gem bo from global " - "gem_handle %d for drm_fd %d\n", - target_flink, mfd[i]); - } - } - } - - igt_subtest("render") { - igt_info("running dummy loop on render\n"); - dummy_reloc_loop(I915_EXEC_RENDER); - igt_info("dummy loop run on render completed\n"); - } - - igt_subtest("bsd") { - gem_require_ring(fd, I915_EXEC_BSD); - sleep(2); - igt_info("running dummy loop on bsd\n"); - dummy_reloc_loop(I915_EXEC_BSD); - igt_info("dummy loop run on bsd completed\n"); - } - - igt_subtest("blt") { - gem_require_ring(fd, I915_EXEC_BLT); - sleep(2); - igt_info("running dummy loop on blt\n"); - dummy_reloc_loop(I915_EXEC_BLT); - igt_info("dummy loop run on blt completed\n"); - } - -#ifdef I915_EXEC_VEBOX - igt_subtest("vebox") { - gem_require_ring(fd, I915_EXEC_VEBOX); - sleep(2); - igt_info("running dummy loop on vebox\n"); - dummy_reloc_loop(LOCAL_I915_EXEC_VEBOX); - igt_info("dummy loop run on vebox completed\n"); - } -#endif - - igt_subtest("bsd-ring1") { - igt_require(gem_has_bsd2(fd)); - sleep(2); - igt_info("running dummy loop on bsd-ring1\n"); - dummy_reloc_loop(I915_EXEC_BSD|LOCAL_I915_EXEC_BSD_RING1); - igt_info("dummy loop run on bsd-ring1 completed\n"); - } - - igt_subtest("bsd-ring2") { - igt_require(gem_has_bsd2(fd)); - sleep(2); - igt_info("running dummy loop on bsd-ring2\n"); - dummy_reloc_loop(I915_EXEC_BSD|LOCAL_I915_EXEC_BSD_RING2); - igt_info("dummy loop run on bsd-ring2 completed\n"); - } - - igt_subtest("mixed") { - if (num_rings > 1) { - sleep(2); - igt_info("running dummy loop on random rings\n"); - dummy_reloc_loop_random_ring(num_rings); - igt_info("dummy loop run on random rings completed\n"); - } - } - igt_subtest("mixed_multi_fd") { - if (num_rings > 1) { - sleep(2); - igt_info("running dummy loop on random rings based on " - "multi drm_fd\n"); - dummy_reloc_loop_random_ring_multi_fd(num_rings); - igt_info("dummy loop run on random rings based on " - "multi drm_fd completed\n"); - } - } - igt_fixture { - int i; - /* Free the buffer/batchbuffer/buffer mgr for multi-fd */ - { - for (i = 0; i < NUM_FD; i++) { - dri_bo_unreference(mbuffer[i]); - intel_batchbuffer_free(mbatch[i]); - drm_intel_bufmgr_destroy(mbufmgr[i]); - close(mfd[i]); - } - } - drm_intel_bo_unreference(target_buffer); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_evict_alignment.c b/tests/gem_evict_alignment.c deleted file mode 100644 index c0757705..00000000 --- a/tests/gem_evict_alignment.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright © 2011,2012 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/* - * Testcase: run a couple of big batches to force the unbind on misalignment code. - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "igt_aux.h" -#include "igt_gt.h" - -IGT_TEST_DESCRIPTION("Run a couple of big batches to force the unbind on" - " misalignment code."); - -#define HEIGHT 256 -#define WIDTH 1024 - -static void -copy(int fd, uint32_t dst, uint32_t src, uint32_t *all_bo, int n_bo, int alignment, int error) -{ - uint32_t batch[12]; - struct drm_i915_gem_relocation_entry reloc[2]; - struct drm_i915_gem_exec_object2 *obj; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - int n, ret, i=0; - - batch[i++] = (XY_SRC_COPY_BLT_CMD | - XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB | 6); - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - batch[i - 1] += 2; - batch[i++] = (3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - WIDTH*4; - 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) - batch[i++] = 0; /* FIXME */ - batch[i++] = 0; /* src x1,y1 */ - batch[i++] = WIDTH*4; - batch[i++] = 0; /* src reloc */ - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - batch[i++] = 0; /* FIXME */ - 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 = 0; - 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 = 0; - reloc[1].offset = 7 * sizeof(batch[0]); - reloc[1].presumed_offset = 0; - reloc[1].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[1].write_domain = 0; - - obj = calloc(n_bo + 1, sizeof(*obj)); - for (n = 0; n < n_bo; n++) { - obj[n].handle = all_bo[n]; - obj[n].alignment = alignment; - } - obj[n].handle = handle; - obj[n].relocation_count = 2; - obj[n].relocs_ptr = (uintptr_t)reloc; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = n_bo + 1; - 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; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - if (ret) - ret = errno; - igt_assert(ret == error); - - gem_close(fd, handle); - free(obj); -} - -static void minor_evictions(int fd, int size, int count) -{ - uint32_t *bo, *sel; - int n, m, alignment, pass, fail; - - intel_require_memory(2 * count, size, CHECK_RAM); - - bo = malloc(3*count*sizeof(*bo)); - igt_assert(bo); - - for (n = 0; n < 2*count; n++) - bo[n] = gem_create(fd, size); - - sel = bo + n; - for (alignment = m = 4096; alignment <= size; alignment <<= 1) { - for (fail = 0; fail < 10; fail++) { - for (pass = 0; pass < 100; pass++) { - for (n = 0; n < count; n++, m += 7) - sel[n] = bo[m%(2*count)]; - copy(fd, sel[0], sel[1], sel, count, alignment, 0); - } - copy(fd, bo[0], bo[0], bo, 2*count, alignment, ENOSPC); - } - } - - for (n = 0; n < 2*count; n++) - gem_close(fd, bo[n]); - free(bo); -} - -static void major_evictions(int fd, int size, int count) -{ - int n, m, loop, alignment, max; - uint32_t *bo; - - intel_require_memory(count, size, CHECK_RAM); - - bo = malloc(count*sizeof(*bo)); - igt_assert(bo); - - for (n = 0; n < count; n++) - bo[n] = gem_create(fd, size); - - max = gem_aperture_size(fd) - size; - for (alignment = m = 4096; alignment < max; alignment <<= 1) { - for (loop = 0; loop < 100; loop++, m += 17) { - n = m % count; - copy(fd, bo[n], bo[n], &bo[n], 1, alignment, 0); - } - } - - for (n = 0; n < count; n++) - gem_close(fd, bo[n]); - free(bo); -} - -int fd; - -igt_main -{ - int size, count; - - igt_fixture { - fd = drm_open_any(); - } - - igt_subtest("minor-normal") { - size = 1024 * 1024; - count = 3*gem_aperture_size(fd) / size / 4; - minor_evictions(fd, size, count); - } - - igt_subtest("major-normal") { - size = 3*gem_aperture_size(fd) / 4; - count = 4; - major_evictions(fd, size, count); - } - - igt_fork_signal_helper(); - igt_subtest("minor-interruptible") { - size = 1024 * 1024; - count = 3*gem_aperture_size(fd) / size / 4; - minor_evictions(fd, size, count); - } - - igt_subtest("major-interruptible") { - size = 3*gem_aperture_size(fd) / 4; - count = 4; - major_evictions(fd, size, count); - } - - if (igt_fork_hang_helper()) { - igt_subtest("minor-hang") { - size = 1024 * 1024; - count = 3*gem_aperture_size(fd) / size / 4; - minor_evictions(fd, size, count); - } - - igt_subtest("major-hang") { - size = 3*gem_aperture_size(fd) / 4; - count = 4; - major_evictions(fd, size, count); - } - igt_stop_hang_helper(); - } - igt_stop_signal_helper(); - - igt_fixture - close(fd); -} diff --git a/tests/gem_evict_everything.c b/tests/gem_evict_everything.c deleted file mode 100644 index 15ab382a..00000000 --- a/tests/gem_evict_everything.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright © 2011,2012,2014 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/* - * Testcase: run a couple of big batches to force the eviction code. - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "igt_gt.h" - -#include "eviction_common.c" - -IGT_TEST_DESCRIPTION("Run a couple of big batches to force the eviction" - " code."); - -#define HEIGHT 256 -#define WIDTH 1024 - -static int -copy(int fd, uint32_t dst, uint32_t src, uint32_t *all_bo, int n_bo) -{ - uint32_t batch[12]; - struct drm_i915_gem_relocation_entry reloc[2]; - struct drm_i915_gem_exec_object2 *obj; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - int n, ret, i=0; - - batch[i++] = (XY_SRC_COPY_BLT_CMD | - XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB | 6); - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - batch[i - 1] += 2; - batch[i++] = (3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - WIDTH*4; - 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) - batch[i++] = 0; /* FIXME */ - batch[i++] = 0; /* src x1,y1 */ - batch[i++] = WIDTH*4; - batch[i++] = 0; /* src reloc */ - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - batch[i++] = 0; /* FIXME */ - 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 = 0; - 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 = 0; - reloc[1].offset = 7 * sizeof(batch[0]); - if (intel_gen(intel_get_drm_devid(fd)) >= 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; - - obj = calloc(n_bo + 1, sizeof(*obj)); - for (n = 0; n < n_bo; n++) - obj[n].handle = all_bo[n]; - obj[n].handle = handle; - obj[n].relocation_count = 2; - obj[n].relocs_ptr = (uintptr_t)reloc; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = n_bo + 1; - 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; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - if (ret) - ret = errno; - - gem_close(fd, handle); - free(obj); - - return ret; -} - -static void clear(int fd, uint32_t handle, int size) -{ - void *base = gem_mmap__cpu(fd, handle, 0, size, PROT_READ | PROT_WRITE); - - igt_assert(base != NULL); - memset(base, 0, size); - munmap(base, size); -} - -static struct igt_eviction_test_ops fault_ops = { - .create = gem_create, - .close = gem_close, - .copy = copy, - .clear = clear, -}; - -static void test_forking_evictions(int fd, int size, int count, - unsigned flags) -{ - int trash_count; - - trash_count = intel_get_total_ram_mb() * 11 / 10; - intel_require_memory(trash_count, size, CHECK_RAM | CHECK_SWAP); - - forking_evictions(fd, &fault_ops, size, count, trash_count, flags); -} - -static void test_swapping_evictions(int fd, int size, int count) -{ - int trash_count; - - trash_count = intel_get_total_ram_mb() * 11 / 10; - intel_require_memory(trash_count, size, CHECK_RAM | CHECK_SWAP); - - swapping_evictions(fd, &fault_ops, size, count, trash_count); -} - -static void test_minor_evictions(int fd, int size, int count) -{ - minor_evictions(fd, &fault_ops, size, count); -} - -static void test_major_evictions(int fd, int size, int count) -{ - major_evictions(fd, &fault_ops, size, count); -} - -igt_main -{ - int size, count, fd; - size = count = 0; - fd = -1; - - igt_fixture { - fd = drm_open_any(); - - size = 1024 * 1024; - count = 3*gem_aperture_size(fd) / size / 4; - } - - for (unsigned flags = 0; flags < ALL_FORKING_EVICTIONS + 1; flags++) { - igt_subtest_f("forked%s%s%s-%s", - flags & FORKING_EVICTIONS_SWAPPING ? "-swapping" : "", - flags & FORKING_EVICTIONS_DUP_DRMFD ? "-multifd" : "", - flags & FORKING_EVICTIONS_MEMORY_PRESSURE ? - "-mempressure" : "", - flags & FORKING_EVICTIONS_INTERRUPTIBLE ? - "interruptible" : "normal") { - test_forking_evictions(fd, size, count, flags); - } - } - - igt_subtest("swapping-normal") - test_swapping_evictions(fd, size, count); - - igt_subtest("minor-normal") - test_minor_evictions(fd, size, count); - - igt_subtest("major-normal") { - size = 3*gem_aperture_size(fd) / 4; - count = 4; - test_major_evictions(fd, size, count); - } - - igt_fixture { - size = 1024 * 1024; - count = 3*gem_aperture_size(fd) / size / 4; - } - - igt_fork_signal_helper(); - - igt_subtest("swapping-interruptible") - test_swapping_evictions(fd, size, count); - - igt_subtest("minor-interruptible") - test_minor_evictions(fd, size, count); - - igt_subtest("major-interruptible") { - size = 3*gem_aperture_size(fd) / 4; - count = 4; - test_major_evictions(fd, size, count); - } - - if (igt_fork_hang_helper()) { - igt_subtest("swapping-hang") - test_swapping_evictions(fd, size, count); - - igt_subtest("minor-hang") - test_minor_evictions(fd, size, count); - - igt_subtest("major-hang") { - size = 3*gem_aperture_size(fd) / 4; - count = 4; - test_major_evictions(fd, size, count); - } - - igt_stop_hang_helper(); - } - igt_stop_signal_helper(); - - igt_fixture { - close(fd); - } -} diff --git a/tests/gem_exec_bad_domains.c b/tests/gem_exec_bad_domains.c deleted file mode 100644 index 818e5853..00000000 --- a/tests/gem_exec_bad_domains.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -/* Testcase: Test whether the kernel rejects relocations with non-gpu domains - * - * If it does not, it'll oops somewhen later on because we don't expect that. - */ - -IGT_TEST_DESCRIPTION("Test whether the kernel rejects relocations with non-gpu" - " domains."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -#define BAD_GTT_DEST ((512*1024*1024)) /* past end of aperture */ - -static int -run_batch(void) -{ - unsigned int used = batch->ptr - batch->buffer; - int ret; - - if (used == 0) - return 0; - - /* Round batchbuffer usage to 2 DWORDs. */ - if ((used & 4) == 0) { - *(uint32_t *) (batch->ptr) = 0; /* noop */ - batch->ptr += 4; - } - - /* Mark the end of the buffer. */ - *(uint32_t *)(batch->ptr) = MI_BATCH_BUFFER_END; /* noop */ - batch->ptr += 4; - used = batch->ptr - batch->buffer; - - ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->buffer); - igt_assert(ret == 0); - - batch->ptr = NULL; - - ret = drm_intel_bo_mrb_exec(batch->bo, used, NULL, 0, 0, 0); - - intel_batchbuffer_reset(batch); - - return ret; -} - -#define I915_GEM_GPU_DOMAINS \ - (I915_GEM_DOMAIN_RENDER | \ - I915_GEM_DOMAIN_SAMPLER | \ - I915_GEM_DOMAIN_COMMAND | \ - I915_GEM_DOMAIN_INSTRUCTION | \ - I915_GEM_DOMAIN_VERTEX) - -static void multi_write_domain(int fd) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec[2]; - struct drm_i915_gem_relocation_entry reloc[1]; - uint32_t handle, handle_target; - int ret; - - handle = gem_create(fd, 4096); - handle_target = gem_create(fd, 4096); - - exec[0].handle = handle_target; - exec[0].relocation_count = 0; - exec[0].relocs_ptr = 0; - exec[0].alignment = 0; - exec[0].offset = 0; - exec[0].flags = 0; - exec[0].rsvd1 = 0; - exec[0].rsvd2 = 0; - - exec[1].handle = handle; - exec[1].relocation_count = 1; - exec[1].relocs_ptr = (uintptr_t) reloc; - exec[1].alignment = 0; - exec[1].offset = 0; - exec[1].flags = 0; - exec[1].rsvd1 = 0; - exec[1].rsvd2 = 0; - - reloc[0].offset = 4; - reloc[0].delta = 0; - reloc[0].target_handle = handle_target; - reloc[0].read_domains = I915_GEM_DOMAIN_RENDER | I915_GEM_DOMAIN_INSTRUCTION; - reloc[0].write_domain = I915_GEM_DOMAIN_RENDER | I915_GEM_DOMAIN_INSTRUCTION; - reloc[0].presumed_offset = 0; - - execbuf.buffers_ptr = (uintptr_t)exec; - execbuf.buffer_count = 2; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = 0; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - ret = drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - igt_assert(ret != 0 && errno == EINVAL); - - gem_close(fd, handle); - gem_close(fd, handle_target); -} - -int fd; -drm_intel_bo *tmp; - -igt_main -{ - igt_fixture { - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - tmp = drm_intel_bo_alloc(bufmgr, "tmp", 128 * 128, 4096); - } - - igt_subtest("cpu-domain") { - BEGIN_BATCH(2, 1); - OUT_BATCH(0); - OUT_RELOC(tmp, I915_GEM_DOMAIN_CPU, 0, 0); - ADVANCE_BATCH(); - igt_assert(run_batch() == -EINVAL); - - BEGIN_BATCH(2, 1); - OUT_BATCH(0); - OUT_RELOC(tmp, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU, 0); - ADVANCE_BATCH(); - igt_assert(run_batch() == -EINVAL); - } - - igt_subtest("gtt-domain") { - BEGIN_BATCH(2, 1); - OUT_BATCH(0); - OUT_RELOC(tmp, I915_GEM_DOMAIN_GTT, 0, 0); - ADVANCE_BATCH(); - igt_assert(run_batch() == -EINVAL); - - BEGIN_BATCH(2, 1); - OUT_BATCH(0); - OUT_RELOC(tmp, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT, 0); - ADVANCE_BATCH(); - igt_assert(run_batch() == -EINVAL); - } - - /* Note: Older kernels disallow this. Punt on the skip check though - * since this is too old. */ - igt_subtest("conflicting-write-domain") { - BEGIN_BATCH(4, 2); - OUT_BATCH(0); - OUT_RELOC(tmp, I915_GEM_DOMAIN_RENDER, - I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0); - OUT_RELOC(tmp, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - ADVANCE_BATCH(); - igt_assert(run_batch() == 0); - } - - igt_subtest("double-write-domain") - multi_write_domain(fd); - - igt_subtest("invalid-gpu-domain") { - BEGIN_BATCH(2, 1); - OUT_BATCH(0); - OUT_RELOC(tmp, ~(I915_GEM_GPU_DOMAINS | I915_GEM_DOMAIN_GTT | I915_GEM_DOMAIN_CPU), - 0, 0); - ADVANCE_BATCH(); - igt_assert(run_batch() == -EINVAL); - - BEGIN_BATCH(2, 1); - OUT_BATCH(0); - OUT_RELOC(tmp, I915_GEM_DOMAIN_GTT << 1, - I915_GEM_DOMAIN_GTT << 1, 0); - ADVANCE_BATCH(); - igt_assert(run_batch() == -EINVAL); - } - - igt_fixture { - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_exec_big.c b/tests/gem_exec_big.c deleted file mode 100644 index 15337e66..00000000 --- a/tests/gem_exec_big.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright © 2011,2012 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/* - * Testcase: run a nop batch which is really big - * - * Mostly useful to stress-test the error-capture code - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Run a large nop batch to stress test the error capture" - " code."); - -static void exec1(int fd, uint32_t handle, uint32_t reloc_ofs, unsigned flags, uint32_t *ptr) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[1]; - struct drm_i915_gem_relocation_entry gem_reloc[1]; - uint32_t tmp; - - gem_reloc[0].offset = reloc_ofs; - gem_reloc[0].delta = 0; - gem_reloc[0].target_handle = handle; - gem_reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - gem_reloc[0].write_domain = 0; - gem_reloc[0].presumed_offset = 0; - - gem_exec[0].handle = handle; - gem_exec[0].relocation_count = 1; - gem_exec[0].relocs_ptr = (uintptr_t) gem_reloc; - gem_exec[0].alignment = 0; - gem_exec[0].offset = 0; - gem_exec[0].flags = 0; - gem_exec[0].rsvd1 = 0; - gem_exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = flags; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - /* Avoid hitting slowpaths in the reloc processing which might yield a - * presumed_offset of -1. Happens when the batch is still busy from the - * last round. */ - gem_sync(fd, handle); - - gem_execbuf(fd, &execbuf); - - igt_warn_on(gem_reloc[0].presumed_offset == -1); - - if (ptr) { - igt_assert_eq(ptr[reloc_ofs/sizeof(*ptr)], - gem_reloc[0].presumed_offset); - } else { - gem_read(fd, handle, reloc_ofs, &tmp, 4); - igt_assert_eq(tmp, gem_reloc[0].presumed_offset); - } -} - -static void execN(int fd, uint32_t handle, uint32_t batch_size, unsigned flags, uint32_t *ptr) -{ -#define reloc_ofs(N, T) ((((N)+1) << 12) - 4*(1 + ((N) == ((T)-1)))) - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[1]; - struct drm_i915_gem_relocation_entry *gem_reloc; - int n, nreloc = batch_size >> 12; - uint32_t tmp; - - gem_reloc = calloc(nreloc, sizeof(*gem_reloc)); - igt_assert(gem_reloc); - - for (n = 0; n < nreloc; n++) { - gem_reloc[n].offset = reloc_ofs(n, nreloc); - gem_reloc[n].target_handle = handle; - gem_reloc[n].read_domains = I915_GEM_DOMAIN_RENDER; - } - - memset(gem_exec, 0, sizeof(gem_exec)); - gem_exec[0].handle = handle; - gem_exec[0].relocation_count = nreloc; - gem_exec[0].relocs_ptr = (uintptr_t)gem_reloc; - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.flags = flags; - - /* Avoid hitting slowpaths in the reloc processing which might yield a - * presumed_offset of -1. Happens when the batch is still busy from the - * last round. */ - gem_sync(fd, handle); - - gem_execbuf(fd, &execbuf); - for (n = 0; n < nreloc; n++) - igt_warn_on(gem_reloc[n].presumed_offset == -1); - - if (ptr) { - for (n = 0; n < nreloc; n++) - igt_assert_eq(ptr[reloc_ofs(n, nreloc)/sizeof(*ptr)], - gem_reloc[n].presumed_offset); - } else { - for (n = 0; n < nreloc; n++) { - gem_read(fd, handle, reloc_ofs(n, nreloc), &tmp, 4); - igt_assert_eq(tmp, gem_reloc[n].presumed_offset); - } - } - - free(gem_reloc); -#undef reloc_ofs -} - -igt_simple_main -{ - uint32_t batch[2] = {MI_BATCH_BUFFER_END}; - int fd; - uint32_t reloc_ofs; - unsigned batch_size; - int max; - - fd = drm_open_any(); - max = 3 * gem_aperture_size(fd) / 4; - - intel_require_memory(1, max, CHECK_RAM); - - for (batch_size = 4096; batch_size <= max; ) { - uint32_t handle, *ptr; - - handle = gem_create(fd, batch_size); - gem_write(fd, handle, 0, batch, sizeof(batch)); - - ptr = NULL; - if (gem_mmap__has_wc(fd)) - ptr = gem_mmap__wc(fd, handle, 0, batch_size, PROT_READ); - - for (reloc_ofs = 4096; reloc_ofs < batch_size; reloc_ofs += 4096) { - igt_debug("batch_size %u, reloc_ofs %u\n", - batch_size, reloc_ofs); - exec1(fd, handle, reloc_ofs, 0, ptr); - exec1(fd, handle, reloc_ofs, I915_EXEC_SECURE, ptr); - } - - igt_debug("batch_size %u, all %d relocs\n", - batch_size, batch_size >> 12); - execN(fd, handle, batch_size, 0, ptr); - execN(fd, handle, batch_size, I915_EXEC_SECURE, ptr); - - if (ptr) - munmap(ptr, batch_size); - gem_madvise(fd, handle, I915_MADV_DONTNEED); - - if (batch_size < max && 2*batch_size > max) - batch_size = max; - else - batch_size *= 2; - } - - close(fd); -} diff --git a/tests/gem_exec_blt.c b/tests/gem_exec_blt.c deleted file mode 100644 index fd206581..00000000 --- a/tests/gem_exec_blt.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" - -#define OBJECT_SIZE 16384 - -#define COPY_BLT_CMD (2<<29|0x53<<22|0x6) -#define BLT_WRITE_ALPHA (1<<21) -#define BLT_WRITE_RGB (1<<20) -#define BLT_SRC_TILED (1<<15) -#define BLT_DST_TILED (1<<11) - -static int gem_linear_blt(int fd, - uint32_t *batch, - uint32_t src, - uint32_t dst, - uint32_t length, - struct drm_i915_gem_relocation_entry *reloc) -{ - uint32_t *b = batch; - int height = length / (16 * 1024); - - igt_assert(height <= 1<<16); - - if (height) { - int i = 0; - b[i++] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - b[i-1]+=2; - b[i++] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024); - b[i++] = 0; - b[i++] = height << 16 | (4*1024); - b[i++] = 0; - reloc->offset = (b-batch+4) * sizeof(uint32_t); - reloc->delta = 0; - reloc->target_handle = dst; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = I915_GEM_DOMAIN_RENDER; - reloc->presumed_offset = 0; - reloc++; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - b[i++] = 0; /* FIXME */ - - b[i++] = 0; - b[i++] = 16*1024; - b[i++] = 0; - reloc->offset = (b-batch+7) * sizeof(uint32_t); - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - reloc->offset += sizeof(uint32_t); - reloc->delta = 0; - reloc->target_handle = src; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = 0; - reloc->presumed_offset = 0; - reloc++; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - b[i++] = 0; /* FIXME */ - - b += i; - length -= height * 16*1024; - } - - if (length) { - int i = 0; - b[i++] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - b[i-1]+=2; - b[i++] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024); - b[i++] = height << 16; - b[i++] = (1+height) << 16 | (length / 4); - b[i++] = 0; - reloc->offset = (b-batch+4) * sizeof(uint32_t); - reloc->delta = 0; - reloc->target_handle = dst; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = I915_GEM_DOMAIN_RENDER; - reloc->presumed_offset = 0; - reloc++; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - b[i++] = 0; /* FIXME */ - - b[i++] = height << 16; - b[i++] = 16*1024; - b[i++] = 0; - reloc->offset = (b-batch+7) * sizeof(uint32_t); - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - reloc->offset += sizeof(uint32_t); - reloc->delta = 0; - reloc->target_handle = src; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = 0; - reloc->presumed_offset = 0; - reloc++; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - b[i++] = 0; /* FIXME */ - - b += i; - } - - b[0] = MI_BATCH_BUFFER_END; - b[1] = 0; - - return (b+2 - batch) * sizeof(uint32_t); -} - -static double elapsed(const struct timeval *start, - const struct timeval *end, - int loop) -{ - return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec))/loop; -} - -static const char *bytes_per_sec(char *buf, double v) -{ - const char *order[] = { - "", - "KiB", - "MiB", - "GiB", - "TiB", - "PiB", - NULL, - }, **o = order; - - while (v > 1024 && o[1]) { - v /= 1024; - o++; - } - sprintf(buf, "%.1f%s/s", v, *o); - return buf; -} - -static uint32_t dumb_create(int fd) -{ - struct drm_mode_create_dumb arg; - int ret; - - arg.bpp = 32; - arg.width = 32; - arg.height = 32; - - ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg); - igt_assert(ret == 0); - igt_assert(arg.size >= 4096); - - return arg.handle; -} - -static void run(int object_size, bool dumb) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec[3]; - struct drm_i915_gem_relocation_entry reloc[4]; - uint32_t buf[20]; - uint32_t handle, src, dst; - int fd, len, count; - int ring; - - fd = drm_open_any(); - if (dumb) - handle = dumb_create(fd); - else - handle = gem_create(fd, 4096); - - src = gem_create(fd, object_size); - dst = gem_create(fd, object_size); - - len = gem_linear_blt(fd, buf, src, dst, object_size, reloc); - gem_write(fd, handle, 0, buf, len); - - exec[0].handle = src; - exec[0].relocation_count = 0; - exec[0].relocs_ptr = 0; - exec[0].alignment = 0; - exec[0].offset = 0; - exec[0].flags = 0; - exec[0].rsvd1 = 0; - exec[0].rsvd2 = 0; - - exec[1].handle = dst; - exec[1].relocation_count = 0; - exec[1].relocs_ptr = 0; - exec[1].alignment = 0; - exec[1].offset = 0; - exec[1].flags = 0; - exec[1].rsvd1 = 0; - exec[1].rsvd2 = 0; - - exec[2].handle = handle; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - exec[2].relocation_count = len > 56 ? 4 : 2; - else - exec[2].relocation_count = len > 40 ? 4 : 2; - exec[2].relocs_ptr = (uintptr_t)reloc; - exec[2].alignment = 0; - exec[2].offset = 0; - exec[2].flags = 0; - exec[2].rsvd1 = 0; - exec[2].rsvd2 = 0; - - ring = 0; - if (HAS_BLT_RING(intel_get_drm_devid(fd))) - ring = I915_EXEC_BLT; - - execbuf.buffers_ptr = (uintptr_t)exec; - execbuf.buffer_count = 3; - execbuf.batch_start_offset = 0; - execbuf.batch_len = len; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - for (count = 1; count <= 1<<12; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - for (int loop = 0; loop < count; loop++) - gem_execbuf(fd, &execbuf); - gem_sync(fd, handle); - gettimeofday(&end, NULL); - igt_info("Time to blt %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - gem_close(fd, handle); - - close(fd); -} - -int main(int argc, char **argv) -{ - int i; - - igt_subtest_init(argc, argv); - - igt_skip_on_simulation(); - - igt_subtest("normal") { - if (argc > 1) { - for (i = 1; i < argc; i++) { - int object_size = atoi(argv[i]); - if (object_size) - run((object_size + 3) & -4, false); - } - } else - run(OBJECT_SIZE, false); - } - - igt_subtest("dumb-buf") { - if (argc > 1) { - for (i = 1; i < argc; i++) { - int object_size = atoi(argv[i]); - if (object_size) - run((object_size + 3) & -4, true); - } - } else - run(OBJECT_SIZE, true); - } - - igt_exit(); -} diff --git a/tests/gem_exec_faulting_reloc.c b/tests/gem_exec_faulting_reloc.c deleted file mode 100644 index 9f121126..00000000 --- a/tests/gem_exec_faulting_reloc.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_debugfs.h" - -/* Testcase: Submit patches with relocations in memory that will fault - * - * To be really evil, use a gtt mmap for them. - */ - -IGT_TEST_DESCRIPTION("Submit patches with relocations in memory that will" - " fault."); - -#define OBJECT_SIZE 16384 - -#define COPY_BLT_CMD_NOLEN (2<<29|0x53<<22) -#define BLT_WRITE_ALPHA (1<<21) -#define BLT_WRITE_RGB (1<<20) -#define BLT_SRC_TILED (1<<15) -#define BLT_DST_TILED (1<<11) - -uint32_t devid; - -static int gem_linear_blt(uint32_t *batch, - uint32_t src, - uint32_t dst, - uint32_t length, - struct drm_i915_gem_relocation_entry *reloc) -{ - uint32_t *b = batch; - int height = length / (16 * 1024); - - igt_assert(height <= 1<<16); - - if (height) { - int i = 0; - b[i++] = COPY_BLT_CMD_NOLEN | BLT_WRITE_ALPHA | BLT_WRITE_RGB; - if (intel_gen(devid) >= 8) - b[i-1] |= 8; - else - b[i-1] |= 6; - b[i++] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024); - b[i++] = 0; - b[i++] = height << 16 | (4*1024); - b[i++] = 0; - reloc->offset = (b-batch+4) * sizeof(uint32_t); - reloc->delta = 0; - reloc->target_handle = dst; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = I915_GEM_DOMAIN_RENDER; - reloc->presumed_offset = 0; - reloc++; - - if (intel_gen(devid) >= 8) - b[i++] = 0; /* FIXME: use real high dword */ - - b[i++] = 0; - b[i++] = 16*1024; - b[i++] = 0; - reloc->offset = (b-batch+7) * sizeof(uint32_t); - if (intel_gen(devid) >= 8) { - reloc->offset += sizeof(uint32_t); - b[i++] = 0; /* FIXME: use real high dword */ - } - reloc->delta = 0; - reloc->target_handle = src; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = 0; - reloc->presumed_offset = 0; - reloc++; - - if (intel_gen(devid) >= 8) - b += 10; - else - b += 8; - length -= height * 16*1024; - } - - if (length) { - int i = 0; - b[i++] = COPY_BLT_CMD_NOLEN | BLT_WRITE_ALPHA | BLT_WRITE_RGB; - if (intel_gen(devid) >= 8) - b[i-1] |= 8; - else - b[i-1] |= 6; - b[i++] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024); - b[i++] = height << 16; - b[i++] = (1+height) << 16 | (length / 4); - b[i++] = 0; - reloc->offset = (b-batch+4) * sizeof(uint32_t); - reloc->delta = 0; - reloc->target_handle = dst; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = I915_GEM_DOMAIN_RENDER; - reloc->presumed_offset = 0; - reloc++; - if (intel_gen(devid) >= 8) - b[i++] = 0; /* FIXME: use real high dword */ - - b[i++] = height << 16; - b[i++] = 16*1024; - b[i++] = 0; - reloc->offset = (b-batch+7) * sizeof(uint32_t); - if (intel_gen(devid) >= 8) { - reloc->offset += sizeof(uint32_t); - b[i++] = 0; /* FIXME: use real high dword */ - } - reloc->delta = 0; - reloc->target_handle = src; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = 0; - reloc->presumed_offset = 0; - reloc++; - - if (intel_gen(devid) >= 8) - b += 10; - else - b += 8; - } - - b[0] = MI_BATCH_BUFFER_END; - b[1] = 0; - - return (b+2 - batch) * sizeof(uint32_t); -} - -static void run(int object_size) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec[3]; - struct drm_i915_gem_relocation_entry reloc[4]; - uint32_t buf[40]; - uint32_t handle, handle_relocs, src, dst; - void *gtt_relocs; - int fd, len; - int ring; - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - handle = gem_create(fd, 4096); - src = gem_create(fd, object_size); - dst = gem_create(fd, object_size); - - len = gem_linear_blt(buf, src, dst, object_size, reloc); - gem_write(fd, handle, 0, buf, len); - - exec[0].handle = src; - exec[0].relocation_count = 0; - exec[0].relocs_ptr = 0; - exec[0].alignment = 0; - exec[0].offset = 0; - exec[0].flags = 0; - exec[0].rsvd1 = 0; - exec[0].rsvd2 = 0; - - exec[1].handle = dst; - exec[1].relocation_count = 0; - exec[1].relocs_ptr = 0; - exec[1].alignment = 0; - exec[1].offset = 0; - exec[1].flags = 0; - exec[1].rsvd1 = 0; - exec[1].rsvd2 = 0; - - handle_relocs = gem_create(fd, 4096); - gem_write(fd, handle_relocs, 0, reloc, sizeof(reloc)); - gtt_relocs = gem_mmap(fd, handle_relocs, 4096, - PROT_READ | PROT_WRITE); - igt_assert(gtt_relocs); - - exec[2].handle = handle; - if (intel_gen(devid) >= 8) - exec[2].relocation_count = len > 56 ? 4 : 2; - else - exec[2].relocation_count = len > 40 ? 4 : 2; - /* A newly mmap gtt bo will fault on first access. */ - exec[2].relocs_ptr = (uintptr_t)gtt_relocs; - exec[2].alignment = 0; - exec[2].offset = 0; - exec[2].flags = 0; - exec[2].rsvd1 = 0; - exec[2].rsvd2 = 0; - - ring = 0; - if (HAS_BLT_RING(devid)) - ring = I915_EXEC_BLT; - - execbuf.buffers_ptr = (uintptr_t)exec; - execbuf.buffer_count = 3; - execbuf.batch_start_offset = 0; - execbuf.batch_len = len; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - gem_execbuf(fd, &execbuf); - gem_sync(fd, handle); - - gem_close(fd, handle); - - close(fd); -} - -igt_main -{ - igt_subtest("normal") - run(OBJECT_SIZE); - igt_subtest("no-prefault") { - igt_disable_prefault(); - run(OBJECT_SIZE); - igt_enable_prefault(); - } -} diff --git a/tests/gem_exec_lut_handle.c b/tests/gem_exec_lut_handle.c deleted file mode 100644 index c2d490f9..00000000 --- a/tests/gem_exec_lut_handle.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright © 2012 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/* Exercises the basic execbuffer using the handle LUT interface */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Exercises the basic execbuffer using the handle LUT" - " interface."); - -#define BATCH_SIZE (1024*1024) - -#define LOCAL_I915_EXEC_NO_RELOC (1<<11) -#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12) - -#define MAX_NUM_EXEC 2048 -#define MAX_NUM_RELOC 4096 - -#define USE_LUT 0x1 -#define SKIP_RELOC 0x2 -#define NO_RELOC 0x4 - -struct drm_i915_gem_exec_object2 gem_exec[MAX_NUM_EXEC+1]; -struct drm_i915_gem_relocation_entry gem_reloc[MAX_NUM_RELOC]; - -static uint32_t state = 0x12345678; - -static uint32_t -hars_petruska_f54_1_random (void) -{ -#define rol(x,k) ((x << k) | (x >> (32-k))) - return state = (state ^ rol (state, 5) ^ rol (state, 24)) + 0x37798849; -#undef rol -} - - -static int exec(int fd, int num_exec, int num_relocs, unsigned flags) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 *objects; - int i; - - gem_exec[MAX_NUM_EXEC].relocation_count = num_relocs; - gem_exec[MAX_NUM_EXEC].relocs_ptr = (uintptr_t) gem_reloc; - - objects = gem_exec + MAX_NUM_EXEC - num_exec; - - for (i = 0; i < num_relocs; i++) { - int target = hars_petruska_f54_1_random() % num_exec; - gem_reloc[i].offset = 1024; - gem_reloc[i].delta = 0; - gem_reloc[i].target_handle = - flags & USE_LUT ? target : objects[target].handle; - gem_reloc[i].read_domains = I915_GEM_DOMAIN_RENDER; - gem_reloc[i].write_domain = 0; - gem_reloc[i].presumed_offset = 0; - if (flags & SKIP_RELOC) - gem_reloc[i].presumed_offset = objects[target].offset; - } - - execbuf.buffers_ptr = (uintptr_t)objects; - execbuf.buffer_count = num_exec + 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = 0; - if (flags & USE_LUT) - execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT; - if (flags & NO_RELOC) - execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - return drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); -} - -#define ELAPSED(a,b) (1e6*((b)->tv_sec - (a)->tv_sec) + ((b)->tv_usec - (a)->tv_usec)) -igt_simple_main -{ - uint32_t batch[2] = {MI_BATCH_BUFFER_END}; - int fd, n, m, count; - const struct { - const char *name; - unsigned int flags; - } pass[] = { - { .name = "relocation", .flags = 0 }, - { .name = "skip-relocs", .flags = SKIP_RELOC }, - { .name = "no-relocs", .flags = NO_RELOC }, - { .name = NULL }, - }, *p; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - for (n = 0; n < MAX_NUM_EXEC; n++) { - gem_exec[n].handle = gem_create(fd, 4096); - gem_exec[n].relocation_count = 0; - gem_exec[n].relocs_ptr = 0; - gem_exec[n].alignment = 0; - gem_exec[n].offset = 0; - gem_exec[n].flags = 0; - gem_exec[n].rsvd1 = 0; - gem_exec[n].rsvd2 = 0; - } - - gem_exec[n].handle = gem_create(fd, 4096); - gem_write(fd, gem_exec[n].handle, 0, batch, sizeof(batch)); - - igt_skip_on(exec(fd, 1, 0, USE_LUT)); - - for (p = pass; p->name != NULL; p++) { - for (n = 1; n <= MAX_NUM_EXEC; n *= 2) { - double elapsed[16][2]; - double s_x, s_y, s_xx, s_xy; - double A, B; - int i, j; - - for (i = 0, m = 1; m <= MAX_NUM_RELOC; m *= 2, i++) { - struct timeval start, end; - - do_or_die(exec(fd, n, m, 0 | p->flags)); - gettimeofday(&start, NULL); - for (count = 0; count < 1000; count++) - do_or_die(exec(fd, n, m, 0 | p->flags)); - gettimeofday(&end, NULL); - gem_sync(fd, gem_exec[MAX_NUM_EXEC].handle); - elapsed[i][0] = ELAPSED(&start, &end); - - do_or_die(exec(fd, n, m, USE_LUT | p->flags)); - gettimeofday(&start, NULL); - for (count = 0; count < 1000; count++) - do_or_die(exec(fd, n, m, USE_LUT | p->flags)); - gettimeofday(&end, NULL); - gem_sync(fd, gem_exec[MAX_NUM_EXEC].handle); - elapsed[i][1] = ELAPSED(&start, &end); - } - - igt_info("%s: buffers=%4d:", p->name, n); - - s_x = s_y = s_xx = s_xy = 0; - for (j = 0; j < i; j++) { - int k = 1 << j; - s_x += k; - s_y += elapsed[j][0]; - s_xx += k * k; - s_xy += k * elapsed[j][0]; - } - B = (s_xy - s_x * s_y / j) / (s_xx - s_x * s_x / j); - A = s_y / j - B * s_x / j; - igt_info(" old=%7.0f + %.1f*reloc,", A, B); - - s_x = s_y = s_xx = s_xy = 0; - for (j = 0; j < i; j++) { - int k = 1 << j; - s_x += k; - s_y += elapsed[j][1]; - s_xx += k * k; - s_xy += k * elapsed[j][1]; - } - B = (s_xy - s_x * s_y / j) / (s_xx - s_x * s_x / j); - A = s_y / j - B * s_x / j; - igt_info(" lut=%7.0f + %.1f*reloc (ns)", A, B); - - igt_info("\n"); - } - } -} diff --git a/tests/gem_exec_nop.c b/tests/gem_exec_nop.c deleted file mode 100644 index 542f98c3..00000000 --- a/tests/gem_exec_nop.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" - -#define LOCAL_I915_EXEC_VEBOX (4<<0) - -static double elapsed(const struct timeval *start, - const struct timeval *end, - int loop) -{ - return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec))/loop; -} - -static int exec(int fd, uint32_t handle, int loops, unsigned ring_id) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[1]; - int ret = 0; - - gem_exec[0].handle = handle; - gem_exec[0].relocation_count = 0; - gem_exec[0].relocs_ptr = 0; - gem_exec[0].alignment = 0; - gem_exec[0].offset = 0; - gem_exec[0].flags = 0; - gem_exec[0].rsvd1 = 0; - gem_exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring_id; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - while (loops-- && ret == 0) { - ret = drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - } - gem_sync(fd, handle); - - return ret; -} - -static void loop(int fd, uint32_t handle, unsigned ring_id, const char *ring_name) -{ - int count; - - gem_require_ring(fd, ring_id); - - for (count = 1; count <= SLOW_QUICK(1<<17, 1<<4); count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - igt_assert(exec(fd, handle, count, ring_id) == 0); - gettimeofday(&end, NULL); - igt_info("Time to exec x %d: %7.3fµs (ring=%s)\n", - count, elapsed(&start, &end, count), ring_name); - fflush(stdout); - } -} - -uint32_t batch[2] = {MI_BATCH_BUFFER_END}; -uint32_t handle; -int fd; - -igt_main -{ - igt_fixture { - fd = drm_open_any(); - - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, sizeof(batch)); - } - - igt_subtest("render") - loop(fd, handle, I915_EXEC_RENDER, "render"); - - igt_subtest("bsd") - loop(fd, handle, I915_EXEC_BSD, "bsd"); - - igt_subtest("blt") - loop(fd, handle, I915_EXEC_BLT, "blt"); - - igt_subtest("vebox") - loop(fd, handle, LOCAL_I915_EXEC_VEBOX, "vebox"); - - igt_fixture { - gem_close(fd, handle); - - close(fd); - } -} diff --git a/tests/gem_exec_params.c b/tests/gem_exec_params.c deleted file mode 100644 index 54f0dc33..00000000 --- a/tests/gem_exec_params.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2014 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: - * Daniel Vetter - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -#define LOCAL_I915_EXEC_VEBOX (4<<0) -#define LOCAL_I915_EXEC_BSD_MASK (3<<13) -#define LOCAL_I915_EXEC_BSD_RING1 (1<<13) -#define LOCAL_I915_EXEC_BSD_RING2 (2<<13) - -struct drm_i915_gem_execbuffer2 execbuf; -struct drm_i915_gem_exec_object2 gem_exec[1]; -uint32_t batch[2] = {MI_BATCH_BUFFER_END}; -uint32_t handle, devid; -int fd; - -igt_main -{ - igt_fixture { - fd = drm_open_any(); - - devid = intel_get_drm_devid(fd); - - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, sizeof(batch)); - - gem_exec[0].handle = handle; - gem_exec[0].relocation_count = 0; - gem_exec[0].relocs_ptr = 0; - gem_exec[0].alignment = 0; - gem_exec[0].offset = 0; - gem_exec[0].flags = 0; - gem_exec[0].rsvd1 = 0; - gem_exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = 0; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - } - - igt_subtest("control") { - igt_assert(drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf) == 0); - execbuf.flags = I915_EXEC_RENDER; - igt_assert(drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf) == 0); - } - -#define RUN_FAIL(expected_errno) do { \ - igt_assert(drmIoctl(fd, \ - DRM_IOCTL_I915_GEM_EXECBUFFER2, \ - &execbuf) == -1); \ - igt_assert_eq(errno, expected_errno); \ - } while(0) - - igt_subtest("no-bsd") { - igt_require(!gem_has_bsd(fd)); - execbuf.flags = I915_EXEC_BSD; - RUN_FAIL(EINVAL); - } - igt_subtest("no-blt") { - igt_require(!gem_has_blt(fd)); - execbuf.flags = I915_EXEC_BLT; - RUN_FAIL(EINVAL); - } - igt_subtest("no-vebox") { - igt_require(!gem_has_vebox(fd)); - execbuf.flags = LOCAL_I915_EXEC_VEBOX; - RUN_FAIL(EINVAL); - } - igt_subtest("invalid-ring") { - execbuf.flags = I915_EXEC_RING_MASK; - RUN_FAIL(EINVAL); - } - - igt_subtest("invalid-ring2") { - execbuf.flags = LOCAL_I915_EXEC_VEBOX+1; - RUN_FAIL(EINVAL); - } - - igt_subtest("invalid-bsd-ring") { - igt_require(gem_has_bsd2(fd)); - execbuf.flags = I915_EXEC_BSD | LOCAL_I915_EXEC_BSD_MASK; - RUN_FAIL(EINVAL); - } - - igt_subtest("invalid-bsd1-flag-on-render") { - execbuf.flags = I915_EXEC_RENDER | LOCAL_I915_EXEC_BSD_RING1; - RUN_FAIL(EINVAL); - } - - igt_subtest("invalid-bsd2-flag-on-render") { - execbuf.flags = I915_EXEC_RENDER | LOCAL_I915_EXEC_BSD_RING2; - RUN_FAIL(EINVAL); - } - - igt_subtest("invalid-bsd1-flag-on-blt") { - execbuf.flags = I915_EXEC_BLT | LOCAL_I915_EXEC_BSD_RING1; - RUN_FAIL(EINVAL); - } - - igt_subtest("invalid-bsd2-flag-on-blt") { - execbuf.flags = I915_EXEC_BLT | LOCAL_I915_EXEC_BSD_RING2; - RUN_FAIL(EINVAL); - } - - igt_subtest("invalid-bsd1-flag-on-vebox") { - igt_require(gem_has_vebox(fd)); - execbuf.flags = LOCAL_I915_EXEC_VEBOX | LOCAL_I915_EXEC_BSD_RING1; - RUN_FAIL(EINVAL); - } - - igt_subtest("invalid-bsd2-flag-on-vebox") { - igt_require(gem_has_vebox(fd)); - execbuf.flags = LOCAL_I915_EXEC_VEBOX | LOCAL_I915_EXEC_BSD_RING2; - RUN_FAIL(EINVAL); - } - - igt_subtest("rel-constants-invalid-ring") { - igt_require(gem_has_bsd(fd)); - execbuf.flags = I915_EXEC_BSD | I915_EXEC_CONSTANTS_ABSOLUTE; - RUN_FAIL(EINVAL); - } - - igt_subtest("rel-constants-invalid-rel-gen5") { - igt_require(intel_gen(devid) > 5); - execbuf.flags = I915_EXEC_RENDER | I915_EXEC_CONSTANTS_REL_SURFACE; - RUN_FAIL(EINVAL); - } - - igt_subtest("rel-constants-invalid") { - execbuf.flags = I915_EXEC_RENDER | (I915_EXEC_CONSTANTS_REL_SURFACE+(1<<6)); - RUN_FAIL(EINVAL); - } - - igt_subtest("sol-reset-invalid") { - igt_require(gem_has_bsd(fd)); - execbuf.flags = I915_EXEC_BSD | I915_EXEC_GEN7_SOL_RESET; - RUN_FAIL(EINVAL); - } - - igt_subtest("sol-reset-not-gen7") { - igt_require(intel_gen(devid) != 7); - execbuf.flags = I915_EXEC_RENDER | I915_EXEC_GEN7_SOL_RESET; - RUN_FAIL(EINVAL); - } - - igt_subtest("secure-non-root") { - igt_fork(child, 1) { - igt_drop_root(); - - execbuf.flags = I915_EXEC_RENDER | I915_EXEC_SECURE; - RUN_FAIL(EPERM); - } - - igt_waitchildren(); - } - - igt_subtest("secure-non-master") { - do_or_die(drmDropMaster(fd)); - execbuf.flags = I915_EXEC_RENDER | I915_EXEC_SECURE; - RUN_FAIL(EPERM); - do_or_die(drmSetMaster(fd)); - igt_assert(drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf) == 0); - } - - /* HANDLE_LUT and NO_RELOC are already exercised by gem_exec_lut_handle */ - - igt_subtest("invalid-flag") { - execbuf.flags = I915_EXEC_RENDER | (I915_EXEC_HANDLE_LUT << 1); - RUN_FAIL(EINVAL); - } - - /* rsvd1 aka context id is already exercised by gem_ctx_bad_exec */ - - igt_subtest("cliprects-invalid") { - igt_require(intel_gen(devid) >= 5); - execbuf.flags = 0; - execbuf.num_cliprects = 1; - RUN_FAIL(EINVAL); - execbuf.num_cliprects = 0; - } - -#define DIRT(name) \ - igt_subtest(#name "-dirt") { \ - execbuf.flags = 0; \ - execbuf.name = 1; \ - RUN_FAIL(EINVAL); \ - execbuf.name = 0; \ - } - - DIRT(rsvd2); - DIRT(cliprects_ptr); - DIRT(DR1); - DIRT(DR4); -#undef DIRT - -#undef RUN_FAIL - - igt_fixture { - gem_close(fd, handle); - - close(fd); - } -} diff --git a/tests/gem_exec_parse.c b/tests/gem_exec_parse.c deleted file mode 100644 index fff166a4..00000000 --- a/tests/gem_exec_parse.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * 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. - * - */ - -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <errno.h> - -#include <drm.h> - -#include "drmtest.h" -#include "ioctl_wrappers.h" -#include "intel_chipset.h" - -#ifndef I915_PARAM_CMD_PARSER_VERSION -#define I915_PARAM_CMD_PARSER_VERSION 28 -#endif - -static int __gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf) -{ - if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf)) - return -errno; - - return 0; -} - -static void exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds, - int size, int patch_offset, uint64_t expected_value) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 objs[2]; - struct drm_i915_gem_relocation_entry reloc[1]; - - uint32_t target_bo = gem_create(fd, 4096); - uint64_t actual_value = 0; - - gem_write(fd, cmd_bo, 0, cmds, size); - - reloc[0].offset = patch_offset; - reloc[0].delta = 0; - reloc[0].target_handle = target_bo; - reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; - reloc[0].presumed_offset = 0; - - objs[0].handle = target_bo; - objs[0].relocation_count = 0; - objs[0].relocs_ptr = 0; - objs[0].alignment = 0; - objs[0].offset = 0; - objs[0].flags = 0; - objs[0].rsvd1 = 0; - objs[0].rsvd2 = 0; - - objs[1].handle = cmd_bo; - objs[1].relocation_count = 1; - objs[1].relocs_ptr = (uintptr_t)reloc; - objs[1].alignment = 0; - objs[1].offset = 0; - objs[1].flags = 0; - objs[1].rsvd1 = 0; - objs[1].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)objs; - execbuf.buffer_count = 2; - execbuf.batch_start_offset = 0; - execbuf.batch_len = size; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = I915_EXEC_RENDER; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - gem_execbuf(fd, &execbuf); - gem_sync(fd, cmd_bo); - - gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value)); - igt_assert_eq(expected_value, actual_value); - - gem_close(fd, target_bo); -} - -static void exec_batch(int fd, uint32_t cmd_bo, uint32_t *cmds, - int size, int ring, int expected_ret) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 objs[1]; - - gem_write(fd, cmd_bo, 0, cmds, size); - - objs[0].handle = cmd_bo; - objs[0].relocation_count = 0; - objs[0].relocs_ptr = 0; - objs[0].alignment = 0; - objs[0].offset = 0; - objs[0].flags = 0; - objs[0].rsvd1 = 0; - objs[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)objs; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = size; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret); - - gem_sync(fd, cmd_bo); -} - -static void exec_split_batch(int fd, uint32_t *cmds, - int size, int ring, int expected_ret) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 objs[1]; - uint32_t cmd_bo; - uint32_t noop[1024] = { 0 }; - const int alloc_size = 4096 * 2; - const int actual_start_offset = 4096-sizeof(uint32_t); - - /* Allocate and fill a 2-page batch with noops */ - cmd_bo = gem_create(fd, alloc_size); - gem_write(fd, cmd_bo, 0, noop, sizeof(noop)); - gem_write(fd, cmd_bo, 4096, noop, sizeof(noop)); - - /* Write the provided commands such that the first dword - * of the command buffer is the last dword of the first - * page (i.e. the command is split across the two pages). - */ - gem_write(fd, cmd_bo, actual_start_offset, cmds, size); - - objs[0].handle = cmd_bo; - objs[0].relocation_count = 0; - objs[0].relocs_ptr = 0; - objs[0].alignment = 0; - objs[0].offset = 0; - objs[0].flags = 0; - objs[0].rsvd1 = 0; - objs[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)objs; - execbuf.buffer_count = 1; - /* NB: We want batch_start_offset and batch_len to point to the block - * of the actual commands (i.e. at the last dword of the first page), - * but have to adjust both the start offset and length to meet the - * kernel driver's requirements on the alignment of those fields. - */ - execbuf.batch_start_offset = actual_start_offset & ~0x7; - execbuf.batch_len = - ALIGN(size + actual_start_offset - execbuf.batch_start_offset, - 0x8); - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret); - - gem_sync(fd, cmd_bo); - gem_close(fd, cmd_bo); -} - -static void exec_batch_chained(int fd, uint32_t cmd_bo, uint32_t *cmds, - int size, int patch_offset, - uint64_t expected_value) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 objs[3]; - struct drm_i915_gem_relocation_entry reloc; - struct drm_i915_gem_relocation_entry first_level_reloc; - - uint32_t target_bo = gem_create(fd, 4096); - uint32_t first_level_bo = gem_create(fd, 4096); - uint64_t actual_value = 0; - - static uint32_t first_level_cmds[] = { - MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965, - 0, - MI_BATCH_BUFFER_END, - 0, - }; - - if (IS_HASWELL(intel_get_drm_devid(fd))) - first_level_cmds[0] |= MI_BATCH_NON_SECURE_HSW; - - gem_write(fd, first_level_bo, 0, - first_level_cmds, sizeof(first_level_cmds)); - gem_write(fd, cmd_bo, 0, cmds, size); - - reloc.offset = patch_offset; - reloc.delta = 0; - reloc.target_handle = target_bo; - reloc.read_domains = I915_GEM_DOMAIN_RENDER; - reloc.write_domain = I915_GEM_DOMAIN_RENDER; - reloc.presumed_offset = 0; - - first_level_reloc.offset = 4; - first_level_reloc.delta = 0; - first_level_reloc.target_handle = cmd_bo; - first_level_reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION; - first_level_reloc.write_domain = 0; - first_level_reloc.presumed_offset = 0; - - objs[0].handle = target_bo; - objs[0].relocation_count = 0; - objs[0].relocs_ptr = 0; - objs[0].alignment = 0; - objs[0].offset = 0; - objs[0].flags = 0; - objs[0].rsvd1 = 0; - objs[0].rsvd2 = 0; - - objs[1].handle = cmd_bo; - objs[1].relocation_count = 1; - objs[1].relocs_ptr = (uintptr_t)&reloc; - objs[1].alignment = 0; - objs[1].offset = 0; - objs[1].flags = 0; - objs[1].rsvd1 = 0; - objs[1].rsvd2 = 0; - - objs[2].handle = first_level_bo; - objs[2].relocation_count = 1; - objs[2].relocs_ptr = (uintptr_t)&first_level_reloc; - objs[2].alignment = 0; - objs[2].offset = 0; - objs[2].flags = 0; - objs[2].rsvd1 = 0; - objs[2].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)objs; - execbuf.buffer_count = 3; - execbuf.batch_start_offset = 0; - execbuf.batch_len = sizeof(first_level_cmds); - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = I915_EXEC_RENDER; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - gem_execbuf(fd, &execbuf); - gem_sync(fd, cmd_bo); - - gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value)); - igt_assert_eq(expected_value, actual_value); - - gem_close(fd, first_level_bo); - gem_close(fd, target_bo); -} - -uint32_t handle; -int fd; - -#define MI_ARB_ON_OFF (0x8 << 23) -#define MI_DISPLAY_FLIP ((0x14 << 23) | 1) - -#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2) -#define PIPE_CONTROL_QW_WRITE (1<<14) -#define PIPE_CONTROL_LRI_POST_OP (1<<23) - -#define OACONTROL 0x2360 - -igt_main -{ - igt_fixture { - int parser_version = 0; - drm_i915_getparam_t gp; - int rc; - - fd = drm_open_any(); - - gp.param = I915_PARAM_CMD_PARSER_VERSION; - gp.value = &parser_version; - rc = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); - igt_require(!rc && parser_version > 0); - - igt_require(gem_uses_aliasing_ppgtt(fd)); - - handle = gem_create(fd, 4096); - - /* ATM cmd parser only exists on gen7. */ - igt_require(intel_gen(intel_get_drm_devid(fd)) == 7); - } - - igt_subtest("basic-allowed") { - uint32_t pc[] = { - GFX_OP_PIPE_CONTROL, - PIPE_CONTROL_QW_WRITE, - 0, /* To be patched */ - 0x12000000, - 0, - MI_BATCH_BUFFER_END, - }; - exec_batch_patched(fd, handle, - pc, sizeof(pc), - 8, /* patch offset, */ - 0x12000000); - } - - igt_subtest("basic-rejected") { - uint32_t arb_on_off[] = { - MI_ARB_ON_OFF, - MI_BATCH_BUFFER_END, - }; - uint32_t display_flip[] = { - MI_DISPLAY_FLIP, - 0, 0, 0, - MI_BATCH_BUFFER_END, - 0 - }; - exec_batch(fd, handle, - arb_on_off, sizeof(arb_on_off), - I915_EXEC_RENDER, - -EINVAL); - exec_batch(fd, handle, - arb_on_off, sizeof(arb_on_off), - I915_EXEC_BSD, - -EINVAL); - if (gem_has_vebox(fd)) { - exec_batch(fd, handle, - arb_on_off, sizeof(arb_on_off), - I915_EXEC_VEBOX, - -EINVAL); - } - exec_batch(fd, handle, - display_flip, sizeof(display_flip), - I915_EXEC_BLT, - -EINVAL); - } - - igt_subtest("registers") { - uint32_t lri_bad[] = { - MI_LOAD_REGISTER_IMM, - 0, /* disallowed register address */ - 0x12000000, - MI_BATCH_BUFFER_END, - }; - uint32_t lri_ok[] = { - MI_LOAD_REGISTER_IMM, - 0x5280, /* allowed register address (SO_WRITE_OFFSET[0]) */ - 0x1, - MI_BATCH_BUFFER_END, - }; - exec_batch(fd, handle, - lri_bad, sizeof(lri_bad), - I915_EXEC_RENDER, - -EINVAL); - exec_batch(fd, handle, - lri_ok, sizeof(lri_ok), - I915_EXEC_RENDER, - 0); - } - - igt_subtest("bitmasks") { - uint32_t pc[] = { - GFX_OP_PIPE_CONTROL, - (PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_LRI_POST_OP), - 0, /* To be patched */ - 0x12000000, - 0, - MI_BATCH_BUFFER_END, - }; - exec_batch(fd, handle, - pc, sizeof(pc), - I915_EXEC_RENDER, - -EINVAL); - } - - igt_subtest("batch-without-end") { - uint32_t noop[1024] = { 0 }; - exec_batch(fd, handle, - noop, sizeof(noop), - I915_EXEC_RENDER, - -EINVAL); - } - - igt_subtest("cmd-crossing-page") { - uint32_t lri_ok[] = { - MI_LOAD_REGISTER_IMM, - 0x5280, /* allowed register address (SO_WRITE_OFFSET[0]) */ - 0x1, - MI_BATCH_BUFFER_END, - }; - exec_split_batch(fd, - lri_ok, sizeof(lri_ok), - I915_EXEC_RENDER, - 0); - } - - igt_subtest("oacontrol-tracking") { - uint32_t lri_ok[] = { - MI_LOAD_REGISTER_IMM, - OACONTROL, - 0x31337000, - MI_LOAD_REGISTER_IMM, - OACONTROL, - 0x0, - MI_BATCH_BUFFER_END, - 0 - }; - uint32_t lri_bad[] = { - MI_LOAD_REGISTER_IMM, - OACONTROL, - 0x31337000, - MI_BATCH_BUFFER_END, - }; - uint32_t lri_extra_bad[] = { - MI_LOAD_REGISTER_IMM, - OACONTROL, - 0x31337000, - MI_LOAD_REGISTER_IMM, - OACONTROL, - 0x0, - MI_LOAD_REGISTER_IMM, - OACONTROL, - 0x31337000, - MI_BATCH_BUFFER_END, - }; - exec_batch(fd, handle, - lri_ok, sizeof(lri_ok), - I915_EXEC_RENDER, - 0); - exec_batch(fd, handle, - lri_bad, sizeof(lri_bad), - I915_EXEC_RENDER, - -EINVAL); - exec_batch(fd, handle, - lri_extra_bad, sizeof(lri_extra_bad), - I915_EXEC_RENDER, - -EINVAL); - } - - igt_subtest("chained-batch") { - uint32_t pc[] = { - GFX_OP_PIPE_CONTROL, - PIPE_CONTROL_QW_WRITE, - 0, /* To be patched */ - 0x12000000, - 0, - MI_BATCH_BUFFER_END, - }; - exec_batch_chained(fd, handle, - pc, sizeof(pc), - 8, /* patch offset, */ - 0x12000000); - } - - igt_fixture { - gem_close(fd, handle); - - close(fd); - } -} diff --git a/tests/gem_fd_exhaustion.c b/tests/gem_fd_exhaustion.c deleted file mode 100644 index 8ba631f6..00000000 --- a/tests/gem_fd_exhaustion.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2014 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/resource.h> -#include <sys/time.h> -#include <fcntl.h> -#include <limits.h> - -#include "drmtest.h" -#include "ioctl_wrappers.h" -#include "igt_aux.h" - - -#define FD_ARR_SZ 100 -int fd_arr[FD_ARR_SZ]; - -igt_simple_main -{ - int fd, i; - struct rlimit rlim; - unsigned nofile_rlim; - FILE *file_max = fopen("/proc/sys/fs/file-max", "r"); - igt_assert(fscanf(file_max, "%u", &nofile_rlim) == 1); - fclose(file_max); - - igt_info("System limit for open files is %u\n", nofile_rlim); - - igt_assert(getrlimit(RLIMIT_NOFILE, &rlim) == 0); - rlim.rlim_cur = nofile_rlim; - rlim.rlim_max = nofile_rlim; - igt_assert(setrlimit(RLIMIT_NOFILE, &rlim) == 0); - - fd = drm_open_any(); - - igt_assert(open("/dev/null", O_RDONLY) >= 0); - - igt_fork(n, 1) { - igt_drop_root(); - - for (i = 0; ; i++) { - int tmp_fd = open("/dev/null", O_RDONLY); - uint32_t handle; - - if (tmp_fd >= 0 && i < FD_ARR_SZ) - fd_arr[i] = tmp_fd; - - handle = __gem_create(fd, 4096); - if (handle) - gem_close(fd, handle); - - - if (tmp_fd < 0) { - /* Ensure we actually hit the failure path ... */ - igt_assert(handle == 0); - igt_info("fd exhaustion after %i rounds.\n", i); - break; - } - } - - /* The child will free all the fds when exiting, so no need to - * clean up to mess to ensure that the parent can at least run - * the exit handlers. */ - } - - igt_waitchildren(); - - close(fd); -} diff --git a/tests/gem_fence_thrash.c b/tests/gem_fence_thrash.c deleted file mode 100644 index 1fc05794..00000000 --- a/tests/gem_fence_thrash.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright © 2008-9 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: - * Eric Anholt <eric@anholt.net> - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <pthread.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -#define OBJECT_SIZE (128*1024) /* restricted to 1MiB alignment on i915 fences */ - -/* Before introduction of the LRU list for fences, allocation of a fence for a page - * fault would use the first inactive fence (i.e. in preference one with no outstanding - * GPU activity, or it would wait on the first to finish). Given the choice, it would simply - * reuse the fence that had just been allocated for the previous page-fault - the worst choice - * when copying between two buffers and thus constantly swapping fences. - */ - -struct test { - int fd; - int tiling; - int num_surfaces; -}; - -static void * -bo_create (int fd, int tiling) -{ - void *ptr; - int handle; - - handle = gem_create(fd, OBJECT_SIZE); - - /* dirty cpu caches a bit ... */ - ptr = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr); - memset(ptr, 0, OBJECT_SIZE); - munmap(ptr, OBJECT_SIZE); - - gem_set_tiling(fd, handle, tiling, 1024); - - ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr); - - /* XXX: mmap_gtt pulls the bo into the GTT read domain. */ - gem_sync(fd, handle); - - return ptr; -} - -static void * -bo_copy (void *_arg) -{ - struct test *t = (struct test *)_arg; - int fd = t->fd; - int n; - char *a, *b; - - a = bo_create (fd, t->tiling); - b = bo_create (fd, t->tiling); - - for (n = 0; n < 1000; n++) { - memcpy (a, b, OBJECT_SIZE); - sched_yield (); - } - - return NULL; -} - -static void -_bo_write_verify(struct test *t) -{ - int fd = t->fd; - int i, k; - uint32_t **s; - uint32_t v; - unsigned int dwords = OBJECT_SIZE >> 2; - const char *tile_str[] = { "none", "x", "y" }; - - igt_assert(t->tiling >= 0 && t->tiling <= I915_TILING_Y); - igt_assert(t->num_surfaces > 0); - - s = calloc(sizeof(*s), t->num_surfaces); - igt_assert(s); - - for (k = 0; k < t->num_surfaces; k++) - s[k] = bo_create(fd, t->tiling); - - for (k = 0; k < t->num_surfaces; k++) { - volatile uint32_t *a = s[k]; - - for (i = 0; i < dwords; i++) { - a[i] = i; - v = a[i]; - igt_assert_f(v == i, - "tiling %s: write failed at %d (%x)\n", - tile_str[t->tiling], i, v); - } - - for (i = 0; i < dwords; i++) { - v = a[i]; - igt_assert_f(v == i, - "tiling %s: verify failed at %d (%x)\n", - tile_str[t->tiling], i, v); - } - } - - for (k = 0; k < t->num_surfaces; k++) - munmap(s[k], OBJECT_SIZE); - - free(s); -} - -static void * -bo_write_verify(void *_arg) -{ - struct test *t = (struct test *)_arg; - int i; - - for (i = 0; i < 10; i++) - _bo_write_verify(t); - - return 0; -} - -static int run_test(int threads_per_fence, void *f, int tiling, - int surfaces_per_thread) -{ - struct test t; - pthread_t *threads; - int n, num_fences, num_threads; - - t.fd = drm_open_any(); - t.tiling = tiling; - t.num_surfaces = surfaces_per_thread; - - num_fences = gem_available_fences(t.fd); - igt_assert(num_fences > 0); - - num_threads = threads_per_fence * num_fences; - - igt_info("%s: threads %d, fences %d, tiling %d, surfaces per thread %d\n", - f == bo_copy ? "copy" : "write-verify", num_threads, - num_fences, tiling, surfaces_per_thread); - - if (threads_per_fence) { - threads = calloc(sizeof(*threads), num_threads); - igt_assert(threads != NULL); - - for (n = 0; n < num_threads; n++) - pthread_create (&threads[n], NULL, f, &t); - - for (n = 0; n < num_threads; n++) - pthread_join (threads[n], NULL); - } else { - void *(*func)(void *) = f; - igt_assert(func(&t) == (void *)0); - } - - close(t.fd); - - return 0; -} - -igt_main -{ - igt_skip_on_simulation(); - - igt_subtest("bo-write-verify-none") - igt_assert(run_test(0, bo_write_verify, I915_TILING_NONE, 80) == 0); - - igt_subtest("bo-write-verify-x") - igt_assert(run_test(0, bo_write_verify, I915_TILING_X, 80) == 0); - - igt_subtest("bo-write-verify-y") - igt_assert(run_test(0, bo_write_verify, I915_TILING_Y, 80) == 0); - - igt_subtest("bo-write-verify-threaded-none") - igt_assert(run_test(5, bo_write_verify, I915_TILING_NONE, 2) == 0); - - igt_subtest("bo-write-verify-threaded-x") { - igt_assert(run_test(2, bo_write_verify, I915_TILING_X, 2) == 0); - igt_assert(run_test(5, bo_write_verify, I915_TILING_X, 2) == 0); - igt_assert(run_test(10, bo_write_verify, I915_TILING_X, 2) == 0); - igt_assert(run_test(20, bo_write_verify, I915_TILING_X, 2) == 0); - } - - igt_subtest("bo-write-verify-threaded-y") { - igt_assert(run_test(2, bo_write_verify, I915_TILING_Y, 2) == 0); - igt_assert(run_test(5, bo_write_verify, I915_TILING_Y, 2) == 0); - igt_assert(run_test(10, bo_write_verify, I915_TILING_Y, 2) == 0); - igt_assert(run_test(20, bo_write_verify, I915_TILING_Y, 2) == 0); - } - - igt_subtest("bo-copy") - igt_assert(run_test(1, bo_copy, I915_TILING_X, 1) == 0); -} diff --git a/tests/gem_fence_upload.c b/tests/gem_fence_upload.c deleted file mode 100644 index 9595bc82..00000000 --- a/tests/gem_fence_upload.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright © 2014 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/time.h> -#include <pthread.h> -#include "drm.h" -#include "i915_drm.h" -#include "drmtest.h" -#include "ioctl_wrappers.h" - -#define OBJECT_SIZE (1024*1024) /* restricted to 1MiB alignment on i915 fences */ - -static double elapsed(const struct timeval *start, - const struct timeval *end) -{ - return (end->tv_sec - start->tv_sec) + 1e-6*(end->tv_usec - start->tv_usec); -} - -static void performance(void) -{ - int n, loop, count; - int fd, num_fences; - double linear[2], tiled[2]; - - fd = drm_open_any(); - - num_fences = gem_available_fences(fd); - igt_require(num_fences > 0); - - for (count = 2; count < 4*num_fences; count *= 2) { - struct timeval start, end; - uint32_t handle[count]; - void *ptr[count]; - - for (n = 0; n < count; n++) { - handle[n] = gem_create(fd, OBJECT_SIZE); - ptr[n] = gem_mmap(fd, handle[n], OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr[n]); - } - - gettimeofday(&start, NULL); - for (loop = 0; loop < 1024; loop++) { - for (n = 0; n < count; n++) - memset(ptr[n], 0, OBJECT_SIZE); - } - gettimeofday(&end, NULL); - - linear[count != 2] = count * loop / elapsed(&start, &end); - igt_info("Upload rate for %d linear surfaces: %7.3fMiB/s\n", count, linear[count != 2]); - - for (n = 0; n < count; n++) - gem_set_tiling(fd, handle[n], I915_TILING_X, 1024); - - gettimeofday(&start, NULL); - for (loop = 0; loop < 1024; loop++) { - for (n = 0; n < count; n++) - memset(ptr[n], 0, OBJECT_SIZE); - } - gettimeofday(&end, NULL); - - tiled[count != 2] = count * loop / elapsed(&start, &end); - igt_info("Upload rate for %d tiled surfaces: %7.3fMiB/s\n", count, tiled[count != 2]); - - for (n = 0; n < count; n++) { - munmap(ptr[n], OBJECT_SIZE); - gem_close(fd, handle[n]); - } - - } - - errno = 0; - igt_assert(linear[1] > 0.75 * linear[0]); - igt_assert(tiled[1] > 0.75 * tiled[0]); -} - -struct thread_performance { - pthread_t thread; - int id, count, direction, loops; - void **ptr; -}; - -static void *read_thread_performance(void *closure) -{ - struct thread_performance *t = closure; - uint32_t x = 0; - int n, m; - - for (n = 0; n < t->loops; n++) { - uint32_t *src = t->ptr[rand() % t->count]; - src += (rand() % 256) * 4096 / 4; - for (m = 0; m < 4096/4; m++) - x += src[m]; - } - - return (void *)(uintptr_t)x; -} - -static void *write_thread_performance(void *closure) -{ - struct thread_performance *t = closure; - int n; - - for (n = 0; n < t->loops; n++) { - uint32_t *dst = t->ptr[rand() % t->count]; - dst += (rand() % 256) * 4096 / 4; - memset(dst, 0, 4096); - } - - return NULL; -} - -#define READ (1<<0) -#define WRITE (1<<1) -static const char *direction_string(unsigned mask) -{ - switch (mask) { - case READ: return "Download"; - case WRITE: return "Upload"; - case READ | WRITE: return "Combined"; - default: return "Unknown"; - } -} -static void thread_performance(unsigned mask) -{ - const int loops = 4096; - int n, count; - int fd, num_fences; - double linear[2], tiled[2]; - - fd = drm_open_any(); - - num_fences = gem_available_fences(fd); - igt_require(num_fences > 0); - - for (count = 2; count < 4*num_fences; count *= 2) { - const int nthreads = (mask & READ ? count : 0) + (mask & WRITE ? count : 0); - struct timeval start, end; - struct thread_performance readers[count]; - struct thread_performance writers[count]; - uint32_t handle[count]; - void *ptr[count]; - - for (n = 0; n < count; n++) { - handle[n] = gem_create(fd, OBJECT_SIZE); - ptr[n] = gem_mmap(fd, handle[n], OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr[n]); - - if (mask & READ) { - readers[n].id = n; - readers[n].direction = READ; - readers[n].ptr = ptr; - readers[n].count = count; - readers[n].loops = loops; - } - - if (mask & WRITE) { - writers[n].id = count - n - 1; - writers[n].direction = WRITE; - writers[n].ptr = ptr; - writers[n].count = count; - writers[n].loops = loops; - } - } - - gettimeofday(&start, NULL); - for (n = 0; n < count; n++) { - if (mask & READ) - pthread_create(&readers[n].thread, NULL, read_thread_performance, &readers[n]); - if (mask & WRITE) - pthread_create(&writers[n].thread, NULL, write_thread_performance, &writers[n]); - } - for (n = 0; n < count; n++) { - if (mask & READ) - pthread_join(readers[n].thread, NULL); - if (mask & WRITE) - pthread_join(writers[n].thread, NULL); - } - gettimeofday(&end, NULL); - - linear[count != 2] = nthreads * loops / elapsed(&start, &end) / (OBJECT_SIZE / 4096); - igt_info("%s rate for %d linear surfaces, %d threads: %7.3fMiB/s\n", direction_string(mask), count, nthreads, linear[count != 2]); - - for (n = 0; n < count; n++) - gem_set_tiling(fd, handle[n], I915_TILING_X, 1024); - - gettimeofday(&start, NULL); - for (n = 0; n < count; n++) { - if (mask & READ) - pthread_create(&readers[n].thread, NULL, read_thread_performance, &readers[n]); - if (mask & WRITE) - pthread_create(&writers[n].thread, NULL, write_thread_performance, &writers[n]); - } - for (n = 0; n < count; n++) { - if (mask & READ) - pthread_join(readers[n].thread, NULL); - if (mask & WRITE) - pthread_join(writers[n].thread, NULL); - } - gettimeofday(&end, NULL); - - tiled[count != 2] = nthreads * loops / elapsed(&start, &end) / (OBJECT_SIZE / 4096); - igt_info("%s rate for %d tiled surfaces, %d threads: %7.3fMiB/s\n", direction_string(mask), count, nthreads, tiled[count != 2]); - - for (n = 0; n < count; n++) { - munmap(ptr[n], OBJECT_SIZE); - gem_close(fd, handle[n]); - } - } - - errno = 0; - igt_assert(linear[1] > 0.75 * linear[0]); - igt_assert(tiled[1] > 0.75 * tiled[0]); -} - -struct thread_contention { - pthread_t thread; - uint32_t handle; - int loops, fd; -}; -static void *no_contention(void *closure) -{ - struct thread_contention *t = closure; - int n; - - for (n = 0; n < t->loops; n++) { - uint32_t *ptr = gem_mmap(t->fd, t->handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr); - memset(ptr + (rand() % 256) * 4096 / 4, 0, 4096); - munmap(ptr, OBJECT_SIZE); - } - - return NULL; -} - -static void *wc_mmap(void *closure) -{ - struct thread_contention *t = closure; - int n; - - for (n = 0; n < t->loops; n++) { - uint32_t *ptr = gem_mmap__wc(t->fd, t->handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr); - memset(ptr + (rand() % 256) * 4096 / 4, 0, 4096); - munmap(ptr, OBJECT_SIZE); - } - - return NULL; -} - -static void thread_contention(void) -{ - const int loops = 4096; - int n, count; - int fd, num_fences; - double linear[2], tiled[2]; - - fd = drm_open_any(); - - num_fences = gem_available_fences(fd); - igt_require(num_fences > 0); - - for (count = 1; count < 4*num_fences; count *= 2) { - struct timeval start, end; - struct thread_contention threads[count]; - - for (n = 0; n < count; n++) { - threads[n].handle = gem_create(fd, OBJECT_SIZE); - threads[n].loops = loops; - threads[n].fd = fd; - } - - gettimeofday(&start, NULL); - for (n = 0; n < count; n++) - pthread_create(&threads[n].thread, NULL, no_contention, &threads[n]); - for (n = 0; n < count; n++) - pthread_join(threads[n].thread, NULL); - gettimeofday(&end, NULL); - - linear[count != 2] = count * loops / elapsed(&start, &end) / (OBJECT_SIZE / 4096); - igt_info("Contended upload rate for %d linear threads: %7.3fMiB/s\n", count, linear[count != 2]); - - for (n = 0; n < count; n++) - gem_set_tiling(fd, threads[n].handle, I915_TILING_X, 1024); - - gettimeofday(&start, NULL); - for (n = 0; n < count; n++) - pthread_create(&threads[n].thread, NULL, no_contention, &threads[n]); - for (n = 0; n < count; n++) - pthread_join(threads[n].thread, NULL); - gettimeofday(&end, NULL); - - tiled[count != 2] = count * loops / elapsed(&start, &end) / (OBJECT_SIZE / 4096); - igt_info("Contended upload rate for %d tiled threads: %7.3fMiB/s\n", count, tiled[count != 2]); - - for (n = 0; n < count; n++) { - gem_close(fd, threads[n].handle); - } - } - - errno = 0; - igt_assert(linear[1] > 0.75 * linear[0]); - igt_assert(tiled[1] > 0.75 * tiled[0]); -} - -static void wc_contention(void) -{ - const int loops = 4096; - int n, count; - int fd, num_fences; - double linear[2], tiled[2]; - - fd = drm_open_any(); - gem_require_mmap_wc(fd); - - num_fences = gem_available_fences(fd); - igt_require(num_fences > 0); - - for (count = 1; count < 4*num_fences; count *= 2) { - struct timeval start, end; - struct thread_contention threads[count]; - - for (n = 0; n < count; n++) { - threads[n].handle = gem_create(fd, OBJECT_SIZE); - threads[n].loops = loops; - threads[n].fd = fd; - } - - gettimeofday(&start, NULL); - for (n = 0; n < count; n++) - pthread_create(&threads[n].thread, NULL, wc_mmap, &threads[n]); - for (n = 0; n < count; n++) - pthread_join(threads[n].thread, NULL); - gettimeofday(&end, NULL); - - linear[count != 2] = count * loops / elapsed(&start, &end) / (OBJECT_SIZE / 4096); - igt_info("Contended upload rate for %d linear threads/wc: %7.3fMiB/s\n", count, linear[count != 2]); - - for (n = 0; n < count; n++) - gem_set_tiling(fd, threads[n].handle, I915_TILING_X, 1024); - - gettimeofday(&start, NULL); - for (n = 0; n < count; n++) - pthread_create(&threads[n].thread, NULL, wc_mmap, &threads[n]); - for (n = 0; n < count; n++) - pthread_join(threads[n].thread, NULL); - gettimeofday(&end, NULL); - - tiled[count != 2] = count * loops / elapsed(&start, &end) / (OBJECT_SIZE / 4096); - igt_info("Contended upload rate for %d tiled threads/wc: %7.3fMiB/s\n", count, tiled[count != 2]); - - for (n = 0; n < count; n++) { - gem_close(fd, threads[n].handle); - } - } - - errno = 0; - igt_assert(linear[1] > 0.75 * linear[0]); - igt_assert(tiled[1] > 0.75 * tiled[0]); -} - -igt_main -{ - igt_skip_on_simulation(); - - igt_subtest("performance") - performance(); - igt_subtest("thread-contention") - thread_contention(); - igt_subtest("wc-contention") - wc_contention(); - igt_subtest("thread-performance-read") - thread_performance(READ); - igt_subtest("thread-performance-write") - thread_performance(WRITE); - igt_subtest("thread-performance-both") - thread_performance(READ | WRITE); -} diff --git a/tests/gem_fenced_exec_thrash.c b/tests/gem_fenced_exec_thrash.c deleted file mode 100644 index 75f251cc..00000000 --- a/tests/gem_fenced_exec_thrash.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#define _GNU_SOURCE - -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test execbuf fence accounting."); - -#define WIDTH 1024 -#define HEIGHT 1024 -#define OBJECT_SIZE (4*WIDTH*HEIGHT) - -#define BATCH_SIZE 4096 - -#define MAX_FENCES 32 - -/* - * Testcase: execbuf fence accounting - * - * We had a bug where we were falsely accounting upon reservation already - * fenced buffers as occupying a fence register even if they did not require - * one for the batch. - * - * We aim to exercise this by performing a sequence of fenced BLT - * with 2*num_avail_fence buffers, but alternating which half are fenced in - * each command. - */ - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -uint32_t devid; - -static void emit_dummy_load(void) -{ - int i; - uint32_t tile_flags = 0; - uint32_t tiling_mode = I915_TILING_X; - unsigned long pitch; - drm_intel_bo *dummy_bo; - - dummy_bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled dummy_bo", 2048, 2048, - 4, &tiling_mode, &pitch, 0); - - if (IS_965(devid)) { - pitch /= 4; - tile_flags = XY_SRC_COPY_BLT_SRC_TILED | - XY_SRC_COPY_BLT_DST_TILED; - } - - for (i = 0; i < 5; i++) { - BLIT_COPY_BATCH_START(tile_flags); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - pitch); - OUT_BATCH(0 << 16 | 1024); - OUT_BATCH((2048) << 16 | (2048)); - OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(pitch); - OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 6) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } - } - intel_batchbuffer_flush(batch); - - drm_intel_bo_unreference(dummy_bo); -} - -static uint32_t -tiled_bo_create (int fd) -{ - uint32_t handle; - - handle = gem_create(fd, OBJECT_SIZE); - - gem_set_tiling(fd, handle, I915_TILING_X, WIDTH*4); - - return handle; -} - -static uint32_t -batch_create (int fd) -{ - uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 }; - uint32_t batch_handle; - - batch_handle = gem_create(fd, BATCH_SIZE); - - gem_write(fd, batch_handle, 0, buf, sizeof(buf)); - - return batch_handle; -} - -static void fill_reloc(struct drm_i915_gem_relocation_entry *reloc, uint32_t handle) -{ - reloc->offset = 2 * sizeof(uint32_t); - reloc->target_handle = handle; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = 0; -} - -#define BUSY_LOAD (1 << 0) -#define INTERRUPTIBLE (1 << 1) - -static void run_test(int fd, int num_fences, int expected_errno, - unsigned flags) -{ - struct drm_i915_gem_execbuffer2 execbuf[2]; - struct drm_i915_gem_exec_object2 exec[2][2*MAX_FENCES+3]; - struct drm_i915_gem_relocation_entry reloc[2*MAX_FENCES+2]; - - int i, n; - int loop = 1000; - - if (flags & BUSY_LOAD) { - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - /* Takes forever otherwise. */ - loop = 50; - } - - if (flags & INTERRUPTIBLE) - igt_fork_signal_helper(); - - memset(execbuf, 0, sizeof(execbuf)); - memset(exec, 0, sizeof(exec)); - memset(reloc, 0, sizeof(reloc)); - - for (n = 0; n < 2*num_fences; n++) { - uint32_t handle = tiled_bo_create(fd); - exec[1][2*num_fences - n-1].handle = exec[0][n].handle = handle; - fill_reloc(&reloc[n], handle); - } - - for (i = 0; i < 2; i++) { - for (n = 0; n < num_fences; n++) - exec[i][n].flags = EXEC_OBJECT_NEEDS_FENCE; - - exec[i][2*num_fences].handle = batch_create(fd); - exec[i][2*num_fences].relocs_ptr = (uintptr_t)reloc; - exec[i][2*num_fences].relocation_count = 2*num_fences; - - execbuf[i].buffers_ptr = (uintptr_t)exec[i]; - execbuf[i].buffer_count = 2*num_fences+1; - execbuf[i].batch_len = 2*sizeof(uint32_t); - } - - do { - int ret; - - if (flags & BUSY_LOAD) - emit_dummy_load(); - - ret = drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf[0]); - igt_assert(expected_errno ? - ret < 0 && errno == expected_errno : - ret == 0); - - ret = drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf[1]); - igt_assert(expected_errno ? - ret < 0 && errno == expected_errno : - ret == 0); - } while (--loop); - - if (flags & INTERRUPTIBLE) - igt_stop_signal_helper(); -} - -int fd; -int num_fences; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - num_fences = gem_available_fences(fd); - igt_assert(num_fences > 4); - devid = intel_get_drm_devid(fd); - - igt_assert(num_fences <= MAX_FENCES); - } - - igt_subtest("2-spare-fences") - run_test(fd, num_fences - 2, 0, 0); - for (unsigned flags = 0; flags < 4; flags++) { - igt_subtest_f("no-spare-fences%s%s", - flags & BUSY_LOAD ? "-busy" : "", - flags & INTERRUPTIBLE ? "-interruptible" : "") - run_test(fd, num_fences, 0, flags); - } - igt_subtest("too-many-fences") - run_test(fd, num_fences + 1, intel_gen(devid) >= 4 ? 0 : EDEADLK, 0); - - igt_fixture - close(fd); -} diff --git a/tests/gem_flink.c b/tests/gem_flink.c deleted file mode 100644 index 627a6778..00000000 --- a/tests/gem_flink.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright © 2008 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: - * Eric Anholt <eric@anholt.net> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -static void -test_flink(int fd) -{ - struct drm_i915_gem_create create; - struct drm_gem_flink flink; - struct drm_gem_open open_struct; - int ret; - - igt_info("Testing flink and open.\n"); - - memset(&create, 0, sizeof(create)); - create.size = 16 * 1024; - ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); - igt_assert(ret == 0); - - flink.handle = create.handle; - ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - igt_assert(ret == 0); - - open_struct.name = flink.name; - ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open_struct); - igt_assert(ret == 0); - igt_assert(open_struct.handle != 0); -} - -static void -test_double_flink(int fd) -{ - struct drm_i915_gem_create create; - struct drm_gem_flink flink; - struct drm_gem_flink flink2; - int ret; - - igt_info("Testing repeated flink.\n"); - - memset(&create, 0, sizeof(create)); - create.size = 16 * 1024; - ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); - igt_assert(ret == 0); - - flink.handle = create.handle; - ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - igt_assert(ret == 0); - - flink2.handle = create.handle; - ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink2); - igt_assert(ret == 0); - igt_assert(flink2.name == flink.name); -} - -static void -test_bad_flink(int fd) -{ - struct drm_gem_flink flink; - int ret; - - igt_info("Testing error return on bad flink ioctl.\n"); - - flink.handle = 0x10101010; - ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - igt_assert(ret == -1 && errno == ENOENT); -} - -static void -test_bad_open(int fd) -{ - struct drm_gem_open open_struct; - int ret; - - igt_info("Testing error return on bad open ioctl.\n"); - - open_struct.name = 0x10101010; - ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open_struct); - - igt_assert(ret == -1 && errno == ENOENT); -} - -static void -test_flink_lifetime(int fd) -{ - struct drm_i915_gem_create create; - struct drm_gem_flink flink; - struct drm_gem_open open_struct; - int ret, fd2; - - igt_info("Testing flink lifetime.\n"); - - fd2 = drm_open_any(); - - memset(&create, 0, sizeof(create)); - create.size = 16 * 1024; - ret = ioctl(fd2, DRM_IOCTL_I915_GEM_CREATE, &create); - igt_assert(ret == 0); - - flink.handle = create.handle; - ret = ioctl(fd2, DRM_IOCTL_GEM_FLINK, &flink); - igt_assert(ret == 0); - - open_struct.name = flink.name; - ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open_struct); - igt_assert(ret == 0); - igt_assert(open_struct.handle != 0); - - close(fd2); - fd2 = drm_open_any(); - - open_struct.name = flink.name; - ret = ioctl(fd2, DRM_IOCTL_GEM_OPEN, &open_struct); - igt_assert(ret == 0); - igt_assert(open_struct.handle != 0); -} - -int fd; - -igt_main -{ - igt_fixture - fd = drm_open_any(); - - igt_subtest("basic") - test_flink(fd); - igt_subtest("double-flink") - test_double_flink(fd); - igt_subtest("bad-flink") - test_bad_flink(fd); - igt_subtest("bad-open") - test_bad_open(fd); - igt_subtest("flink-lifetime") - test_flink_lifetime(fd); -} diff --git a/tests/gem_flink_race.c b/tests/gem_flink_race.c deleted file mode 100644 index 26f32585..00000000 --- a/tests/gem_flink_race.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - */ - -#define _GNU_SOURCE -#include <sys/ioctl.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <pthread.h> -#include <errno.h> - -#include "drmtest.h" -#include "ioctl_wrappers.h" -#include "intel_bufmgr.h" -#include "igt_debugfs.h" - -IGT_TEST_DESCRIPTION("Check for flink/open vs. gem close races."); - -/* Testcase: check for flink/open vs. gem close races - * - * The gem flink open ioctl had a little race with gem close which could result - * in the flink name and corresponding reference getting leaked. - */ - -/* We want lockless and I'm to lazy to dig out an atomic libarary. On x86 this - * works, too. */ -volatile int pls_die = 0; -int fd; - -static int get_object_count(void) -{ - FILE *file; - int scanned, ret; - - igt_drop_caches_set(DROP_RETIRE); - - file = igt_debugfs_fopen("i915_gem_objects", "r"); - - scanned = fscanf(file, "%i objects", &ret); - igt_assert(scanned == 1); - - return ret; -} - - -static void *thread_fn_flink_name(void *p) -{ - struct drm_gem_open open_struct; - int ret; - - while (!pls_die) { - memset(&open_struct, 0, sizeof(open_struct)); - - open_struct.name = 1; - ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open_struct); - if (ret == 0) { - uint32_t name = gem_flink(fd, open_struct.handle); - - igt_assert(name == 1); - - gem_close(fd, open_struct.handle); - } else - igt_assert(errno == ENOENT); - } - - return (void *)0; -} - -static void test_flink_name(void) -{ - pthread_t *threads; - int r, i, num_threads; - void *status; - - num_threads = sysconf(_SC_NPROCESSORS_ONLN) - 1; - if (!num_threads) - num_threads = 1; - - threads = calloc(num_threads, sizeof(pthread_t)); - - fd = drm_open_any(); - - for (i = 0; i < num_threads; i++) { - r = pthread_create(&threads[i], NULL, - thread_fn_flink_name, NULL); - igt_assert(r == 0); - } - - for (i = 0; i < 1000000; i++) { - uint32_t handle; - - handle = gem_create(fd, 4096); - - gem_flink(fd, handle); - - gem_close(fd, handle); - } - - pls_die = 1; - - for (i = 0; i < num_threads; i++) { - pthread_join(threads[i], &status); - igt_assert(status == 0); - } - - close(fd); -} - -static void *thread_fn_flink_close(void *p) -{ - struct drm_gem_flink flink; - struct drm_gem_close close_bo; - uint32_t handle; - - while (!pls_die) { - /* We want to race gem close against flink on handle one.*/ - handle = gem_create(fd, 4096); - if (handle != 1) - gem_close(fd, handle); - - /* raw ioctl since we expect this to fail */ - flink.handle = 1; - ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - - close_bo.handle = 1; - ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo); - } - - return (void *)0; -} - -static void test_flink_close(void) -{ - pthread_t *threads; - int r, i, num_threads; - int obj_count; - void *status; - int fake; - - /* Allocate exit handler fds in here so that we dont screw - * up the counts */ - fake = drm_open_any(); - - obj_count = get_object_count(); - - num_threads = sysconf(_SC_NPROCESSORS_ONLN); - - threads = calloc(num_threads, sizeof(pthread_t)); - - fd = drm_open_any(); - - for (i = 0; i < num_threads; i++) { - r = pthread_create(&threads[i], NULL, - thread_fn_flink_close, NULL); - igt_assert(r == 0); - } - - sleep(5); - - pls_die = 1; - - for (i = 0; i < num_threads; i++) { - pthread_join(threads[i], &status); - igt_assert(status == 0); - } - - close(fd); - - obj_count = get_object_count() - obj_count; - - igt_info("leaked %i objects\n", obj_count); - - close(fake); - - igt_assert(obj_count == 0); -} - -igt_main -{ - igt_skip_on_simulation(); - - igt_subtest("flink_name") - test_flink_name(); - - igt_subtest("flink_close") - test_flink_close(); -} diff --git a/tests/gem_gpgpu_fill.c b/tests/gem_gpgpu_fill.c deleted file mode 100644 index df0d7c8b..00000000 --- a/tests/gem_gpgpu_fill.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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: - * Damien Lespiau <damien.lespiau@intel.com> - * Xiang, Haihao <haihao.xiang@intel.com> - */ - -/* - * This file is a basic test for the gpgpu_fill() function, a very simple - * workload for the GPGPU pipeline. - */ - -#include <stdbool.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -#define WIDTH 64 -#define HEIGHT 64 -#define STRIDE (WIDTH) -#define SIZE (HEIGHT*STRIDE) - -#define COLOR_C4 0xc4 -#define COLOR_4C 0x4c - -typedef struct { - int drm_fd; - uint32_t devid; - drm_intel_bufmgr *bufmgr; - uint8_t linear[WIDTH * HEIGHT]; -} data_t; - -static void scratch_buf_init(data_t *data, struct igt_buf *buf, - int width, int height, int stride, uint8_t color) -{ - drm_intel_bo *bo; - int i; - - bo = drm_intel_bo_alloc(data->bufmgr, "", SIZE, 4096); - for (i = 0; i < width * height; i++) - data->linear[i] = color; - gem_write(data->drm_fd, bo->handle, 0, data->linear, - sizeof(data->linear)); - - buf->bo = bo; - buf->stride = stride; - buf->tiling = I915_TILING_NONE; - buf->size = SIZE; -} - -static void -scratch_buf_check(data_t *data, struct igt_buf *buf, int x, int y, - uint8_t color) -{ - uint8_t val; - - gem_read(data->drm_fd, buf->bo->handle, 0, - data->linear, sizeof(data->linear)); - val = data->linear[y * WIDTH + x]; - igt_assert_f(val == color, - "Expected 0x%02x, found 0x%02x at (%d,%d)\n", - color, val, x, y); -} - -igt_simple_main -{ - data_t data = {0, }; - struct intel_batchbuffer *batch = NULL; - struct igt_buf dst; - igt_fillfunc_t gpgpu_fill = NULL; - int i, j; - - data.drm_fd = drm_open_any_render(); - data.devid = intel_get_drm_devid(data.drm_fd); - - data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096); - igt_assert(data.bufmgr); - - gpgpu_fill = igt_get_gpgpu_fillfunc(data.devid); - - igt_require_f(gpgpu_fill, - "no gpgpu-fill function\n"); - - batch = intel_batchbuffer_alloc(data.bufmgr, data.devid); - igt_assert(batch); - - scratch_buf_init(&data, &dst, WIDTH, HEIGHT, STRIDE, COLOR_C4); - - for (i = 0; i < WIDTH; i++) { - for (j = 0; j < HEIGHT; j++) { - scratch_buf_check(&data, &dst, i, j, COLOR_C4); - } - } - - gpgpu_fill(batch, - &dst, 0, 0, WIDTH / 2, HEIGHT / 2, - COLOR_4C); - - for (i = 0; i < WIDTH; i++) { - for (j = 0; j < HEIGHT; j++) { - if (i < WIDTH / 2 && j < HEIGHT / 2) - scratch_buf_check(&data, &dst, i, j, COLOR_4C); - else - scratch_buf_check(&data, &dst, i, j, COLOR_C4); - } - } -} diff --git a/tests/gem_gtt_cpu_tlb.c b/tests/gem_gtt_cpu_tlb.c deleted file mode 100644 index a019061c..00000000 --- a/tests/gem_gtt_cpu_tlb.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright © 2009 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/** @file gem_gtt_cpu_tlb.c - * - * This test checks whether gtt tlbs for cpu access are correctly invalidated. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" - -IGT_TEST_DESCRIPTION("Check whether gtt tlbs for cpu access are correctly" - " invalidated."); - -#define OBJ_SIZE (1024*1024) - -#define PAGE_SIZE 4096 - -static uint32_t -create_bo(int fd) -{ - uint32_t handle; - uint32_t *data; - int i; - - handle = gem_create(fd, OBJ_SIZE); - - /* Fill the BO with dwords starting at start_val */ - data = gem_mmap(fd, handle, OBJ_SIZE, PROT_READ | PROT_WRITE); - for (i = 0; i < OBJ_SIZE/4; i++) - data[i] = i; - munmap(data, OBJ_SIZE); - - return handle; -} - -igt_simple_main -{ - int fd; - int i; - uint32_t handle; - - uint32_t *ptr; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - handle = gem_create(fd, OBJ_SIZE); - - /* touch one page */ - ptr = gem_mmap(fd, handle, OBJ_SIZE, PROT_READ | PROT_WRITE); - *ptr = 0xdeadbeef; - munmap(ptr, OBJ_SIZE); - - gem_close(fd, handle); - - /* stirr up the page allocator a bit. */ - ptr = malloc(OBJ_SIZE); - igt_assert(ptr); - memset(ptr, 0x1, OBJ_SIZE); - - handle = create_bo(fd); - - /* Read a bunch of random subsets of the data and check that they come - * out right. - */ - gem_read(fd, handle, 0, ptr, OBJ_SIZE); - for (i = 0; i < OBJ_SIZE/4; i++) - igt_assert(ptr[i] == i); - - close(fd); -} diff --git a/tests/gem_gtt_hog.c b/tests/gem_gtt_hog.c deleted file mode 100644 index 9f1b4f6c..00000000 --- a/tests/gem_gtt_hog.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright © 2014 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <sys/wait.h> - -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" - -static const uint32_t canary = 0xdeadbeef; - -typedef struct data { - int fd; - int devid; - int intel_gen; -} data_t; - -static double elapsed(const struct timeval *start, - const struct timeval *end) -{ - return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec); -} - -static void busy(data_t *data, uint32_t handle, int size, int loops) -{ - struct drm_i915_gem_relocation_entry reloc[20]; - struct drm_i915_gem_exec_object2 gem_exec[2]; - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_pwrite gem_pwrite; - struct drm_i915_gem_create create; - uint32_t buf[170], *b; - int i; - - memset(reloc, 0, sizeof(reloc)); - memset(gem_exec, 0, sizeof(gem_exec)); - memset(&execbuf, 0, sizeof(execbuf)); - - b = buf; - for (i = 0; i < 20; i++) { - *b++ = XY_COLOR_BLT_CMD_NOLEN | - ((data->intel_gen >= 8) ? 5 : 4) | - COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; - *b++ = 0xf0 << 16 | 1 << 25 | 1 << 24 | 4096; - *b++ = 0; - *b++ = size >> 12 << 16 | 1024; - reloc[i].offset = (b - buf) * sizeof(uint32_t); - reloc[i].target_handle = handle; - reloc[i].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[i].write_domain = I915_GEM_DOMAIN_RENDER; - *b++ = 0; - if (data->intel_gen >= 8) - *b++ = 0; - *b++ = canary; - } - *b++ = MI_BATCH_BUFFER_END; - if ((b - buf) & 1) - *b++ = 0; - - gem_exec[0].handle = handle; - gem_exec[0].flags = EXEC_OBJECT_NEEDS_FENCE; - - create.handle = 0; - create.size = 4096; - drmIoctl(data->fd, DRM_IOCTL_I915_GEM_CREATE, &create); - gem_exec[1].handle = create.handle; - gem_exec[1].relocation_count = 20; - gem_exec[1].relocs_ptr = (uintptr_t)reloc; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 2; - execbuf.batch_len = (b - buf) * sizeof(buf[0]); - execbuf.flags = 1 << 11; - if (HAS_BLT_RING(data->devid)) - execbuf.flags |= I915_EXEC_BLT; - - gem_pwrite.handle = gem_exec[1].handle; - gem_pwrite.offset = 0; - gem_pwrite.size = execbuf.batch_len; - gem_pwrite.data_ptr = (uintptr_t)buf; - if (drmIoctl(data->fd, DRM_IOCTL_I915_GEM_PWRITE, &gem_pwrite) == 0) { - while (loops--) - drmIoctl(data->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - } - - drmIoctl(data->fd, DRM_IOCTL_GEM_CLOSE, &create.handle); -} - -static void run(data_t *data, int child) -{ - const int size = 4096 * (256 + child * child); - const int tiling = child % 2; - const int write = child % 2; - uint32_t handle = gem_create(data->fd, size); - uint32_t *ptr; - uint32_t x; - - igt_assert(handle); - - if (tiling != I915_TILING_NONE) - gem_set_tiling(data->fd, handle, tiling, 4096); - - /* load up the unfaulted bo */ - busy(data, handle, size, 100); - - /* Note that we ignore the API and rely on the implict - * set-to-gtt-domain within the fault handler. - */ - if (write) { - ptr = gem_mmap(data->fd, handle, size, PROT_READ | PROT_WRITE); - ptr[rand() % (size / 4)] = canary; - } else - ptr = gem_mmap(data->fd, handle, size, PROT_READ); - x = ptr[rand() % (size / 4)]; - munmap(ptr, size); - - igt_assert(x == canary); -} - -igt_simple_main -{ - struct timeval start, end; - pid_t children[64]; - data_t data = {}; - - /* check for an intel gpu before goint nuts. */ - int fd = drm_open_any(); - close(fd); - - igt_skip_on_simulation(); - - data.fd = drm_open_any(); - data.devid = intel_get_drm_devid(data.fd); - data.intel_gen = intel_gen(data.devid); - - gettimeofday(&start, NULL); - igt_fork(child, ARRAY_SIZE(children)) - run(&data, child); - igt_waitchildren(); - gettimeofday(&end, NULL); - - igt_info("Time to execute %lu children: %7.3fms\n", - ARRAY_SIZE(children), elapsed(&start, &end) / 1000); -} diff --git a/tests/gem_gtt_speed.c b/tests/gem_gtt_speed.c deleted file mode 100644 index d5e745ed..00000000 --- a/tests/gem_gtt_speed.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright © 2010 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: - * Eric Anholt <eric@anholt.net> - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -#define OBJECT_SIZE 16384 - -static double elapsed(const struct timeval *start, - const struct timeval *end, - int loop) -{ - return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec))/loop; -} - -int main(int argc, char **argv) -{ - struct timeval start, end; - uint8_t *buf; - uint32_t handle; - int size = OBJECT_SIZE; - int loop, i, tiling; - int fd; - - igt_simple_init(argc, argv); - - igt_skip_on_simulation(); - - if (argc > 1) - size = atoi(argv[1]); - if (size == 0) { - igt_warn("Invalid object size specified\n"); - return 1; - } - - buf = malloc(size); - memset(buf, 0, size); - fd = drm_open_any(); - - handle = gem_create(fd, size); - igt_assert(handle); - - for (tiling = I915_TILING_NONE; tiling <= I915_TILING_Y; tiling++) { - if (tiling != I915_TILING_NONE) { - igt_info("\nSetting tiling mode to %s\n", - tiling == I915_TILING_X ? "X" : "Y"); - gem_set_tiling(fd, handle, tiling, 512); - } - - if (tiling == I915_TILING_NONE) { - gem_set_domain(fd, handle, - I915_GEM_DOMAIN_CPU, - I915_GEM_DOMAIN_CPU); - - { - uint32_t *base = gem_mmap__cpu(fd, handle, 0, size, PROT_READ | PROT_WRITE); - volatile uint32_t *ptr = base; - int x = 0; - - for (i = 0; i < size/sizeof(*ptr); i++) - x += ptr[i]; - - /* force overtly clever gcc to actually compute x */ - ptr[0] = x; - - munmap(base, size); - - /* mmap read */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - base = gem_mmap__cpu(fd, handle, 0, size, PROT_READ | PROT_WRITE); - ptr = base; - x = 0; - - for (i = 0; i < size/sizeof(*ptr); i++) - x += ptr[i]; - - /* force overtly clever gcc to actually compute x */ - ptr[0] = x; - - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to read %dk through a CPU map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - /* mmap write */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - base = gem_mmap__cpu(fd, handle, 0, size, PROT_READ | PROT_WRITE); - ptr = base; - - for (i = 0; i < size/sizeof(*ptr); i++) - ptr[i] = i; - - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to write %dk through a CPU map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - base = gem_mmap__cpu(fd, handle, 0, size, PROT_READ | PROT_WRITE); - memset(base, 0, size); - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to clear %dk through a CPU map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - gettimeofday(&start, NULL); - base = gem_mmap__cpu(fd, handle, 0, size, PROT_READ | PROT_WRITE); - for (loop = 0; loop < 1000; loop++) - memset(base, 0, size); - munmap(base, size); - gettimeofday(&end, NULL); - igt_info("Time to clear %dk through a cached CPU map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - } - - /* CPU pwrite */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) - gem_write(fd, handle, 0, buf, size); - gettimeofday(&end, NULL); - igt_info("Time to pwrite %dk through the CPU: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - /* CPU pread */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) - gem_read(fd, handle, 0, buf, size); - gettimeofday(&end, NULL); - igt_info("Time to pread %dk through the CPU: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - } - - /* prefault into gtt */ - { - uint32_t *base = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE); - volatile uint32_t *ptr = base; - int x = 0; - - for (i = 0; i < size/sizeof(*ptr); i++) - x += ptr[i]; - - /* force overtly clever gcc to actually compute x */ - ptr[0] = x; - - munmap(base, size); - } - /* mmap read */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - uint32_t *base = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE); - volatile uint32_t *ptr = base; - int x = 0; - - for (i = 0; i < size/sizeof(*ptr); i++) - x += ptr[i]; - - /* force overtly clever gcc to actually compute x */ - ptr[0] = x; - - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to read %dk through a GTT map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - if (gem_mmap__has_wc(fd)) { - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE); - volatile uint32_t *ptr = base; - int x = 0; - - for (i = 0; i < size/sizeof(*ptr); i++) - x += ptr[i]; - - /* force overtly clever gcc to actually compute x */ - ptr[0] = x; - - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to read %dk through a WC map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - } - - - /* mmap write */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - uint32_t *base = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE); - volatile uint32_t *ptr = base; - - for (i = 0; i < size/sizeof(*ptr); i++) - ptr[i] = i; - - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to write %dk through a GTT map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - if (gem_mmap__has_wc(fd)) { - /* mmap write */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE); - volatile uint32_t *ptr = base; - - for (i = 0; i < size/sizeof(*ptr); i++) - ptr[i] = i; - - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to write %dk through a WC map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - } - - /* mmap clear */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - uint32_t *base = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE); - memset(base, 0, size); - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to clear %dk through a GTT map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - if (gem_mmap__has_wc(fd)) { - /* mmap clear */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE); - memset(base, 0, size); - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to clear %dk through a WC map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - } - - gettimeofday(&start, NULL);{ - uint32_t *base = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE); - for (loop = 0; loop < 1000; loop++) - memset(base, 0, size); - munmap(base, size); - } gettimeofday(&end, NULL); - igt_info("Time to clear %dk through a cached GTT map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - if (gem_mmap__has_wc(fd)) { - gettimeofday(&start, NULL);{ - uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE); - for (loop = 0; loop < 1000; loop++) - memset(base, 0, size); - munmap(base, size); - } gettimeofday(&end, NULL); - igt_info("Time to clear %dk through a cached WC map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - } - - /* mmap read */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - uint32_t *base = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE); - volatile uint32_t *ptr = base; - int x = 0; - - for (i = 0; i < size/sizeof(*ptr); i++) - x += ptr[i]; - - /* force overtly clever gcc to actually compute x */ - ptr[0] = x; - - munmap(base, size); - } - gettimeofday(&end, NULL); - igt_info("Time to read %dk (again) through a GTT map: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - if (tiling == I915_TILING_NONE) { - /* GTT pwrite */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) - gem_write(fd, handle, 0, buf, size); - gettimeofday(&end, NULL); - igt_info("Time to pwrite %dk through the GTT: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - /* GTT pread */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) - gem_read(fd, handle, 0, buf, size); - gettimeofday(&end, NULL); - igt_info("Time to pread %dk through the GTT: %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - /* GTT pwrite, including clflush */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - gem_write(fd, handle, 0, buf, size); - gem_sync(fd, handle); - } - gettimeofday(&end, NULL); - igt_info("Time to pwrite %dk through the GTT (clflush): %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - /* GTT pread, including clflush */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - gem_sync(fd, handle); - gem_read(fd, handle, 0, buf, size); - } - gettimeofday(&end, NULL); - igt_info("Time to pread %dk through the GTT (clflush): %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - /* partial writes */ - igt_info("Now partial writes.\n"); - size /= 4; - - /* partial GTT pwrite, including clflush */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - gem_write(fd, handle, 0, buf, size); - gem_sync(fd, handle); - } - gettimeofday(&end, NULL); - igt_info("Time to pwrite %dk through the GTT (clflush): %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - /* partial GTT pread, including clflush */ - gettimeofday(&start, NULL); - for (loop = 0; loop < 1000; loop++) { - gem_sync(fd, handle); - gem_read(fd, handle, 0, buf, size); - } - gettimeofday(&end, NULL); - igt_info("Time to pread %dk through the GTT (clflush): %7.3fµs\n", - size/1024, elapsed(&start, &end, loop)); - - size *= 4; - } - } - - gem_close(fd, handle); - close(fd); - - igt_exit(); -} diff --git a/tests/gem_hang.c b/tests/gem_hang.c deleted file mode 100644 index 8767615c..00000000 --- a/tests/gem_hang.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * Jesse Barnes <jbarnes@virtuousgeek.org> (based on gem_bad_blit.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_chipset.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static int bad_pipe; - -static void -gpu_hang(void) -{ - int cmd; - - cmd = bad_pipe ? MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW : - MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; - - BEGIN_BATCH(6, 0); - /* The documentation says that the LOAD_SCAN_LINES command - * always comes in pairs. Don't ask me why. */ - OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | (bad_pipe << 20)); - OUT_BATCH((0 << 16) | 2048); - OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | (bad_pipe << 20)); - OUT_BATCH((0 << 16) | 2048); - OUT_BATCH(MI_WAIT_FOR_EVENT | cmd); - OUT_BATCH(MI_NOOP); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -int main(int argc, char **argv) -{ - int fd; - - igt_simple_init(argc, argv); - - igt_assert_f(argc == 2, - "usage: %s <disabled pipe number>\n", - argv[0]); - - bad_pipe = atoi(argv[1]); - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - gpu_hang(); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - - igt_exit(); -} diff --git a/tests/gem_hangcheck_forcewake.c b/tests/gem_hangcheck_forcewake.c deleted file mode 100644 index f274fabb..00000000 --- a/tests/gem_hangcheck_forcewake.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Provoke the hangcheck timer on an otherwise idle" - " system."); - -/* - * Testcase: Provoke the hangcheck timer on an otherwise idle system - * - * This tries to hit forcewake locking bugs when the hangcheck runs. Somehow we - * often luck out and the hangcheck runs while someone else is already holding - * the dev->struct_mutex. - * - * It's imperative that nothing else runs while this test runs, i.e. kill your X - * session, please. - */ - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -uint32_t blob[2048*2048]; - -#define MAX_BLT_SIZE 128 -igt_simple_main -{ - drm_intel_bo *bo = NULL; - uint32_t tiling_mode = I915_TILING_X; - unsigned long pitch, act_size; - int fd, i, devid; - - igt_skip_on_simulation(); - - memset(blob, 'A', sizeof(blob)); - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - devid = intel_get_drm_devid(fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - act_size = 2048; - igt_info("filling ring\n"); - drm_intel_bo_unreference(bo); - bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled bo", act_size, act_size, - 4, &tiling_mode, &pitch, 0); - - drm_intel_bo_subdata(bo, 0, act_size*act_size*4, blob); - - if (IS_965(devid)) - pitch /= 4; - - for (i = 0; i < 10000; i++) { - BLIT_COPY_BATCH_START(XY_SRC_COPY_BLT_SRC_TILED | - XY_SRC_COPY_BLT_DST_TILED); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - pitch); - OUT_BATCH(0 << 16 | 1024); - OUT_BATCH((2048) << 16 | (2048)); - OUT_RELOC_FENCED(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(pitch); - OUT_RELOC_FENCED(bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 6) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } - } - - igt_info("waiting\n"); - sleep(10); - - igt_info("done waiting, check dmesg\n"); - drm_intel_bo_unreference(bo); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_largeobject.c b/tests/gem_largeobject.c deleted file mode 100644 index 0f929f8f..00000000 --- a/tests/gem_largeobject.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright © 2008 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: - * Jesse Barnes <jbarnes@virtuousgeek.org> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -/* Should take 64 pages to store the page pointers on 64 bit */ -#define OBJ_SIZE (128 * 1024 * 1024) - -unsigned char data[OBJ_SIZE]; - -static void -test_large_object(int fd) -{ - struct drm_i915_gem_create create; - struct drm_i915_gem_pin pin; - uint32_t obj_size; - char *ptr; - - memset(&create, 0, sizeof(create)); - memset(&pin, 0, sizeof(pin)); - - if (gem_aperture_size(fd)*3/4 < OBJ_SIZE/2) - obj_size = OBJ_SIZE / 4; - else if (gem_aperture_size(fd)*3/4 < OBJ_SIZE) - obj_size = OBJ_SIZE / 2; - else - obj_size = OBJ_SIZE; - create.size = obj_size; - igt_info("obj size %i\n", obj_size); - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) == 0); - - /* prefault */ - ptr = gem_mmap__gtt(fd, create.handle, obj_size, PROT_WRITE | PROT_READ); - *ptr = 0; - - gem_write(fd, create.handle, 0, data, obj_size); - - /* kernel should clean this up for us */ -} - -igt_simple_main -{ - int fd; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - test_large_object(fd); -} diff --git a/tests/gem_linear_blits.c b/tests/gem_linear_blits.c deleted file mode 100644 index 13c2ab75..00000000 --- a/tests/gem_linear_blits.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * - */ - -/** @file gem_linear_blits.c - * - * This is a test of doing many blits, with a working set - * larger than the aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "intel_chipset.h" -#include "drmtest.h" -#include "intel_io.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test doing many blits with a working set larger than the" - " aperture size."); - -#define WIDTH 512 -#define HEIGHT 512 - -static uint32_t linear[WIDTH*HEIGHT]; - -static void -copy(int fd, uint32_t dst, uint32_t src) -{ - 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 ret, i=0; - - 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) - batch[i - 1] |= 8; - else - batch[i - 1] |= 6; - - batch[i++] = (3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - WIDTH*4; - 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) - 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) - 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 = 0; - 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 = 0; - reloc[1].offset = 7 * sizeof(batch[0]); - if (intel_gen(intel_get_drm_devid(fd)) >= 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; - - obj[0].handle = dst; - obj[0].relocation_count = 0; - obj[0].relocs_ptr = 0; - obj[0].alignment = 0; - obj[0].offset = 0; - obj[0].flags = 0; - obj[0].rsvd1 = 0; - obj[0].rsvd2 = 0; - - obj[1].handle = src; - obj[1].relocation_count = 0; - obj[1].relocs_ptr = 0; - obj[1].alignment = 0; - obj[1].offset = 0; - obj[1].flags = 0; - obj[1].rsvd1 = 0; - obj[1].rsvd2 = 0; - - obj[2].handle = handle; - obj[2].relocation_count = 2; - obj[2].relocs_ptr = (uintptr_t)reloc; - obj[2].alignment = 0; - obj[2].offset = 0; - obj[2].flags = 0; - obj[2].rsvd1 = obj[2].rsvd2 = 0; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = 3; - 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; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - while (ret && errno == EBUSY) { - drmCommandNone(fd, DRM_I915_GEM_THROTTLE); - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - } - igt_assert(ret == 0); - - gem_close(fd, handle); -} - -static uint32_t -create_bo(int fd, uint32_t val) -{ - uint32_t handle; - int i; - - handle = gem_create(fd, sizeof(linear)); - - /* Fill the BO with dwords starting at val */ - for (i = 0; i < WIDTH*HEIGHT; i++) - linear[i] = val++; - gem_write(fd, handle, 0, linear, sizeof(linear)); - - return handle; -} - -static void -check_bo(int fd, uint32_t handle, uint32_t val) -{ - int i; - - gem_read(fd, handle, 0, linear, sizeof(linear)); - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(linear[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, linear[i], i * 4); - val++; - } -} - -static void run_test(int fd, int count) -{ - uint32_t *handle, *start_val; - uint32_t start = 0; - int i; - - igt_debug("Using %d 1MiB buffers\n", count); - - handle = malloc(sizeof(uint32_t)*count*2); - start_val = handle + count; - - for (i = 0; i < count; i++) { - handle[i] = create_bo(fd, start); - start_val[i] = start; - start += 1024 * 1024 / 4; - } - - igt_info("Verifying initialisation...\n"); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Cyclic blits, forward...\n"); - for (i = 0; i < count * 4; i++) { - int src = i % count; - int dst = (i + 1) % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Cyclic blits, backward...\n"); - for (i = 0; i < count * 4; i++) { - int src = (i + 1) % count; - int dst = i % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Random blits...\n"); - for (i = 0; i < count * 4; i++) { - int src = random() % count; - int dst = random() % count; - - if (src == dst) - continue; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) { - check_bo(fd, handle[i], start_val[i]); - gem_close(fd, handle[i]); - } - - free(handle); -} - -int main(int argc, char **argv) -{ - int fd = 0; - - igt_subtest_init(argc, argv); - - igt_fixture { - fd = drm_open_any(); - } - - igt_subtest("basic") - run_test(fd, 2); - - igt_subtest("normal") { - int count; - - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - igt_require(count > 1); - intel_require_memory(count, sizeof(linear), CHECK_RAM); - run_test(fd, count); - } - - igt_subtest("interruptible") { - int count; - - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - igt_require(count > 1); - intel_require_memory(count, sizeof(linear), CHECK_RAM); - igt_fork_signal_helper(); - run_test(fd, count); - igt_stop_signal_helper(); - } - - igt_exit(); -} diff --git a/tests/gem_lut_handle.c b/tests/gem_lut_handle.c deleted file mode 100644 index 7fc72f1a..00000000 --- a/tests/gem_lut_handle.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright © 2012,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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/* Exercises the basic execbuffer using the handle LUT interface */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Exercises the basic execbuffer using the handle LUT" - " interface."); - -#define BATCH_SIZE (1024*1024) - -#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12) - -#define NORMAL 0 -#define USE_LUT 0x1 -#define BROKEN 0x2 - -static int exec(int fd, uint32_t handle, unsigned int flags) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[1]; - struct drm_i915_gem_relocation_entry gem_reloc[1]; - - gem_reloc[0].offset = 1024; - gem_reloc[0].delta = 0; - gem_reloc[0].target_handle = - !!(flags & USE_LUT) ^ !!(flags & BROKEN) ? 0 : handle; - gem_reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - gem_reloc[0].write_domain = 0; - gem_reloc[0].presumed_offset = 0; - - gem_exec[0].handle = handle; - gem_exec[0].relocation_count = 1; - gem_exec[0].relocs_ptr = (uintptr_t) gem_reloc; - gem_exec[0].alignment = 0; - gem_exec[0].offset = 0; - gem_exec[0].flags = 0; - gem_exec[0].rsvd1 = 0; - gem_exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = flags & USE_LUT ? LOCAL_I915_EXEC_HANDLE_LUT : 0; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - if (drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf)) - return -errno; - - return 0; -} - -static int many_exec(int fd, uint32_t batch, int num_exec, int num_reloc, unsigned flags) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 *gem_exec; - struct drm_i915_gem_relocation_entry *gem_reloc; - unsigned max_handle = batch; - int ret, n; - - gem_exec = calloc(num_exec+1, sizeof(*gem_exec)); - gem_reloc = calloc(num_reloc, sizeof(*gem_reloc)); - igt_assert(gem_exec && gem_reloc); - - for (n = 0; n < num_exec; n++) { - gem_exec[n].handle = gem_create(fd, 4096); - if (gem_exec[n].handle > max_handle) - max_handle = gem_exec[n].handle; - gem_exec[n].relocation_count = 0; - gem_exec[n].relocs_ptr = 0; - gem_exec[n].alignment = 0; - gem_exec[n].offset = 0; - gem_exec[n].flags = 0; - gem_exec[n].rsvd1 = 0; - gem_exec[n].rsvd2 = 0; - } - - gem_exec[n].handle = batch; - gem_exec[n].relocation_count = num_reloc; - gem_exec[n].relocs_ptr = (uintptr_t) gem_reloc; - - if (flags & USE_LUT) - max_handle = num_exec + 1; - max_handle++; - - for (n = 0; n < num_reloc; n++) { - uint32_t target; - - if (flags & BROKEN) { - target = -(rand() % 4096) - 1; - } else { - target = rand() % (num_exec + 1); - if ((flags & USE_LUT) == 0) - target = gem_exec[target].handle; - } - - gem_reloc[n].offset = 1024; - gem_reloc[n].delta = 0; - gem_reloc[n].target_handle = target; - gem_reloc[n].read_domains = I915_GEM_DOMAIN_RENDER; - gem_reloc[n].write_domain = 0; - gem_reloc[n].presumed_offset = 0; - } - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = num_exec + 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = flags & USE_LUT ? LOCAL_I915_EXEC_HANDLE_LUT : 0; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - ret = drmIoctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - if (ret < 0) - ret = -errno; - - for (n = 0; n < num_exec; n++) - gem_close(fd, gem_exec[n].handle); - - free(gem_exec); - free(gem_reloc); - - return ret; -} - -#define fail(x) igt_assert((x) == -ENOENT) -#define pass(x) igt_assert((x) == 0) - -igt_simple_main -{ - 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)); - - igt_skip_on(exec(fd, handle, USE_LUT)); - - 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) == -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)); - } -} diff --git a/tests/gem_madvise.c b/tests/gem_madvise.c deleted file mode 100644 index 58ab629f..00000000 --- a/tests/gem_madvise.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright © 2014 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <setjmp.h> -#include <signal.h> - -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Checks that the kernel reports EFAULT when trying to use" - " purged bo."); - -#define OBJECT_SIZE (1024*1024) - -/* Testcase: checks that the kernel reports EFAULT when trying to use purged bo - * - */ - -static jmp_buf jmp; - -static void sigtrap(int sig) -{ - longjmp(jmp, sig); -} - -static void -dontneed_before_mmap(void) -{ - int fd = drm_open_any(); - uint32_t handle; - char *ptr; - - handle = gem_create(fd, OBJECT_SIZE); - gem_madvise(fd, handle, I915_MADV_DONTNEED); - ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr == NULL); - igt_assert(errno == EFAULT); - close(fd); -} - -static void -dontneed_after_mmap(void) -{ - int fd = drm_open_any(); - uint32_t handle; - char *ptr; - - handle = gem_create(fd, OBJECT_SIZE); - ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr != NULL); - gem_madvise(fd, handle, I915_MADV_DONTNEED); - close(fd); - - signal(SIGBUS, sigtrap); - switch (setjmp(jmp)) { - case SIGBUS: - break; - case 0: - *ptr = 0; - default: - igt_assert(!"reached"); - break; - } - munmap(ptr, OBJECT_SIZE); - signal(SIGBUS, SIG_DFL); -} - -static void -dontneed_before_pwrite(void) -{ - int fd = drm_open_any(); - uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 }; - struct drm_i915_gem_pwrite gem_pwrite; - - gem_pwrite.handle = gem_create(fd, OBJECT_SIZE); - gem_pwrite.offset = 0; - gem_pwrite.size = sizeof(buf); - gem_pwrite.data_ptr = (uintptr_t)buf; - gem_madvise(fd, gem_pwrite.handle, I915_MADV_DONTNEED); - - igt_assert(drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &gem_pwrite)); - igt_assert(errno == EFAULT); - - gem_close(fd, gem_pwrite.handle); - close(fd); -} - -static void -dontneed_before_exec(void) -{ - int fd = drm_open_any(); - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec; - uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 }; - - memset(&execbuf, 0, sizeof(execbuf)); - memset(&exec, 0, sizeof(exec)); - - exec.handle = gem_create(fd, OBJECT_SIZE); - gem_write(fd, exec.handle, 0, buf, sizeof(buf)); - gem_madvise(fd, exec.handle, I915_MADV_DONTNEED); - - execbuf.buffers_ptr = (uintptr_t)&exec; - execbuf.buffer_count = 1; - execbuf.batch_len = sizeof(buf); - gem_execbuf(fd, &execbuf); - - gem_close(fd, exec.handle); - close(fd); -} - -igt_main -{ - igt_skip_on_simulation(); - - igt_subtest("dontneed-before-mmap") - dontneed_before_mmap(); - - igt_subtest("dontneed-after-mmap") - dontneed_after_mmap(); - - igt_subtest("dontneed-before-pwrite") - dontneed_before_pwrite(); - - igt_subtest("dontneed-before-exec") - dontneed_before_exec(); -} diff --git a/tests/gem_media_fill.c b/tests/gem_media_fill.c deleted file mode 100644 index ade56f25..00000000 --- a/tests/gem_media_fill.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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: - * Damien Lespiau <damien.lespiau@intel.com> - * Xiang, Haihao <haihao.xiang@intel.com> - */ - -/* - * This file is a basic test for the media_fill() function, a very simple - * workload for the Media pipeline. - */ - -#include <stdbool.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Basic test for the media_fill() function, a very simple" - " workload for the Media pipeline."); - -#define WIDTH 64 -#define STRIDE (WIDTH) -#define HEIGHT 64 -#define SIZE (HEIGHT*STRIDE) - -#define COLOR_C4 0xc4 -#define COLOR_4C 0x4c - -typedef struct { - int drm_fd; - uint32_t devid; - drm_intel_bufmgr *bufmgr; - uint8_t linear[WIDTH * HEIGHT]; -} data_t; - -static void scratch_buf_init(data_t *data, struct igt_buf *buf, - int width, int height, int stride, uint8_t color) -{ - drm_intel_bo *bo; - int i; - - bo = drm_intel_bo_alloc(data->bufmgr, "", SIZE, 4096); - for (i = 0; i < width * height; i++) - data->linear[i] = color; - gem_write(data->drm_fd, bo->handle, 0, data->linear, - sizeof(data->linear)); - - buf->bo = bo; - buf->stride = stride; - buf->tiling = I915_TILING_NONE; - buf->size = SIZE; -} - -static void -scratch_buf_check(data_t *data, struct igt_buf *buf, int x, int y, - uint8_t color) -{ - uint8_t val; - - gem_read(data->drm_fd, buf->bo->handle, 0, - data->linear, sizeof(data->linear)); - val = data->linear[y * WIDTH + x]; - igt_assert_f(val == color, - "Expected 0x%02x, found 0x%02x at (%d,%d)\n", - color, val, x, y); -} - -igt_simple_main -{ - data_t data = {0, }; - struct intel_batchbuffer *batch = NULL; - struct igt_buf dst; - igt_fillfunc_t media_fill = NULL; - int i, j; - - data.drm_fd = drm_open_any_render(); - data.devid = intel_get_drm_devid(data.drm_fd); - - data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096); - igt_assert(data.bufmgr); - - media_fill = igt_get_media_fillfunc(data.devid); - - igt_require_f(media_fill, - "no media-fill function\n"); - - batch = intel_batchbuffer_alloc(data.bufmgr, data.devid); - igt_assert(batch); - - scratch_buf_init(&data, &dst, WIDTH, HEIGHT, STRIDE, COLOR_C4); - - for (i = 0; i < WIDTH; i++) { - for (j = 0; j < HEIGHT; j++) { - scratch_buf_check(&data, &dst, i, j, COLOR_C4); - } - } - - media_fill(batch, - &dst, 0, 0, WIDTH / 2, HEIGHT / 2, - COLOR_4C); - - for (i = 0; i < WIDTH; i++) { - for (j = 0; j < HEIGHT; j++) { - if (i < WIDTH / 2 && j < HEIGHT / 2) - scratch_buf_check(&data, &dst, i, j, COLOR_4C); - else - scratch_buf_check(&data, &dst, i, j, COLOR_C4); - } - } -} diff --git a/tests/gem_mmap.c b/tests/gem_mmap.c deleted file mode 100644 index bbc5c4cf..00000000 --- a/tests/gem_mmap.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright © 2008 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: - * Eric Anholt <eric@anholt.net> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -#define OBJECT_SIZE 16384 -int fd; -int handle; - -igt_main -{ - struct drm_i915_gem_mmap arg; - uint8_t expected[OBJECT_SIZE]; - uint8_t buf[OBJECT_SIZE]; - uint8_t *addr; - int ret; - - igt_fixture - fd = drm_open_any(); - - igt_subtest("bad-object") { - memset(&arg, 0, sizeof(arg)); - arg.handle = 0x10101010; - arg.offset = 0; - arg.size = 4096; - ret = ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, &arg); - igt_assert(ret == -1 && errno == ENOENT); - } - - igt_subtest("new-object") { - handle = gem_create(fd, OBJECT_SIZE); - arg.handle = handle; - arg.offset = 0; - arg.size = OBJECT_SIZE; - ret = ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, &arg); - igt_assert(ret == 0); - addr = (uint8_t *)(uintptr_t)arg.addr_ptr; - - igt_info("Testing contents of newly created object.\n"); - memset(expected, 0, sizeof(expected)); - igt_assert(memcmp(addr, expected, sizeof(expected)) == 0); - - igt_info("Testing coherency of writes and mmap reads.\n"); - memset(buf, 0, sizeof(buf)); - memset(buf + 1024, 0x01, 1024); - memset(expected + 1024, 0x01, 1024); - gem_write(fd, handle, 0, buf, OBJECT_SIZE); - igt_assert(memcmp(buf, addr, sizeof(buf)) == 0); - - igt_info("Testing that mapping stays after close\n"); - gem_close(fd, handle); - igt_assert(memcmp(buf, addr, sizeof(buf)) == 0); - - igt_info("Testing unmapping\n"); - munmap(addr, OBJECT_SIZE); - } - - igt_subtest("short-mmap") { - igt_assert(OBJECT_SIZE > 4096); - handle = gem_create(fd, OBJECT_SIZE); - addr = gem_mmap__cpu(fd, handle, 0, 4096, PROT_WRITE); - memset(addr, 0, 4096); - munmap(addr, 4096); - gem_close(fd, handle); - } - - igt_fixture - close(fd); -} diff --git a/tests/gem_mmap_gtt.c b/tests/gem_mmap_gtt.c deleted file mode 100644 index 55c66a29..00000000 --- a/tests/gem_mmap_gtt.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#define _GNU_SOURCE -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <pthread.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_debugfs.h" - -static int OBJECT_SIZE = 16*1024*1024; - -static void set_domain(int fd, uint32_t handle) -{ - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); -} - -static void * -mmap_bo(int fd, uint32_t handle) -{ - void *ptr; - - ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr != MAP_FAILED); - - return ptr; -} - -static void * -create_pointer(int fd) -{ - uint32_t handle; - void *ptr; - - handle = gem_create(fd, OBJECT_SIZE); - - ptr = mmap_bo(fd, handle); - - gem_close(fd, handle); - - return ptr; -} - -static void -test_access(int fd) -{ - uint32_t handle, flink, handle2; - struct drm_i915_gem_mmap_gtt mmap_arg; - int fd2; - - handle = gem_create(fd, OBJECT_SIZE); - igt_assert(handle); - - fd2 = drm_open_any(); - - /* Check that fd1 can mmap. */ - mmap_arg.handle = handle; - igt_assert(drmIoctl(fd, - DRM_IOCTL_I915_GEM_MMAP_GTT, - &mmap_arg) == 0); - - igt_assert(mmap64(0, OBJECT_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, mmap_arg.offset)); - - /* Check that the same offset on the other fd doesn't work. */ - igt_assert(mmap64(0, OBJECT_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, fd2, mmap_arg.offset) == MAP_FAILED); - igt_assert(errno == EACCES); - - flink = gem_flink(fd, handle); - igt_assert(flink); - handle2 = gem_open(fd2, flink); - igt_assert(handle2); - - /* Recheck that it works after flink. */ - /* Check that the same offset on the other fd doesn't work. */ - igt_assert(mmap64(0, OBJECT_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, fd2, mmap_arg.offset)); -} - -static void -test_short(int fd) -{ - struct drm_i915_gem_mmap_gtt mmap_arg; - int pages, p; - - mmap_arg.handle = gem_create(fd, OBJECT_SIZE); - igt_assert(mmap_arg.handle); - - igt_assert(drmIoctl(fd, - DRM_IOCTL_I915_GEM_MMAP_GTT, - &mmap_arg) == 0); - for (pages = 1; pages <= OBJECT_SIZE / 4096; pages <<= 1) { - uint8_t *r, *w; - - w = mmap64(0, pages * 4096, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, mmap_arg.offset); - igt_assert(w != MAP_FAILED); - - r = mmap64(0, pages * 4096, PROT_READ, - MAP_SHARED, fd, mmap_arg.offset); - igt_assert(r != MAP_FAILED); - - for (p = 0; p < pages; p++) { - w[4096*p] = r[4096*p]; - w[4096*p+4095] = r[4096*p+4095]; - } - - munmap(r, pages * 4096); - munmap(w, pages * 4096); - } - gem_close(fd, mmap_arg.handle); -} - -static void -test_copy(int fd) -{ - void *src, *dst; - - /* copy from a fresh src to fresh dst to force pagefault on both */ - src = create_pointer(fd); - dst = create_pointer(fd); - - memcpy(dst, src, OBJECT_SIZE); - memcpy(src, dst, OBJECT_SIZE); - - munmap(dst, OBJECT_SIZE); - munmap(src, OBJECT_SIZE); -} - -enum test_read_write { - READ_BEFORE_WRITE, - READ_AFTER_WRITE, -}; - -static void -test_read_write(int fd, enum test_read_write order) -{ - uint32_t handle; - void *ptr; - volatile uint32_t val = 0; - - handle = gem_create(fd, OBJECT_SIZE); - - ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr != MAP_FAILED); - - if (order == READ_BEFORE_WRITE) { - val = *(uint32_t *)ptr; - *(uint32_t *)ptr = val; - } else { - *(uint32_t *)ptr = val; - val = *(uint32_t *)ptr; - } - - gem_close(fd, handle); - munmap(ptr, OBJECT_SIZE); -} - -static void -test_read_write2(int fd, enum test_read_write order) -{ - uint32_t handle; - void *r, *w; - volatile uint32_t val = 0; - - handle = gem_create(fd, OBJECT_SIZE); - - r = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ); - igt_assert(r != MAP_FAILED); - - w = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(w != MAP_FAILED); - - if (order == READ_BEFORE_WRITE) { - val = *(uint32_t *)r; - *(uint32_t *)w = val; - } else { - *(uint32_t *)w = val; - val = *(uint32_t *)r; - } - - gem_close(fd, handle); - munmap(r, OBJECT_SIZE); - munmap(w, OBJECT_SIZE); -} - -static void -test_write(int fd) -{ - void *src; - uint32_t dst; - - /* copy from a fresh src to fresh dst to force pagefault on both */ - src = create_pointer(fd); - dst = gem_create(fd, OBJECT_SIZE); - - gem_write(fd, dst, 0, src, OBJECT_SIZE); - - gem_close(fd, dst); - munmap(src, OBJECT_SIZE); -} - -static void -test_write_gtt(int fd) -{ - uint32_t dst; - char *dst_gtt; - void *src; - - dst = gem_create(fd, OBJECT_SIZE); - - /* prefault object into gtt */ - dst_gtt = mmap_bo(fd, dst); - set_domain(fd, dst); - memset(dst_gtt, 0, OBJECT_SIZE); - munmap(dst_gtt, OBJECT_SIZE); - - src = create_pointer(fd); - - gem_write(fd, dst, 0, src, OBJECT_SIZE); - - gem_close(fd, dst); - munmap(src, OBJECT_SIZE); -} - -static void -test_read(int fd) -{ - void *dst; - uint32_t src; - - /* copy from a fresh src to fresh dst to force pagefault on both */ - dst = create_pointer(fd); - src = gem_create(fd, OBJECT_SIZE); - - gem_read(fd, src, 0, dst, OBJECT_SIZE); - - gem_close(fd, src); - munmap(dst, OBJECT_SIZE); -} - -static void -test_write_cpu_read_gtt(int fd) -{ - uint32_t handle; - uint32_t *src, *dst; - - igt_require(gem_has_llc(fd)); - - handle = gem_create(fd, OBJECT_SIZE); - - dst = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ); - igt_assert(dst != (uint32_t *)MAP_FAILED); - - src = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE); - igt_assert(src != (uint32_t *)MAP_FAILED); - - gem_close(fd, handle); - - memset(src, 0xaa, OBJECT_SIZE); - igt_assert(memcmp(dst, src, OBJECT_SIZE) == 0); - - munmap(src, OBJECT_SIZE); - munmap(dst, OBJECT_SIZE); -} - -struct thread_fault_concurrent { - pthread_t thread; - int id; - uint32_t **ptr; -}; - -static void * -thread_fault_concurrent(void *closure) -{ - struct thread_fault_concurrent *t = closure; - uint32_t val = 0; - int n; - - for (n = 0; n < 32; n++) { - if (n & 1) - *t->ptr[(n + t->id) % 32] = val; - else - val = *t->ptr[(n + t->id) % 32]; - } - - return NULL; -} - -static void -test_fault_concurrent(int fd) -{ - uint32_t *ptr[32]; - struct thread_fault_concurrent thread[64]; - int n; - - for (n = 0; n < 32; n++) { - ptr[n] = create_pointer(fd); - } - - for (n = 0; n < 64; n++) { - thread[n].ptr = ptr; - thread[n].id = n; - pthread_create(&thread[n].thread, NULL, thread_fault_concurrent, &thread[n]); - } - - for (n = 0; n < 64; n++) - pthread_join(thread[n].thread, NULL); - - for (n = 0; n < 32; n++) { - munmap(ptr[n], OBJECT_SIZE); - } -} - -static void -run_without_prefault(int fd, - void (*func)(int fd)) -{ - igt_disable_prefault(); - func(fd); - igt_enable_prefault(); -} - -int fd; - -igt_main -{ - if (igt_run_in_simulation()) - OBJECT_SIZE = 1 * 1024 * 1024; - - igt_fixture - fd = drm_open_any(); - - igt_subtest("access") - test_access(fd); - igt_subtest("short") - test_short(fd); - igt_subtest("copy") - test_copy(fd); - igt_subtest("read") - test_read(fd); - igt_subtest("write") - test_write(fd); - igt_subtest("write-gtt") - test_write_gtt(fd); - igt_subtest("read-write") - test_read_write(fd, READ_BEFORE_WRITE); - igt_subtest("write-read") - test_read_write(fd, READ_AFTER_WRITE); - igt_subtest("read-write-distinct") - test_read_write2(fd, READ_BEFORE_WRITE); - igt_subtest("write-read-distinct") - test_read_write2(fd, READ_AFTER_WRITE); - igt_subtest("fault-concurrent") - test_fault_concurrent(fd); - igt_subtest("read-no-prefault") - run_without_prefault(fd, test_read); - igt_subtest("write-no-prefault") - run_without_prefault(fd, test_write); - igt_subtest("write-gtt-no-prefault") - run_without_prefault(fd, test_write_gtt); - igt_subtest("write-cpu-read-gtt") - test_write_cpu_read_gtt(fd); - - igt_fixture - close(fd); -} diff --git a/tests/gem_mmap_offset_exhaustion.c b/tests/gem_mmap_offset_exhaustion.c deleted file mode 100644 index b0310501..00000000 --- a/tests/gem_mmap_offset_exhaustion.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright © 2012 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Checks whether the kernel handles mmap offset exhaustion" - " correctly."); - -#define OBJECT_SIZE (1024*1024) - -/* Testcase: checks whether the kernel handles mmap offset exhaustion correctly - * - * Currently the kernel doesn't reap the mmap offset of purged objects, albeit - * there's nothing that prevents it ABI-wise and it helps to get out of corners - * (because drm_mm is only 32bit on 32bit archs unfortunately. - * - * Note that on 64bit machines we have plenty of address space (because drm_mm - * uses unsigned long). - */ - -static void -create_and_map_bo(int fd) -{ - uint32_t handle; - char *ptr; - - handle = gem_create(fd, OBJECT_SIZE); - - ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr); - - /* touch it to force it into the gtt */ - *ptr = 0; - - /* but then unmap it again because we only have limited address space on - * 32 bit */ - munmap(ptr, OBJECT_SIZE); - - /* we happily leak objects to exhaust mmap offset space, the kernel will - * reap backing storage. */ - gem_madvise(fd, handle, I915_MADV_DONTNEED); -} - -igt_simple_main -{ - int fd, i; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - /* we have 32bit of address space, so try to fit one MB more - * than that. */ - for (i = 0; i < 4096 + 1; i++) - create_and_map_bo(fd); - - close(fd); -} diff --git a/tests/gem_mmap_wc.c b/tests/gem_mmap_wc.c deleted file mode 100644 index 73a97d55..00000000 --- a/tests/gem_mmap_wc.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#define _GNU_SOURCE -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <pthread.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_debugfs.h" - -struct local_i915_gem_mmap_v2 { - uint32_t handle; - uint32_t pad; - uint64_t offset; - uint64_t size; - uint64_t addr_ptr; - uint64_t flags; -#define I915_MMAP_WC 0x1 -}; -#define LOCAL_IOCTL_I915_GEM_MMAP_v2 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct local_i915_gem_mmap_v2) - -static int OBJECT_SIZE = 16*1024*1024; - -static void set_domain(int fd, uint32_t handle) -{ - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); -} - -static void * -mmap_bo(int fd, uint32_t handle) -{ - void *ptr; - - ptr = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr && ptr != MAP_FAILED); - - return ptr; -} - -static void * -create_pointer(int fd) -{ - uint32_t handle; - void *ptr; - - handle = gem_create(fd, OBJECT_SIZE); - - ptr = mmap_bo(fd, handle); - set_domain(fd, handle); - - gem_close(fd, handle); - - return ptr; -} - -static void -test_invalid_flags(int fd) -{ - struct drm_i915_getparam gp; - struct local_i915_gem_mmap_v2 arg; - uint64_t flag = I915_MMAP_WC; - int val = -1; - - memset(&arg, 0, sizeof(arg)); - arg.handle = gem_create(fd, 4096); - arg.offset = 0; - arg.size = 4096; - - memset(&gp, 0, sizeof(gp)); - gp.param = 30; /* MMAP_VERSION */ - gp.value = &val; - - /* Do we have the new mmap_ioctl? */ - do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); - - if (val >= 1) { - /* - * Only MMAP_WC flag is supported in version 1, so any other - * flag should be rejected. - */ - flag <<= 1; - while (flag) { - arg.flags = flag; - igt_assert(drmIoctl(fd, - LOCAL_IOCTL_I915_GEM_MMAP_v2, - &arg) == -1); - igt_assert_eq(errno, EINVAL); - flag <<= 1; - } - } - - gem_close(fd, arg.handle); -} - -static void -test_copy(int fd) -{ - void *src, *dst; - - gem_require_mmap_wc(fd); - - /* copy from a fresh src to fresh dst to force pagefault on both */ - src = create_pointer(fd); - dst = create_pointer(fd); - - memcpy(dst, src, OBJECT_SIZE); - memcpy(src, dst, OBJECT_SIZE); - - munmap(dst, OBJECT_SIZE); - munmap(src, OBJECT_SIZE); -} - -enum test_read_write { - READ_BEFORE_WRITE, - READ_AFTER_WRITE, -}; - -static void -test_read_write(int fd, enum test_read_write order) -{ - uint32_t handle; - void *ptr; - volatile uint32_t val = 0; - - handle = gem_create(fd, OBJECT_SIZE); - set_domain(fd, handle); - - ptr = mmap_bo(fd, handle); - igt_assert(ptr != MAP_FAILED); - - if (order == READ_BEFORE_WRITE) { - val = *(uint32_t *)ptr; - *(uint32_t *)ptr = val; - } else { - *(uint32_t *)ptr = val; - val = *(uint32_t *)ptr; - } - - gem_close(fd, handle); - munmap(ptr, OBJECT_SIZE); -} - -static void -test_read_write2(int fd, enum test_read_write order) -{ - uint32_t handle; - void *r, *w; - volatile uint32_t val = 0; - - gem_require_mmap_wc(fd); - - handle = gem_create(fd, OBJECT_SIZE); - set_domain(fd, handle); - - r = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ); - igt_assert(r != MAP_FAILED); - - w = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(w != MAP_FAILED); - - if (order == READ_BEFORE_WRITE) { - val = *(uint32_t *)r; - *(uint32_t *)w = val; - } else { - *(uint32_t *)w = val; - val = *(uint32_t *)r; - } - - gem_close(fd, handle); - munmap(r, OBJECT_SIZE); - munmap(w, OBJECT_SIZE); -} - -static void -test_write(int fd) -{ - void *src; - uint32_t dst; - - gem_require_mmap_wc(fd); - - /* copy from a fresh src to fresh dst to force pagefault on both */ - src = create_pointer(fd); - dst = gem_create(fd, OBJECT_SIZE); - - gem_write(fd, dst, 0, src, OBJECT_SIZE); - - gem_close(fd, dst); - munmap(src, OBJECT_SIZE); -} - -static void -test_write_gtt(int fd) -{ - uint32_t dst; - char *dst_gtt; - void *src; - - gem_require_mmap_wc(fd); - - dst = gem_create(fd, OBJECT_SIZE); - set_domain(fd, dst); - - /* prefault object into gtt */ - dst_gtt = mmap_bo(fd, dst); - memset(dst_gtt, 0, OBJECT_SIZE); - munmap(dst_gtt, OBJECT_SIZE); - - src = create_pointer(fd); - - gem_write(fd, dst, 0, src, OBJECT_SIZE); - - gem_close(fd, dst); - munmap(src, OBJECT_SIZE); -} - -static void -test_read(int fd) -{ - void *dst; - uint32_t src; - - gem_require_mmap_wc(fd); - - /* copy from a fresh src to fresh dst to force pagefault on both */ - dst = create_pointer(fd); - src = gem_create(fd, OBJECT_SIZE); - - gem_read(fd, src, 0, dst, OBJECT_SIZE); - - gem_close(fd, src); - munmap(dst, OBJECT_SIZE); -} - -static void -test_write_cpu_read_wc(int fd) -{ - uint32_t handle; - uint32_t *src, *dst; - - gem_require_mmap_wc(fd); - - handle = gem_create(fd, OBJECT_SIZE); - - dst = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ); - igt_assert(dst != (uint32_t *)MAP_FAILED); - - src = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE); - igt_assert(src != (uint32_t *)MAP_FAILED); - - memset(src, 0xaa, OBJECT_SIZE); - set_domain(fd, handle); - igt_assert(memcmp(dst, src, OBJECT_SIZE) == 0); - gem_close(fd, handle); - - munmap(src, OBJECT_SIZE); - munmap(dst, OBJECT_SIZE); -} - -static void -test_write_gtt_read_wc(int fd) -{ - uint32_t handle; - uint32_t *src, *dst; - - gem_require_mmap_wc(fd); - - handle = gem_create(fd, OBJECT_SIZE); - set_domain(fd, handle); - - dst = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ); - igt_assert(dst != (uint32_t *)MAP_FAILED); - - src = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE); - igt_assert(src != (uint32_t *)MAP_FAILED); - - memset(src, 0xaa, OBJECT_SIZE); - igt_assert(memcmp(dst, src, OBJECT_SIZE) == 0); - gem_close(fd, handle); - - munmap(src, OBJECT_SIZE); - munmap(dst, OBJECT_SIZE); -} - -static void -test_set_cache_level(int fd) -{ - struct drm_mode_cursor arg; - struct drm_mode_card_res res; - uint32_t crtc[32]; - int active_crtc = 0; - int n; - - /* We want to trigger an old WARN in set-cache-level when - * it sees an unbound object in the GTT domain, following - * the introduction of mmap(wc). - */ - - memset(&arg, 0, sizeof(arg)); - arg.flags = DRM_MODE_CURSOR_BO; - arg.width = arg.height = 64; - arg.handle = gem_create(fd, 64*64*4); - set_domain(fd, arg.handle); - - /* Bind the object to the cursor to force set-cache-level(DISPLAY) */ - memset(&res, 0, sizeof(res)); - res.count_crtcs = 32; - res.crtc_id_ptr = (uintptr_t)crtc; - do_ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res); - for (n = 0; n < res.count_crtcs; n++) { - struct drm_mode_crtc mode; - - memset(&mode, 0, sizeof(mode)); - mode.crtc_id = crtc[n]; - do_ioctl(fd, DRM_IOCTL_MODE_GETCRTC, &mode); - - if (!mode.mode_valid) - continue; - - active_crtc++; - - arg.crtc_id = crtc[n]; - do_ioctl(fd, DRM_IOCTL_MODE_CURSOR, &arg); - } - - gem_close(fd, arg.handle); - igt_require(active_crtc); -} - -struct thread_fault_concurrent { - pthread_t thread; - int id; - uint32_t **ptr; -}; - -static void * -thread_fault_concurrent(void *closure) -{ - struct thread_fault_concurrent *t = closure; - uint32_t val = 0; - int n; - - for (n = 0; n < 32; n++) { - if (n & 1) - *t->ptr[(n + t->id) % 32] = val; - else - val = *t->ptr[(n + t->id) % 32]; - } - - return NULL; -} - -static void -test_fault_concurrent(int fd) -{ - uint32_t *ptr[32]; - struct thread_fault_concurrent thread[64]; - int n; - - gem_require_mmap_wc(fd); - - for (n = 0; n < 32; n++) { - ptr[n] = create_pointer(fd); - } - - for (n = 0; n < 64; n++) { - thread[n].ptr = ptr; - thread[n].id = n; - pthread_create(&thread[n].thread, NULL, thread_fault_concurrent, &thread[n]); - } - - for (n = 0; n < 64; n++) - pthread_join(thread[n].thread, NULL); - - for (n = 0; n < 32; n++) { - munmap(ptr[n], OBJECT_SIZE); - } -} - -static void -run_without_prefault(int fd, - void (*func)(int fd)) -{ - igt_disable_prefault(); - func(fd); - igt_enable_prefault(); -} - -int fd; - -igt_main -{ - if (igt_run_in_simulation()) - OBJECT_SIZE = 1 * 1024 * 1024; - - igt_fixture - fd = drm_open_any(); - - igt_subtest("invalid-flags") - test_invalid_flags(fd); - igt_subtest("copy") - test_copy(fd); - igt_subtest("read") - test_read(fd); - igt_subtest("write") - test_write(fd); - igt_subtest("write-gtt") - test_write_gtt(fd); - igt_subtest("read-write") - test_read_write(fd, READ_BEFORE_WRITE); - igt_subtest("write-read") - test_read_write(fd, READ_AFTER_WRITE); - igt_subtest("read-write-distinct") - test_read_write2(fd, READ_BEFORE_WRITE); - igt_subtest("write-read-distinct") - test_read_write2(fd, READ_AFTER_WRITE); - igt_subtest("fault-concurrent") - test_fault_concurrent(fd); - igt_subtest("read-no-prefault") - run_without_prefault(fd, test_read); - igt_subtest("write-no-prefault") - run_without_prefault(fd, test_write); - igt_subtest("write-gtt-no-prefault") - run_without_prefault(fd, test_write_gtt); - igt_subtest("write-cpu-read-wc") - test_write_cpu_read_wc(fd); - igt_subtest("write-gtt-read-wc") - test_write_gtt_read_wc(fd); - igt_subtest("set-cache-level") - test_set_cache_level(fd); - - igt_fixture - close(fd); -} diff --git a/tests/gem_multi_bsd_sync_loop.c b/tests/gem_multi_bsd_sync_loop.c deleted file mode 100644 index 0766eb61..00000000 --- a/tests/gem_multi_bsd_sync_loop.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright © 2014 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> (based on gem_ring_sync_loop_*.c) - * Zhao Yakui <yakui.zhao@intel.com> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "i830_reg.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Basic check of ring<->ring sync using a dummy reloc."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *target_buffer; - -#define NUM_FD 50 - -static int mfd[NUM_FD]; -static drm_intel_bufmgr *mbufmgr[NUM_FD]; -static struct intel_batchbuffer *mbatch[NUM_FD]; -static drm_intel_bo *mbuffer[NUM_FD]; - - -/* - * Testcase: Basic check of ring<->ring sync using a dummy reloc - * - * Extremely efficient at catching missed irqs with semaphores=0 ... - */ - -#define MI_COND_BATCH_BUFFER_END (0x36<<23 | 1) -#define MI_DO_COMPARE (1<<21) - -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, mindex; - ring = random() % num_rings + 1; - mindex = random() % NUM_FD; - batch = mbatch[mindex]; - 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(mbuffer[mindex], 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(mbuffer[mindex], 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); -} - -igt_simple_main -{ - int fd; - int devid; - int i; - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - gem_require_ring(fd, I915_EXEC_BLT); - - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert_f(bufmgr, "fail to initialize the buf manager\n"); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - - target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert_f(target_buffer, "fail to create the gem bo\n"); - - /* Create multiple drm_fd and map one gem_object among multi drm_fd */ - { - unsigned int target_flink; - char buffer_name[32]; - igt_assert(dri_bo_flink(target_buffer, &target_flink) == 0); - - for (i = 0; i < NUM_FD; i++) { - sprintf(buffer_name, "Target buffer %d\n", i); - mfd[i] = drm_open_any(); - mbufmgr[i] = drm_intel_bufmgr_gem_init(mfd[i], 4096); - igt_assert_f(mbufmgr[i], - "fail to initialize buf manager for drm_fd %d\n", - mfd[i]); - drm_intel_bufmgr_gem_enable_reuse(mbufmgr[i]); - mbatch[i] = intel_batchbuffer_alloc(mbufmgr[i], devid); - igt_assert_f(mbatch[i], - "fail to create batchbuffer for drm_fd %d\n", - mfd[i]); - mbuffer[i] = intel_bo_gem_create_from_name(mbufmgr[i], buffer_name, target_flink); - igt_assert_f(mbuffer[i], - "fail to create buffer bo from global " - "gem handle %d for drm_fd %d\n", - target_flink, mfd[i]); - } - } - - store_dword_loop(fd); - - { - for (i = 0; i < NUM_FD; i++) { - dri_bo_unreference(mbuffer[i]); - intel_batchbuffer_free(mbatch[i]); - drm_intel_bufmgr_destroy(mbufmgr[i]); - close(mfd[i]); - } - } - drm_intel_bo_unreference(target_buffer); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_non_secure_batch.c b/tests/gem_non_secure_batch.c deleted file mode 100644 index d00ce456..00000000 --- a/tests/gem_non_secure_batch.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> (based on gem_storedw_*.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "i830_reg.h" - -IGT_TEST_DESCRIPTION("Basic check of non-secure batches."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -/* - * Testcase: Basic check of non-secure batches - * - * This test tries to stop the render ring with a MI_LOAD_REG command, which - * should fail if the non-secure handling works correctly. - */ - -static int num_rings = 1; - -static void -mi_lri_loop(void) -{ - int i; - - srandom(0xdeadbeef); - - for (i = 0; i < 0x100; i++) { - int ring = random() % num_rings + 1; - - BEGIN_BATCH(4, 0); - OUT_BATCH(MI_LOAD_REGISTER_IMM); - OUT_BATCH(0x203c); /* RENDER RING CTL */ - OUT_BATCH(0); /* try to stop the ring */ - OUT_BATCH(MI_NOOP); - ADVANCE_BATCH(); - - intel_batchbuffer_flush_on_ring(batch, ring); - } -} - -igt_simple_main -{ - int fd; - int devid; - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - if (HAS_BSD_RING(devid)) - num_rings++; - - if (HAS_BLT_RING(devid)) - num_rings++; - - - igt_info("num rings detected: %i\n", num_rings); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - - mi_lri_loop(); - gem_quiescent_gpu(fd); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_partial_pwrite_pread.c b/tests/gem_partial_pwrite_pread.c deleted file mode 100644 index 0be749c1..00000000 --- a/tests/gem_partial_pwrite_pread.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test pwrite/pread consistency when touching partial" - " cachelines."); - -/* - * Testcase: pwrite/pread consistency when touching partial cachelines - * - * Some fancy new pwrite/pread optimizations clflush in-line while - * reading/writing. Check whether all required clflushes happen. - * - */ - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -drm_intel_bo *scratch_bo; -drm_intel_bo *staging_bo; -#define BO_SIZE (4*4096) -uint32_t devid; -uint64_t mappable_gtt_limit; -int fd; - -static void -copy_bo(drm_intel_bo *src, drm_intel_bo *dst) -{ - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 4096); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH((BO_SIZE/4096) << 16 | 1024); - OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(4096); - OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -static void -blt_bo_fill(drm_intel_bo *tmp_bo, drm_intel_bo *bo, int val) -{ - uint8_t *gtt_ptr; - int i; - - drm_intel_gem_bo_map_gtt(tmp_bo); - gtt_ptr = tmp_bo->virtual; - - for (i = 0; i < BO_SIZE; i++) - gtt_ptr[i] = val; - - drm_intel_gem_bo_unmap_gtt(tmp_bo); - - if (bo->offset < mappable_gtt_limit && - (IS_G33(devid) || intel_gen(devid) >= 4)) - igt_trash_aperture(); - - copy_bo(tmp_bo, bo); -} - -#define MAX_BLT_SIZE 128 -#define ROUNDS 1000 -uint8_t tmp[BO_SIZE]; - -static void test_partial_reads(void) -{ - int i, j; - - igt_info("checking partial reads\n"); - for (i = 0; i < ROUNDS; i++) { - int start, len; - int val = i % 256; - - blt_bo_fill(staging_bo, scratch_bo, i); - - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - drm_intel_bo_get_subdata(scratch_bo, start, len, tmp); - for (j = 0; j < len; j++) { - igt_assert_f(tmp[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - - igt_progress("partial reads test: ", i, ROUNDS); - } - -} - -static void test_partial_writes(void) -{ - int i, j; - uint8_t *gtt_ptr; - - igt_info("checking partial writes\n"); - for (i = 0; i < ROUNDS; i++) { - int start, len; - int val = i % 256; - - blt_bo_fill(staging_bo, scratch_bo, i); - - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - memset(tmp, i + 63, BO_SIZE); - - drm_intel_bo_subdata(scratch_bo, start, len, tmp); - - copy_bo(scratch_bo, staging_bo); - drm_intel_gem_bo_map_gtt(staging_bo); - gtt_ptr = staging_bo->virtual; - - for (j = 0; j < start; j++) { - igt_assert_f(gtt_ptr[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - for (; j < start + len; j++) { - igt_assert_f(gtt_ptr[j] == tmp[0], - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], i); - } - for (; j < BO_SIZE; j++) { - igt_assert_f(gtt_ptr[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - drm_intel_gem_bo_unmap_gtt(staging_bo); - - igt_progress("partial writes test: ", i, ROUNDS); - } - -} - -static void test_partial_read_writes(void) -{ - int i, j; - uint8_t *gtt_ptr; - - igt_info("checking partial writes after partial reads\n"); - for (i = 0; i < ROUNDS; i++) { - int start, len; - int val = i % 256; - - blt_bo_fill(staging_bo, scratch_bo, i); - - /* partial read */ - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - drm_intel_bo_get_subdata(scratch_bo, start, len, tmp); - for (j = 0; j < len; j++) { - igt_assert_f(tmp[j] == val, - "mismatch in read at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - - /* Change contents through gtt to make the pread cachelines - * stale. */ - val = (i + 17) % 256; - blt_bo_fill(staging_bo, scratch_bo, val); - - /* partial write */ - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - memset(tmp, i + 63, BO_SIZE); - - drm_intel_bo_subdata(scratch_bo, start, len, tmp); - - copy_bo(scratch_bo, staging_bo); - drm_intel_gem_bo_map_gtt(staging_bo); - gtt_ptr = staging_bo->virtual; - - for (j = 0; j < start; j++) { - igt_assert_f(gtt_ptr[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - for (; j < start + len; j++) { - igt_assert_f(gtt_ptr[j] == tmp[0], - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], tmp[0]); - } - for (; j < BO_SIZE; j++) { - igt_assert_f(gtt_ptr[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - drm_intel_gem_bo_unmap_gtt(staging_bo); - - igt_progress("partial read/writes test: ", i, ROUNDS); - } -} - -static void do_tests(int cache_level, const char *suffix) -{ - igt_fixture { - if (cache_level != -1) - gem_set_caching(fd, scratch_bo->handle, cache_level); - } - - igt_subtest_f("reads%s", suffix) - test_partial_reads(); - - igt_subtest_f("write%s", suffix) - test_partial_writes(); - - igt_subtest_f("writes-after-reads%s", suffix) - test_partial_read_writes(); -} - -igt_main -{ - srandom(0xdeadbeef); - - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - devid = intel_get_drm_devid(fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - /* overallocate the buffers we're actually using because */ - scratch_bo = drm_intel_bo_alloc(bufmgr, "scratch bo", BO_SIZE, 4096); - staging_bo = drm_intel_bo_alloc(bufmgr, "staging bo", BO_SIZE, 4096); - - igt_init_aperture_trashers(bufmgr); - mappable_gtt_limit = gem_mappable_aperture_size(); - } - - do_tests(-1, ""); - - /* Repeat the tests using different levels of snooping */ - do_tests(0, "-uncached"); - do_tests(1, "-snoop"); - do_tests(2, "-display"); - - igt_fixture { - igt_cleanup_aperture_trashers(); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_persistent_relocs.c b/tests/gem_persistent_relocs.c deleted file mode 100644 index cab52a87..00000000 --- a/tests/gem_persistent_relocs.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#define _GNU_SOURCE -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <signal.h> -#include <sys/wait.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_debugfs.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test persistent relocations as used by uxa/libva."); - -/* - * Testcase: Persistent relocations as used by uxa/libva - * - */ - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -uint32_t blob[2048*2048]; -#define NUM_TARGET_BOS 16 -drm_intel_bo *pc_target_bo[NUM_TARGET_BOS]; -drm_intel_bo *dummy_bo; -drm_intel_bo *special_bos[NUM_TARGET_BOS]; -uint32_t relocs_bo_handle[NUM_TARGET_BOS]; -void *gtt_relocs_ptr[NUM_TARGET_BOS]; -uint32_t devid; -int special_reloc_ofs; -int special_line_ofs; -int special_batch_len; - -int small_pitch = 64; - -static drm_intel_bo *create_special_bo(void) -{ - drm_intel_bo *bo; - uint32_t data[1024]; - int len = 0; -#define BATCH(dw) data[len++] = (dw); - - memset(data, 0, 4096); - bo = drm_intel_bo_alloc(bufmgr, "special batch", 4096, 4096); - - if (intel_gen(devid) >= 8) { - BATCH(MI_NOOP); - BATCH(XY_COLOR_BLT_CMD_NOLEN | 5 | - COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); - } else { - BATCH(XY_COLOR_BLT_CMD_NOLEN | 4 | - COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); - } - - BATCH((3 << 24) | (0xf0 << 16) | small_pitch); - special_line_ofs = 4*len; - BATCH(0); - BATCH(1 << 16 | 1); - special_reloc_ofs = 4*len; - BATCH(0); - if (intel_gen(devid) >= 8) - BATCH(0); /* FIXME */ - BATCH(0xdeadbeef); - -#define CMD_POLY_STIPPLE_OFFSET 0x7906 - /* batchbuffer end */ - if (IS_GEN5(batch->devid)) { - BATCH(CMD_POLY_STIPPLE_OFFSET << 16); - BATCH(0); - } - igt_assert(len % 2 == 0); - BATCH(MI_NOOP); - BATCH(MI_BATCH_BUFFER_END); - - drm_intel_bo_subdata(bo, 0, 4096, data); - special_batch_len = len*4; - - return bo; -} - -static void emit_dummy_load(int pitch) -{ - int i; - uint32_t tile_flags = 0; - - if (IS_965(devid)) { - pitch /= 4; - tile_flags = XY_SRC_COPY_BLT_SRC_TILED | - XY_SRC_COPY_BLT_DST_TILED; - } - - for (i = 0; i < 5; i++) { - BLIT_COPY_BATCH_START(tile_flags); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - pitch); - OUT_BATCH(0 << 16 | 1024); - OUT_BATCH((2048) << 16 | (2048)); - OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(pitch); - OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 6) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } - } - intel_batchbuffer_flush(batch); -} - -static void faulting_reloc_and_emit(int fd, drm_intel_bo *target_bo, - void *gtt_relocs, drm_intel_bo *special_bo) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec[2]; - int ring; - - if (intel_gen(devid) >= 6) - ring = I915_EXEC_BLT; - else - ring = 0; - - exec[0].handle = target_bo->handle; - exec[0].relocation_count = 0; - exec[0].relocs_ptr = 0; - exec[0].alignment = 0; - exec[0].offset = 0; - exec[0].flags = 0; - exec[0].rsvd1 = 0; - exec[0].rsvd2 = 0; - - exec[1].handle = special_bo->handle; - exec[1].relocation_count = 1; - /* A newly mmap gtt bo will fault on first access. */ - exec[1].relocs_ptr = (uintptr_t)gtt_relocs; - exec[1].alignment = 0; - exec[1].offset = 0; - exec[1].flags = 0; - exec[1].rsvd1 = 0; - exec[1].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)exec; - execbuf.buffer_count = 2; - execbuf.batch_start_offset = 0; - execbuf.batch_len = special_batch_len; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - gem_execbuf(fd, &execbuf); -} - -static void do_test(int fd, bool faulting_reloc) -{ - uint32_t tiling_mode = I915_TILING_X; - unsigned long pitch, act_size; - uint32_t test; - int i, repeat; - - if (faulting_reloc) - igt_disable_prefault(); - - act_size = 2048; - dummy_bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled dummy_bo", act_size, act_size, - 4, &tiling_mode, &pitch, 0); - - drm_intel_bo_subdata(dummy_bo, 0, act_size*act_size*4, blob); - - for (i = 0; i < NUM_TARGET_BOS; i++) { - struct drm_i915_gem_relocation_entry reloc[1]; - - special_bos[i] = create_special_bo(); - pc_target_bo[i] = drm_intel_bo_alloc(bufmgr, "special batch", 4096, 4096); - igt_assert(pc_target_bo[i]->offset == 0); - - reloc[0].offset = special_reloc_ofs; - reloc[0].delta = 0; - reloc[0].target_handle = pc_target_bo[i]->handle; - reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; - reloc[0].presumed_offset = 0; - - relocs_bo_handle[i] = gem_create(fd, 4096); - gem_write(fd, relocs_bo_handle[i], 0, reloc, sizeof(reloc)); - gtt_relocs_ptr[i] = gem_mmap(fd, relocs_bo_handle[i], 4096, - PROT_READ | PROT_WRITE); - igt_assert(gtt_relocs_ptr[i]); - - } - - /* repeat must be smaller than 4096/small_pitch */ - for (repeat = 0; repeat < 8; repeat++) { - for (i = 0; i < NUM_TARGET_BOS; i++) { - uint32_t data[2] = { - (repeat << 16) | 0, - ((repeat + 1) << 16) | 1 - }; - - drm_intel_bo_subdata(special_bos[i], special_line_ofs, 8, &data); - - emit_dummy_load(pitch); - faulting_reloc_and_emit(fd, pc_target_bo[i], - gtt_relocs_ptr[i], - special_bos[i]); - } - } - - /* Only check at the end to avoid unnecessarily synchronous behaviour. */ - for (i = 0; i < NUM_TARGET_BOS; i++) { - /* repeat must be smaller than 4096/small_pitch */ - for (repeat = 0; repeat < 8; repeat++) { - drm_intel_bo_get_subdata(pc_target_bo[i], - repeat*small_pitch, 4, &test); - igt_assert_f(test == 0xdeadbeef, - "mismatch in buffer %i: 0x%08x instead of 0xdeadbeef at offset %i\n", - i, test, repeat*small_pitch); - } - drm_intel_bo_unreference(pc_target_bo[i]); - drm_intel_bo_unreference(special_bos[i]); - gem_close(fd, relocs_bo_handle[i]); - munmap(gtt_relocs_ptr[i], 4096); - } - - drm_intel_gem_bo_map_gtt(dummy_bo); - drm_intel_gem_bo_unmap_gtt(dummy_bo); - - drm_intel_bo_unreference(dummy_bo); - - if (faulting_reloc) - igt_enable_prefault(); -} - -#define INTERRUPT (1 << 0) -#define FAULTING (1 << 1) -#define THRASH (1 << 2) -#define THRASH_INACTIVE (1 << 3) -#define ALL_FLAGS (INTERRUPT | FAULTING | THRASH | THRASH_INACTIVE) -static void do_forked_test(int fd, unsigned flags) -{ - int num_threads = sysconf(_SC_NPROCESSORS_ONLN); - struct igt_helper_process thrasher = {}; - - if (flags & (THRASH | THRASH_INACTIVE)) { - uint64_t val = (flags & THRASH_INACTIVE) ? - (DROP_RETIRE | DROP_BOUND | DROP_UNBOUND) : DROP_ALL; - - igt_fork_helper(&thrasher) { - while (1) { - usleep(1000); - igt_drop_caches_set(val); - } - } - } - - igt_fork(i, num_threads) { - /* re-create process local data */ - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - if (flags & INTERRUPT) - igt_fork_signal_helper(); - - do_test(fd, flags & FAULTING); - - if (flags & INTERRUPT) - igt_stop_signal_helper(); - } - - igt_waitchildren(); - if (flags & (THRASH | THRASH_INACTIVE)) - igt_stop_helper(&thrasher); -} - -int fd; - -#define MAX_BLT_SIZE 128 -igt_main -{ - igt_skip_on_simulation(); - - memset(blob, 'A', sizeof(blob)); - - igt_fixture { - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - /* disable reuse, otherwise the test fails */ - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - devid = intel_get_drm_devid(fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - } - - igt_subtest("normal") - do_test(fd, false); - - igt_fork_signal_helper(); - igt_subtest("interruptible") - do_test(fd, false); - igt_stop_signal_helper(); - - for (unsigned flags = 0; flags <= ALL_FLAGS; flags++) { - if ((flags & THRASH) && (flags & THRASH_INACTIVE)) - continue; - - igt_subtest_f("forked%s%s%s%s", - flags & INTERRUPT ? "-interruptible" : "", - flags & FAULTING ? "-faulting-reloc" : "", - flags & THRASH ? "-thrashing" : "", - flags & THRASH_INACTIVE ? "-thrash-inactive" : "") - do_forked_test(fd, flags); - } - - igt_fixture { - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_pin.c b/tests/gem_pin.c deleted file mode 100644 index b35496e7..00000000 --- a/tests/gem_pin.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright © 20013 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/* Exercises pinning of small bo */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Exercises pinning of small buffer objects."); - -#define COPY_BLT_CMD (2<<29|0x53<<22|0x6) -#define BLT_WRITE_ALPHA (1<<21) -#define BLT_WRITE_RGB (1<<20) - -static void exec(int fd, uint32_t handle, uint32_t offset) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec[1]; - struct drm_i915_gem_relocation_entry gem_reloc[1]; - - gem_reloc[0].offset = 1024; - gem_reloc[0].delta = 0; - gem_reloc[0].target_handle = handle; - gem_reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - gem_reloc[0].write_domain = 0; - gem_reloc[0].presumed_offset = 0; - - gem_exec[0].handle = handle; - gem_exec[0].relocation_count = 1; - gem_exec[0].relocs_ptr = (uintptr_t) gem_reloc; - gem_exec[0].alignment = 0; - gem_exec[0].offset = 0; - gem_exec[0].flags = 0; - gem_exec[0].rsvd1 = 0; - gem_exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = 0; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - igt_assert(gem_exec[0].offset == offset); -} - -static int gem_linear_blt(int fd, - uint32_t *batch, - uint32_t src, - uint32_t dst, - uint32_t length, - struct drm_i915_gem_relocation_entry *reloc) -{ - uint32_t *b = batch; - - *b++ = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB; - *b++ = 0x66 << 16 | 1 << 25 | 1 << 24 | (4*1024); - *b++ = 0; - *b++ = (length / (4*1024)) << 16 | 1024; - *b++ = 0; - reloc->offset = (b-batch-1) * sizeof(uint32_t); - reloc->delta = 0; - reloc->target_handle = dst; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = I915_GEM_DOMAIN_RENDER; - reloc->presumed_offset = 0; - reloc++; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - *b++ = 0; /* FIXME */ - - *b++ = 0; - *b++ = 4*1024; - *b++ = 0; - reloc->offset = (b-batch-1) * sizeof(uint32_t); - reloc->delta = 0; - reloc->target_handle = src; - reloc->read_domains = I915_GEM_DOMAIN_RENDER; - reloc->write_domain = 0; - reloc->presumed_offset = 0; - reloc++; - if (intel_gen(intel_get_drm_devid(fd)) >= 8) - *b++ = 0; /* FIXME */ - - *b++ = MI_BATCH_BUFFER_END; - *b++ = 0; - - return (b - batch) * sizeof(uint32_t); -} - -static void make_busy(int fd, uint32_t handle) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 obj[2]; - struct drm_i915_gem_relocation_entry reloc[2]; - uint32_t batch[20]; - uint32_t tmp; - int count; - - tmp = gem_create(fd, 1024*1024); - - obj[0].handle = tmp; - obj[0].relocation_count = 0; - obj[0].relocs_ptr = 0; - obj[0].alignment = 0; - obj[0].offset = 0; - obj[0].flags = 0; - obj[0].rsvd1 = 0; - obj[0].rsvd2 = 0; - - obj[1].handle = handle; - obj[1].relocation_count = 2; - obj[1].relocs_ptr = (uintptr_t) reloc; - obj[1].alignment = 0; - obj[1].offset = 0; - obj[1].flags = 0; - obj[1].rsvd1 = 0; - obj[1].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)obj; - execbuf.buffer_count = 2; - execbuf.batch_start_offset = 0; - execbuf.batch_len = gem_linear_blt(fd, batch, tmp, tmp, 1024*1024,reloc); - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = 0; - if (HAS_BLT_RING(intel_get_drm_devid(fd))) - execbuf.flags |= I915_EXEC_BLT; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - gem_write(fd, handle, 0, batch, execbuf.batch_len); - for (count = 0; count < 10; count++) - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - gem_close(fd, tmp); -} - -static int test_can_pin(int fd) -{ - struct drm_i915_gem_pin pin; - int ret; - - pin.handle = gem_create(fd, 4096);; - pin.alignment = 0; - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_PIN, &pin); - gem_close(fd, pin.handle); - - return ret == 0;; -} - -static uint32_t gem_pin(int fd, int handle, int alignment) -{ - struct drm_i915_gem_pin pin; - - pin.handle = handle; - pin.alignment = alignment; - do_ioctl(fd, DRM_IOCTL_I915_GEM_PIN, &pin); - return pin.offset; -} - -igt_simple_main -{ - const uint32_t batch[2] = {MI_BATCH_BUFFER_END}; - struct timeval start, now; - uint32_t *handle, *offset; - int fd, i; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - igt_require(test_can_pin(fd)); - - handle = malloc(sizeof(uint32_t)*100); - offset = malloc(sizeof(uint32_t)*100); - - /* Race creation/use against interrupts */ - igt_fork_signal_helper(); - gettimeofday(&start, NULL); - do { - for (i = 0; i < 100; i++) { - if (i & 1) { - /* pin anidle bo */ - handle[i] = gem_create(fd, 4096); - offset[i] = gem_pin(fd, handle[i], 0); - igt_assert(offset[i]); - gem_write(fd, handle[i], 0, batch, sizeof(batch)); - } else { - /* try to pin an anidle bo */ - handle[i] = gem_create(fd, 4096); - make_busy(fd, handle[i]); - offset[i] = gem_pin(fd, handle[i], 256*1024); - igt_assert(offset[i]); - igt_assert((offset[i] & (256*1024-1)) == 0); - gem_write(fd, handle[i], 0, batch, sizeof(batch)); - } - } - for (i = 0; i < 1000; i++) { - int j = rand() % 100; - exec(fd, handle[j], offset[j]); - } - for (i = 0; i < 100; i++) - gem_close(fd, handle[i]); - gettimeofday(&now, NULL); - } while ((now.tv_sec - start.tv_sec)*1000 + (now.tv_usec - start.tv_usec) / 1000 < 10000); - igt_stop_signal_helper(); -} diff --git a/tests/gem_pipe_control_store_loop.c b/tests/gem_pipe_control_store_loop.c deleted file mode 100644 index 86ee4050..00000000 --- a/tests/gem_pipe_control_store_loop.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> (based on gem_storedw_*.c) - * - */ - -/* - * Testcase: (TLB-)Coherency of pipe_control QW writes - * - * Writes a counter-value into an always newly allocated target bo (by disabling - * buffer reuse). Decently trashes on tlb inconsistencies, too. - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "intel_io.h" - -IGT_TEST_DESCRIPTION("Test (TLB-)Coherency of pipe_control QW writes."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -uint32_t devid; - -#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2) -#define PIPE_CONTROL_WRITE_IMMEDIATE (1<<14) -#define PIPE_CONTROL_WRITE_TIMESTAMP (3<<14) -#define PIPE_CONTROL_DEPTH_STALL (1<<13) -#define PIPE_CONTROL_WC_FLUSH (1<<12) -#define PIPE_CONTROL_IS_FLUSH (1<<11) /* MBZ on Ironlake */ -#define PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */ -#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1) -#define PIPE_CONTROL_CS_STALL (1<<20) -#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ - -/* Like the store dword test, but we create new command buffers each time */ -static void -store_pipe_control_loop(bool preuse_buffer) -{ - int i, val = 0; - uint32_t *buf; - drm_intel_bo *target_bo; - - for (i = 0; i < SLOW_QUICK(0x10000, 4); i++) { - /* we want to check tlb consistency of the pipe_control target, - * so get a new buffer every time around */ - target_bo = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_bo); - - if (preuse_buffer) { - COLOR_BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | (0xf0 << 16) | 64); - OUT_BATCH(0); - OUT_BATCH(1 << 16 | 1); - - /* - * IMPORTANT: We need to preuse the buffer in a - * different domain than what the pipe control write - * (and kernel wa) uses! - */ - OUT_RELOC_FENCED(target_bo, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); - OUT_BATCH(0xdeadbeef); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); - } - - /* gem_storedw_batches_loop.c is a bit overenthusiastic with - * creating new batchbuffers - with buffer reuse disabled, the - * support code will do that for us. */ - if (batch->gen >= 8) { - BEGIN_BATCH(4, 1); - OUT_BATCH(GFX_OP_PIPE_CONTROL + 1); - OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE); - OUT_RELOC_FENCED(target_bo, - I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, - PIPE_CONTROL_GLOBAL_GTT); - OUT_BATCH(val); /* write data */ - ADVANCE_BATCH(); - - } else if (batch->gen >= 6) { - /* work-around hw issue, see intel_emit_post_sync_nonzero_flush - * in mesa sources. */ - BEGIN_BATCH(4, 1); - OUT_BATCH(GFX_OP_PIPE_CONTROL); - OUT_BATCH(PIPE_CONTROL_CS_STALL | - PIPE_CONTROL_STALL_AT_SCOREBOARD); - OUT_BATCH(0); /* address */ - OUT_BATCH(0); /* write data */ - ADVANCE_BATCH(); - - BEGIN_BATCH(4, 1); - OUT_BATCH(GFX_OP_PIPE_CONTROL); - OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE); - OUT_RELOC(target_bo, - I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, - PIPE_CONTROL_GLOBAL_GTT); - OUT_BATCH(val); /* write data */ - ADVANCE_BATCH(); - } else if (batch->gen >= 4) { - BEGIN_BATCH(4, 1); - OUT_BATCH(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_WC_FLUSH | - PIPE_CONTROL_TC_FLUSH | - PIPE_CONTROL_WRITE_IMMEDIATE | 2); - OUT_RELOC(target_bo, - I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, - PIPE_CONTROL_GLOBAL_GTT); - OUT_BATCH(val); - OUT_BATCH(0xdeadbeef); - ADVANCE_BATCH(); - } - - intel_batchbuffer_flush_on_ring(batch, 0); - - drm_intel_bo_map(target_bo, 1); - - buf = target_bo->virtual; - igt_assert(buf[0] == val); - - drm_intel_bo_unmap(target_bo); - /* Make doublesure that this buffer won't get reused. */ - drm_intel_bo_disable_reuse(target_bo); - drm_intel_bo_unreference(target_bo); - - val++; - } -} - -int fd; - -igt_main -{ - igt_fixture { - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - - igt_skip_on(IS_GEN2(devid) || IS_GEN3(devid)); - igt_skip_on(devid == PCI_CHIP_I965_G); /* has totally broken pipe control */ - - /* IMPORTANT: No call to - * drm_intel_bufmgr_gem_enable_reuse(bufmgr); - * here because we wan't to have fresh buffers (to trash the tlb) - * every time! */ - - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - } - - igt_subtest("fresh-buffer") - store_pipe_control_loop(false); - - igt_subtest("reused-buffer") - store_pipe_control_loop(true); - - igt_fixture { - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_ppgtt.c b/tests/gem_ppgtt.c deleted file mode 100644 index 5bf773c2..00000000 --- a/tests/gem_ppgtt.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include <stdbool.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -#define WIDTH 512 -#define STRIDE (WIDTH*4) -#define HEIGHT 512 -#define SIZE (HEIGHT*STRIDE) - -static drm_intel_bo *create_bo(drm_intel_bufmgr *bufmgr, - uint32_t pixel) -{ - drm_intel_bo *bo; - uint32_t *v; - - bo = drm_intel_bo_alloc(bufmgr, "surface", SIZE, 4096); - igt_assert(bo); - - do_or_die(drm_intel_bo_map(bo, 1)); - v = bo->virtual; - for (int i = 0; i < SIZE/4; i++) - v[i] = pixel; - drm_intel_bo_unmap(bo); - - return bo; -} - -static void scratch_buf_init(struct igt_buf *buf, - drm_intel_bufmgr *bufmgr, - uint32_t pixel) -{ - buf->bo = create_bo(bufmgr, pixel); - buf->stride = STRIDE; - buf->tiling = I915_TILING_NONE; - buf->size = SIZE; -} - -static void scratch_buf_fini(struct igt_buf *buf) -{ - dri_bo_unreference(buf->bo); - memset(buf, 0, sizeof(*buf)); -} - -static void fork_rcs_copy(int target, dri_bo **dst, int count, unsigned flags) -#define CREATE_CONTEXT 0x1 -{ - igt_render_copyfunc_t render_copy; - int devid; - - for (int child = 0; child < count; child++) { - int fd = drm_open_any(); - drm_intel_bufmgr *bufmgr; - - devid = intel_get_drm_devid(fd); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - - dst[child] = create_bo(bufmgr, ~0); - - if (flags & CREATE_CONTEXT) { - drm_intel_context *ctx; - - ctx = drm_intel_gem_context_create(dst[child]->bufmgr); - igt_require(ctx); - } - - render_copy = igt_get_render_copyfunc(devid); - igt_require_f(render_copy, - "no render-copy function\n"); - } - - igt_fork(child, count) { - struct intel_batchbuffer *batch; - struct igt_buf buf; - - batch = intel_batchbuffer_alloc(dst[child]->bufmgr, - devid); - igt_assert(batch); - - if (flags & CREATE_CONTEXT) { - drm_intel_context *ctx; - - ctx = drm_intel_gem_context_create(dst[child]->bufmgr); - intel_batchbuffer_set_context(batch, ctx); - } - - buf.bo = dst[child]; - buf.stride = STRIDE; - buf.tiling = I915_TILING_NONE; - buf.size = SIZE; - - for (int i = 0; i <= target; i++) { - struct igt_buf src; - - scratch_buf_init(&src, dst[child]->bufmgr, - i | child << 16); - - render_copy(batch, NULL, - &src, 0, 0, - WIDTH, HEIGHT, - &buf, 0, 0); - - scratch_buf_fini(&src); - } - } -} - -static void fork_bcs_copy(int target, dri_bo **dst, int count) -{ - int devid; - - for (int child = 0; child < count; child++) { - drm_intel_bufmgr *bufmgr; - int fd = drm_open_any(); - - devid = intel_get_drm_devid(fd); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - - dst[child] = create_bo(bufmgr, ~0); - } - - igt_fork(child, count) { - struct intel_batchbuffer *batch; - - batch = intel_batchbuffer_alloc(dst[child]->bufmgr, - devid); - igt_assert(batch); - - for (int i = 0; i <= target; i++) { - dri_bo *src[2]; - - src[0] = create_bo(dst[child]->bufmgr, - ~0); - src[1] = create_bo(dst[child]->bufmgr, - i | child << 16); - - intel_copy_bo(batch, src[0], src[1], SIZE); - intel_copy_bo(batch, dst[child], src[0], SIZE); - - dri_bo_unreference(src[1]); - dri_bo_unreference(src[0]); - } - } -} - -static void surfaces_check(dri_bo **bo, int count, uint32_t expected) -{ - for (int child = 0; child < count; child++) { - uint32_t *ptr; - - do_or_die(drm_intel_bo_map(bo[child], 0)); - ptr = bo[child]->virtual; - for (int j = 0; j < SIZE/4; j++) - igt_assert_eq(ptr[j], expected | child << 16); - drm_intel_bo_unmap(bo[child]); - } -} - -#define N_CHILD 8 -int main(int argc, char **argv) -{ - igt_subtest_init(argc, argv); - - igt_subtest("blt-vs-render-ctx0") { - dri_bo *bcs[1], *rcs[N_CHILD]; - - fork_bcs_copy(0x4000, bcs, 1); - fork_rcs_copy(0x8000 / N_CHILD, rcs, N_CHILD, 0); - - igt_waitchildren(); - - surfaces_check(bcs, 1, 0x4000); - surfaces_check(rcs, N_CHILD, 0x8000 / N_CHILD); - } - - igt_subtest("blt-vs-render-ctxN") { - dri_bo *bcs[1], *rcs[N_CHILD]; - - fork_rcs_copy(0x8000 / N_CHILD, rcs, N_CHILD, CREATE_CONTEXT); - fork_bcs_copy(0x4000, bcs, 1); - - igt_waitchildren(); - - surfaces_check(bcs, 1, 0x4000); - surfaces_check(rcs, N_CHILD, 0x8000 / N_CHILD); - } - - igt_exit(); -} diff --git a/tests/gem_pread.c b/tests/gem_pread.c deleted file mode 100644 index cc83948b..00000000 --- a/tests/gem_pread.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -#define OBJECT_SIZE 16384 - -static void do_gem_read(int fd, uint32_t handle, void *buf, int len, int loops) -{ - while (loops--) - gem_read(fd, handle, 0, buf, len); -} - -static double elapsed(const struct timeval *start, - const struct timeval *end, - int loop) -{ - return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec))/loop; -} - -static const char *bytes_per_sec(char *buf, double v) -{ - const char *order[] = { - "", - "KiB", - "MiB", - "GiB", - "TiB", - NULL, - }, **o = order; - - while (v > 1000 && o[1]) { - v /= 1000; - o++; - } - sprintf(buf, "%.1f%s/s", v, *o); - return buf; -} - - -uint32_t *src, dst; -int fd, count; - -int main(int argc, char **argv) -{ - int object_size = 0; - uint32_t buf[20]; - const struct { - int level; - const char *name; - } cache[] = { - { 0, "uncached" }, - { 1, "snoop" }, - { 2, "display" }, - { -1 }, - }, *c; - - igt_subtest_init(argc, argv); - igt_skip_on_simulation(); - - if (argc > 1 && atoi(argv[1])) - object_size = atoi(argv[1]); - if (object_size == 0) - object_size = OBJECT_SIZE; - object_size = (object_size + 3) & -4; - - igt_fixture { - fd = drm_open_any(); - - dst = gem_create(fd, object_size); - src = malloc(object_size); - } - - igt_subtest("normal") { - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - do_gem_read(fd, dst, src, object_size, count); - gettimeofday(&end, NULL); - igt_info("Time to pread %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - - for (c = cache; c->level != -1; c++) { - igt_subtest(c->name) { - gem_set_caching(fd, dst, c->level); - - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - do_gem_read(fd, dst, src, object_size, count); - gettimeofday(&end, NULL); - igt_info("Time to %s pread %d bytes x %6d: %7.3fµs, %s\n", - c->name, object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - } - - igt_fixture { - free(src); - gem_close(fd, dst); - - close(fd); - } - - igt_exit(); -} diff --git a/tests/gem_pread_after_blit.c b/tests/gem_pread_after_blit.c deleted file mode 100644 index 8ed43100..00000000 --- a/tests/gem_pread_after_blit.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * - */ - -/** @file gem_pread_after_blit.c - * - * This is a test of pread's behavior when getting values out of just-drawn-to - * buffers. - * - * The goal is to catch failure in the whole-buffer-flush or - * ranged-buffer-flush paths in the kernel. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_aux.h" -#include "igt_gt.h" - -IGT_TEST_DESCRIPTION("Test pread behavior when getting values out of" - " just-drawn-to buffers."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static const int width = 512, height = 512; -static const int size = 1024 * 1024; - -#define PAGE_SIZE 4096 - -static drm_intel_bo * -create_bo(uint32_t val) -{ - drm_intel_bo *bo; - uint32_t *vaddr; - int i; - - bo = drm_intel_bo_alloc(bufmgr, "src bo", size, 4096); - - /* Fill the BO with dwords starting at start_val */ - drm_intel_bo_map(bo, 1); - vaddr = bo->virtual; - - for (i = 0; i < 1024 * 1024 / 4; i++) - vaddr[i] = val++; - - drm_intel_bo_unmap(bo); - - return bo; -} - -static void -verify_large_read(drm_intel_bo *bo, uint32_t val) -{ - uint32_t buf[size / 4]; - int i; - - drm_intel_bo_get_subdata(bo, 0, size, buf); - - for (i = 0; i < size / 4; i++) { - igt_assert_f(buf[i] == val, - "Unexpected value 0x%08x instead of " - "0x%08x at offset 0x%08x (%p)\n", - buf[i], val, i * 4, buf); - val++; - } -} - -/** This reads at the size that Mesa usees for software fallbacks. */ -static void -verify_small_read(drm_intel_bo *bo, uint32_t val) -{ - uint32_t buf[4096 / 4]; - int offset, i; - - for (i = 0; i < 4096 / 4; i++) - buf[i] = 0x00c0ffee; - - for (offset = 0; offset < size; offset += PAGE_SIZE) { - drm_intel_bo_get_subdata(bo, offset, PAGE_SIZE, buf); - - for (i = 0; i < PAGE_SIZE; i += 4) { - igt_assert_f(buf[i / 4] == val, - "Unexpected value 0x%08x instead of " - "0x%08x at offset 0x%08x\n", - buf[i / 4], val, i * 4); - val++; - } - } -} - -typedef struct igt_hang_ring (*do_hang)(int fd); - -static struct igt_hang_ring no_hang(int fd) -{ - return (struct igt_hang_ring){0}; -} - -static struct igt_hang_ring bcs_hang(int fd) -{ - return igt_hang_ring(fd, batch->gen >= 6 ? I915_EXEC_BLT : I915_EXEC_DEFAULT); -} - -static void do_test(int fd, int cache_level, - drm_intel_bo *src[2], - const uint32_t start[2], - drm_intel_bo *tmp[2], - int loop, do_hang do_hang_func) -{ - struct igt_hang_ring hang; - - if (cache_level != -1) { - gem_set_caching(fd, tmp[0]->handle, cache_level); - gem_set_caching(fd, tmp[1]->handle, cache_level); - } - - do { - /* First, do a full-buffer read after blitting */ - intel_copy_bo(batch, tmp[0], src[0], width*height*4); - hang = do_hang_func(fd); - verify_large_read(tmp[0], start[0]); - igt_post_hang_ring(fd, hang); - intel_copy_bo(batch, tmp[0], src[1], width*height*4); - hang = do_hang_func(fd); - verify_large_read(tmp[0], start[1]); - igt_post_hang_ring(fd, hang); - - intel_copy_bo(batch, tmp[0], src[0], width*height*4); - hang = do_hang_func(fd); - verify_small_read(tmp[0], start[0]); - igt_post_hang_ring(fd, hang); - intel_copy_bo(batch, tmp[0], src[1], width*height*4); - hang = do_hang_func(fd); - verify_small_read(tmp[0], start[1]); - igt_post_hang_ring(fd, hang); - - intel_copy_bo(batch, tmp[0], src[0], width*height*4); - hang = do_hang_func(fd); - verify_large_read(tmp[0], start[0]); - igt_post_hang_ring(fd, hang); - - intel_copy_bo(batch, tmp[0], src[0], width*height*4); - intel_copy_bo(batch, tmp[1], src[1], width*height*4); - hang = do_hang_func(fd); - verify_large_read(tmp[0], start[0]); - verify_large_read(tmp[1], start[1]); - igt_post_hang_ring(fd, hang); - - intel_copy_bo(batch, tmp[0], src[0], width*height*4); - intel_copy_bo(batch, tmp[1], src[1], width*height*4); - hang = do_hang_func(fd); - verify_large_read(tmp[1], start[1]); - verify_large_read(tmp[0], start[0]); - igt_post_hang_ring(fd, hang); - - intel_copy_bo(batch, tmp[1], src[0], width*height*4); - intel_copy_bo(batch, tmp[0], src[1], width*height*4); - hang = do_hang_func(fd); - verify_large_read(tmp[0], start[1]); - verify_large_read(tmp[1], start[0]); - igt_post_hang_ring(fd, hang); - } while (--loop); -} - -drm_intel_bo *src[2], *dst[2]; -int fd; - -igt_main -{ - const uint32_t start[2] = {0, 1024 * 1024 / 4}; - const struct { - const char *name; - int cache; - } tests[] = { - { "default", -1 }, - { "uncached", 0 }, - { "snooped", 1 }, - { "display", 2 }, - { NULL, -1 }, - }, *t; - - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - src[0] = create_bo(start[0]); - src[1] = create_bo(start[1]); - - dst[0] = drm_intel_bo_alloc(bufmgr, "dst bo", size, 4096); - dst[1] = drm_intel_bo_alloc(bufmgr, "dst bo", size, 4096); - } - - for (t = tests; t->name; t++) { - igt_subtest_f("%s-normal", t->name) - do_test(fd, t->cache, src, start, dst, 1, no_hang); - - igt_fork_signal_helper(); - igt_subtest_f("%s-interruptible", t->name) - do_test(fd, t->cache, src, start, dst, 100, no_hang); - igt_stop_signal_helper(); - - igt_subtest_f("%s-hang", t->name) { - igt_require_hang_ring(fd, -1); - do_test(fd, t->cache, src, start, dst, 1, bcs_hang); - } - } - - igt_fixture { - drm_intel_bo_unreference(src[0]); - drm_intel_bo_unreference(src[1]); - drm_intel_bo_unreference(dst[0]); - drm_intel_bo_unreference(dst[1]); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - } - - close(fd); -} diff --git a/tests/gem_pwrite.c b/tests/gem_pwrite.c deleted file mode 100644 index 6378b0a4..00000000 --- a/tests/gem_pwrite.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -#define OBJECT_SIZE 16384 - -#define COPY_BLT_CMD (2<<29|0x53<<22|0x6) -#define BLT_WRITE_ALPHA (1<<21) -#define BLT_WRITE_RGB (1<<20) -#define BLT_SRC_TILED (1<<15) -#define BLT_DST_TILED (1<<11) - -static void do_gem_write(int fd, uint32_t handle, void *buf, int len, int loops) -{ - while (loops--) - gem_write(fd, handle, 0, buf, len); -} - -static double elapsed(const struct timeval *start, - const struct timeval *end, - int loop) -{ - return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec))/loop; -} - -static const char *bytes_per_sec(char *buf, double v) -{ - const char *order[] = { - "", - "KiB", - "MiB", - "GiB", - "TiB", - NULL, - }, **o = order; - - while (v > 1000 && o[1]) { - v /= 1000; - o++; - } - sprintf(buf, "%.1f%s/s", v, *o); - return buf; -} - - -uint32_t *src, dst; -int fd; - -int main(int argc, char **argv) -{ - int object_size = 0; - uint32_t buf[20]; - int count; - const struct { - int level; - const char *name; - } cache[] = { - { 0, "uncached" }, - { 1, "snoop" }, - { 2, "display" }, - { -1 }, - }, *c; - - igt_skip_on_simulation(); - - igt_subtest_init(argc, argv); - - if (argc > 1 && atoi(argv[1])) - object_size = atoi(argv[1]); - if (object_size == 0) - object_size = OBJECT_SIZE; - object_size = (object_size + 3) & -4; - - igt_fixture { - fd = drm_open_any(); - - dst = gem_create(fd, object_size); - src = malloc(object_size); - } - - igt_subtest("normal") { - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - do_gem_write(fd, dst, src, object_size, count); - gettimeofday(&end, NULL); - igt_info("Time to pwrite %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - - for (c = cache; c->level != -1; c++) { - igt_subtest(c->name) { - gem_set_caching(fd, dst, c->level); - - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - do_gem_write(fd, dst, src, object_size, count); - gettimeofday(&end, NULL); - igt_info("Time to %s pwrite %d bytes x %6d: %7.3fµs, %s\n", - c->name, object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - } - - igt_fixture { - free(src); - gem_close(fd, dst); - - close(fd); - } - - igt_exit(); -} diff --git a/tests/gem_pwrite_pread.c b/tests/gem_pwrite_pread.c deleted file mode 100644 index 88c2070e..00000000 --- a/tests/gem_pwrite_pread.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" - -#define OBJECT_SIZE 16384 - -#define COPY_BLT_CMD (2<<29|0x53<<22) -#define BLT_WRITE_ALPHA (1<<21) -#define BLT_WRITE_RGB (1<<20) -#define BLT_SRC_TILED (1<<15) -#define BLT_DST_TILED (1<<11) - -uint32_t is_64bit; -uint32_t exec_flags; - -static inline void build_batch(uint32_t *batch, int len, uint32_t *batch_len) -{ - unsigned int i = 0; - - batch[i++] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB | (is_64bit ? 8 : 6); - batch[i++] = 0xcc << 16 | 1 << 25 | 1 << 24 | len; - batch[i++] = 0; - batch[i++] = 1 << 16 | (len / 4); - batch[i++] = 0; /* dst */ - if (is_64bit) - batch[i++] = 0; - batch[i++] = 0; - batch[i++] = len; - batch[i++] = 0; /* src */ - if (is_64bit) - batch[i++] = 0; - batch[i++] = MI_BATCH_BUFFER_END; - batch[i++] = 0; - - *batch_len = i * 4; -} - -#define BUILD_EXEC \ - uint32_t batch[12]; \ - struct drm_i915_gem_relocation_entry reloc[] = { \ - { dst, 0, 4*sizeof(uint32_t), 0, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER }, \ - { src, 0, (is_64bit ? 8 : 7)*sizeof(uint32_t), 0, I915_GEM_DOMAIN_RENDER, 0 }, \ - }; \ - struct drm_i915_gem_exec_object2 exec[] = { \ - { src }, \ - { dst }, \ - { gem_create(fd, 4096), 2, (uintptr_t)reloc } \ - }; \ - struct drm_i915_gem_execbuffer2 execbuf = { \ - (uintptr_t)exec, 3, \ - 0, 0, \ - 0, 0, 0, 0, \ - exec_flags, \ - }; \ - build_batch(batch, len, &execbuf.batch_len); \ - gem_write(fd, exec[2].handle, 0, batch, execbuf.batch_len); - - -static void copy(int fd, uint32_t src, uint32_t dst, void *buf, int len, int loops) -{ - BUILD_EXEC; - - while (loops--) { - gem_write(fd, src, 0, buf, len); - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - gem_read(fd, dst, 0, buf, len); - } - - gem_close(fd, exec[2].handle); -} - -static void as_gtt_mmap(int fd, uint32_t src, uint32_t dst, void *buf, int len, int loops) -{ - uint32_t *src_ptr, *dst_ptr; - BUILD_EXEC; - - src_ptr = gem_mmap__gtt(fd, src, OBJECT_SIZE, PROT_WRITE); - dst_ptr = gem_mmap__gtt(fd, dst, OBJECT_SIZE, PROT_READ); - - while (loops--) { - gem_set_domain(fd, src, - I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - memcpy(src_ptr, buf, len); - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - gem_set_domain(fd, dst, - I915_GEM_DOMAIN_GTT, 0); - memcpy(buf, dst_ptr, len); - } - - munmap(dst_ptr, len); - munmap(src_ptr, len); - gem_close(fd, exec[2].handle); -} - - -static void as_cpu_mmap(int fd, uint32_t src, uint32_t dst, void *buf, int len, int loops) -{ - uint32_t *src_ptr, *dst_ptr; - BUILD_EXEC; - - src_ptr = gem_mmap__cpu(fd, src, 0, OBJECT_SIZE, PROT_WRITE); - dst_ptr = gem_mmap__cpu(fd, dst, 0, OBJECT_SIZE, PROT_READ); - - while (loops--) { - gem_set_domain(fd, src, - I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); - memcpy(src_ptr, buf, len); - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - gem_set_domain(fd, dst, - I915_GEM_DOMAIN_CPU, 0); - memcpy(buf, dst_ptr, len); - } - - munmap(dst_ptr, len); - munmap(src_ptr, len); - gem_close(fd, exec[2].handle); -} - -static void test_copy(int fd, uint32_t src, uint32_t dst, uint32_t *buf, int len) -{ - int i; - BUILD_EXEC; - - for (i = 0; i < len/4; i++) - buf[i] = i; - - gem_write(fd, src, 0, buf, len); - memset(buf, 0, len); - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - gem_read(fd, dst, 0, buf, len); - - gem_close(fd, exec[2].handle); - - for (i = 0; i < len/4; i++) - igt_assert(buf[i] == i); -} - -static void test_as_gtt_mmap(int fd, uint32_t src, uint32_t dst, int len) -{ - uint32_t *src_ptr, *dst_ptr; - int i; - BUILD_EXEC; - - src_ptr = gem_mmap__gtt(fd, src, OBJECT_SIZE, PROT_WRITE); - dst_ptr = gem_mmap__gtt(fd, dst, OBJECT_SIZE, PROT_READ); - - gem_set_domain(fd, src, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - for (i = 0; i < len/4; i++) - src_ptr[i] = i; - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - gem_close(fd, exec[2].handle); - - gem_set_domain(fd, dst, I915_GEM_DOMAIN_GTT, 0); - for (i = 0; i < len/4; i++) - igt_assert(dst_ptr[i] == i); - - munmap(dst_ptr, len); - munmap(src_ptr, len); -} - -static void test_as_cpu_mmap(int fd, uint32_t src, uint32_t dst, int len) -{ - uint32_t *src_ptr, *dst_ptr; - int i; - BUILD_EXEC; - - src_ptr = gem_mmap__cpu(fd, src, 0, OBJECT_SIZE, PROT_WRITE); - dst_ptr = gem_mmap__cpu(fd, dst, 0, OBJECT_SIZE, PROT_READ); - - gem_set_domain(fd, src, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); - for (i = 0; i < len/4; i++) - src_ptr[i] = i; - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)); - gem_close(fd, exec[2].handle); - - gem_set_domain(fd, dst, I915_GEM_DOMAIN_CPU, 0); - for (i = 0; i < len/4; i++) - igt_assert(dst_ptr[i] == i); - - munmap(dst_ptr, len); - munmap(src_ptr, len); -} - -static double elapsed(const struct timeval *start, - const struct timeval *end, - int loop) -{ - return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec))/loop; -} - -static const char *bytes_per_sec(char *buf, double v) -{ - const char *order[] = { - "", - "KiB", - "MiB", - "GiB", - "TiB", - NULL, - }, **o = order; - - while (v > 1000 && o[1]) { - v /= 1000; - o++; - } - sprintf(buf, "%.1f%s/s", v, *o); - return buf; -} - -uint32_t *tmp, src, dst; -int fd; - -int main(int argc, char **argv) -{ - int object_size = 0; - uint32_t buf[20]; - int count; - - igt_subtest_init(argc, argv); - igt_skip_on_simulation(); - - if (argc > 1) - object_size = atoi(argv[1]); - if (object_size == 0) - object_size = OBJECT_SIZE; - object_size = (object_size + 3) & -4; - - igt_fixture { - uint32_t devid; - - fd = drm_open_any(); - - dst = gem_create(fd, object_size); - src = gem_create(fd, object_size); - tmp = malloc(object_size); - - gem_set_caching(fd, src, 0); - gem_set_caching(fd, dst, 0); - - devid = intel_get_drm_devid(fd); - is_64bit = intel_gen(devid) >= 8; - exec_flags = HAS_BLT_RING(devid) ? I915_EXEC_BLT : 0; - } - - igt_subtest("uncached-copy-correctness") - test_copy(fd, src, dst, tmp, object_size); - igt_subtest("uncached-copy-performance") { - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - copy(fd, src, dst, tmp, object_size, count); - gettimeofday(&end, NULL); - igt_info("Time to uncached copy %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - - igt_subtest("uncached-pwrite-blt-gtt_mmap-correctness") - test_as_gtt_mmap(fd, src, dst, object_size); - igt_subtest("uncached-pwrite-blt-gtt_mmap-performance") { - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - as_gtt_mmap(fd, src, dst, tmp, object_size, count); - gettimeofday(&end, NULL); - igt_info("** mmap uncached copy %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - - igt_fixture { - gem_set_caching(fd, src, 1); - gem_set_caching(fd, dst, 1); - } - - igt_subtest("snooped-copy-correctness") - test_copy(fd, src, dst, tmp, object_size); - igt_subtest("snooped-copy-performance") { - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - copy(fd, src, dst, tmp, object_size, count); - gettimeofday(&end, NULL); - igt_info("Time to snooped copy %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - - igt_subtest("snooped-pwrite-blt-cpu_mmap-correctness") - test_as_cpu_mmap(fd, src, dst, object_size); - igt_subtest("snooped-pwrite-blt-cpu_mmap-performance") { - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - as_cpu_mmap(fd, src, dst, tmp, object_size, count); - gettimeofday(&end, NULL); - igt_info("** mmap snooped copy %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - - igt_fixture { - gem_set_caching(fd, src, 2); - gem_set_caching(fd, dst, 2); - } - - igt_subtest("display-copy-correctness") - test_copy(fd, src, dst, tmp, object_size); - igt_subtest("display-copy-performance") { - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - copy(fd, src, dst, tmp, object_size, count); - gettimeofday(&end, NULL); - igt_info("Time to display copy %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - - igt_subtest("display-pwrite-blt-gtt_mmap-correctness") - test_as_gtt_mmap(fd, src, dst, object_size); - igt_subtest("display-pwrite-blt-gtt_mmap-performance") { - for (count = 1; count <= 1<<17; count <<= 1) { - struct timeval start, end; - - gettimeofday(&start, NULL); - as_gtt_mmap(fd, src, dst, tmp, object_size, count); - gettimeofday(&end, NULL); - igt_info("** mmap display copy %d bytes x %6d: %7.3fµs, %s\n", - object_size, count, - elapsed(&start, &end, count), - bytes_per_sec((char *)buf, object_size/elapsed(&start, &end, count)*1e6)); - fflush(stdout); - } - } - - igt_fixture { - free(tmp); - gem_close(fd, src); - gem_close(fd, dst); - - close(fd); - } - - igt_exit(); -} diff --git a/tests/gem_readwrite.c b/tests/gem_readwrite.c deleted file mode 100644 index a8a7105e..00000000 --- a/tests/gem_readwrite.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright © 2008 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: - * Eric Anholt <eric@anholt.net> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" - -#define OBJECT_SIZE 16384 - -static int -do_read(int fd, int handle, void *buf, int offset, int size) -{ - struct drm_i915_gem_pread gem_pread; - - /* Ensure that we don't have any convenient data in buf in case - * we fail. - */ - memset(buf, 0xd0, size); - - memset(&gem_pread, 0, sizeof(gem_pread)); - gem_pread.handle = handle; - gem_pread.data_ptr = (uintptr_t)buf; - gem_pread.size = size; - gem_pread.offset = offset; - - return ioctl(fd, DRM_IOCTL_I915_GEM_PREAD, &gem_pread); -} - -static int -do_write(int fd, int handle, void *buf, int offset, int size) -{ - struct drm_i915_gem_pwrite gem_pwrite; - - memset(&gem_pwrite, 0, sizeof(gem_pwrite)); - gem_pwrite.handle = handle; - gem_pwrite.data_ptr = (uintptr_t)buf; - gem_pwrite.size = size; - gem_pwrite.offset = offset; - - return ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &gem_pwrite); -} - -int fd; -uint32_t handle; - -igt_main -{ - uint8_t expected[OBJECT_SIZE]; - uint8_t buf[OBJECT_SIZE]; - int ret; - - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - - handle = gem_create(fd, OBJECT_SIZE); - } - - igt_subtest("new-obj") { - igt_info("Testing contents of newly created object.\n"); - ret = do_read(fd, handle, buf, 0, OBJECT_SIZE); - igt_assert(ret == 0); - memset(&expected, 0, sizeof(expected)); - igt_assert(memcmp(expected, buf, sizeof(expected)) == 0); - } - - igt_subtest("beyond-EOB") { - igt_info("Testing read beyond end of buffer.\n"); - ret = do_read(fd, handle, buf, OBJECT_SIZE / 2, OBJECT_SIZE); - igt_assert(ret == -1 && errno == EINVAL); - } - - igt_subtest("read-write") { - igt_info("Testing full write of buffer\n"); - memset(buf, 0, sizeof(buf)); - memset(buf + 1024, 0x01, 1024); - memset(expected + 1024, 0x01, 1024); - ret = do_write(fd, handle, buf, 0, OBJECT_SIZE); - igt_assert(ret == 0); - ret = do_read(fd, handle, buf, 0, OBJECT_SIZE); - igt_assert(ret == 0); - igt_assert(memcmp(buf, expected, sizeof(buf)) == 0); - - igt_info("Testing partial write of buffer\n"); - memset(buf + 4096, 0x02, 1024); - memset(expected + 4096, 0x02, 1024); - ret = do_write(fd, handle, buf + 4096, 4096, 1024); - igt_assert(ret == 0); - ret = do_read(fd, handle, buf, 0, OBJECT_SIZE); - igt_assert(ret == 0); - igt_assert(memcmp(buf, expected, sizeof(buf)) == 0); - - igt_info("Testing partial read of buffer\n"); - ret = do_read(fd, handle, buf, 512, 1024); - igt_assert(ret == 0); - igt_assert(memcmp(buf, expected + 512, 1024) == 0); - } - - igt_subtest("read-bad-handle") { - igt_info("Testing read of bad buffer handle\n"); - ret = do_read(fd, 1234, buf, 0, 1024); - igt_assert(ret == -1 && errno == ENOENT); - } - - igt_subtest("write-bad-handle") { - igt_info("Testing write of bad buffer handle\n"); - ret = do_write(fd, 1234, buf, 0, 1024); - igt_assert(ret == -1 && errno == ENOENT); - } - - igt_fixture - close(fd); -} diff --git a/tests/gem_reg_read.c b/tests/gem_reg_read.c deleted file mode 100644 index d3e68d9f..00000000 --- a/tests/gem_reg_read.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright © 2012 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: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" - -struct local_drm_i915_reg_read { - __u64 offset; - __u64 val; /* Return value */ -}; - -#define REG_READ_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x31, struct local_drm_i915_reg_read) - -static uint64_t timer_query(int fd) -{ - struct local_drm_i915_reg_read reg_read; - - reg_read.offset = 0x2358; - igt_fail_on_f(drmIoctl(fd, REG_READ_IOCTL, ®_read), - "positive test case failed: "); - - return reg_read.val; -} - -igt_simple_main -{ - struct local_drm_i915_reg_read reg_read; - int fd, ret; - - fd = drm_open_any(); - - reg_read.offset = 0x2358; - ret = drmIoctl(fd, REG_READ_IOCTL, ®_read); - igt_assert(ret == 0 || errno == EINVAL); - igt_require(ret == 0); - - reg_read.val = timer_query(fd); - sleep(1); - /* Check that timer is moving and isn't busted. */ - igt_assert(timer_query(fd) != reg_read.val); - - /* bad reg */ - reg_read.offset = 0x12345678; - ret = drmIoctl(fd, REG_READ_IOCTL, ®_read); - - igt_assert(ret != 0 && errno == EINVAL); - - close(fd); -} diff --git a/tests/gem_reloc_overflow.c b/tests/gem_reloc_overflow.c deleted file mode 100644 index ea591711..00000000 --- a/tests/gem_reloc_overflow.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright © 2013 Google - * 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: - * Kees Cook <keescook@chromium.org> - * Daniel Vetter <daniel.vetter@ffwll.ch> - * Rafael Barbalho <rafael.barbalho@intel.com> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <unistd.h> -#include <malloc.h> -#include <limits.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "intel_chipset.h" -#include "drmtest.h" -#include "intel_io.h" - -IGT_TEST_DESCRIPTION("Check that kernel relocation overflows are caught."); - -/* - * Testcase: Kernel relocation overflows are caught. - */ - -int fd, entries, num; -size_t reloc_size; -uint32_t *handles; -struct drm_i915_gem_exec_object2 *execobjs; -struct drm_i915_gem_execbuffer2 execbuf = { 0 }; -struct drm_i915_gem_relocation_entry *reloc; - -uint32_t handle; -uint32_t batch_handle; - -static void source_offset_tests(int devid, bool reloc_gtt) -{ - struct drm_i915_gem_relocation_entry single_reloc; - void *dst_gtt; - const char *relocation_type; - - if (reloc_gtt) - relocation_type = "reloc-gtt"; - else - relocation_type = "reloc-cpu"; - - igt_fixture { - handle = gem_create(fd, 8192); - - execobjs[1].handle = batch_handle; - execobjs[1].relocation_count = 0; - execobjs[1].relocs_ptr = 0; - - execobjs[0].handle = handle; - execobjs[0].relocation_count = 1; - execobjs[0].relocs_ptr = (uintptr_t) &single_reloc; - execbuf.buffer_count = 2; - - if (reloc_gtt) { - dst_gtt = gem_mmap(fd, handle, 8192, PROT_READ | PROT_WRITE); - igt_assert(dst_gtt != MAP_FAILED); - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - memset(dst_gtt, 0, 8192); - munmap(dst_gtt, 8192); - relocation_type = "reloc-gtt"; - } else { - relocation_type = "reloc-cpu"; - } - } - - /* Special tests for 64b relocs. */ - igt_subtest_f("source-offset-page-stradle-gen8-%s", relocation_type) { - igt_require(intel_gen(devid) >= 8); - single_reloc.offset = 4096 - 4; - single_reloc.delta = 0; - single_reloc.target_handle = handle; - single_reloc.read_domains = I915_GEM_DOMAIN_RENDER; - single_reloc.write_domain = I915_GEM_DOMAIN_RENDER; - single_reloc.presumed_offset = 0; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) == 0); - single_reloc.delta = 1024; - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) == 0); - } - - igt_subtest_f("source-offset-end-gen8-%s", relocation_type) { - igt_require(intel_gen(devid) >= 8); - single_reloc.offset = 8192 - 8; - single_reloc.delta = 0; - single_reloc.target_handle = handle; - single_reloc.read_domains = I915_GEM_DOMAIN_RENDER; - single_reloc.write_domain = I915_GEM_DOMAIN_RENDER; - single_reloc.presumed_offset = 0; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) == 0); - } - - igt_subtest_f("source-offset-overflow-gen8-%s", relocation_type) { - igt_require(intel_gen(devid) >= 8); - single_reloc.offset = 8192 - 4; - single_reloc.delta = 0; - single_reloc.target_handle = handle; - single_reloc.read_domains = I915_GEM_DOMAIN_RENDER; - single_reloc.write_domain = I915_GEM_DOMAIN_RENDER; - single_reloc.presumed_offset = 0; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) != 0); - igt_assert(errno == EINVAL); - } - - /* Tests for old 4byte relocs on pre-gen8. */ - igt_subtest_f("source-offset-end-%s", relocation_type) { - igt_require(intel_gen(devid) < 8); - single_reloc.offset = 8192 - 4; - single_reloc.delta = 0; - single_reloc.target_handle = handle; - single_reloc.read_domains = I915_GEM_DOMAIN_RENDER; - single_reloc.write_domain = I915_GEM_DOMAIN_RENDER; - single_reloc.presumed_offset = 0; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) == 0); - } - - igt_subtest_f("source-offset-big-%s", relocation_type) { - single_reloc.offset = 8192; - single_reloc.delta = 0; - single_reloc.target_handle = handle; - single_reloc.read_domains = I915_GEM_DOMAIN_RENDER; - single_reloc.write_domain = I915_GEM_DOMAIN_RENDER; - single_reloc.presumed_offset = 0; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) != 0); - igt_assert(errno == EINVAL); - } - - igt_subtest_f("source-offset-negative-%s", relocation_type) { - single_reloc.offset = (int64_t) -4; - single_reloc.delta = 0; - single_reloc.target_handle = handle; - single_reloc.read_domains = I915_GEM_DOMAIN_RENDER; - single_reloc.write_domain = I915_GEM_DOMAIN_RENDER; - single_reloc.presumed_offset = 0; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) != 0); - igt_assert(errno == EINVAL); - } - - igt_subtest_f("source-offset-unaligned-%s", relocation_type) { - single_reloc.offset = 1; - single_reloc.delta = 0; - single_reloc.target_handle = handle; - single_reloc.read_domains = I915_GEM_DOMAIN_RENDER; - single_reloc.write_domain = I915_GEM_DOMAIN_RENDER; - single_reloc.presumed_offset = 0; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) != 0); - igt_assert(errno == EINVAL); - } - - igt_fixture { - gem_close(fd, handle); - } -} - -static void reloc_tests(void) -{ - int i; - unsigned int total_unsigned = 0; - - igt_subtest("invalid-address") { - /* Attempt unmapped single entry. */ - execobjs[0].relocation_count = 1; - execobjs[0].relocs_ptr = 0; - execbuf.buffer_count = 1; - - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - igt_assert(errno == EFAULT); - } - - igt_subtest("single-overflow") { - /* Attempt single overflowed entry. */ - execobjs[0].relocation_count = (1 << 31); - execobjs[0].relocs_ptr = (uintptr_t)reloc; - execbuf.buffer_count = 1; - - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - igt_assert(errno == EINVAL); - } - - igt_fixture { - execobjs[0].handle = batch_handle; - execobjs[0].relocation_count = 0; - execobjs[0].relocs_ptr = 0; - - execbuf.buffer_count = 1; - - /* Make sure the batch would succeed except for the thing we're - * testing. */ - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) == 0); - } - - igt_subtest("batch-start-unaligned") { - execbuf.batch_start_offset = 1; - execbuf.batch_len = 8; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) != 0); - igt_assert(errno == EINVAL); - } - - igt_subtest("batch-end-unaligned") { - execbuf.batch_start_offset = 0; - execbuf.batch_len = 7; - - igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) != 0); - igt_assert(errno == EINVAL); - } - - igt_fixture { - /* Undo damage for next tests. */ - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - } - - igt_subtest("wrapped-overflow") { - /* Attempt wrapped overflow entries. */ - for (i = 0; i < num; i++) { - struct drm_i915_gem_exec_object2 *obj = &execobjs[i]; - obj->handle = handles[i]; - - if (i == num - 1) { - /* Wraps to 1 on last count. */ - obj->relocation_count = 1 - total_unsigned; - obj->relocs_ptr = (uintptr_t)reloc; - } else { - obj->relocation_count = entries; - obj->relocs_ptr = (uintptr_t)reloc; - } - - total_unsigned += obj->relocation_count; - } - execbuf.buffer_count = num; - - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - igt_assert(errno == EINVAL); - } -} - -static void buffer_count_tests(void) -{ - igt_subtest("buffercount-overflow") { - for (int i = 0; i < num; i++) { - execobjs[i].relocation_count = 0; - execobjs[i].relocs_ptr = 0; - execobjs[i].handle = handles[i]; - } - - execobjs[0].relocation_count = 0; - execobjs[0].relocs_ptr = 0; - /* We only have num buffers actually, but the overflow will make - * sure we blow up the kernel before we blow up userspace. */ - execbuf.buffer_count = num; - - /* Put a real batch at the end. */ - execobjs[num - 1].handle = batch_handle; - - /* Make sure the basic thing would work first ... */ - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - igt_assert(errno == 0); - - /* ... then be evil: Overflow of the pointer table (which has a - * bit of lead datastructures, so no + 1 needed to overflow). */ - execbuf.buffer_count = INT_MAX / sizeof(void *); - - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - igt_assert(errno == EINVAL); - - /* ... then be evil: Copying/allocating the array. */ - execbuf.buffer_count = UINT_MAX / sizeof(execobjs[0]) + 1; - - errno = 0; - ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - igt_assert(errno == EINVAL); - } -} - -igt_main -{ - int devid = 0; - - igt_fixture { - int ring; - uint32_t batch_data [2] = { MI_NOOP, MI_BATCH_BUFFER_END }; - - fd = drm_open_any(); - - devid = intel_get_drm_devid(fd); - - /* Create giant reloc buffer area. */ - num = 257; - entries = ((1ULL << 32) / (num - 1)); - reloc_size = entries * sizeof(struct drm_i915_gem_relocation_entry); - reloc = mmap(NULL, reloc_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); - igt_assert(reloc != MAP_FAILED); - - /* Allocate the handles we'll need to wrap. */ - handles = calloc(num, sizeof(*handles)); - for (int i = 0; i < num; i++) - handles[i] = gem_create(fd, 4096); - - if (intel_gen(devid) >= 6) - ring = I915_EXEC_BLT; - else - ring = 0; - - /* Create relocation objects. */ - execobjs = calloc(num, sizeof(*execobjs)); - execbuf.buffers_ptr = (uintptr_t)execobjs; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - batch_handle = gem_create(fd, 4096); - - gem_write(fd, batch_handle, 0, batch_data, sizeof(batch_data)); - } - - reloc_tests(); - - source_offset_tests(devid, false); - source_offset_tests(devid, true); - - buffer_count_tests(); - - igt_fixture { - gem_close(fd, batch_handle); - close(fd); - } -} diff --git a/tests/gem_reloc_vs_gpu.c b/tests/gem_reloc_vs_gpu.c deleted file mode 100644 index 79f182b4..00000000 --- a/tests/gem_reloc_vs_gpu.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright © 2011,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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#define _GNU_SOURCE -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <signal.h> -#include <sys/wait.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_debugfs.h" -#include "igt_aux.h" -#include "igt_gt.h" - -IGT_TEST_DESCRIPTION("Test kernel relocations vs. gpu races."); - -/* - * Testcase: Kernel relocations vs. gpu races - * - */ - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -uint32_t blob[2048*2048]; -#define NUM_TARGET_BOS 16 -drm_intel_bo *pc_target_bo[NUM_TARGET_BOS]; -drm_intel_bo *dummy_bo; -drm_intel_bo *special_bo; -uint32_t devid; -int special_reloc_ofs; -int special_batch_len; - -static void create_special_bo(void) -{ - uint32_t data[1024]; - int len = 0; - int small_pitch = 64; -#define BATCH(dw) data[len++] = (dw); - - memset(data, 0, 4096); - special_bo = drm_intel_bo_alloc(bufmgr, "special batch", 4096, 4096); - - if (intel_gen(devid) >= 8) { - BATCH(MI_NOOP); - BATCH(XY_COLOR_BLT_CMD_NOLEN | 5 | - COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); - } else { - BATCH(XY_COLOR_BLT_CMD_NOLEN | 4 | - COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); - } - - BATCH((3 << 24) | (0xf0 << 16) | small_pitch); - BATCH(0); - BATCH(1 << 16 | 1); - special_reloc_ofs = 4*len; - BATCH(0); - if (intel_gen(devid) >= 8) - BATCH(0); - BATCH(0xdeadbeef); - -#define CMD_POLY_STIPPLE_OFFSET 0x7906 - /* batchbuffer end */ - if (IS_GEN5(batch->devid)) { - BATCH(CMD_POLY_STIPPLE_OFFSET << 16); - BATCH(0); - } - igt_assert(len % 2 == 0); - BATCH(MI_NOOP); - BATCH(MI_BATCH_BUFFER_END); - - drm_intel_bo_subdata(special_bo, 0, 4096, data); - special_batch_len = len*4; -} - -static void emit_dummy_load(int pitch) -{ - int i; - uint32_t tile_flags = 0; - - if (IS_965(devid)) { - pitch /= 4; - tile_flags = XY_SRC_COPY_BLT_SRC_TILED | - XY_SRC_COPY_BLT_DST_TILED; - } - - for (i = 0; i < 10; i++) { - BLIT_COPY_BATCH_START(tile_flags); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - pitch); - OUT_BATCH(0 << 16 | 1024); - OUT_BATCH((2048) << 16 | (2048)); - OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(pitch); - OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 6) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } - } - intel_batchbuffer_flush(batch); -} - -static void reloc_and_emit(int fd, drm_intel_bo *target_bo, bool faulting_reloc) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec[2]; - struct drm_i915_gem_relocation_entry reloc[1]; - uint32_t handle_relocs; - void *gtt_relocs; - - memset(&execbuf, 0, sizeof(execbuf)); - memset(exec, 0, sizeof(exec)); - memset(reloc, 0, sizeof(reloc)); - - exec[0].handle = target_bo->handle; - - reloc[0].offset = special_reloc_ofs; - reloc[0].target_handle = target_bo->handle; - reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; - /* We do not track the last patched value, so force the relocation - * every time. - */ - reloc[0].presumed_offset = -1; - - handle_relocs = gem_create(fd, 4096); - gem_write(fd, handle_relocs, 0, reloc, sizeof(reloc)); - gtt_relocs = gem_mmap(fd, handle_relocs, 4096, - PROT_READ | PROT_WRITE); - igt_assert(gtt_relocs); - - exec[1].handle = special_bo->handle; - exec[1].relocation_count = 1; - /* A newly mmap gtt bo will fault on first access. */ - if (faulting_reloc) - exec[1].relocs_ptr = (uintptr_t)gtt_relocs; - else - exec[1].relocs_ptr = (uintptr_t)reloc; - - execbuf.buffers_ptr = (uintptr_t)exec; - execbuf.buffer_count = 2; - execbuf.batch_len = special_batch_len; - if (intel_gen(devid) >= 6) - execbuf.flags |= I915_EXEC_BLT; - - gem_execbuf(fd, &execbuf); - - gem_close(fd, handle_relocs); -} - -static struct igt_hang_ring no_hang(int fd) -{ - return (struct igt_hang_ring){0}; -} - -static struct igt_hang_ring bcs_hang(int fd) -{ - return igt_hang_ring(fd, I915_EXEC_BLT); -} - -static void do_test(int fd, bool faulting_reloc, - struct igt_hang_ring (*do_hang)(int fd)) -{ - uint32_t tiling_mode = I915_TILING_X; - unsigned long pitch, act_size; - uint32_t test; - int i; - - if (faulting_reloc) - igt_disable_prefault(); - - act_size = 2048; - dummy_bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled dummy_bo", act_size, act_size, - 4, &tiling_mode, &pitch, 0); - - drm_intel_bo_subdata(dummy_bo, 0, act_size*act_size*4, blob); - - create_special_bo(); - - for (i = 0; i < NUM_TARGET_BOS; i++) { - struct igt_hang_ring hang; - - pc_target_bo[i] = drm_intel_bo_alloc(bufmgr, "special batch", 4096, 4096); - emit_dummy_load(pitch); - igt_assert(pc_target_bo[i]->offset == 0); - hang = do_hang(fd); - - reloc_and_emit(fd, pc_target_bo[i], faulting_reloc); - - igt_post_hang_ring(fd, hang); - } - - /* Only check at the end to avoid unnecessary synchronous behaviour. */ - for (i = 0; i < NUM_TARGET_BOS; i++) { - drm_intel_bo_get_subdata(pc_target_bo[i], 0, 4, &test); - igt_assert_f(test == 0xdeadbeef, - "mismatch in buffer %i: 0x%08x instead of 0xdeadbeef\n", i, test); - drm_intel_bo_unreference(pc_target_bo[i]); - } - - drm_intel_gem_bo_map_gtt(dummy_bo); - drm_intel_gem_bo_unmap_gtt(dummy_bo); - - drm_intel_bo_unreference(special_bo); - drm_intel_bo_unreference(dummy_bo); - - if (faulting_reloc) - igt_enable_prefault(); -} - -#define INTERRUPT (1 << 0) -#define FAULTING (1 << 1) -#define THRASH (1 << 2) -#define THRASH_INACTIVE (1 << 3) -#define HANG (1 << 4) -#define ALL_FLAGS (HANG | INTERRUPT | FAULTING | THRASH | THRASH_INACTIVE) -static void do_forked_test(int fd, unsigned flags) -{ - int num_threads = sysconf(_SC_NPROCESSORS_ONLN); - struct igt_helper_process thrasher = {}; - - if (flags & HANG) - igt_require_hang_ring(fd, I915_EXEC_BLT); - - if (flags & (THRASH | THRASH_INACTIVE)) { - uint64_t val = (flags & THRASH_INACTIVE) ? - (DROP_RETIRE | DROP_BOUND | DROP_UNBOUND) : DROP_ALL; - - igt_fork_helper(&thrasher) { - while (1) { - usleep(1000); - igt_drop_caches_set(val); - } - } - } - - igt_fork(i, num_threads * 4) { - /* re-create process local data */ - fd = drm_open_any(); - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - if (flags & INTERRUPT) - igt_fork_signal_helper(); - - do_test(fd, flags & FAULTING, flags & HANG ? bcs_hang : no_hang); - - if (flags & INTERRUPT) - igt_stop_signal_helper(); - } - - igt_waitchildren(); - if (flags & (THRASH | THRASH_INACTIVE)) - igt_stop_helper(&thrasher); -} - -int fd; - -#define MAX_BLT_SIZE 128 -igt_main -{ - igt_skip_on_simulation(); - - memset(blob, 'A', sizeof(blob)); - - igt_fixture { - fd = drm_open_any(); - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - /* disable reuse, otherwise the test fails */ - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - devid = intel_get_drm_devid(fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - } - - igt_subtest("normal") - do_test(fd, false, no_hang); - - igt_subtest("faulting-reloc") - do_test(fd, true, no_hang); - - igt_fork_signal_helper(); - igt_subtest("interruptible") - do_test(fd, false, no_hang); - - igt_subtest("interruptible-hang") { - igt_require_hang_ring(fd, I915_EXEC_BLT); - do_test(fd, false, bcs_hang); - } - - igt_subtest("faulting-reloc-interruptible") - do_test(fd, true, no_hang); - - igt_subtest("faulting-reloc-interruptible-hang") { - igt_require_hang_ring(fd, I915_EXEC_BLT); - do_test(fd, true, bcs_hang); - } - igt_stop_signal_helper(); - - for (unsigned flags = 0; flags <= ALL_FLAGS; flags++) { - if ((flags & THRASH) && (flags & THRASH_INACTIVE)) - continue; - - igt_subtest_f("forked%s%s%s%s%s", - flags & INTERRUPT ? "-interruptible" : "", - flags & FAULTING ? "-faulting-reloc" : "", - flags & THRASH ? "-thrashing" : "", - flags & THRASH_INACTIVE ? "-thrash-inactive" : "", - flags & HANG ? "-hang": "") - do_forked_test(fd, flags); - } - - igt_fixture { - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_render_copy.c b/tests/gem_render_copy.c deleted file mode 100644 index df1ac881..00000000 --- a/tests/gem_render_copy.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * 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: - * Damien Lespiau <damien.lespiau@intel.com> - */ - -/* - * This file is a basic test for the render_copy() function, a very simple - * workload for the 3D engine. - */ - -#include <stdbool.h> -#include <unistd.h> -#include <cairo.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Basic test for the render_copy() function."); - -#define WIDTH 512 -#define STRIDE (WIDTH*4) -#define HEIGHT 512 -#define SIZE (HEIGHT*STRIDE) - -#define SRC_COLOR 0xffff00ff -#define DST_COLOR 0xfff0ff00 - -typedef struct { - int drm_fd; - uint32_t devid; - drm_intel_bufmgr *bufmgr; - uint32_t linear[WIDTH * HEIGHT]; -} data_t; -static int opt_dump_png = false; -static int check_all_pixels = false; - -static void scratch_buf_write_to_png(struct igt_buf *buf, const char *filename) -{ - cairo_surface_t *surface; - cairo_status_t ret; - - drm_intel_bo_map(buf->bo, 0); - surface = cairo_image_surface_create_for_data(buf->bo->virtual, - CAIRO_FORMAT_RGB24, - igt_buf_width(buf), - igt_buf_height(buf), - buf->stride); - ret = cairo_surface_write_to_png(surface, filename); - igt_assert(ret == CAIRO_STATUS_SUCCESS); - cairo_surface_destroy(surface); - drm_intel_bo_unmap(buf->bo); -} - -static void scratch_buf_init(data_t *data, struct igt_buf *buf, - int width, int height, int stride, uint32_t color) -{ - drm_intel_bo *bo; - int i; - - bo = drm_intel_bo_alloc(data->bufmgr, "", SIZE, 4096); - for (i = 0; i < width * height; i++) - data->linear[i] = color; - gem_write(data->drm_fd, bo->handle, 0, data->linear, - sizeof(data->linear)); - - buf->bo = bo; - buf->stride = stride; - buf->tiling = I915_TILING_NONE; - buf->size = SIZE; -} - -static void -scratch_buf_check(data_t *data, struct igt_buf *buf, int x, int y, - uint32_t color) -{ - uint32_t val; - - gem_read(data->drm_fd, buf->bo->handle, 0, - data->linear, sizeof(data->linear)); - val = data->linear[y * WIDTH + x]; - igt_assert_f(val == color, - "Expected 0x%08x, found 0x%08x at (%d,%d)\n", - color, val, x, y); -} - -static int opt_handler(int opt, int opt_index) -{ - if (opt == 'd') { - opt_dump_png = true; - } - - if (opt == 'a') { - check_all_pixels = true; - } - - return 0; -} - -int main(int argc, char **argv) -{ - data_t data = {0, }; - struct intel_batchbuffer *batch = NULL; - struct igt_buf src, dst; - igt_render_copyfunc_t render_copy = NULL; - int opt_dump_aub = igt_aub_dump_enabled(); - - igt_simple_init_parse_opts(&argc, argv, "da", NULL, NULL, opt_handler); - - igt_fixture { - data.drm_fd = drm_open_any_render(); - data.devid = intel_get_drm_devid(data.drm_fd); - - data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096); - igt_assert(data.bufmgr); - - render_copy = igt_get_render_copyfunc(data.devid); - igt_require_f(render_copy, - "no render-copy function\n"); - - batch = intel_batchbuffer_alloc(data.bufmgr, data.devid); - igt_assert(batch); - } - - scratch_buf_init(&data, &src, WIDTH, HEIGHT, STRIDE, SRC_COLOR); - scratch_buf_init(&data, &dst, WIDTH, HEIGHT, STRIDE, DST_COLOR); - - scratch_buf_check(&data, &src, WIDTH / 2, HEIGHT / 2, SRC_COLOR); - scratch_buf_check(&data, &dst, WIDTH / 2, HEIGHT / 2, DST_COLOR); - - if (opt_dump_png) { - scratch_buf_write_to_png(&src, "source.png"); - scratch_buf_write_to_png(&dst, "destination.png"); - } - - if (opt_dump_aub) { - drm_intel_bufmgr_gem_set_aub_filename(data.bufmgr, - "rendercopy.aub"); - drm_intel_bufmgr_gem_set_aub_dump(data.bufmgr, true); - } - - /* This will copy the src to the mid point of the dst buffer. Presumably - * the out of bounds accesses will get clipped. - * Resulting buffer should look like: - * _______ - * |dst|dst| - * |dst|src| - * ------- - */ - render_copy(batch, NULL, - &src, 0, 0, WIDTH, HEIGHT, - &dst, WIDTH / 2, HEIGHT / 2); - - if (opt_dump_png) - scratch_buf_write_to_png(&dst, "result.png"); - - if (opt_dump_aub) { - drm_intel_gem_bo_aub_dump_bmp(dst.bo, - 0, 0, WIDTH, HEIGHT, - AUB_DUMP_BMP_FORMAT_ARGB_8888, - STRIDE, 0); - drm_intel_bufmgr_gem_set_aub_dump(data.bufmgr, false); - } else if (check_all_pixels) { - uint32_t val; - int i, j; - gem_read(data.drm_fd, dst.bo->handle, 0, - data.linear, sizeof(data.linear)); - for (i = 0; i < WIDTH; i++) { - for (j = 0; j < HEIGHT; j++) { - uint32_t color = DST_COLOR; - val = data.linear[j * WIDTH + i]; - if (j >= HEIGHT/2 && i >= WIDTH/2) - color = SRC_COLOR; - - igt_assert_f(val == color, - "Expected 0x%08x, found 0x%08x at (%d,%d)\n", - color, val, i, j); - } - } - } else { - scratch_buf_check(&data, &dst, 10, 10, DST_COLOR); - scratch_buf_check(&data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR); - } - - igt_exit(); -} diff --git a/tests/gem_render_copy_redux.c b/tests/gem_render_copy_redux.c deleted file mode 100644 index 43d4c5af..00000000 --- a/tests/gem_render_copy_redux.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright © 2013-2014 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: - * Damien Lespiau <damien.lespiau@intel.com> - */ - -/* - * This file is an "advanced" test for the render_copy() function, a very simple - * workload for the 3D engine. The basic test in gem_render_copy.c is intentionally - * kept extremely simple to allow for aub instrumentation and to ease debugging of - * the render copy functions themselves. This test on the overhand aims to stress - * the execbuffer interface with a simple render workload. - */ - -#include <stdbool.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Advanced test for the render_copy() function."); - -#define WIDTH 512 -#define STRIDE (WIDTH*4) -#define HEIGHT 512 -#define SIZE (HEIGHT*STRIDE) - -#define SRC_COLOR 0xffff00ff -#define DST_COLOR 0xfff0ff00 - -typedef struct { - int fd; - uint32_t devid; - drm_intel_bufmgr *bufmgr; - struct intel_batchbuffer *batch; - igt_render_copyfunc_t render_copy; - uint32_t linear[WIDTH * HEIGHT]; -} data_t; - -static void data_init(data_t *data) -{ - data->fd = drm_open_any(); - data->devid = intel_get_drm_devid(data->fd); - - data->bufmgr = drm_intel_bufmgr_gem_init(data->fd, 4096); - igt_assert(data->bufmgr); - - data->render_copy = igt_get_render_copyfunc(data->devid); - igt_require_f(data->render_copy, - "no render-copy function\n"); - - data->batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(data->batch); -} - -static void data_fini(data_t *data) -{ - intel_batchbuffer_free(data->batch); - drm_intel_bufmgr_destroy(data->bufmgr); - close(data->fd); -} - -static void scratch_buf_init(data_t *data, struct igt_buf *buf, - int width, int height, int stride, uint32_t color) -{ - drm_intel_bo *bo; - int i; - - bo = drm_intel_bo_alloc(data->bufmgr, "", SIZE, 4096); - for (i = 0; i < width * height; i++) - data->linear[i] = color; - gem_write(data->fd, bo->handle, 0, data->linear, - sizeof(data->linear)); - - buf->bo = bo; - buf->stride = stride; - buf->tiling = I915_TILING_NONE; - buf->size = SIZE; -} - -static void scratch_buf_fini(data_t *data, struct igt_buf *buf) -{ - dri_bo_unreference(buf->bo); - memset(buf, 0, sizeof(*buf)); -} - -static void -scratch_buf_check(data_t *data, struct igt_buf *buf, int x, int y, - uint32_t color) -{ - uint32_t val; - - gem_read(data->fd, buf->bo->handle, 0, - data->linear, sizeof(data->linear)); - val = data->linear[y * WIDTH + x]; - igt_assert_f(val == color, - "Expected 0x%08x, found 0x%08x at (%d,%d)\n", - color, val, x, y); -} - -static void copy(data_t *data) -{ - struct igt_buf src, dst; - - scratch_buf_init(data, &src, WIDTH, HEIGHT, STRIDE, SRC_COLOR); - scratch_buf_init(data, &dst, WIDTH, HEIGHT, STRIDE, DST_COLOR); - - scratch_buf_check(data, &src, WIDTH / 2, HEIGHT / 2, SRC_COLOR); - scratch_buf_check(data, &dst, WIDTH / 2, HEIGHT / 2, DST_COLOR); - - data->render_copy(data->batch, NULL, - &src, 0, 0, WIDTH, HEIGHT, - &dst, WIDTH / 2, HEIGHT / 2); - - scratch_buf_check(data, &dst, 10, 10, DST_COLOR); - scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR); - - scratch_buf_fini(data, &src); - scratch_buf_fini(data, &dst); -} - -static void copy_flink(data_t *data) -{ - data_t local; - struct igt_buf src, dst; - struct igt_buf local_src, local_dst; - struct igt_buf flink; - uint32_t name; - - data_init(&local); - - scratch_buf_init(data, &src, WIDTH, HEIGHT, STRIDE, 0); - scratch_buf_init(data, &dst, WIDTH, HEIGHT, STRIDE, DST_COLOR); - - data->render_copy(data->batch, NULL, - &src, 0, 0, WIDTH, HEIGHT, - &dst, WIDTH, HEIGHT); - - scratch_buf_init(&local, &local_src, WIDTH, HEIGHT, STRIDE, 0); - scratch_buf_init(&local, &local_dst, WIDTH, HEIGHT, STRIDE, SRC_COLOR); - - local.render_copy(local.batch, NULL, - &local_src, 0, 0, WIDTH, HEIGHT, - &local_dst, WIDTH, HEIGHT); - - - drm_intel_bo_flink(local_dst.bo, &name); - flink = local_dst; - flink.bo = drm_intel_bo_gem_create_from_name(data->bufmgr, "flink", name); - - data->render_copy(data->batch, NULL, - &flink, 0, 0, WIDTH, HEIGHT, - &dst, WIDTH / 2, HEIGHT / 2); - - scratch_buf_check(data, &dst, 10, 10, DST_COLOR); - scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR); - - scratch_buf_check(data, &dst, 10, 10, DST_COLOR); - scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR); - - scratch_buf_fini(data, &src); - scratch_buf_fini(data, &flink); - scratch_buf_fini(data, &dst); - - scratch_buf_fini(&local, &local_src); - scratch_buf_fini(&local, &local_dst); - - data_fini(&local); -} - -int main(int argc, char **argv) -{ - data_t data = {0, }; - - igt_subtest_init(argc, argv); - - igt_fixture { - data_init(&data); - } - - igt_subtest("normal") { - int loop = 100; - while (loop--) - copy(&data); - } - - igt_subtest("interruptible") { - int loop = 100; - igt_fork_signal_helper(); - while (loop--) - copy(&data); - igt_stop_signal_helper(); - } - - igt_subtest("flink") { - int loop = 100; - while (loop--) - copy_flink(&data); - } - - igt_subtest("flink-interruptible") { - int loop = 100; - igt_fork_signal_helper(); - while (loop--) - copy_flink(&data); - igt_stop_signal_helper(); - } - - igt_exit(); -} diff --git a/tests/gem_render_linear_blits.c b/tests/gem_render_linear_blits.c deleted file mode 100644 index 60ba8316..00000000 --- a/tests/gem_render_linear_blits.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/** @file gem_linear_render_blits.c - * - * This is a test of doing many blits, with a working set - * larger than the aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -#define WIDTH 512 -#define STRIDE (WIDTH*4) -#define HEIGHT 512 -#define SIZE (HEIGHT*STRIDE) - -static uint32_t linear[WIDTH*HEIGHT]; -static igt_render_copyfunc_t render_copy; - -static void -check_bo(int fd, uint32_t handle, uint32_t val) -{ - int i; - - gem_read(fd, handle, 0, linear, sizeof(linear)); - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(linear[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, linear[i], i * 4); - val++; - } -} - -int main(int argc, char **argv) -{ - drm_intel_bufmgr *bufmgr; - struct intel_batchbuffer *batch; - uint32_t *start_val; - drm_intel_bo **bo; - uint32_t start = 0; - int i, j, fd, count; - - igt_simple_init(argc, argv); - - fd = drm_open_any(); - - render_copy = igt_get_render_copyfunc(intel_get_drm_devid(fd)); - igt_require(render_copy); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - count = 0; - if (igt_run_in_simulation()) - count = 2; - if (argc > 1) - count = atoi(argv[1]); - - if (count == 0) - count = 3 * gem_aperture_size(fd) / SIZE / 2; - else if (count < 2) { - igt_warn("count must be >= 2\n"); - return 1; - } - - if (count > intel_get_total_ram_mb() * 9 / 10) { - count = intel_get_total_ram_mb() * 9 / 10; - igt_info("not enough RAM to run test, reducing buffer count\n"); - } - - bo = malloc(sizeof(*bo)*count); - start_val = malloc(sizeof(*start_val)*count); - - for (i = 0; i < count; i++) { - bo[i] = drm_intel_bo_alloc(bufmgr, "", SIZE, 4096); - start_val[i] = start; - for (j = 0; j < WIDTH*HEIGHT; j++) - linear[j] = start++; - gem_write(fd, bo[i]->handle, 0, linear, sizeof(linear)); - } - - igt_info("Verifying initialisation...\n"); - for (i = 0; i < count; i++) - check_bo(fd, bo[i]->handle, start_val[i]); - - igt_info("Cyclic blits, forward...\n"); - for (i = 0; i < count * 4; i++) { - struct igt_buf src, dst; - - src.bo = bo[i % count]; - src.stride = STRIDE; - src.tiling = I915_TILING_NONE; - src.size = SIZE; - - dst.bo = bo[(i + 1) % count]; - dst.stride = STRIDE; - dst.tiling = I915_TILING_NONE; - dst.size = SIZE; - - render_copy(batch, NULL, &src, 0, 0, WIDTH, HEIGHT, &dst, 0, 0); - start_val[(i + 1) % count] = start_val[i % count]; - } - for (i = 0; i < count; i++) - check_bo(fd, bo[i]->handle, start_val[i]); - - if (igt_run_in_simulation()) - return 0; - - igt_info("Cyclic blits, backward...\n"); - for (i = 0; i < count * 4; i++) { - struct igt_buf src, dst; - - src.bo = bo[(i + 1) % count]; - src.stride = STRIDE; - src.tiling = I915_TILING_NONE; - src.size = SIZE; - - dst.bo = bo[i % count]; - dst.stride = STRIDE; - dst.tiling = I915_TILING_NONE; - dst.size = SIZE; - - render_copy(batch, NULL, &src, 0, 0, WIDTH, HEIGHT, &dst, 0, 0); - start_val[i % count] = start_val[(i + 1) % count]; - } - for (i = 0; i < count; i++) - check_bo(fd, bo[i]->handle, start_val[i]); - - igt_info("Random blits...\n"); - for (i = 0; i < count * 4; i++) { - struct igt_buf src, dst; - int s = random() % count; - int d = random() % count; - - if (s == d) - continue; - - src.bo = bo[s]; - src.stride = STRIDE; - src.tiling = I915_TILING_NONE; - src.size = SIZE; - - dst.bo = bo[d]; - dst.stride = STRIDE; - dst.tiling = I915_TILING_NONE; - dst.size = SIZE; - - render_copy(batch, NULL, &src, 0, 0, WIDTH, HEIGHT, &dst, 0, 0); - start_val[d] = start_val[s]; - } - for (i = 0; i < count; i++) - check_bo(fd, bo[i]->handle, start_val[i]); - - igt_exit(); -} diff --git a/tests/gem_render_tiled_blits.c b/tests/gem_render_tiled_blits.c deleted file mode 100644 index dc22529c..00000000 --- a/tests/gem_render_tiled_blits.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/** @file gem_linear_render_blits.c - * - * This is a test of doing many blits, with a working set - * larger than the aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -#define WIDTH 512 -#define STRIDE (WIDTH*4) -#define HEIGHT 512 -#define SIZE (HEIGHT*STRIDE) - -static igt_render_copyfunc_t render_copy; -static drm_intel_bo *linear; -static uint32_t data[WIDTH*HEIGHT]; -static int snoop; - -static void -check_bo(struct intel_batchbuffer *batch, struct igt_buf *buf, uint32_t val) -{ - struct igt_buf tmp; - uint32_t *ptr; - int i; - - tmp.bo = linear; - tmp.stride = STRIDE; - tmp.tiling = I915_TILING_NONE; - tmp.size = SIZE; - - render_copy(batch, NULL, buf, 0, 0, WIDTH, HEIGHT, &tmp, 0, 0); - if (snoop) { - do_or_die(dri_bo_map(linear, 0)); - ptr = linear->virtual; - } else { - do_or_die(drm_intel_bo_get_subdata(linear, 0, sizeof(data), data)); - ptr = data; - } - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(ptr[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, ptr[i], i * 4); - val++; - } - if (ptr != data) - dri_bo_unmap(linear); -} - -int main(int argc, char **argv) -{ - drm_intel_bufmgr *bufmgr; - struct intel_batchbuffer *batch; - uint32_t *start_val; - struct igt_buf *buf; - uint32_t start = 0; - int i, j, fd, count; - uint32_t devid; - - igt_simple_init(argc, argv); - - igt_skip_on_simulation(); - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - render_copy = igt_get_render_copyfunc(devid); - igt_require(render_copy); - - snoop = 1; - if (IS_GEN2(devid)) /* chipset only handles cached -> uncached */ - snoop = 0; - if (IS_BROADWATER(devid) || IS_CRESTLINE(devid)) /* snafu */ - snoop = 0; - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_set_vma_cache_size(bufmgr, 32); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - count = 0; - if (argc > 1) - count = atoi(argv[1]); - if (count == 0) - count = 3 * gem_aperture_size(fd) / SIZE / 2; - else if (count < 2) { - igt_warn("count must be >= 2\n"); - return 1; - } - - if (count > intel_get_total_ram_mb() * 9 / 10) { - count = intel_get_total_ram_mb() * 9 / 10; - igt_info("not enough RAM to run test, reducing buffer count\n"); - } - - igt_info("Using %d 1MiB buffers\n", count); - - linear = drm_intel_bo_alloc(bufmgr, "linear", WIDTH*HEIGHT*4, 0); - if (snoop) { - gem_set_caching(fd, linear->handle, 1); - igt_info("Using a snoop linear buffer for comparisons\n"); - } - - buf = malloc(sizeof(*buf)*count); - start_val = malloc(sizeof(*start_val)*count); - - for (i = 0; i < count; i++) { - uint32_t tiling = I915_TILING_X + (random() & 1); - unsigned long pitch = STRIDE; - uint32_t *ptr; - - buf[i].bo = drm_intel_bo_alloc_tiled(bufmgr, "", - WIDTH, HEIGHT, 4, - &tiling, &pitch, 0); - buf[i].stride = pitch; - buf[i].tiling = tiling; - buf[i].size = SIZE; - - start_val[i] = start; - - do_or_die(drm_intel_gem_bo_map_gtt(buf[i].bo)); - ptr = buf[i].bo->virtual; - for (j = 0; j < WIDTH*HEIGHT; j++) - ptr[j] = start++; - drm_intel_gem_bo_unmap_gtt(buf[i].bo); - } - - igt_info("Verifying initialisation...\n"); - for (i = 0; i < count; i++) - check_bo(batch, &buf[i], start_val[i]); - - igt_info("Cyclic blits, forward...\n"); - for (i = 0; i < count * 4; i++) { - int src = i % count; - int dst = (i + 1) % count; - - render_copy(batch, NULL, buf+src, 0, 0, WIDTH, HEIGHT, buf+dst, 0, 0); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(batch, &buf[i], start_val[i]); - - igt_info("Cyclic blits, backward...\n"); - for (i = 0; i < count * 4; i++) { - int src = (i + 1) % count; - int dst = i % count; - - render_copy(batch, NULL, buf+src, 0, 0, WIDTH, HEIGHT, buf+dst, 0, 0); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(batch, &buf[i], start_val[i]); - - igt_info("Random blits...\n"); - for (i = 0; i < count * 4; i++) { - int src = random() % count; - int dst = random() % count; - - if (src == dst) - continue; - - render_copy(batch, NULL, buf+src, 0, 0, WIDTH, HEIGHT, buf+dst, 0, 0); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(batch, &buf[i], start_val[i]); - - igt_exit(); -} diff --git a/tests/gem_reset_stats.c b/tests/gem_reset_stats.c deleted file mode 100644 index d3cfe8b1..00000000 --- a/tests/gem_reset_stats.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* - * Copyright (c) 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: - * Mika Kuoppala <mika.kuoppala@intel.com> - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <time.h> -#include <signal.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_gt.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_aux.h" - -#define RS_NO_ERROR 0 -#define RS_BATCH_ACTIVE (1 << 0) -#define RS_BATCH_PENDING (1 << 1) -#define RS_UNKNOWN (1 << 2) - -static uint32_t devid; - -struct local_drm_i915_reset_stats { - __u32 ctx_id; - __u32 flags; - __u32 reset_count; - __u32 batch_active; - __u32 batch_pending; - __u32 pad; -}; - -#define MAX_FD 32 - -#define GET_RESET_STATS_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x32, struct local_drm_i915_reset_stats) - -#define LOCAL_I915_EXEC_VEBOX (4 << 0) - -struct target_ring; - -static bool gem_has_render(int fd) -{ - return true; -} - -static const struct target_ring { - uint32_t exec; - bool (*present)(int fd); - const char *name; -} rings[] = { - { I915_EXEC_RENDER, gem_has_render, "render" }, - { I915_EXEC_BLT, gem_has_blt, "blt" }, - { I915_EXEC_BSD, gem_has_bsd, "bsd" }, - { LOCAL_I915_EXEC_VEBOX, gem_has_vebox, "vebox" }, -}; - -static void check_context(const struct target_ring *ring) -{ - int fd = drm_open_any(); - - gem_context_destroy(fd, - gem_context_create(fd)); - close(fd); - - igt_require(ring->exec == I915_EXEC_RENDER); -} - -#define NUM_RINGS (sizeof(rings)/sizeof(struct target_ring)) - -static const struct target_ring *current_ring; - -static int gem_reset_stats(int fd, int ctx_id, - struct local_drm_i915_reset_stats *rs) -{ - int ret; - - rs->ctx_id = ctx_id; - rs->flags = 0; - rs->reset_count = rand(); - rs->batch_active = rand(); - rs->batch_pending = rand(); - rs->pad = 0; - - do { - ret = ioctl(fd, GET_RESET_STATS_IOCTL, rs); - } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); - - if (ret < 0) - return -errno; - - return 0; -} - -static int gem_reset_status(int fd, int ctx_id) -{ - int ret; - struct local_drm_i915_reset_stats rs; - - ret = gem_reset_stats(fd, ctx_id, &rs); - if (ret) - return ret; - - if (rs.batch_active) - return RS_BATCH_ACTIVE; - if (rs.batch_pending) - return RS_BATCH_PENDING; - - return RS_NO_ERROR; -} - -static int gem_exec(int fd, struct drm_i915_gem_execbuffer2 *execbuf) -{ - int ret; - - ret = ioctl(fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - execbuf); - - if (ret < 0) - return -errno; - - return 0; -} - -static int exec_valid_ring(int fd, int ctx, int ring) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec; - int ret; - - uint32_t buf[2] = { MI_BATCH_BUFFER_END, 0 }; - - exec.handle = gem_create(fd, 4096); - gem_write(fd, exec.handle, 0, buf, sizeof(buf)); - exec.relocation_count = 0; - exec.relocs_ptr = 0; - exec.alignment = 0; - exec.offset = 0; - exec.flags = 0; - exec.rsvd1 = 0; - exec.rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)&exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = sizeof(buf); - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, ctx); - execbuf.rsvd2 = 0; - - ret = gem_exec(fd, &execbuf); - if (ret < 0) - return ret; - - return exec.handle; -} - -static int exec_valid(int fd, int ctx) -{ - return exec_valid_ring(fd, ctx, current_ring->exec); -} - -#define BUFSIZE (4 * 1024) -#define ITEMS (BUFSIZE >> 2) - -static int inject_hang_ring(int fd, int ctx, int ring, bool ignore_ban_error) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec; - uint64_t gtt_off; - uint32_t *buf; - int roff, i; - unsigned cmd_len = 2; - enum stop_ring_flags flags; - - srandom(time(NULL)); - - if (intel_gen(devid) >= 8) - cmd_len = 3; - - buf = malloc(BUFSIZE); - igt_assert(buf != NULL); - - buf[0] = MI_BATCH_BUFFER_END; - buf[1] = MI_NOOP; - - exec.handle = gem_create(fd, BUFSIZE); - gem_write(fd, exec.handle, 0, buf, BUFSIZE); - exec.relocation_count = 0; - exec.relocs_ptr = 0; - exec.alignment = 0; - exec.offset = 0; - exec.flags = 0; - exec.rsvd1 = 0; - exec.rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)&exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = BUFSIZE; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, ctx); - execbuf.rsvd2 = 0; - - igt_assert(gem_exec(fd, &execbuf) == 0); - - gtt_off = exec.offset; - - for (i = 0; i < ITEMS; i++) - buf[i] = MI_NOOP; - - roff = random() % (ITEMS - cmd_len - 1); - buf[roff] = MI_BATCH_BUFFER_START | (cmd_len - 2); - buf[roff + 1] = (gtt_off & 0xfffffffc) + (roff << 2); - if (cmd_len == 3) - buf[roff + 2] = (gtt_off & 0xffffffff00000000ull) >> 32; - - buf[roff + cmd_len] = MI_BATCH_BUFFER_END; - - igt_debug("loop injected at 0x%lx (off 0x%x, bo_start 0x%lx, bo_end 0x%lx)\n", - (long unsigned int)((roff << 2) + gtt_off), - roff << 2, (long unsigned int)gtt_off, - (long unsigned int)(gtt_off + BUFSIZE - 1)); - gem_write(fd, exec.handle, 0, buf, BUFSIZE); - - exec.relocation_count = 0; - exec.relocs_ptr = 0; - exec.alignment = 0; - exec.offset = 0; - exec.flags = 0; - exec.rsvd1 = 0; - exec.rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)&exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = BUFSIZE; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring; - i915_execbuffer2_set_context_id(execbuf, ctx); - execbuf.rsvd2 = 0; - - igt_assert(gem_exec(fd, &execbuf) == 0); - - igt_assert(gtt_off == exec.offset); - - free(buf); - - flags = igt_to_stop_ring_flag(ring); - - flags |= STOP_RING_ALLOW_BAN; - - if (!ignore_ban_error) - flags |= STOP_RING_ALLOW_ERRORS; - - igt_set_stop_rings(flags); - - return exec.handle; -} - -static int inject_hang(int fd, int ctx) -{ - return inject_hang_ring(fd, ctx, current_ring->exec, false); -} - -static int inject_hang_no_ban_error(int fd, int ctx) -{ - return inject_hang_ring(fd, ctx, current_ring->exec, true); -} - -static int _assert_reset_status(int fd, int ctx, int status) -{ - int rs; - - rs = gem_reset_status(fd, ctx); - if (rs < 0) { - igt_info("reset status for %d ctx %d returned %d\n", - fd, ctx, rs); - return rs; - } - - if (rs != status) { - igt_info("%d:%d reset status %d differs from assumed %d\n", - fd, ctx, rs, status); - - return 1; - } - - return 0; -} - -#define assert_reset_status(fd, ctx, status) \ - igt_assert(_assert_reset_status(fd, ctx, status) == 0) - -static void test_rs(int num_fds, int hang_index, int rs_assumed_no_hang) -{ - int i; - int fd[MAX_FD]; - int h[MAX_FD]; - - igt_assert (num_fds <= MAX_FD); - igt_assert (hang_index < MAX_FD); - - for (i = 0; i < num_fds; i++) { - fd[i] = drm_open_any(); - igt_assert(fd[i]); - } - - for (i = 0; i < num_fds; i++) - assert_reset_status(fd[i], 0, RS_NO_ERROR); - - for (i = 0; i < num_fds; i++) { - if (i == hang_index) - h[i] = inject_hang(fd[i], 0); - else - h[i] = exec_valid(fd[i], 0); - } - - gem_sync(fd[num_fds - 1], h[num_fds - 1]); - - for (i = 0; i < num_fds; i++) { - if (hang_index < 0) { - assert_reset_status(fd[i], 0, rs_assumed_no_hang); - continue; - } - - if (i < hang_index) - assert_reset_status(fd[i], 0, RS_NO_ERROR); - if (i == hang_index) - assert_reset_status(fd[i], 0, RS_BATCH_ACTIVE); - if (i > hang_index) - assert_reset_status(fd[i], 0, RS_BATCH_PENDING); - } - - for (i = 0; i < num_fds; i++) { - gem_close(fd[i], h[i]); - close(fd[i]); - } -} - -#define MAX_CTX 100 -static void test_rs_ctx(int num_fds, int num_ctx, int hang_index, - int hang_context) -{ - int i, j; - int fd[MAX_FD]; - int h[MAX_FD][MAX_CTX]; - int ctx[MAX_FD][MAX_CTX]; - - igt_assert (num_fds <= MAX_FD); - igt_assert (hang_index < MAX_FD); - - igt_assert (num_ctx <= MAX_CTX); - igt_assert (hang_context < MAX_CTX); - - test_rs(num_fds, -1, RS_NO_ERROR); - - for (i = 0; i < num_fds; i++) { - fd[i] = drm_open_any(); - igt_assert(fd[i]); - assert_reset_status(fd[i], 0, RS_NO_ERROR); - - for (j = 0; j < num_ctx; j++) { - ctx[i][j] = gem_context_create(fd[i]); - - } - - assert_reset_status(fd[i], 0, RS_NO_ERROR); - } - - for (i = 0; i < num_fds; i++) { - - assert_reset_status(fd[i], 0, RS_NO_ERROR); - - for (j = 0; j < num_ctx; j++) - assert_reset_status(fd[i], ctx[i][j], RS_NO_ERROR); - - assert_reset_status(fd[i], 0, RS_NO_ERROR); - } - - for (i = 0; i < num_fds; i++) { - for (j = 0; j < num_ctx; j++) { - if (i == hang_index && j == hang_context) - h[i][j] = inject_hang(fd[i], ctx[i][j]); - else - h[i][j] = exec_valid(fd[i], ctx[i][j]); - } - } - - gem_sync(fd[num_fds - 1], ctx[num_fds - 1][num_ctx - 1]); - - for (i = 0; i < num_fds; i++) - assert_reset_status(fd[i], 0, RS_NO_ERROR); - - for (i = 0; i < num_fds; i++) { - for (j = 0; j < num_ctx; j++) { - if (i < hang_index) - assert_reset_status(fd[i], ctx[i][j], RS_NO_ERROR); - if (i == hang_index && j < hang_context) - assert_reset_status(fd[i], ctx[i][j], RS_NO_ERROR); - if (i == hang_index && j == hang_context) - assert_reset_status(fd[i], ctx[i][j], - RS_BATCH_ACTIVE); - if (i == hang_index && j > hang_context) - assert_reset_status(fd[i], ctx[i][j], - RS_BATCH_PENDING); - if (i > hang_index) - assert_reset_status(fd[i], ctx[i][j], - RS_BATCH_PENDING); - } - } - - for (i = 0; i < num_fds; i++) { - for (j = 0; j < num_ctx; j++) { - gem_close(fd[i], h[i][j]); - gem_context_destroy(fd[i], ctx[i][j]); - } - - assert_reset_status(fd[i], 0, RS_NO_ERROR); - - close(fd[i]); - } -} - -static void test_ban(void) -{ - int h1,h2,h3,h4,h5,h6,h7; - int fd_bad, fd_good; - int retry = 10; - int active_count = 0, pending_count = 0; - struct local_drm_i915_reset_stats rs_bad, rs_good; - - fd_bad = drm_open_any(); - - fd_good = drm_open_any(); - - assert_reset_status(fd_bad, 0, RS_NO_ERROR); - assert_reset_status(fd_good, 0, RS_NO_ERROR); - - h1 = exec_valid(fd_bad, 0); - igt_assert(h1 >= 0); - h5 = exec_valid(fd_good, 0); - igt_assert(h5 >= 0); - - assert_reset_status(fd_bad, 0, RS_NO_ERROR); - assert_reset_status(fd_good, 0, RS_NO_ERROR); - - h2 = inject_hang_no_ban_error(fd_bad, 0); - igt_assert(h2 >= 0); - active_count++; - /* Second hang will be pending for this */ - pending_count++; - - h6 = exec_valid(fd_good, 0); - h7 = exec_valid(fd_good, 0); - - while (retry--) { - h3 = inject_hang_no_ban_error(fd_bad, 0); - igt_assert(h3 >= 0); - gem_sync(fd_bad, h3); - active_count++; - /* This second hand will count as pending */ - assert_reset_status(fd_bad, 0, RS_BATCH_ACTIVE); - - h4 = exec_valid(fd_bad, 0); - if (h4 == -EIO) { - gem_close(fd_bad, h3); - break; - } - - /* Should not happen often but sometimes hang is declared too slow - * due to our way of faking hang using loop */ - - igt_assert(h4 >= 0); - gem_close(fd_bad, h3); - gem_close(fd_bad, h4); - - igt_info("retrying for ban (%d)\n", retry); - } - - igt_assert(h4 == -EIO); - assert_reset_status(fd_bad, 0, RS_BATCH_ACTIVE); - - gem_sync(fd_good, h7); - assert_reset_status(fd_good, 0, RS_BATCH_PENDING); - - igt_assert(gem_reset_stats(fd_good, 0, &rs_good) == 0); - igt_assert(gem_reset_stats(fd_bad, 0, &rs_bad) == 0); - - igt_assert(rs_bad.batch_active == active_count); - igt_assert(rs_bad.batch_pending == pending_count); - igt_assert(rs_good.batch_active == 0); - igt_assert(rs_good.batch_pending == 2); - - gem_close(fd_bad, h1); - gem_close(fd_bad, h2); - gem_close(fd_good, h6); - gem_close(fd_good, h7); - - h1 = exec_valid(fd_good, 0); - igt_assert(h1 >= 0); - gem_close(fd_good, h1); - - close(fd_bad); - close(fd_good); - - igt_assert(gem_reset_status(fd_bad, 0) < 0); - igt_assert(gem_reset_status(fd_good, 0) < 0); -} - -static void test_ban_ctx(void) -{ - int h1,h2,h3,h4,h5,h6,h7; - int ctx_good, ctx_bad; - int fd; - int retry = 10; - int active_count = 0, pending_count = 0; - struct local_drm_i915_reset_stats rs_bad, rs_good; - - fd = drm_open_any(); - - assert_reset_status(fd, 0, RS_NO_ERROR); - - ctx_good = gem_context_create(fd); - ctx_bad = gem_context_create(fd); - - assert_reset_status(fd, 0, RS_NO_ERROR); - assert_reset_status(fd, ctx_good, RS_NO_ERROR); - assert_reset_status(fd, ctx_bad, RS_NO_ERROR); - - h1 = exec_valid(fd, ctx_bad); - igt_assert(h1 >= 0); - h5 = exec_valid(fd, ctx_good); - igt_assert(h5 >= 0); - - assert_reset_status(fd, ctx_good, RS_NO_ERROR); - assert_reset_status(fd, ctx_bad, RS_NO_ERROR); - - h2 = inject_hang_no_ban_error(fd, ctx_bad); - igt_assert(h2 >= 0); - active_count++; - /* Second hang will be pending for this */ - pending_count++; - - h6 = exec_valid(fd, ctx_good); - h7 = exec_valid(fd, ctx_good); - - while (retry--) { - h3 = inject_hang_no_ban_error(fd, ctx_bad); - igt_assert(h3 >= 0); - gem_sync(fd, h3); - active_count++; - /* This second hand will count as pending */ - assert_reset_status(fd, ctx_bad, RS_BATCH_ACTIVE); - - h4 = exec_valid(fd, ctx_bad); - if (h4 == -EIO) { - gem_close(fd, h3); - break; - } - - /* Should not happen often but sometimes hang is declared too slow - * due to our way of faking hang using loop */ - - igt_assert(h4 >= 0); - gem_close(fd, h3); - gem_close(fd, h4); - - igt_info("retrying for ban (%d)\n", retry); - } - - igt_assert(h4 == -EIO); - assert_reset_status(fd, ctx_bad, RS_BATCH_ACTIVE); - - gem_sync(fd, h7); - assert_reset_status(fd, ctx_good, RS_BATCH_PENDING); - - igt_assert(gem_reset_stats(fd, ctx_good, &rs_good) == 0); - igt_assert(gem_reset_stats(fd, ctx_bad, &rs_bad) == 0); - - igt_assert(rs_bad.batch_active == active_count); - igt_assert(rs_bad.batch_pending == pending_count); - igt_assert(rs_good.batch_active == 0); - igt_assert(rs_good.batch_pending == 2); - - gem_close(fd, h1); - gem_close(fd, h2); - gem_close(fd, h6); - gem_close(fd, h7); - - h1 = exec_valid(fd, ctx_good); - igt_assert(h1 >= 0); - gem_close(fd, h1); - - gem_context_destroy(fd, ctx_good); - gem_context_destroy(fd, ctx_bad); - igt_assert(gem_reset_status(fd, ctx_good) < 0); - igt_assert(gem_reset_status(fd, ctx_bad) < 0); - igt_assert(exec_valid(fd, ctx_good) < 0); - igt_assert(exec_valid(fd, ctx_bad) < 0); - - close(fd); -} - -static void test_unrelated_ctx(void) -{ - int h1,h2; - int fd1,fd2; - int ctx_guilty, ctx_unrelated; - - fd1 = drm_open_any(); - fd2 = drm_open_any(); - assert_reset_status(fd1, 0, RS_NO_ERROR); - assert_reset_status(fd2, 0, RS_NO_ERROR); - ctx_guilty = gem_context_create(fd1); - ctx_unrelated = gem_context_create(fd2); - - assert_reset_status(fd1, ctx_guilty, RS_NO_ERROR); - assert_reset_status(fd2, ctx_unrelated, RS_NO_ERROR); - - h1 = inject_hang(fd1, ctx_guilty); - igt_assert(h1 >= 0); - gem_sync(fd1, h1); - assert_reset_status(fd1, ctx_guilty, RS_BATCH_ACTIVE); - assert_reset_status(fd2, ctx_unrelated, RS_NO_ERROR); - - h2 = exec_valid(fd2, ctx_unrelated); - igt_assert(h2 >= 0); - gem_sync(fd2, h2); - assert_reset_status(fd1, ctx_guilty, RS_BATCH_ACTIVE); - assert_reset_status(fd2, ctx_unrelated, RS_NO_ERROR); - gem_close(fd1, h1); - gem_close(fd2, h2); - - gem_context_destroy(fd1, ctx_guilty); - gem_context_destroy(fd2, ctx_unrelated); - - close(fd1); - close(fd2); -} - -static int get_reset_count(int fd, int ctx) -{ - int ret; - struct local_drm_i915_reset_stats rs; - - ret = gem_reset_stats(fd, ctx, &rs); - if (ret) - return ret; - - return rs.reset_count; -} - -static void test_close_pending_ctx(void) -{ - int fd, h; - uint32_t ctx; - - fd = drm_open_any(); - ctx = gem_context_create(fd); - - assert_reset_status(fd, ctx, RS_NO_ERROR); - - h = inject_hang(fd, ctx); - igt_assert(h >= 0); - gem_context_destroy(fd, ctx); - igt_assert(__gem_context_destroy(fd, ctx) == -ENOENT); - - gem_close(fd, h); - close(fd); -} - -static void test_close_pending(void) -{ - int fd, h; - - fd = drm_open_any(); - - assert_reset_status(fd, 0, RS_NO_ERROR); - - h = inject_hang(fd, 0); - igt_assert(h >= 0); - - gem_close(fd, h); - close(fd); -} - -static void exec_noop_on_each_ring(int fd, const bool reverse) -{ - uint32_t batch[2] = {MI_BATCH_BUFFER_END, 0}; - uint32_t handle; - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec[1]; - - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, sizeof(batch)); - - exec[0].handle = handle; - exec[0].relocation_count = 0; - exec[0].relocs_ptr = 0; - exec[0].alignment = 0; - exec[0].offset = 0; - exec[0].flags = 0; - exec[0].rsvd1 = 0; - exec[0].rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = 8; - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = 0; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - for (unsigned i = 0; i < NUM_RINGS; i++) { - const struct target_ring *ring; - - ring = reverse ? &rings[NUM_RINGS - 1 - i] : &rings[i]; - - if (ring->present(fd)) { - execbuf.flags = ring->exec; - do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - } - } - - gem_sync(fd, handle); - gem_close(fd, handle); -} - -static void test_close_pending_fork(const bool reverse) -{ - int pid; - int fd, h; - - fd = drm_open_any(); - - assert_reset_status(fd, 0, RS_NO_ERROR); - - h = inject_hang(fd, 0); - igt_assert(h >= 0); - - sleep(1); - - /* Avoid helpers as we need to kill the child - * without any extra signal handling on behalf of - * lib/drmtest.c - */ - pid = fork(); - if (pid == 0) { - const int fd2 = drm_open_any(); - igt_assert(fd2 >= 0); - - /* The crucial component is that we schedule the same noop batch - * on each ring. This exercises batch_obj reference counting, - * when gpu is reset and ring lists are cleared. - */ - exec_noop_on_each_ring(fd2, reverse); - - close(fd2); - return; - } else { - igt_assert(pid > 0); - sleep(1); - - /* Kill the child to reduce refcounts on - batch_objs */ - kill(pid, SIGKILL); - } - - gem_close(fd, h); - close(fd); - - /* Then we just wait on hang to happen */ - fd = drm_open_any(); - - h = exec_valid(fd, 0); - igt_assert(h >= 0); - - gem_sync(fd, h); - gem_close(fd, h); - close(fd); -} - -static void test_reset_count(const bool create_ctx) -{ - int fd, h, ctx; - long c1, c2; - - fd = drm_open_any(); - if (create_ctx) - ctx = gem_context_create(fd); - else - ctx = 0; - - assert_reset_status(fd, ctx, RS_NO_ERROR); - - c1 = get_reset_count(fd, ctx); - igt_assert(c1 >= 0); - - h = inject_hang(fd, ctx); - igt_assert (h >= 0); - gem_sync(fd, h); - - assert_reset_status(fd, ctx, RS_BATCH_ACTIVE); - c2 = get_reset_count(fd, ctx); - igt_assert(c2 >= 0); - igt_assert(c2 == (c1 + 1)); - - igt_fork(child, 1) { - igt_drop_root(); - - c2 = get_reset_count(fd, ctx); - - if (ctx == 0) - igt_assert(c2 == -EPERM); - else - igt_assert(c2 == 0); - } - - igt_waitchildren(); - - gem_close(fd, h); - - if (create_ctx) - gem_context_destroy(fd, ctx); - - close(fd); -} - -static int _test_params(int fd, int ctx, uint32_t flags, uint32_t pad) -{ - struct local_drm_i915_reset_stats rs; - int ret; - - rs.ctx_id = ctx; - rs.flags = flags; - rs.reset_count = rand(); - rs.batch_active = rand(); - rs.batch_pending = rand(); - rs.pad = pad; - - do { - ret = ioctl(fd, GET_RESET_STATS_IOCTL, &rs); - } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); - - if (ret < 0) - return -errno; - - return 0; -} - -typedef enum { root = 0, user } cap_t; - -static void _check_param_ctx(const int fd, const int ctx, const cap_t cap) -{ - const uint32_t bad = rand() + 1; - - if (ctx == 0) { - if (cap == root) - igt_assert(_test_params(fd, ctx, 0, 0) == 0); - else - igt_assert(_test_params(fd, ctx, 0, 0) == -EPERM); - } - - igt_assert(_test_params(fd, ctx, 0, bad) == -EINVAL); - igt_assert(_test_params(fd, ctx, bad, 0) == -EINVAL); - igt_assert(_test_params(fd, ctx, bad, bad) == -EINVAL); -} - -static void check_params(const int fd, const int ctx, cap_t cap) -{ - igt_assert(ioctl(fd, GET_RESET_STATS_IOCTL, 0) == -1); - igt_assert(_test_params(fd, 0xbadbad, 0, 0) == -ENOENT); - - _check_param_ctx(fd, ctx, cap); -} - -static void _test_param(const int fd, const int ctx) -{ - check_params(fd, ctx, root); - - igt_fork(child, 1) { - check_params(fd, ctx, root); - - igt_drop_root(); - - check_params(fd, ctx, user); - } - - check_params(fd, ctx, root); - - igt_waitchildren(); -} - -static void test_params_ctx(void) -{ - int fd, ctx; - - fd = drm_open_any(); - ctx = gem_context_create(fd); - - _test_param(fd, ctx); - - close(fd); -} - -static void test_params(void) -{ - int fd; - - fd = drm_open_any(); - - _test_param(fd, 0); - - close(fd); - -} - -static void defer_hangcheck(int ring_num) -{ - int fd, count_start, count_end; - int seconds = 30; - const struct target_ring *next_ring; - fd = drm_open_any(); - - do { - next_ring = &rings[(++ring_num) % NUM_RINGS]; - - if (next_ring->present(fd)) - break; - - } while(next_ring != current_ring); - - igt_skip_on(next_ring == current_ring); - - count_start = get_reset_count(fd, 0); - igt_assert(count_start >= 0); - - igt_assert(inject_hang_ring(fd, 0, current_ring->exec, true)); - while (--seconds) { - igt_assert(exec_valid_ring(fd, 0, next_ring->exec)); - - count_end = get_reset_count(fd, 0); - igt_assert(count_end >= 0); - - if (count_end > count_start) - break; - - sleep(1); - } - - igt_assert(count_end > count_start); - - close(fd); -} - -static bool gem_has_reset_stats(int fd) -{ - struct local_drm_i915_reset_stats rs; - int ret; - - /* Carefully set flags and pad to zero, otherwise - we get -EINVAL - */ - memset(&rs, 0, sizeof(rs)); - - ret = drmIoctl(fd, GET_RESET_STATS_IOCTL, &rs); - if (ret == 0) - return true; - - /* If we get EPERM, we have support but did not - have CAP_SYSADM */ - if (ret == -1 && errno == EPERM) - return true; - - return false; -} - -static void check_gpu_ok(void) -{ - int retry_count = 30; - enum stop_ring_flags flags; - int fd; - - igt_debug("checking gpu state\n"); - - while (retry_count--) { - flags = igt_get_stop_rings(); - if (flags == 0) - break; - - igt_debug("waiting previous hang to clear\n"); - sleep(1); - } - - igt_assert(flags == 0); - - fd = drm_open_any(); - gem_quiescent_gpu(fd); - close(fd); -} - -#define RUN_TEST(...) do { check_gpu_ok(); __VA_ARGS__; check_gpu_ok(); } while (0) -#define RUN_CTX_TEST(...) do { check_context(current_ring); RUN_TEST(__VA_ARGS__); } while (0) - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - int fd; - - bool has_reset_stats; - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - has_reset_stats = gem_has_reset_stats(fd); - - close(fd); - - igt_require_f(has_reset_stats, - "No reset stats ioctl support. Too old kernel?\n"); - } - - igt_subtest("params") - test_params(); - - for (int i = 0; i < NUM_RINGS; i++) { - const char *name; - - current_ring = &rings[i]; - name = current_ring->name; - - igt_fixture { - int fd = drm_open_any(); - gem_require_ring(fd, current_ring->exec); - close(fd); - } - - igt_fixture - igt_require_f(intel_gen(devid) >= 4, - "gen %d doesn't support reset\n", intel_gen(devid)); - - igt_subtest_f("params-ctx-%s", name) - RUN_CTX_TEST(test_params_ctx()); - - igt_subtest_f("reset-stats-%s", name) - RUN_TEST(test_rs(4, 1, 0)); - - igt_subtest_f("reset-stats-ctx-%s", name) - RUN_CTX_TEST(test_rs_ctx(4, 4, 1, 2)); - - igt_subtest_f("ban-%s", name) - RUN_TEST(test_ban()); - - igt_subtest_f("ban-ctx-%s", name) - RUN_CTX_TEST(test_ban_ctx()); - - igt_subtest_f("reset-count-%s", name) - RUN_TEST(test_reset_count(false)); - - igt_subtest_f("reset-count-ctx-%s", name) - RUN_CTX_TEST(test_reset_count(true)); - - igt_subtest_f("unrelated-ctx-%s", name) - RUN_CTX_TEST(test_unrelated_ctx()); - - igt_subtest_f("close-pending-%s", name) - RUN_TEST(test_close_pending()); - - igt_subtest_f("close-pending-ctx-%s", name) - RUN_CTX_TEST(test_close_pending_ctx()); - - igt_subtest_f("close-pending-fork-%s", name) - RUN_TEST(test_close_pending_fork(false)); - - igt_subtest_f("close-pending-fork-reverse-%s", name) - RUN_TEST(test_close_pending_fork(true)); - - igt_subtest_f("defer-hangcheck-%s", name) - RUN_TEST(defer_hangcheck(i)); - - } -} diff --git a/tests/gem_ring_sync_copy.c b/tests/gem_ring_sync_copy.c deleted file mode 100644 index f5ffddc3..00000000 --- a/tests/gem_ring_sync_copy.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * 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: - * Damien Lespiau <damien.lespiau@intel.com> - */ - -/* - * The goal of this test is to ensure that we respect inter ring dependencies - * - * For each pair of rings R1, R2 where we have copy support (i.e. blt, - * rendercpy and mediafill) do: - * - Throw a busy load onto R1. gem_concurrent_blt just uses lots of buffers - * for this effect. - * - Fill three buffers A, B, C with unique data. - * - Copy A to B on ring R1 - * - * Then come the three different variants. - * - Copy B to C on ring R2, check that C now contains what A originally - * contained. This is the write->read hazard. gem_concurrent_blt calls this - * early read. - * - Copy C to A on ring R2, check that B now contains what A originally - * contained. This is the read->write hazard, gem_concurrent_blt calls it - * overwrite_source. - * - Copy C to B on ring R2 and check that B contains what C originally - * contained. This is the write/write hazard. gem_concurrent_blt doesn't - * have that since for the cpu case it's too boring. - * - */ - -#include <stdlib.h> -#include <stdbool.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Ensure inter-ring dependencies are respected."); - -#define WIDTH 512 -#define HEIGHT 512 -#define NUM_BUSY_BUFFERS 32 - -typedef struct { - int drm_fd; - uint32_t devid; - drm_intel_bufmgr *bufmgr; - struct intel_batchbuffer *batch; - - /* number of buffers to keep the ring busy for a while */ - unsigned int n_buffers_load; - - uint32_t linear[WIDTH * HEIGHT]; - - struct { - igt_render_copyfunc_t copy; - struct igt_buf *srcs; - struct igt_buf *dsts; - } render; - - struct { - drm_intel_bo **srcs; - drm_intel_bo **dsts; - } blitter; - -} data_t; - -enum ring { - RENDER, - BLITTER, -}; - -enum test { - TEST_WRITE_READ, - TEST_READ_WRITE, - TEST_WRITE_WRITE, -}; - -static const char *ring_name(enum ring ring) -{ - const char *names[] = { - "render", - "blitter", - }; - - return names[ring]; -} - -static drm_intel_bo *bo_create(data_t *data, int width, int height, int val) -{ - drm_intel_bo *bo; - int i; - - bo = drm_intel_bo_alloc(data->bufmgr, "", 4 * width * height, 4096); - igt_assert(bo); - - for (i = 0; i < width * height; i++) - data->linear[i] = val; - gem_write(data->drm_fd, bo->handle, 0, data->linear, - sizeof(data->linear)); - - return bo; -} - -static void bo_check(data_t *data, drm_intel_bo *bo, uint32_t val) -{ - int i; - - gem_read(data->drm_fd, bo->handle, 0, - data->linear, sizeof(data->linear)); - for (i = 0; i < WIDTH * HEIGHT; i++) - igt_assert_eq_u32(data->linear[i], val); -} - -static void scratch_buf_init_from_bo(struct igt_buf *buf, drm_intel_bo *bo) -{ - buf->bo = bo; - buf->stride = 4 * WIDTH; - buf->tiling = I915_TILING_NONE; - buf->size = 4 * WIDTH * HEIGHT; -} - -static void scratch_buf_init(data_t *data, struct igt_buf *buf, - int width, int height, uint32_t color) -{ - drm_intel_bo *bo; - - bo = bo_create(data, width, height, color); - scratch_buf_init_from_bo(buf, bo); -} - -/* - * Provide a few ring specific vfuncs for run_test(). - * - * busy() Queue a n_buffers_load workloads onto the ring to keep it busy - * busy_fini() Clean up after busy - * copy() Copy one BO to another - */ - -/* - * Render ring - */ - -static void render_busy(data_t *data) -{ - size_t array_size; - int i; - - /* allocate 32 buffer objects and re-use them as needed */ - array_size = NUM_BUSY_BUFFERS * sizeof(struct igt_buf); - - data->render.srcs = malloc(array_size); - data->render.dsts = malloc(array_size); - - for (i = 0; i < NUM_BUSY_BUFFERS; i++) { - scratch_buf_init(data, &data->render.srcs[i], WIDTH, HEIGHT, - 0xdeadbeef); - scratch_buf_init(data, &data->render.dsts[i], WIDTH, HEIGHT, - 0xdeadbeef); - } - - for (i = 0; i < data->n_buffers_load; i++) { - data->render.copy(data->batch, - NULL, /* context */ - &data->render.srcs[i % NUM_BUSY_BUFFERS], - 0, 0, /* src_x, src_y */ - WIDTH, HEIGHT, - &data->render.dsts[i % NUM_BUSY_BUFFERS], - 0, 0 /* dst_x, dst_y */); - } -} - -static void render_busy_fini(data_t *data) -{ - int i; - - for (i = 0; i < NUM_BUSY_BUFFERS; i++) { - drm_intel_bo_unreference(data->render.srcs[i].bo); - drm_intel_bo_unreference(data->render.dsts[i].bo); - } - - free(data->render.srcs); - free(data->render.dsts); - data->render.srcs = NULL; - data->render.dsts = NULL; -} - -static void render_copy(data_t *data, drm_intel_bo *src, drm_intel_bo *dst) -{ - struct igt_buf src_buf, dst_buf; - - scratch_buf_init_from_bo(&src_buf, src); - scratch_buf_init_from_bo(&dst_buf, dst); - - data->render.copy(data->batch, - NULL, /* context */ - &src_buf, - 0, 0, /* src_x, src_y */ - WIDTH, HEIGHT, - &dst_buf, - 0, 0 /* dst_x, dst_y */); -} - -/* - * Blitter ring - */ - -static void blitter_busy(data_t *data) -{ - size_t array_size; - int i; - - /* allocate 32 buffer objects and re-use them as needed */ - array_size = NUM_BUSY_BUFFERS * sizeof(drm_intel_bo *); - - data->blitter.srcs = malloc(array_size); - data->blitter.dsts = malloc(array_size); - - for (i = 0; i < NUM_BUSY_BUFFERS; i++) { - data->blitter.srcs[i] = bo_create(data, - WIDTH, HEIGHT, - 0xdeadbeef); - data->blitter.dsts[i] = bo_create(data, - WIDTH, HEIGHT, - 0xdeadbeef); - } - - for (i = 0; i < data->n_buffers_load; i++) { - intel_copy_bo(data->batch, - data->blitter.srcs[i % NUM_BUSY_BUFFERS], - data->blitter.dsts[i % NUM_BUSY_BUFFERS], - WIDTH*HEIGHT*4); - } -} - -static void blitter_busy_fini(data_t *data) -{ - int i; - - for (i = 0; i < NUM_BUSY_BUFFERS; i++) { - drm_intel_bo_unreference(data->blitter.srcs[i]); - drm_intel_bo_unreference(data->blitter.dsts[i]); - } - - free(data->blitter.srcs); - free(data->blitter.dsts); - data->blitter.srcs = NULL; - data->blitter.dsts = NULL; -} - -static void blitter_copy(data_t *data, drm_intel_bo *src, drm_intel_bo *dst) -{ - intel_copy_bo(data->batch, dst, src, WIDTH*HEIGHT*4); -} - -struct ring_ops { - void (*busy)(data_t *data); - void (*busy_fini)(data_t *data); - void (*copy)(data_t *data, drm_intel_bo *src, drm_intel_bo *dst); -} ops [] = { - { - .busy = render_busy, - .busy_fini = render_busy_fini, - .copy = render_copy, - }, - { - .busy = blitter_busy, - .busy_fini = blitter_busy_fini, - .copy = blitter_copy, - }, -}; - -static void run_test(data_t *data, enum ring r1, enum ring r2, enum test test) -{ - struct ring_ops *r1_ops = &ops[r1]; - struct ring_ops *r2_ops = &ops[r2]; - drm_intel_bo *a, *b, *c; - - a = bo_create(data, WIDTH, HEIGHT, 0xa); - b = bo_create(data, WIDTH, HEIGHT, 0xb); - c = bo_create(data, WIDTH, HEIGHT, 0xc); - - r1_ops->busy(data); - r1_ops->copy(data, a, b); - - switch (test) { - case TEST_WRITE_READ: - r2_ops->copy(data, b, c); - bo_check(data, c, 0xa); - break; - case TEST_READ_WRITE: - r2_ops->copy(data, c, a); - bo_check(data, b, 0xa); - break; - case TEST_WRITE_WRITE: - r2_ops->copy(data, c, b); - bo_check(data, b, 0xc); - break; - default: - igt_fail(1); - } - - r1_ops->busy_fini(data); -} - -igt_main -{ - data_t data = {0, }; - int i; - struct combination { - int r1, r2; - } ring_combinations [] = { - { RENDER, BLITTER }, - { BLITTER, RENDER }, - }; - - igt_fixture { - data.drm_fd = drm_open_any_render(); - data.devid = intel_get_drm_devid(data.drm_fd); - - data.n_buffers_load = 1000; - - data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096); - igt_assert(data.bufmgr); - drm_intel_bufmgr_gem_enable_reuse(data.bufmgr); - - data.render.copy = igt_get_render_copyfunc(data.devid); - igt_require_f(data.render.copy, - "no render-copy function\n"); - - data.batch = intel_batchbuffer_alloc(data.bufmgr, data.devid); - igt_assert(data.batch); - } - - for (i = 0; i < ARRAY_SIZE(ring_combinations); i++) { - struct combination *c = &ring_combinations[i]; - - igt_subtest_f("sync-%s-%s-write-read", - ring_name(c->r1), ring_name(c->r2)) - run_test(&data, c->r1, c->r2, TEST_WRITE_READ); - - igt_subtest_f("sync-%s-%s-read-write", - ring_name(c->r1), ring_name(c->r2)) - run_test(&data, c->r1, c->r2, TEST_READ_WRITE); - igt_subtest_f("sync-%s-%s-write-write", - ring_name(c->r1), ring_name(c->r2)) - run_test(&data, c->r1, c->r2, TEST_WRITE_WRITE); - } - - igt_fixture { - intel_batchbuffer_free(data.batch); - drm_intel_bufmgr_destroy(data.bufmgr); - close(data.drm_fd); - } -} diff --git a/tests/gem_ring_sync_loop.c b/tests/gem_ring_sync_loop.c deleted file mode 100644 index 4b88530b..00000000 --- a/tests/gem_ring_sync_loop.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> (based on gem_storedw_*.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "i830_reg.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Basic check of ring<->ring sync using a dummy reloc."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *target_buffer; - -/* - * Testcase: Basic check of ring<->ring sync using a dummy reloc - * - * Extremely efficient at catching missed irqs with semaphores=0 ... - */ - -#define MI_COND_BATCH_BUFFER_END (0x36<<23 | 1) -#define MI_DO_COMPARE (1<<21) - -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); -} - -igt_simple_main -{ - int fd; - int devid; - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - gem_require_ring(fd, I915_EXEC_BLT); - - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - - target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_buffer); - - store_dword_loop(fd); - - drm_intel_bo_unreference(target_buffer); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_ringfill.c b/tests/gem_ringfill.c deleted file mode 100644 index 3ecd25e5..00000000 --- a/tests/gem_ringfill.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * - */ - -/** @file gem_ringfill.c - * - * This is a test of doing many tiny batchbuffer operations, in the hope of - * catching failure to manage the ring properly near full. - */ - -#include <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_aux.h" - -struct bo { - const char *ring; - drm_intel_bo *src, *dst, *tmp; -}; - -static const int width = 512, height = 512; - -static void create_bo(drm_intel_bufmgr *bufmgr, - struct bo *b, - const char *ring) -{ - int size = 4 * width * height, i; - uint32_t *map; - - b->ring = ring; - b->src = drm_intel_bo_alloc(bufmgr, "src", size, 4096); - b->dst = drm_intel_bo_alloc(bufmgr, "dst", size, 4096); - b->tmp = drm_intel_bo_alloc(bufmgr, "tmp", size, 4096); - - /* Fill the src with indexes of the pixels */ - drm_intel_bo_map(b->src, true); - map = b->src->virtual; - for (i = 0; i < width * height; i++) - map[i] = i; - drm_intel_bo_unmap(b->src); - - /* Fill the dst with garbage. */ - drm_intel_bo_map(b->dst, true); - map = b->dst->virtual; - for (i = 0; i < width * height; i++) - map[i] = 0xd0d0d0d0; - drm_intel_bo_unmap(b->dst); -} - -static int check_bo(struct bo *b) -{ - const uint32_t *map; - int i, fails = 0; - - drm_intel_bo_map(b->dst, false); - map = b->dst->virtual; - for (i = 0; i < width*height; i++) { - if (map[i] != i && ++fails <= 9) { - int x = i % width; - int y = i / width; - - igt_info("%s: copy #%d at %d,%d failed: read 0x%08x\n", - b->ring, i, x, y, map[i]); - } - } - drm_intel_bo_unmap(b->dst); - - return fails; -} - -static void destroy_bo(struct bo *b) -{ - drm_intel_bo_unreference(b->src); - drm_intel_bo_unreference(b->tmp); - drm_intel_bo_unreference(b->dst); -} - -static int check_ring(drm_intel_bufmgr *bufmgr, - struct intel_batchbuffer *batch, - const char *ring, - igt_render_copyfunc_t copy) -{ - struct igt_buf src, tmp, dst; - struct bo bo; - char output[100]; - int i; - - snprintf(output, 100, "filling %s ring: ", ring); - - create_bo(bufmgr, &bo, ring); - - src.stride = 4 * width; - src.tiling = 0; - src.size = 4 * width * height; - src.num_tiles = 4 * width * height; - dst = tmp = src; - - src.bo = bo.src; - tmp.bo = bo.tmp; - dst.bo = bo.dst; - - /* The ring we've been using is 128k, and each rendering op - * will use at least 8 dwords: - * - * BATCH_START - * BATCH_START offset - * MI_FLUSH - * STORE_DATA_INDEX - * STORE_DATA_INDEX offset - * STORE_DATA_INDEX value - * MI_USER_INTERRUPT - * (padding) - * - * So iterate just a little more than that -- if we don't fill the ring - * doing this, we aren't likely to with this test. - */ - for (i = 0; i < width * height; i++) { - int x = i % width; - int y = i / width; - - igt_progress(output, i, width*height); - - igt_assert(y < height); - - /* Dummy load to fill the ring */ - copy(batch, NULL, &src, 0, 0, width, height, &tmp, 0, 0); - /* And copy the src into dst, pixel by pixel */ - copy(batch, NULL, &src, x, y, 1, 1, &dst, x, y); - } - - /* verify */ - igt_info("verifying\n"); - i = check_bo(&bo); - destroy_bo(&bo); - - return i; -} - -static void blt_copy(struct intel_batchbuffer *batch, - drm_intel_context *context, - struct igt_buf *src, unsigned src_x, unsigned src_y, - unsigned w, unsigned h, - struct igt_buf *dst, unsigned dst_x, unsigned dst_y) -{ - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - dst->stride); - OUT_BATCH((dst_y << 16) | dst_x); /* dst x1,y1 */ - OUT_BATCH(((dst_y + h) << 16) | (dst_x + w)); /* dst x2,y2 */ - OUT_RELOC_FENCED(dst->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH((src_y << 16) | src_x); /* src x1,y1 */ - OUT_BATCH(src->stride); - OUT_RELOC_FENCED(src->bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -int fd; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - } - - igt_subtest("blitter") - check_ring(bufmgr, batch, "blt", blt_copy); - - /* Strictly only required on architectures with a separate BLT ring, - * but lets stress everybody. - */ - igt_subtest("render") { - igt_render_copyfunc_t copy; - - copy = igt_get_render_copyfunc(batch->devid); - igt_require(copy); - - check_ring(bufmgr, batch, "render", copy); - } - - igt_fork_signal_helper(); - igt_subtest("blitter-interruptible") - check_ring(bufmgr, batch, "blt", blt_copy); - - /* Strictly only required on architectures with a separate BLT ring, - * but lets stress everybody. - */ - igt_subtest("render-interruptible") { - igt_render_copyfunc_t copy; - - copy = igt_get_render_copyfunc(batch->devid); - igt_require(copy); - - check_ring(bufmgr, batch, "render", copy); - } - igt_stop_signal_helper(); - - igt_fixture { - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_seqno_wrap.c b/tests/gem_seqno_wrap.c deleted file mode 100644 index ba58ebd2..00000000 --- a/tests/gem_seqno_wrap.c +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Copyright (c) 2012 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: - * Mika Kuoppala <mika.kuoppala@intel.com> - * - */ - -/* - * This test runs blitcopy -> rendercopy with multiple buffers over wrap - * boundary. - */ - -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <limits.h> -#include <signal.h> -#include <errno.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_core.h" -#include "igt_aux.h" -#include "igt_debugfs.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Runs blitcopy -> rendercopy with multiple buffers over" - " wrap boundary."); - -static int devid; -static int card_index = 0; -static uint32_t last_seqno = 0; - -static struct intel_batchbuffer *batch_blt; -static struct intel_batchbuffer *batch_3d; - -struct option_struct { - int rounds; - int background; - int timeout; - int dontwrap; - int prewrap_space; - int random; - int buffers; -}; - -static struct option_struct options; - -static void init_buffer(drm_intel_bufmgr *bufmgr, - struct igt_buf *buf, - drm_intel_bo *bo, - int width, int height) -{ - /* buf->bo = drm_intel_bo_alloc(bufmgr, "", size, 4096); */ - buf->bo = bo; - buf->size = width * height * 4; - igt_assert(buf->bo); - buf->tiling = I915_TILING_NONE; - buf->num_tiles = width * height * 4; - buf->stride = width * 4; -} - -static void -set_bo(drm_intel_bo *bo, uint32_t val, int width, int height) -{ - int size = width * height; - uint32_t *vaddr; - - drm_intel_gem_bo_start_gtt_access(bo, true); - vaddr = bo->virtual; - while (size--) - *vaddr++ = val; -} - -static void -cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height) -{ - int size = width * height; - uint32_t *vaddr; - - drm_intel_gem_bo_start_gtt_access(bo, false); - vaddr = bo->virtual; - while (size--) { - igt_assert_f(*vaddr++ == val, - "%d: 0x%x differs from assumed 0x%x\n" - "seqno_before_test 0x%x, " - " approximated seqno on test fail 0x%x\n", - width * height - size, *vaddr-1, val, - last_seqno, last_seqno + val * 2); - } -} - -static drm_intel_bo * -create_bo(drm_intel_bufmgr *bufmgr, uint32_t val, int width, int height) -{ - drm_intel_bo *bo; - - bo = drm_intel_bo_alloc(bufmgr, "bo", width * height * 4, 0); - igt_assert(bo); - - /* gtt map doesn't have a write parameter, so just keep the mapping - * around (to avoid the set_domain with the gtt write domain set) and - * manually tell the kernel when we start access the gtt. */ - drm_intel_gem_bo_map_gtt(bo); - - set_bo(bo, val, width, height); - - return bo; -} - -static void release_bo(drm_intel_bo *bo) -{ - drm_intel_gem_bo_unmap_gtt(bo); - drm_intel_bo_unreference(bo); -} - -static void render_copyfunc(struct igt_buf *src, - struct igt_buf *dst, - int width, - int height) -{ - const int src_x = 0, src_y = 0, dst_x = 0, dst_y = 0; - igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(devid); - static int warned = 0; - - if (rendercopy) { - rendercopy(batch_3d, NULL, - src, src_x, src_y, - width, height, - dst, dst_x, dst_y); - intel_batchbuffer_flush(batch_3d); - } else { - if (!warned) { - igt_info("No render copy found for this gen, ""test is shallow!\n"); - warned = 1; - } - igt_assert(dst->bo); - igt_assert(src->bo); - intel_copy_bo(batch_blt, dst->bo, src->bo, width*height*4); - intel_batchbuffer_flush(batch_blt); - } -} - -static void exchange_uint(void *array, unsigned i, unsigned j) -{ - unsigned *i_arr = array; - - igt_swap(i_arr[i], i_arr[j]); -} - -static void run_sync_test(int num_buffers, bool verify) -{ - drm_intel_bufmgr *bufmgr; - int max; - drm_intel_bo **src, **dst1, **dst2; - int width = 128, height = 128; - int fd; - int i; - unsigned int *p_dst1, *p_dst2; - struct igt_buf *s_src, *s_dst; - - fd = drm_open_any(); - - gem_quiescent_gpu(fd); - - devid = intel_get_drm_devid(fd); - - max = gem_aperture_size (fd) / (1024 * 1024) / 2; - if (num_buffers > max) - num_buffers = max; - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch_blt = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - igt_assert(batch_blt); - batch_3d = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - igt_assert(batch_3d); - - src = malloc(num_buffers * sizeof(*src)); - igt_assert(src); - - dst1 = malloc(num_buffers * sizeof(*dst1)); - igt_assert(dst1); - - dst2 = malloc(num_buffers * sizeof(*dst2)); - igt_assert(dst2); - - s_src = malloc(num_buffers * sizeof(*s_src)); - igt_assert(s_src); - - s_dst = malloc(num_buffers * sizeof(*s_dst)); - igt_assert(s_dst); - - p_dst1 = malloc(num_buffers * sizeof(unsigned int)); - igt_assert(p_dst1); - - p_dst2 = malloc(num_buffers * sizeof(unsigned int)); - igt_assert(p_dst2); - - for (i = 0; i < num_buffers; i++) { - p_dst1[i] = p_dst2[i] = i; - src[i] = create_bo(bufmgr, i, width, height); - igt_assert(src[i]); - dst1[i] = create_bo(bufmgr, ~i, width, height); - igt_assert(dst1[i]); - dst2[i] = create_bo(bufmgr, ~i, width, height); - igt_assert(dst2[i]); - init_buffer(bufmgr, &s_src[i], src[i], width, height); - init_buffer(bufmgr, &s_dst[i], dst1[i], width, height); - } - - igt_permute_array(p_dst1, num_buffers, exchange_uint); - igt_permute_array(p_dst2, num_buffers, exchange_uint); - - for (i = 0; i < num_buffers; i++) - render_copyfunc(&s_src[i], &s_dst[p_dst1[i]], width, height); - - /* Only sync between buffers if this is actual test run and - * not a seqno filler */ - if (verify) { - for (i = 0; i < num_buffers; i++) - intel_copy_bo(batch_blt, dst2[p_dst2[i]], dst1[p_dst1[i]], - width*height*4); - - for (i = 0; i < num_buffers; i++) { - cmp_bo(dst2[p_dst2[i]], i, width, height); - } - } - - for (i = 0; i < num_buffers; i++) { - release_bo(src[i]); - release_bo(dst1[i]); - release_bo(dst2[i]); - } - - intel_batchbuffer_free(batch_3d); - intel_batchbuffer_free(batch_blt); - drm_intel_bufmgr_destroy(bufmgr); - - free(p_dst1); - free(p_dst2); - free(s_dst); - free(s_src); - free(dst2); - free(dst1); - free(src); - - gem_quiescent_gpu(fd); - - close(fd); -} - -static int __read_seqno(uint32_t *seqno) -{ - int fh; - char buf[32]; - int r; - char *p; - unsigned long int tmp; - - fh = igt_debugfs_open("i915_next_seqno", O_RDONLY); - - r = read(fh, buf, sizeof(buf) - 1); - close(fh); - if (r < 0) { - igt_warn("read"); - return -errno; - } - - buf[r] = 0; - - p = strstr(buf, "0x"); - if (!p) - p = buf; - - errno = 0; - tmp = strtoul(p, NULL, 0); - if (tmp == ULONG_MAX && errno) { - igt_warn("strtoul"); - return -errno; - } - - *seqno = tmp; - - igt_debug("next_seqno: 0x%x\n", *seqno); - - return 0; -} - -static int read_seqno(void) -{ - uint32_t seqno = 0; - int r; - int wrap = 0; - - r = __read_seqno(&seqno); - igt_assert(r == 0); - - if (last_seqno > seqno) - wrap++; - - last_seqno = seqno; - - return wrap; -} - -static int write_seqno(uint32_t seqno) -{ - int fh; - char buf[32]; - int r; - uint32_t rb = -1; - - if (options.dontwrap) - return 0; - - fh = igt_debugfs_open("i915_next_seqno", O_RDWR); - igt_assert(snprintf(buf, sizeof(buf), "0x%x", seqno) > 0); - - r = write(fh, buf, strnlen(buf, sizeof(buf))); - close(fh); - if (r < 0) - return r; - - igt_assert(r == strnlen(buf, sizeof(buf))); - - last_seqno = seqno; - - igt_debug("next_seqno set to: 0x%x\n", seqno); - - r = __read_seqno(&rb); - if (r < 0) - return r; - - if (rb != seqno) { - igt_info("seqno readback differs rb:0x%x vs w:0x%x\n", rb, seqno); - return -1; - } - - return 0; -} - -static uint32_t calc_prewrap_val(void) -{ - const int pval = options.prewrap_space; - - if (options.random == 0) - return pval; - - if (pval == 0) - return 0; - - return (random() % pval); -} - -static void run_test(void) -{ - run_sync_test(options.buffers, true); -} - -static void preset_run_once(void) -{ - igt_assert(write_seqno(1) == 0); - run_test(); - - igt_assert(write_seqno(0x7fffffff) == 0); - run_test(); - - igt_assert(write_seqno(0xffffffff) == 0); - run_test(); - - igt_assert(write_seqno(0xfffffff0) == 0); - run_test(); -} - -static void random_run_once(void) -{ - uint32_t val; - - do { - val = random() % UINT32_MAX; - if (RAND_MAX < UINT32_MAX) - val += random(); - } while (val == 0); - - igt_assert(write_seqno(val) == 0); - run_test(); -} - -static void wrap_run_once(void) -{ - const uint32_t pw_val = calc_prewrap_val(); - - igt_assert(write_seqno(UINT32_MAX - pw_val) == 0); - - while(!read_seqno()) - run_test(); -} - -static void background_run_once(void) -{ - const uint32_t pw_val = calc_prewrap_val(); - - igt_assert(write_seqno(UINT32_MAX - pw_val) == 0); - - while(!read_seqno()) - sleep(3); -} - -static int parse_options(int opt, int opt_index) -{ - switch(opt) { - case 'b': - options.background = 1; - igt_info("running in background inducing wraps\n"); - break; - case 'd': - options.dontwrap = 1; - igt_info("won't wrap after testruns\n"); - break; - case 'n': - options.rounds = atoi(optarg); - igt_info("running %d rounds\n", options.rounds); - break; - case 'i': - options.buffers = atoi(optarg); - igt_info("buffers %d\n", options.buffers); - break; - case 't': - options.timeout = atoi(optarg); - if (options.timeout == 0) - options.timeout = 10; - igt_info("setting timeout to %d seconds\n", options.timeout); - break; - case 'r': - options.random = 0; - break; - case 'p': - options.prewrap_space = atoi(optarg); - igt_info("prewrap set to %d (0x%x)\n", options.prewrap_space, UINT32_MAX - options.prewrap_space); - break; - } - - return 0; -} - -int main(int argc, char **argv) -{ - int wcount = 0; - - static struct option long_options[] = { - {"rounds", required_argument, 0, 'n'}, - {"background", no_argument, 0, 'b'}, - {"timeout", required_argument, 0, 't'}, - {"dontwrap", no_argument, 0, 'd'}, - {"prewrap", required_argument, 0, 'p'}, - {"norandom", no_argument, 0, 'r'}, - {"buffers", required_argument, 0, 'i'}, - { 0, 0, 0, 0 } - }; - - const char *help = - " -b --background run in background inducing wraps\n" - " -n --rounds=num run num times across wrap boundary, 0 == forever\n" - " -t --timeout=sec set timeout to wait for testrun to sec seconds\n" - " -d --dontwrap don't wrap just run the test\n" - " -p --prewrap=n set seqno to WRAP - n for each testrun\n" - " -r --norandom dont randomize prewrap space\n" - " -i --buffers number of buffers to copy\n"; - - options.rounds = SLOW_QUICK(50, 2); - options.background = 0; - options.dontwrap = 0; - options.timeout = 20; - options.random = 1; - options.prewrap_space = 21; - options.buffers = 10; - - igt_simple_init_parse_opts(&argc, argv, "n:bvt:dp:ri:", long_options, - help, parse_options); - - card_index = drm_get_card(); - - srandom(time(NULL)); - - while(options.rounds == 0 || wcount < options.rounds) { - if (options.background) { - background_run_once(); - } else { - preset_run_once(); - random_run_once(); - wrap_run_once(); - } - - wcount++; - - igt_debug("%s done: %d\n", - options.dontwrap ? "tests" : "wraps", wcount); - } - - igt_assert(options.rounds == wcount); - - igt_exit(); -} diff --git a/tests/gem_set_tiling_vs_blt.c b/tests/gem_set_tiling_vs_blt.c deleted file mode 100644 index ab2f8112..00000000 --- a/tests/gem_set_tiling_vs_blt.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright © 2012 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/** @file gem_set_tiling_vs_blt.c - * - * Testcase: Check for proper synchronization of tiling changes vs. tiled gpu - * access - * - * The blitter on gen3 and earlier needs properly set up fences. Which also - * means that for untiled blits we may not set up a fence before that blt has - * finished. - * - * Current kernels have a bug there, but it's pretty hard to hit because you - * need: - * - a blt on an untiled object which is aligned correctly for tiling. - * - a set_tiling to switch that object to tiling - * - another blt without any intervening cpu access that uses this object. - * - * Testcase has been extended to also check tiled->untiled and tiled->tiled - * transitions (i.e. changing stride). - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <stdbool.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "intel_io.h" - -IGT_TEST_DESCRIPTION("Check for proper synchronization of tiling changes vs." - " tiled gpu access."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -uint32_t devid; - -#define TEST_SIZE (1024*1024) -#define TEST_STRIDE (4*1024) -#define TEST_HEIGHT(stride) (TEST_SIZE/(stride)) -#define TEST_WIDTH(stride) ((stride)/4) - -uint32_t data[TEST_SIZE/4]; - -static void do_test(uint32_t tiling, unsigned stride, - uint32_t tiling_after, unsigned stride_after) -{ - drm_intel_bo *busy_bo, *test_bo, *target_bo; - int i, ret; - uint32_t *ptr; - uint32_t test_bo_handle; - uint32_t blt_stride, blt_bits; - bool tiling_changed = false; - - igt_info("filling ring .. "); - busy_bo = drm_intel_bo_alloc(bufmgr, "busy bo bo", 16*1024*1024, 4096); - - for (i = 0; i < 250; i++) { - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 2*1024*4); - OUT_BATCH(0 << 16 | 1024); - OUT_BATCH((2048) << 16 | (2048)); - OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(2*1024*4); - OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 6) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } - } - intel_batchbuffer_flush(batch); - - igt_info("playing tricks .. "); - /* first allocate the target so it gets out of the way of playing funky - * tricks */ - target_bo = drm_intel_bo_alloc(bufmgr, "target bo", TEST_SIZE, 4096); - - /* allocate buffer with parameters _after_ transition we want to check - * and touch it, so that it's properly aligned in the gtt. */ - test_bo = drm_intel_bo_alloc(bufmgr, "tiled busy bo", TEST_SIZE, 4096); - test_bo_handle = test_bo->handle; - ret = drm_intel_bo_set_tiling(test_bo, &tiling_after, stride_after); - igt_assert(ret == 0); - drm_intel_gem_bo_map_gtt(test_bo); - ptr = test_bo->virtual; - *ptr = 0; - ptr = NULL; - drm_intel_gem_bo_unmap_gtt(test_bo); - - drm_intel_bo_unreference(test_bo); - - test_bo = NULL; - - /* note we need a bo bigger than batches, otherwise the buffer reuse - * trick will fail. */ - test_bo = drm_intel_bo_alloc(bufmgr, "busy bo", TEST_SIZE, 4096); - /* double check that the reuse trick worked */ - igt_assert(test_bo_handle == test_bo->handle); - - test_bo_handle = test_bo->handle; - /* ensure we have the right tiling before we start. */ - ret = drm_intel_bo_set_tiling(test_bo, &tiling, stride); - igt_assert(ret == 0); - - if (tiling == I915_TILING_NONE) { - drm_intel_bo_subdata(test_bo, 0, TEST_SIZE, data); - } else { - drm_intel_gem_bo_map_gtt(test_bo); - ptr = test_bo->virtual; - memcpy(ptr, data, TEST_SIZE); - ptr = NULL; - drm_intel_gem_bo_unmap_gtt(test_bo); - } - - blt_stride = stride; - blt_bits = 0; - if (intel_gen(devid) >= 4 && tiling != I915_TILING_NONE) { - blt_stride /= 4; - blt_bits = XY_SRC_COPY_BLT_SRC_TILED; - } - - BLIT_COPY_BATCH_START(blt_bits); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - stride); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH((TEST_HEIGHT(stride)) << 16 | (TEST_WIDTH(stride))); - OUT_RELOC_FENCED(target_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(blt_stride); - OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - intel_batchbuffer_flush(batch); - - drm_intel_bo_unreference(test_bo); - - test_bo = drm_intel_bo_alloc_for_render(bufmgr, "tiled busy bo", TEST_SIZE, 4096); - /* double check that the reuse trick worked */ - igt_assert(test_bo_handle == test_bo->handle); - ret = drm_intel_bo_set_tiling(test_bo, &tiling_after, stride_after); - igt_assert(ret == 0); - - /* Note: We don't care about gen4+ here because the blitter doesn't use - * fences there. So not setting tiling flags on the tiled buffer is ok. - */ - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - stride_after); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH((1) << 16 | (1)); - OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(stride_after); - OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - intel_batchbuffer_flush(batch); - - /* Now try to trick the kernel the kernel into changing up the fencing - * too early. */ - - igt_info("checking .. "); - memset(data, 0, TEST_SIZE); - drm_intel_bo_get_subdata(target_bo, 0, TEST_SIZE, data); - for (i = 0; i < TEST_SIZE/4; i++) - igt_assert(data[i] == i); - - /* check whether tiling on the test_bo actually changed. */ - drm_intel_gem_bo_map_gtt(test_bo); - ptr = test_bo->virtual; - for (i = 0; i < TEST_SIZE/4; i++) - if (ptr[i] != data[i]) - tiling_changed = true; - ptr = NULL; - drm_intel_gem_bo_unmap_gtt(test_bo); - igt_assert(tiling_changed); - - drm_intel_bo_unreference(test_bo); - drm_intel_bo_unreference(target_bo); - drm_intel_bo_unreference(busy_bo); - igt_info("done\n"); -} - -int fd; - -igt_main -{ - int i; - uint32_t tiling, tiling_after; - - igt_skip_on_simulation(); - - igt_fixture { - for (i = 0; i < 1024*256; i++) - data[i] = i; - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - devid = intel_get_drm_devid(fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - } - - igt_subtest("untiled-to-tiled") { - tiling = I915_TILING_NONE; - tiling_after = I915_TILING_X; - do_test(tiling, TEST_STRIDE, tiling_after, TEST_STRIDE); - igt_assert(tiling == I915_TILING_NONE); - igt_assert(tiling_after == I915_TILING_X); - } - - igt_subtest("tiled-to-untiled") { - tiling = I915_TILING_X; - tiling_after = I915_TILING_NONE; - do_test(tiling, TEST_STRIDE, tiling_after, TEST_STRIDE); - igt_assert(tiling == I915_TILING_X); - igt_assert(tiling_after == I915_TILING_NONE); - } - - igt_subtest("tiled-to-tiled") { - tiling = I915_TILING_X; - tiling_after = I915_TILING_X; - do_test(tiling, TEST_STRIDE/2, tiling_after, TEST_STRIDE); - igt_assert(tiling == I915_TILING_X); - igt_assert(tiling_after == I915_TILING_X); - } -} diff --git a/tests/gem_set_tiling_vs_gtt.c b/tests/gem_set_tiling_vs_gtt.c deleted file mode 100644 index 006f50a0..00000000 --- a/tests/gem_set_tiling_vs_gtt.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright © 2012 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Check set_tiling vs gtt mmap coherency."); - -#define OBJECT_SIZE (1024*1024) -#define TEST_STRIDE (1024*4) - -/** - * Testcase: Check set_tiling vs gtt mmap coherency - */ - -igt_simple_main -{ - int fd; - uint32_t *ptr; - uint32_t data[OBJECT_SIZE/4]; - int i; - uint32_t handle; - bool tiling_changed; - int tile_height; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - if (IS_GEN2(intel_get_drm_devid(fd))) - tile_height = 16; - else - tile_height = 8; - - handle = gem_create(fd, OBJECT_SIZE); - ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr); - - /* gtt coherency is done with set_domain in libdrm, don't break that */ - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - for (i = 0; i < OBJECT_SIZE/4; i++) - ptr[i] = data[i] = i; - - gem_set_tiling(fd, handle, I915_TILING_X, TEST_STRIDE); - - igt_info("testing untiled->tiled\n"); - tiling_changed = false; - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, 0); - /* Too lazy to check for the correct tiling, and impossible anyway on - * bit17 swizzling machines. */ - for (i = 0; i < OBJECT_SIZE/4; i++) - if (ptr[i] != data[i]) - tiling_changed = true; - igt_assert(tiling_changed); - - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - for (i = 0; i < OBJECT_SIZE/4; i++) - ptr[i] = data[i] = i; - - gem_set_tiling(fd, handle, I915_TILING_X, TEST_STRIDE*2); - - igt_info("testing tiled->tiled\n"); - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, 0); - for (i = 0; i < OBJECT_SIZE/4; i++) { - int tile_row = i / (TEST_STRIDE * tile_height / 4); - int row = i / (TEST_STRIDE * 2 / 4); - int half = i & (TEST_STRIDE / 4); - int ofs = i % (TEST_STRIDE / 4); - int data_i = (tile_row/2)*(TEST_STRIDE * tile_height / 4) - + row*TEST_STRIDE/4 - + half*tile_height + ofs; - uint32_t val = data[data_i]; - - igt_assert_f(ptr[i] == val, - "mismatch at %i, row=%i, half=%i, ofs=%i, " - "read: 0x%08x, expected: 0x%08x\n", - i, row, half, ofs, - ptr[i], val); - - } - - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - for (i = 0; i < OBJECT_SIZE/4; i++) - ptr[i] = data[i] = i; - - gem_set_tiling(fd, handle, I915_TILING_NONE, 0); - igt_info("testing tiled->untiled\n"); - tiling_changed = false; - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, 0); - /* Too lazy to check for the correct tiling, and impossible anyway on - * bit17 swizzling machines. */ - for (i = 0; i < OBJECT_SIZE/4; i++) - if (ptr[i] != data[i]) - tiling_changed = true; - igt_assert(tiling_changed); - - munmap(ptr, OBJECT_SIZE); - - close(fd); -} diff --git a/tests/gem_set_tiling_vs_pwrite.c b/tests/gem_set_tiling_vs_pwrite.c deleted file mode 100644 index a4bdc64f..00000000 --- a/tests/gem_set_tiling_vs_pwrite.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright © 2012 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" - -IGT_TEST_DESCRIPTION("Check set_tiling vs pwrite coherency."); - -#define OBJECT_SIZE (1024*1024) -#define TEST_STRIDE (1024*4) - -/** - * Testcase: Check set_tiling vs pwrite coherency - */ - -igt_simple_main -{ - int fd; - uint32_t *ptr; - uint32_t data[OBJECT_SIZE/4]; - int i; - uint32_t handle; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - for (i = 0; i < OBJECT_SIZE/4; i++) - data[i] = i; - - handle = gem_create(fd, OBJECT_SIZE); - ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE); - igt_assert(ptr); - - gem_set_tiling(fd, handle, I915_TILING_X, TEST_STRIDE); - - /* touch it */ - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - *ptr = 0xdeadbeef; - - igt_info("testing pwrite on tiled buffer\n"); - gem_write(fd, handle, 0, data, OBJECT_SIZE); - memset(data, 0, OBJECT_SIZE); - gem_read(fd, handle, 0, data, OBJECT_SIZE); - for (i = 0; i < OBJECT_SIZE/4; i++) - igt_assert(i == data[i]); - - /* touch it before changing the tiling, so that the fence sticks around */ - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - *ptr = 0xdeadbeef; - - gem_set_tiling(fd, handle, I915_TILING_NONE, 0); - - igt_info("testing pwrite on untiled, but still fenced buffer\n"); - gem_write(fd, handle, 0, data, OBJECT_SIZE); - memset(data, 0, OBJECT_SIZE); - gem_read(fd, handle, 0, data, OBJECT_SIZE); - for (i = 0; i < OBJECT_SIZE/4; i++) - igt_assert(i == data[i]); - - munmap(ptr, OBJECT_SIZE); - - close(fd); -} diff --git a/tests/gem_storedw_batches_loop.c b/tests/gem_storedw_batches_loop.c deleted file mode 100644 index fef3718f..00000000 --- a/tests/gem_storedw_batches_loop.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * Jesse Barnes <jbarnes@virtuousgeek.org> (based on gem_bad_blit.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_chipset.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" - -static drm_intel_bufmgr *bufmgr; -static drm_intel_bo *target_bo; -static int has_ppgtt = 0; - -#define SECURE_DISPATCH (1<<0) - -/* Like the store dword test, but we create new command buffers each time */ -static void -store_dword_loop(int divider, unsigned flags) -{ - int cmd, i, val = 0; - uint32_t *buf; - drm_intel_bo *cmd_bo; - - igt_info("running storedw loop with stall every %i batch\n", divider); - - cmd = MI_STORE_DWORD_IMM; - if (!has_ppgtt) - cmd |= MI_MEM_VIRTUAL; - - for (i = 0; i < SLOW_QUICK(0x2000, 4); i++) { - int j = 0; - int cmd_address_offset; - cmd_bo = drm_intel_bo_alloc(bufmgr, "cmd bo", 4096, 4096); - igt_assert(cmd_bo); - - /* Upload through cpu mmaps to make sure we don't have a gtt - * mapping which could paper over secure batch submission - * failing to bind that. */ - drm_intel_bo_map(cmd_bo, 1); - buf = cmd_bo->virtual; - - buf[j++] = cmd; - if (intel_gen(drm_intel_bufmgr_gem_get_devid(bufmgr)) >= 8) { - cmd_address_offset = j * 4; - buf[j++] = target_bo->offset; - buf[j++] = 0; - } else { - buf[j++] = 0; - cmd_address_offset = j * 4; - buf[j++] = target_bo->offset; - } - igt_assert(j > 0); - buf[j++] = 0x42000000 + val; - - igt_assert(drm_intel_bo_references(cmd_bo, target_bo) == 0); - - igt_assert(drm_intel_bo_emit_reloc(cmd_bo, cmd_address_offset, target_bo, 0, - I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION) == 0); - buf[j++] = MI_BATCH_BUFFER_END; - buf[j++] = MI_BATCH_BUFFER_END; - - drm_intel_bo_unmap(cmd_bo); - - igt_assert(drm_intel_bo_references(cmd_bo, target_bo) == 1); - -#define LOCAL_I915_EXEC_SECURE (1<<9) - igt_assert(drm_intel_bo_mrb_exec(cmd_bo, j * 4, NULL, 0, 0, - I915_EXEC_BLT | - (flags & SECURE_DISPATCH ? LOCAL_I915_EXEC_SECURE : 0)) - == 0); - - if (i % divider != 0) - goto cont; - - drm_intel_bo_wait_rendering(cmd_bo); - - drm_intel_bo_map(target_bo, 1); - - buf = target_bo->virtual; - igt_assert_f(buf[0] == (0x42000000 | val), - "value mismatch: cur 0x%08x, stored 0x%08x\n", - buf[0], 0x42000000 | val); - - buf[0] = 0; /* let batch write it again */ - drm_intel_bo_unmap(target_bo); - -cont: - drm_intel_bo_unreference(cmd_bo); - - val++; - } - - igt_info("completed %d writes successfully\n", i); -} - -int fd; -int devid; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - has_ppgtt = gem_uses_aliasing_ppgtt(fd); - - /* storedw needs gtt address on gen4+/g33 and snoopable memory. - * Strictly speaking we could implement this now ... */ - igt_require(intel_gen(devid) >= 6); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - - // drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - target_bo = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_bo); - } - - igt_subtest("normal") { - store_dword_loop(1, 0); - store_dword_loop(2, 0); - store_dword_loop(3, 0); - store_dword_loop(5, 0); - } - - igt_subtest("secure-dispatch") { - store_dword_loop(1, SECURE_DISPATCH); - store_dword_loop(2, SECURE_DISPATCH); - store_dword_loop(3, SECURE_DISPATCH); - store_dword_loop(5, SECURE_DISPATCH); - } - - igt_fixture { - drm_intel_bo_unreference(target_bo); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_storedw_loop_blt.c b/tests/gem_storedw_loop_blt.c deleted file mode 100644 index 44e46a84..00000000 --- a/tests/gem_storedw_loop_blt.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * Jesse Barnes <jbarnes@virtuousgeek.org> (based on gem_bad_blit.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Basic blitter MI check using MI_STORE_DATA_IMM."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *target_buffer; -static int has_ppgtt = 0; - -/* - * Testcase: Basic blitter MI check using MI_STORE_DATA_IMM - */ - -static void -emit_store_dword_imm(int devid, drm_intel_bo *dest, uint32_t val) -{ - int cmd; - cmd = MI_STORE_DWORD_IMM; - if (!has_ppgtt) - cmd |= MI_MEM_VIRTUAL; - - BEGIN_BATCH(4, 0); - OUT_BATCH(cmd); - if (batch->gen >= 8) { - OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - OUT_BATCH(val); - } else { - OUT_BATCH(0); /* reserved */ - OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - OUT_BATCH(val); - } - ADVANCE_BATCH(); -} - -static void -store_dword_loop(int devid, int divider) -{ - int i, val = 0; - uint32_t *buf; - - igt_info("running storedw loop on render with stall every %i batch\n", divider); - - for (i = 0; i < SLOW_QUICK(0x2000, 0x10); i++) { - emit_store_dword_imm(devid, target_buffer, val); - intel_batchbuffer_flush_on_ring(batch, I915_EXEC_BLT); - - if (i % divider != 0) - goto cont; - - drm_intel_bo_map(target_buffer, 0); - - buf = target_buffer->virtual; - igt_assert_f(buf[0] == val, - "value mismatch: cur 0x%08x, stored 0x%08x\n", - buf[0], val); - - drm_intel_bo_unmap(target_buffer); - -cont: - val++; - } - - drm_intel_bo_map(target_buffer, 0); - buf = target_buffer->virtual; - - igt_info("completed %d writes successfully, current value: 0x%08x\n", i, - buf[0]); - drm_intel_bo_unmap(target_buffer); -} - -igt_simple_main -{ - int fd; - int devid; - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - has_ppgtt = gem_uses_aliasing_ppgtt(fd); - - igt_skip_on_f(intel_gen(devid) < 6, - "MI_STORE_DATA can only use GTT address on gen4+/g33 and " - "needs snoopable mem on pre-gen6\n"); - - /* This only works with ppgtt */ - igt_require(has_ppgtt); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - - target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_buffer); - - store_dword_loop(devid, 1); - store_dword_loop(devid, 2); - if (!igt_run_in_simulation()) { - store_dword_loop(devid, 3); - store_dword_loop(devid, 5); - } - - drm_intel_bo_unreference(target_buffer); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_storedw_loop_bsd.c b/tests/gem_storedw_loop_bsd.c deleted file mode 100644 index e534c16f..00000000 --- a/tests/gem_storedw_loop_bsd.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * Jesse Barnes <jbarnes@virtuousgeek.org> (based on gem_bad_blit.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Basic bsd MI check using MI_STORE_DATA_IMM."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *target_buffer; -static int has_ppgtt = 0; - -/* - * Testcase: Basic bsd MI check using MI_STORE_DATA_IMM - */ - -static void -emit_store_dword_imm(int devid, drm_intel_bo *dest, uint32_t val) -{ - int cmd; - cmd = MI_STORE_DWORD_IMM; - if (!has_ppgtt) - cmd |= MI_MEM_VIRTUAL; - - BEGIN_BATCH(4, 0); - OUT_BATCH(cmd); - if (batch->gen >= 8) { - OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - OUT_BATCH(val); - } else { - OUT_BATCH(0); /* reserved */ - OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - OUT_BATCH(val); - } - ADVANCE_BATCH(); -} - -static void -store_dword_loop(int devid, int divider) -{ - int i, val = 0; - uint32_t *buf; - - igt_info("running storedw loop on render with stall every %i batch\n", divider); - - for (i = 0; i < SLOW_QUICK(0x2000, 0x10); i++) { - emit_store_dword_imm(devid, target_buffer, val); - intel_batchbuffer_flush_on_ring(batch, I915_EXEC_BSD); - - if (i % divider != 0) - goto cont; - - drm_intel_bo_map(target_buffer, 0); - - buf = target_buffer->virtual; - igt_assert_f(buf[0] == val, - "value mismatch: cur 0x%08x, stored 0x%08x\n", - buf[0], val); - - drm_intel_bo_unmap(target_buffer); - -cont: - val++; - } - - drm_intel_bo_map(target_buffer, 0); - buf = target_buffer->virtual; - - igt_info("completed %d writes successfully, current value: 0x%08x\n", i, - buf[0]); - drm_intel_bo_unmap(target_buffer); -} - -igt_simple_main -{ - int fd; - int devid; - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - has_ppgtt = gem_uses_aliasing_ppgtt(fd); - - igt_skip_on_f(intel_gen(devid) < 6, - "MI_STORE_DATA can only use GTT address on gen4+/g33 and " - "needs snoopable mem on pre-gen6\n"); - - igt_skip_on_f(intel_gen(devid) == 6, - "MI_STORE_DATA broken on gen6 bsd\n"); - - /* This only works with ppgtt */ - igt_require(has_ppgtt); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - - target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_buffer); - - store_dword_loop(devid, 1); - store_dword_loop(devid, 2); - if (!igt_run_in_simulation()) { - store_dword_loop(devid, 3); - store_dword_loop(devid, 5); - } - - drm_intel_bo_unreference(target_buffer); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_storedw_loop_render.c b/tests/gem_storedw_loop_render.c deleted file mode 100644 index 48fb6d4e..00000000 --- a/tests/gem_storedw_loop_render.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * Jesse Barnes <jbarnes@virtuousgeek.org> (based on gem_bad_blit.c) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Basic render MI check using MI_STORE_DATA_IMM."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *target_buffer; -static int has_ppgtt = 0; - -/* - * Testcase: Basic render MI check using MI_STORE_DATA_IMM - */ - -static void -emit_store_dword_imm(int devid, drm_intel_bo *dest, uint32_t val) -{ - int cmd; - cmd = MI_STORE_DWORD_IMM; - if (!has_ppgtt) - cmd |= MI_MEM_VIRTUAL; - - BEGIN_BATCH(4, 0); - OUT_BATCH(cmd); - if (batch->gen >= 8) { - OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - OUT_BATCH(val); - } else { - OUT_BATCH(0); /* reserved */ - OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - OUT_BATCH(val); - } - ADVANCE_BATCH(); -} - -static void -store_dword_loop(int devid, int divider) -{ - int i, val = 0; - uint32_t *buf; - - igt_info("running storedw loop on render with stall every %i batch\n", divider); - - for (i = 0; i < SLOW_QUICK(0x2000, 0x10); i++) { - emit_store_dword_imm(devid, target_buffer, val); - intel_batchbuffer_flush_on_ring(batch, 0); - - if (i % divider != 0) - goto cont; - - drm_intel_bo_map(target_buffer, 0); - - buf = target_buffer->virtual; - igt_assert_f(buf[0] == val, - "value mismatch: cur 0x%08x, stored 0x%08x\n", - buf[0], val); - - drm_intel_bo_unmap(target_buffer); - -cont: - val++; - } - - drm_intel_bo_map(target_buffer, 0); - buf = target_buffer->virtual; - - igt_info("completed %d writes successfully, current value: 0x%08x\n", i, - buf[0]); - drm_intel_bo_unmap(target_buffer); -} - -igt_simple_main -{ - int fd; - int devid; - - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - has_ppgtt = gem_uses_aliasing_ppgtt(fd); - - igt_skip_on_f(intel_gen(devid) < 6, - "MI_STORE_DATA can only use GTT address on gen4+/g33 and " - "needs snoopable mem on pre-gen6\n"); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - - target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_buffer); - - store_dword_loop(devid, 1); - store_dword_loop(devid, 2); - if (!igt_run_in_simulation()) { - store_dword_loop(devid, 3); - store_dword_loop(devid, 5); - } - - drm_intel_bo_unreference(target_buffer); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_storedw_loop_vebox.c b/tests/gem_storedw_loop_vebox.c deleted file mode 100644 index 8643dd39..00000000 --- a/tests/gem_storedw_loop_vebox.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright © 2012 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: - * Xiang, Haihao <haihao.xiang@intel.com> (based on gem_store_dw_loop_*) - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Basic vebox MI check using MI_STORE_DATA_IMM."); - -#define LOCAL_I915_EXEC_VEBOX (4<<0) - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *target_buffer; - -/* - * Testcase: Basic vebox MI check using MI_STORE_DATA_IMM - */ - -static void -store_dword_loop(int divider) -{ - int cmd, i, val = 0; - uint32_t *buf; - - igt_info("running storedw loop on blt with stall every %i batch\n", divider); - - cmd = MI_STORE_DWORD_IMM; - - for (i = 0; i < SLOW_QUICK(0x2000, 0x10); i++) { - BEGIN_BATCH(4, 0); - OUT_BATCH(cmd); - if (batch->gen < 8) - OUT_BATCH(0); /* reserved */ - OUT_RELOC(target_buffer, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - OUT_BATCH(val); - ADVANCE_BATCH(); - - intel_batchbuffer_flush_on_ring(batch, LOCAL_I915_EXEC_VEBOX); - - if (i % divider != 0) - goto cont; - - drm_intel_bo_map(target_buffer, 0); - - buf = target_buffer->virtual; - igt_assert_eq_u32(buf[0], val); - - drm_intel_bo_unmap(target_buffer); - -cont: - val++; - } - - drm_intel_bo_map(target_buffer, 0); - buf = target_buffer->virtual; - - igt_info("completed %d writes successfully, current value: 0x%08x\n", i, - buf[0]); - drm_intel_bo_unmap(target_buffer); -} - -igt_simple_main -{ - int fd; - - fd = drm_open_any(); - - igt_require(gem_has_vebox(fd)); - igt_require(gem_uses_aliasing_ppgtt(fd)); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - igt_require(batch); - - target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_require(target_buffer); - - store_dword_loop(1); - store_dword_loop(2); - if (!igt_run_in_simulation()) { - store_dword_loop(3); - store_dword_loop(5); - } - - drm_intel_bo_unreference(target_buffer); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_stress.c b/tests/gem_stress.c deleted file mode 100644 index cb951af8..00000000 --- a/tests/gem_stress.c +++ /dev/null @@ -1,917 +0,0 @@ -/* - * Copyright © 2011 Daniel Vetter - * - * 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - * Partially based upon gem_tiled_fence_blits.c - */ - -/** @file gem_stress.c - * - * This is a general gem coherency test. It's designed to eventually replicate - * any possible sequence of access patterns. It works by copying a set of tiles - * between two sets of backing buffer objects, randomly permutating the assinged - * position on each copy operations. - * - * The copy operation are done in tiny portions (to reduce any race windows - * for corruptions, hence increasing the chances for observing one) and are - * constantly switched between all means to copy stuff (fenced blitter, unfenced - * render, mmap, pwrite/read). - * - * After every complete move of a set tiling parameters of a buffer are randomly - * changed to simulate the effects of libdrm caching. - * - * Buffers are 1mb big to nicely fit into fences on gen2/3. A few are further - * split up to test relaxed fencing. Using this to push the average working set - * size over the available gtt space forces objects to be mapped as unfenceable - * (and as a side-effect tests gtt map/unmap coherency). - * - * In short: designed for maximum evilness. - */ - -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("General gem coherency test."); - -#define CMD_POLY_STIPPLE_OFFSET 0x7906 - -#define DUCTAPE 0xdead0001 -#define TILESZ 0xdead0002 -#define CHCK_RENDER 0xdead0003 - -/** TODO: - * - beat on relaxed fencing (i.e. mappable/fenceable tracking in the kernel) - * - render copy (to check fence tracking and cache coherency management by the - * kernel) - * - multi-threading: probably just a wrapper script to launch multiple - * instances + an option to accordingly reduce the working set - * - gen6 inter-ring coherency (needs render copy, first) - * - variable buffer size - * - add an option to fork a second process that randomly sends signals to the - * first one (to check consistency of the kernel recovery paths) - */ - -drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -int drm_fd; -int devid; -int num_fences; - -drm_intel_bo *busy_bo; - -struct option_struct { - unsigned scratch_buf_size; - unsigned max_dimension; - unsigned num_buffers; - int trace_tile; - int no_hw; - int gpu_busy_load; - int use_render; - int use_blt; - int forced_tiling; - int use_cpu_maps; - int total_rounds; - int fail; - int tiles_per_buf; - int ducttape; - int tile_size; - int check_render_cpyfn; - int use_signal_helper; -}; - -struct option_struct options; - -#define MAX_BUFS 4096 -#define SCRATCH_BUF_SIZE 1024*1024 -#define BUSY_BUF_SIZE (256*4096) -#define TILE_BYTES(size) ((size)*(size)*sizeof(uint32_t)) - -static struct igt_buf buffers[2][MAX_BUFS]; -/* tile i is at logical position tile_permutation[i] */ -static unsigned *tile_permutation; -static unsigned num_buffers = 0; -static unsigned current_set = 0; -static unsigned target_set = 0; -static unsigned num_total_tiles = 0; - -int fence_storm = 0; -static int gpu_busy_load = 10; - -struct { - unsigned num_failed; - unsigned max_failed_reads; -} stats; - -static void tile2xy(struct igt_buf *buf, unsigned tile, unsigned *x, unsigned *y) -{ - igt_assert(tile < buf->num_tiles); - *x = (tile*options.tile_size) % (buf->stride/sizeof(uint32_t)); - *y = ((tile*options.tile_size) / (buf->stride/sizeof(uint32_t))) * options.tile_size; -} - -static void emit_blt(drm_intel_bo *src_bo, uint32_t src_tiling, unsigned src_pitch, - unsigned src_x, unsigned src_y, unsigned w, unsigned h, - drm_intel_bo *dst_bo, uint32_t dst_tiling, unsigned dst_pitch, - unsigned dst_x, unsigned dst_y) -{ - uint32_t cmd_bits = 0; - - if (IS_965(devid) && src_tiling) { - src_pitch /= 4; - cmd_bits |= XY_SRC_COPY_BLT_SRC_TILED; - } - - if (IS_965(devid) && dst_tiling) { - dst_pitch /= 4; - cmd_bits |= XY_SRC_COPY_BLT_DST_TILED; - } - - /* copy lower half to upper half */ - BLIT_COPY_BATCH_START(cmd_bits); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - dst_pitch); - OUT_BATCH(dst_y << 16 | dst_x); - OUT_BATCH((dst_y+h) << 16 | (dst_x+w)); - OUT_RELOC_FENCED(dst_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(src_y << 16 | src_x); - OUT_BATCH(src_pitch); - OUT_RELOC_FENCED(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 6) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } -} - -/* All this gem trashing wastes too much cpu time, so give the gpu something to - * do to increase changes for races. */ -static void keep_gpu_busy(void) -{ - int tmp; - - tmp = 1 << gpu_busy_load; - igt_assert(tmp <= 1024); - - emit_blt(busy_bo, 0, 4096, 0, 0, tmp, 128, - busy_bo, 0, 4096, 0, 128); -} - -static void set_to_cpu_domain(struct igt_buf *buf, int writing) -{ - gem_set_domain(drm_fd, buf->bo->handle, I915_GEM_DOMAIN_CPU, - writing ? I915_GEM_DOMAIN_CPU : 0); -} - -static unsigned int copyfunc_seq = 0; -static void (*copyfunc)(struct igt_buf *src, unsigned src_x, unsigned src_y, - struct igt_buf *dst, unsigned dst_x, unsigned dst_y, - unsigned logical_tile_no); - -/* stride, x, y in units of uint32_t! */ -static void cpucpy2d(uint32_t *src, unsigned src_stride, unsigned src_x, unsigned src_y, - uint32_t *dst, unsigned dst_stride, unsigned dst_x, unsigned dst_y, - unsigned logical_tile_no) -{ - int i, j; - int failed = 0; - - for (i = 0; i < options.tile_size; i++) { - for (j = 0; j < options.tile_size; j++) { - unsigned dst_ofs = dst_x + j + dst_stride * (dst_y + i); - unsigned src_ofs = src_x + j + src_stride * (src_y + i); - unsigned expect = logical_tile_no*options.tile_size*options.tile_size - + i*options.tile_size + j; - uint32_t tmp = src[src_ofs]; - if (tmp != expect) { - igt_info("mismatch at tile %i pos %i, read %i, expected %i, diff %i\n", logical_tile_no, i * options.tile_size + j, tmp, expect, (int)tmp - expect); - igt_fail_on(options.trace_tile >= 0 && options.fail); - failed++; - } - /* when not aborting, correct any errors */ - dst[dst_ofs] = expect; - } - } - igt_fail_on(failed && options.fail); - - if (failed > stats.max_failed_reads) - stats.max_failed_reads = failed; - if (failed) - stats.num_failed++; -} - -static void cpu_copyfunc(struct igt_buf *src, unsigned src_x, unsigned src_y, - struct igt_buf *dst, unsigned dst_x, unsigned dst_y, - unsigned logical_tile_no) -{ - igt_assert(batch->ptr == batch->buffer); - - if (options.ducttape) - drm_intel_bo_wait_rendering(dst->bo); - - if (options.use_cpu_maps) { - set_to_cpu_domain(src, 0); - set_to_cpu_domain(dst, 1); - } - - cpucpy2d(src->data, src->stride/sizeof(uint32_t), src_x, src_y, - dst->data, dst->stride/sizeof(uint32_t), dst_x, dst_y, - logical_tile_no); -} - -static void prw_copyfunc(struct igt_buf *src, unsigned src_x, unsigned src_y, - struct igt_buf *dst, unsigned dst_x, unsigned dst_y, - unsigned logical_tile_no) -{ - uint32_t tmp_tile[options.tile_size*options.tile_size]; - int i; - - igt_assert(batch->ptr == batch->buffer); - - if (options.ducttape) - drm_intel_bo_wait_rendering(dst->bo); - - if (src->tiling == I915_TILING_NONE) { - for (i = 0; i < options.tile_size; i++) { - unsigned ofs = src_x*sizeof(uint32_t) + src->stride*(src_y + i); - drm_intel_bo_get_subdata(src->bo, ofs, - options.tile_size*sizeof(uint32_t), - tmp_tile + options.tile_size*i); - } - } else { - if (options.use_cpu_maps) - set_to_cpu_domain(src, 0); - - cpucpy2d(src->data, src->stride/sizeof(uint32_t), src_x, src_y, - tmp_tile, options.tile_size, 0, 0, logical_tile_no); - } - - if (dst->tiling == I915_TILING_NONE) { - for (i = 0; i < options.tile_size; i++) { - unsigned ofs = dst_x*sizeof(uint32_t) + dst->stride*(dst_y + i); - drm_intel_bo_subdata(dst->bo, ofs, - options.tile_size*sizeof(uint32_t), - tmp_tile + options.tile_size*i); - } - } else { - if (options.use_cpu_maps) - set_to_cpu_domain(dst, 1); - - cpucpy2d(tmp_tile, options.tile_size, 0, 0, - dst->data, dst->stride/sizeof(uint32_t), dst_x, dst_y, - logical_tile_no); - } -} - -static void blitter_copyfunc(struct igt_buf *src, unsigned src_x, unsigned src_y, - struct igt_buf *dst, unsigned dst_x, unsigned dst_y, - unsigned logical_tile_no) -{ - static unsigned keep_gpu_busy_counter = 0; - - /* check both edges of the fence usage */ - if (keep_gpu_busy_counter & 1 && !fence_storm) - keep_gpu_busy(); - - emit_blt(src->bo, src->tiling, src->stride, src_x, src_y, - options.tile_size, options.tile_size, - dst->bo, dst->tiling, dst->stride, dst_x, dst_y); - - if (!(keep_gpu_busy_counter & 1) && !fence_storm) - keep_gpu_busy(); - - keep_gpu_busy_counter++; - - if (src->tiling) - fence_storm--; - if (dst->tiling) - fence_storm--; - - if (fence_storm <= 1) { - fence_storm = 0; - intel_batchbuffer_flush(batch); - } -} - -static void render_copyfunc(struct igt_buf *src, unsigned src_x, unsigned src_y, - struct igt_buf *dst, unsigned dst_x, unsigned dst_y, - unsigned logical_tile_no) -{ - static unsigned keep_gpu_busy_counter = 0; - igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(devid); - - /* check both edges of the fence usage */ - if (keep_gpu_busy_counter & 1) - keep_gpu_busy(); - - if (rendercopy) { - /* - * Flush outstanding blts so that they don't end up on - * the render ring when that's not allowed (gen6+). - */ - intel_batchbuffer_flush(batch); - rendercopy(batch, NULL, src, src_x, src_y, - options.tile_size, options.tile_size, - dst, dst_x, dst_y); - } else - blitter_copyfunc(src, src_x, src_y, - dst, dst_x, dst_y, - logical_tile_no); - if (!(keep_gpu_busy_counter & 1)) - keep_gpu_busy(); - - keep_gpu_busy_counter++; - intel_batchbuffer_flush(batch); -} - -static void next_copyfunc(int tile) -{ - if (fence_storm) { - if (tile == options.trace_tile) - igt_info(" using fence storm\n"); - return; - } - - if (copyfunc_seq % 61 == 0 - && options.forced_tiling != I915_TILING_NONE) { - if (tile == options.trace_tile) - igt_info(" using fence storm\n"); - fence_storm = num_fences; - copyfunc = blitter_copyfunc; - } else if (copyfunc_seq % 17 == 0) { - if (tile == options.trace_tile) - igt_info(" using cpu\n"); - copyfunc = cpu_copyfunc; - } else if (copyfunc_seq % 19 == 0) { - if (tile == options.trace_tile) - igt_info(" using prw\n"); - copyfunc = prw_copyfunc; - } else if (copyfunc_seq % 3 == 0 && options.use_render) { - if (tile == options.trace_tile) - igt_info(" using render\n"); - copyfunc = render_copyfunc; - } else if (options.use_blt){ - if (tile == options.trace_tile) - igt_info(" using blitter\n"); - copyfunc = blitter_copyfunc; - } else if (options.use_render){ - if (tile == options.trace_tile) - igt_info(" using render\n"); - copyfunc = render_copyfunc; - } else { - copyfunc = cpu_copyfunc; - } - - copyfunc_seq++; -} - -static void fan_out(void) -{ - uint32_t tmp_tile[options.tile_size*options.tile_size]; - uint32_t seq = 0; - int i, k; - unsigned tile, buf_idx, x, y; - - for (i = 0; i < num_total_tiles; i++) { - tile = i; - buf_idx = tile / options.tiles_per_buf; - tile %= options.tiles_per_buf; - - tile2xy(&buffers[current_set][buf_idx], tile, &x, &y); - - for (k = 0; k < options.tile_size*options.tile_size; k++) - tmp_tile[k] = seq++; - - if (options.use_cpu_maps) - set_to_cpu_domain(&buffers[current_set][buf_idx], 1); - - cpucpy2d(tmp_tile, options.tile_size, 0, 0, - buffers[current_set][buf_idx].data, - buffers[current_set][buf_idx].stride / sizeof(uint32_t), - x, y, i); - } - - for (i = 0; i < num_total_tiles; i++) - tile_permutation[i] = i; -} - -static void fan_in_and_check(void) -{ - uint32_t tmp_tile[options.tile_size*options.tile_size]; - unsigned tile, buf_idx, x, y; - int i; - for (i = 0; i < num_total_tiles; i++) { - tile = tile_permutation[i]; - buf_idx = tile / options.tiles_per_buf; - tile %= options.tiles_per_buf; - - tile2xy(&buffers[current_set][buf_idx], tile, &x, &y); - - if (options.use_cpu_maps) - set_to_cpu_domain(&buffers[current_set][buf_idx], 0); - - cpucpy2d(buffers[current_set][buf_idx].data, - buffers[current_set][buf_idx].stride / sizeof(uint32_t), - x, y, - tmp_tile, options.tile_size, 0, 0, - i); - } -} - -static void sanitize_stride(struct igt_buf *buf) -{ - - if (igt_buf_height(buf) > options.max_dimension) - buf->stride = buf->size / options.max_dimension; - - if (igt_buf_height(buf) < options.tile_size) - buf->stride = buf->size / options.tile_size; - - if (igt_buf_width(buf) < options.tile_size) - buf->stride = options.tile_size * sizeof(uint32_t); - - igt_assert(buf->stride <= 8192); - igt_assert(igt_buf_width(buf) <= options.max_dimension); - igt_assert(igt_buf_height(buf) <= options.max_dimension); - - igt_assert(igt_buf_width(buf) >= options.tile_size); - igt_assert(igt_buf_height(buf) >= options.tile_size); - -} - -static void init_buffer(struct igt_buf *buf, unsigned size) -{ - buf->bo = drm_intel_bo_alloc(bufmgr, "tiled bo", size, 4096); - buf->size = size; - igt_assert(buf->bo); - buf->tiling = I915_TILING_NONE; - buf->stride = 4096; - - sanitize_stride(buf); - - if (options.no_hw) - buf->data = malloc(size); - else { - if (options.use_cpu_maps) - drm_intel_bo_map(buf->bo, 1); - else - drm_intel_gem_bo_map_gtt(buf->bo); - buf->data = buf->bo->virtual; - } - - buf->num_tiles = options.tiles_per_buf; -} - -static void exchange_buf(void *array, unsigned i, unsigned j) -{ - struct igt_buf *buf_arr, tmp; - buf_arr = array; - - memcpy(&tmp, &buf_arr[i], sizeof(struct igt_buf)); - memcpy(&buf_arr[i], &buf_arr[j], sizeof(struct igt_buf)); - memcpy(&buf_arr[j], &tmp, sizeof(struct igt_buf)); -} - - -static void init_set(unsigned set) -{ - long int r; - int i; - - igt_permute_array(buffers[set], num_buffers, exchange_buf); - - if (current_set == 1 && options.gpu_busy_load == 0) { - gpu_busy_load++; - if (gpu_busy_load > 10) - gpu_busy_load = 6; - } - - for (i = 0; i < num_buffers; i++) { - r = random(); - if ((r & 3) != 0) - continue; - r >>= 2; - - if ((r & 3) != 0) - buffers[set][i].tiling = I915_TILING_X; - else - buffers[set][i].tiling = I915_TILING_NONE; - r >>= 2; - if (options.forced_tiling >= 0) - buffers[set][i].tiling = options.forced_tiling; - - if (buffers[set][i].tiling == I915_TILING_NONE) { - /* min 64 byte stride */ - r %= 8; - buffers[set][i].stride = 64 * (1 << r); - } else if (IS_GEN2(devid)) { - /* min 128 byte stride */ - r %= 7; - buffers[set][i].stride = 128 * (1 << r); - } else { - /* min 512 byte stride */ - r %= 5; - buffers[set][i].stride = 512 * (1 << r); - } - - sanitize_stride(&buffers[set][i]); - - gem_set_tiling(drm_fd, buffers[set][i].bo->handle, - buffers[set][i].tiling, - buffers[set][i].stride); - - if (options.trace_tile != -1 && i == options.trace_tile/options.tiles_per_buf) - igt_info("changing buffer %i containing tile %i: tiling %i, stride %i\n", i, options.trace_tile, buffers[set][i].tiling, buffers[set][i].stride); - } -} - -static void exchange_uint(void *array, unsigned i, unsigned j) -{ - unsigned *i_arr = array; - - igt_swap(i_arr[i], i_arr[j]); -} - -static void copy_tiles(unsigned *permutation) -{ - unsigned src_tile, src_buf_idx, src_x, src_y; - unsigned dst_tile, dst_buf_idx, dst_x, dst_y; - struct igt_buf *src_buf, *dst_buf; - int i, idx; - for (i = 0; i < num_total_tiles; i++) { - /* tile_permutation is independent of current_permutation, so - * abuse it to randomize the order of the src bos */ - idx = tile_permutation[i]; - src_buf_idx = idx / options.tiles_per_buf; - src_tile = idx % options.tiles_per_buf; - src_buf = &buffers[current_set][src_buf_idx]; - - tile2xy(src_buf, src_tile, &src_x, &src_y); - - dst_buf_idx = permutation[idx] / options.tiles_per_buf; - dst_tile = permutation[idx] % options.tiles_per_buf; - dst_buf = &buffers[target_set][dst_buf_idx]; - - tile2xy(dst_buf, dst_tile, &dst_x, &dst_y); - - if (options.trace_tile == i) - igt_info("copying tile %i from %i (%i, %i) to %i (%i, %i)", i, tile_permutation[i], src_buf_idx, src_tile, permutation[idx], dst_buf_idx, dst_tile); - - if (options.no_hw) { - cpucpy2d(src_buf->data, - src_buf->stride / sizeof(uint32_t), - src_x, src_y, - dst_buf->data, - dst_buf->stride / sizeof(uint32_t), - dst_x, dst_y, - i); - } else { - next_copyfunc(i); - - copyfunc(src_buf, src_x, src_y, dst_buf, dst_x, dst_y, - i); - } - } - - intel_batchbuffer_flush(batch); -} - -static void sanitize_tiles_per_buf(void) -{ - if (options.tiles_per_buf > options.scratch_buf_size / TILE_BYTES(options.tile_size)) - options.tiles_per_buf = options.scratch_buf_size / TILE_BYTES(options.tile_size); -} - -static int parse_options(int opt, int opt_index) -{ - int tmp; - - switch(opt) { - case 'd': - options.no_hw = 1; - igt_info("no-hw debug mode\n"); - break; - case 'S': - options.use_signal_helper = 0; - igt_info("disabling that pesky nuisance who keeps interrupting us\n"); - break; - case 's': - tmp = atoi(optarg); - if (tmp < options.tile_size*8192) - igt_info("scratch buffer size needs to be at least %i\n", options.tile_size * 8192); - else if (tmp & (tmp - 1)) { - igt_info("scratch buffer size needs to be a power-of-two\n"); - } else { - igt_info("fixed scratch buffer size to %u\n", tmp); - options.scratch_buf_size = tmp; - sanitize_tiles_per_buf(); - } - break; - case 'g': - tmp = atoi(optarg); - if (tmp < 0 || tmp > 10) - igt_info("gpu busy load needs to be bigger than 0 and smaller than 10\n"); - else { - igt_info("gpu busy load factor set to %i\n", tmp); - gpu_busy_load = options.gpu_busy_load = tmp; - } - break; - case 'c': - options.num_buffers = atoi(optarg); - igt_info("buffer count set to %i\n", options.num_buffers); - break; - case 't': - options.trace_tile = atoi(optarg); - igt_info("tracing tile %i\n", options.trace_tile); - break; - case 'r': - options.use_render = 0; - igt_info("disabling render copy\n"); - break; - case 'b': - options.use_blt = 0; - igt_info("disabling blt copy\n"); - break; - case 'u': - options.forced_tiling = I915_TILING_NONE; - igt_info("disabling tiling\n"); - break; - case 'x': - if (options.use_cpu_maps) { - igt_info("tiling not possible with cpu maps\n"); - } else { - options.forced_tiling = I915_TILING_X; - igt_info("using only X-tiling\n"); - } - break; - case 'm': - options.use_cpu_maps = 1; - options.forced_tiling = I915_TILING_NONE; - igt_info("disabling tiling\n"); - break; - case 'o': - options.total_rounds = atoi(optarg); - igt_info("total rounds %i\n", options.total_rounds); - break; - case 'f': - options.fail = 0; - igt_info("not failing when detecting errors\n"); - break; - case 'p': - options.tiles_per_buf = atoi(optarg); - igt_info("tiles per buffer %i\n", options.tiles_per_buf); - break; - case DUCTAPE: - options.ducttape = 0; - igt_info("applying duct-tape\n"); - break; - case TILESZ: - options.tile_size = atoi(optarg); - sanitize_tiles_per_buf(); - igt_info("til size %i\n", options.tile_size); - break; - case CHCK_RENDER: - options.check_render_cpyfn = 1; - igt_info("checking render copy function\n"); - break; - } - - /* actually 32767, according to docs, but that kills our nice pot calculations. */ - options.max_dimension = 16*1024; - if (options.use_render) { - if (IS_GEN2(devid) || IS_GEN3(devid)) - options.max_dimension = 2048; - else - options.max_dimension = 8192; - } - igt_info("Limiting buffer to %dx%d\n", options.max_dimension, options.max_dimension); - - return 0; -} - -static void init(void) -{ - int i; - unsigned tmp; - - if (options.num_buffers == 0) { - tmp = gem_aperture_size(drm_fd); - tmp = min(256 * (1024 * 1024), tmp); - num_buffers = 2 * tmp / options.scratch_buf_size / 3; - num_buffers /= 2; - igt_info("using %u buffers\n", num_buffers); - } else - num_buffers = options.num_buffers; - - bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - drm_intel_bufmgr_gem_enable_fenced_relocs(bufmgr); - num_fences = gem_available_fences(drm_fd); - igt_assert(num_fences > 4); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - busy_bo = drm_intel_bo_alloc(bufmgr, "tiled bo", BUSY_BUF_SIZE, 4096); - if (options.forced_tiling >= 0) - gem_set_tiling(drm_fd, busy_bo->handle, options.forced_tiling, 4096); - - for (i = 0; i < num_buffers; i++) { - init_buffer(&buffers[0][i], options.scratch_buf_size); - init_buffer(&buffers[1][i], options.scratch_buf_size); - - num_total_tiles += buffers[0][i].num_tiles; - } - current_set = 0; - - /* just in case it helps reproducability */ - srandom(0xdeadbeef); -} - -static void check_render_copyfunc(void) -{ - struct igt_buf src, dst; - uint32_t *ptr; - int i, j, pass; - - if (!options.check_render_cpyfn) - return; - - init_buffer(&src, options.scratch_buf_size); - init_buffer(&dst, options.scratch_buf_size); - - for (pass = 0; pass < 16; pass++) { - int sx = random() % (igt_buf_width(&src)-options.tile_size); - int sy = random() % (igt_buf_height(&src)-options.tile_size); - int dx = random() % (igt_buf_width(&dst)-options.tile_size); - int dy = random() % (igt_buf_height(&dst)-options.tile_size); - - if (options.use_cpu_maps) - set_to_cpu_domain(&src, 1); - - memset(src.data, 0xff, options.scratch_buf_size); - for (j = 0; j < options.tile_size; j++) { - ptr = (uint32_t*)((char *)src.data + sx*4 + (sy+j) * src.stride); - for (i = 0; i < options.tile_size; i++) - ptr[i] = j * options.tile_size + i; - } - - render_copyfunc(&src, sx, sy, &dst, dx, dy, 0); - - if (options.use_cpu_maps) - set_to_cpu_domain(&dst, 0); - - for (j = 0; j < options.tile_size; j++) { - ptr = (uint32_t*)((char *)dst.data + dx*4 + (dy+j) * dst.stride); - for (i = 0; i < options.tile_size; i++) - if (ptr[i] != j * options.tile_size + i) { - igt_info("render copyfunc mismatch at (%d, %d): found %d, expected %d\n", i, j, ptr[i], j * options.tile_size + i); - } - } - } -} - - -int main(int argc, char **argv) -{ - int i, j; - unsigned *current_permutation, *tmp_permutation; - static struct option long_options[] = { - {"no-hw", 0, 0, 'd'}, - {"buf-size", 1, 0, 's'}, - {"gpu-busy-load", 1, 0, 'g'}, - {"no-signals", 0, 0, 'S'}, - {"buffer-count", 1, 0, 'c'}, - {"trace-tile", 1, 0, 't'}, - {"disable-blt", 0, 0, 'b'}, - {"disable-render", 0, 0, 'r'}, - {"untiled", 0, 0, 'u'}, - {"x-tiled", 0, 0, 'x'}, - {"use-cpu-maps", 0, 0, 'm'}, - {"rounds", 1, 0, 'o'}, - {"no-fail", 0, 0, 'f'}, - {"tiles-per-buf", 0, 0, 'p'}, - {"remove-duct-tape", 0, 0, DUCTAPE}, - {"tile-size", 1, 0, TILESZ}, - {"check-render-cpyfn", 0, 0, CHCK_RENDER}, - {NULL, 0, 0, 0}, - }; - - options.scratch_buf_size = 256*4096; - options.no_hw = 0; - options.use_signal_helper = 1; - options.gpu_busy_load = 0; - options.num_buffers = 0; - options.trace_tile = -1; - options.use_render = 1; - options.use_blt = 1; - options.forced_tiling = -1; - options.use_cpu_maps = 0; - options.total_rounds = 512; - options.fail = 1; - options.ducttape = 1; - options.tile_size = 16; - options.tiles_per_buf = options.scratch_buf_size / TILE_BYTES(options.tile_size); - options.check_render_cpyfn = 0; - - igt_simple_init_parse_opts(&argc, argv,"ds:g:c:t:rbuxmo:fp:", - long_options, NULL, parse_options); - - drm_fd = drm_open_any(); - devid = intel_get_drm_devid(drm_fd); - - /* start our little helper early before too may allocations occur */ - if (options.use_signal_helper) - igt_fork_signal_helper(); - - init(); - - check_render_copyfunc(); - - tile_permutation = malloc(num_total_tiles*sizeof(uint32_t)); - current_permutation = malloc(num_total_tiles*sizeof(uint32_t)); - tmp_permutation = malloc(num_total_tiles*sizeof(uint32_t)); - igt_assert(tile_permutation); - igt_assert(current_permutation); - igt_assert(tmp_permutation); - - fan_out(); - - for (i = 0; i < options.total_rounds; i++) { - igt_info("round %i\n", i); - if (i % 64 == 63) { - fan_in_and_check(); - igt_info("everything correct after %i rounds\n", i + 1); - } - - target_set = (current_set + 1) & 1; - init_set(target_set); - - for (j = 0; j < num_total_tiles; j++) - current_permutation[j] = j; - igt_permute_array(current_permutation, num_total_tiles, exchange_uint); - - copy_tiles(current_permutation); - - memcpy(tmp_permutation, tile_permutation, sizeof(unsigned)*num_total_tiles); - - /* accumulate the permutations */ - for (j = 0; j < num_total_tiles; j++) - tile_permutation[j] = current_permutation[tmp_permutation[j]]; - - current_set = target_set; - } - - fan_in_and_check(); - - igt_info("num failed tiles %u, max incoherent bytes %zd\n", stats.num_failed, stats.max_failed_reads * sizeof(uint32_t)); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(drm_fd); - - igt_stop_signal_helper(); - - igt_exit(); -} diff --git a/tests/gem_threaded_access_tiled.c b/tests/gem_threaded_access_tiled.c deleted file mode 100644 index 3a5921f3..00000000 --- a/tests/gem_threaded_access_tiled.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2012 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: - * Mika Kuoppala <mika.kuoppala@intel.com> - */ - -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <pthread.h> - -#include "drmtest.h" -#include "ioctl_wrappers.h" -#include "intel_bufmgr.h" - -IGT_TEST_DESCRIPTION("Check parallel access to tiled memory."); - -/* Testcase: check parallel access to tiled memory - * - * Parallel access to tiled memory caused sigbus - */ - -#define NUM_THREADS 2 -#define WIDTH 4096 -#define HEIGHT 4096 - -struct thread_ctx { - drm_intel_bo *bo; -}; - -static drm_intel_bufmgr *bufmgr; -static struct thread_ctx tctx[NUM_THREADS]; - -static void *copy_fn(void *p) -{ - unsigned char *buf; - struct thread_ctx *c = p; - - buf = malloc(WIDTH * HEIGHT); - if (buf == NULL) - return (void *)1; - - memcpy(buf, c->bo->virtual, WIDTH * HEIGHT); - - free(buf); - return (void *)0; -} - -static int copy_tile_threaded(drm_intel_bo *bo) -{ - int i; - int r; - pthread_t thr[NUM_THREADS]; - void *status; - - for (i = 0; i < NUM_THREADS; i++) { - tctx[i].bo = bo; - r = pthread_create(&thr[i], NULL, copy_fn, (void *)&tctx[i]); - igt_assert(r == 0); - } - - for (i = 0; i < NUM_THREADS; i++) { - pthread_join(thr[i], &status); - igt_assert(status == 0); - } - - return 0; -} - -igt_simple_main -{ - int fd; - drm_intel_bo *bo; - uint32_t tiling_mode = I915_TILING_Y; - unsigned long pitch = 0; - int r; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - igt_assert(fd >= 0); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - - bo = drm_intel_bo_alloc_tiled(bufmgr, "mmap bo", WIDTH, HEIGHT, 1, - &tiling_mode, &pitch, 0); - igt_assert(bo); - - r = drm_intel_gem_bo_map_gtt(bo); - igt_assert(!r); - - r = copy_tile_threaded(bo); - igt_assert(!r); - - r = drm_intel_gem_bo_unmap_gtt(bo); - igt_assert(!r); - - drm_intel_bo_unreference(bo); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_tiled_blits.c b/tests/gem_tiled_blits.c deleted file mode 100644 index 3fceb811..00000000 --- a/tests/gem_tiled_blits.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * - */ - -/** @file gem_tiled_blits.c - * - * This is a test of doing many tiled blits, with a working set - * larger than the aperture size. - * - * The goal is to catch a couple types of failure; - * - Fence management problems on pre-965. - * - A17 or L-shaped memory tiling workaround problems in acceleration. - * - * The model is to fill a collection of 1MB objects in a way that can't trip - * over A6 swizzling -- upload data to a non-tiled object, blit to the tiled - * object. Then, copy the 1MB objects randomly between each other for a while. - * Finally, download their data through linear objects again and see what - * resulted. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test doing many tiled blits, with a working set larger" - " than the aperture size."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static int width = 512, height = 512; - -static drm_intel_bo * -create_bo(uint32_t start_val) -{ - drm_intel_bo *bo, *linear_bo; - uint32_t *linear; - uint32_t tiling = I915_TILING_X; - int i; - - bo = drm_intel_bo_alloc(bufmgr, "tiled bo", 1024 * 1024, 4096); - do_or_die(drm_intel_bo_set_tiling(bo, &tiling, width * 4)); - igt_assert(tiling == I915_TILING_X); - - linear_bo = drm_intel_bo_alloc(bufmgr, "linear src", 1024 * 1024, 4096); - - /* Fill the BO with dwords starting at start_val */ - do_or_die(drm_intel_bo_map(linear_bo, 1)); - linear = linear_bo->virtual; - for (i = 0; i < 1024 * 1024 / 4; i++) - linear[i] = start_val++; - drm_intel_bo_unmap(linear_bo); - - intel_copy_bo (batch, bo, linear_bo, width*height*4); - - drm_intel_bo_unreference(linear_bo); - - return bo; -} - -static void -check_bo(drm_intel_bo *bo, uint32_t start_val) -{ - drm_intel_bo *linear_bo; - uint32_t *linear; - int i; - - linear_bo = drm_intel_bo_alloc(bufmgr, "linear dst", 1024 * 1024, 4096); - - intel_copy_bo(batch, linear_bo, bo, width*height*4); - - do_or_die(drm_intel_bo_map(linear_bo, 0)); - linear = linear_bo->virtual; - - for (i = 0; i < 1024 * 1024 / 4; i++) { - igt_assert_f(linear[i] == start_val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - start_val, linear[i], i * 4); - start_val++; - } - drm_intel_bo_unmap(linear_bo); - - drm_intel_bo_unreference(linear_bo); -} - -static void run_test(int count) -{ - drm_intel_bo **bo; - uint32_t *bo_start_val; - uint32_t start = 0; - int i; - - igt_debug("Using %d 1MiB buffers\n", count); - - bo = malloc(sizeof(drm_intel_bo *)*count); - bo_start_val = malloc(sizeof(uint32_t)*count); - - for (i = 0; i < count; i++) { - bo[i] = create_bo(start); - bo_start_val[i] = start; - start += 1024 * 1024 / 4; - } - igt_info("Verifying initialisation...\n"); - for (i = 0; i < count; i++) - check_bo(bo[i], bo_start_val[i]); - - igt_info("Cyclic blits, forward...\n"); - for (i = 0; i < count * 4; i++) { - int src = i % count; - int dst = (i+1) % count; - - if (src == dst) - continue; - - intel_copy_bo(batch, bo[dst], bo[src], width*height*4); - bo_start_val[dst] = bo_start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(bo[i], bo_start_val[i]); - - if (igt_run_in_simulation()) { - for (i = 0; i < count; i++) - drm_intel_bo_unreference(bo[i]); - free(bo_start_val); - free(bo); - return; - } - - igt_info("Cyclic blits, backward...\n"); - for (i = 0; i < count * 4; i++) { - int src = (i+1) % count; - int dst = i % count; - - if (src == dst) - continue; - - intel_copy_bo(batch, bo[dst], bo[src], width*height*4); - bo_start_val[dst] = bo_start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(bo[i], bo_start_val[i]); - - igt_info("Random blits...\n"); - for (i = 0; i < count * 4; i++) { - int src = random() % count; - int dst = random() % count; - - if (src == dst) - continue; - - intel_copy_bo(batch, bo[dst], bo[src], width*height*4); - bo_start_val[dst] = bo_start_val[src]; - } - for (i = 0; i < count; i++) { - check_bo(bo[i], bo_start_val[i]); - drm_intel_bo_unreference(bo[i]); - } - - free(bo_start_val); - free(bo); -} - -int fd; - -int main(int argc, char **argv) -{ - igt_subtest_init(argc, argv); - - igt_fixture { - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - drm_intel_bufmgr_gem_set_vma_cache_size(bufmgr, 32); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - } - - igt_subtest("basic") - run_test(2); - - igt_subtest("normal") { - int count; - - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - count += (count & 1) == 0; - intel_require_memory(count, 1024*1024, CHECK_RAM); - - run_test(count); - } - - igt_subtest("interruptible") { - int count; - - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - count += (count & 1) == 0; - intel_require_memory(count, 1024*1024, CHECK_RAM); - - igt_fork_signal_helper(); - run_test(count); - igt_stop_signal_helper(); - } - - igt_fixture { - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } - - igt_exit(); -} diff --git a/tests/gem_tiled_fence_blits.c b/tests/gem_tiled_fence_blits.c deleted file mode 100644 index e3f322e3..00000000 --- a/tests/gem_tiled_fence_blits.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright © 2009,2011 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: - * Eric Anholt <eric@anholt.net> - * - */ - -/** @file gem_tiled_fence_blits.c - * - * This is a test of doing many tiled blits, with a working set - * larger than the aperture size. - * - * The goal is to catch a couple types of failure; - * - Fence management problems on pre-965. - * - A17 or L-shaped memory tiling workaround problems in acceleration. - * - * The model is to fill a collection of 1MB objects in a way that can't trip - * over A6 swizzling -- upload data to a non-tiled object, blit to the tiled - * object. Then, copy the 1MB objects randomly between each other for a while. - * Finally, download their data through linear objects again and see what - * resulted. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static int width = 512, height = 512; -static uint32_t linear[1024*1024/4]; - -static drm_intel_bo * -create_bo(int fd, uint32_t start_val) -{ - drm_intel_bo *bo; - uint32_t tiling = I915_TILING_X; - int ret, i; - - bo = drm_intel_bo_alloc(bufmgr, "tiled bo", 1024 * 1024, 4096); - ret = drm_intel_bo_set_tiling(bo, &tiling, width * 4); - igt_assert(ret == 0); - igt_assert(tiling == I915_TILING_X); - - /* Fill the BO with dwords starting at start_val */ - for (i = 0; i < 1024 * 1024 / 4; i++) - linear[i] = start_val++; - - gem_write(fd, bo->handle, 0, linear, sizeof(linear)); - - return bo; -} - -static void -check_bo(int fd, drm_intel_bo *bo, uint32_t start_val) -{ - int i; - - gem_read(fd, bo->handle, 0, linear, sizeof(linear)); - - for (i = 0; i < 1024 * 1024 / 4; i++) { - igt_assert_f(linear[i] == start_val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - start_val, linear[i], i * 4); - start_val++; - } -} - -igt_simple_main -{ - drm_intel_bo *bo[4096]; - uint32_t bo_start_val[4096]; - uint32_t start = 0; - int fd, i, count; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - if (count > intel_get_total_ram_mb() * 9 / 10) { - count = intel_get_total_ram_mb() * 9 / 10; - igt_info("not enough RAM to run test, reducing buffer count\n"); - } - count |= 1; - igt_info("Using %d 1MiB buffers\n", count); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - for (i = 0; i < count; i++) { - bo[i] = create_bo(fd, start); - bo_start_val[i] = start; - - /* - igt_info("Creating bo %d\n", i); - check_bo(bo[i], bo_start_val[i]); - */ - - start += 1024 * 1024 / 4; - } - - for (i = 0; i < count; i++) { - int src = count - i - 1; - intel_copy_bo(batch, bo[i], bo[src], width*height*4); - bo_start_val[i] = bo_start_val[src]; - } - - for (i = 0; i < count * 4; i++) { - int src = random() % count; - int dst = random() % count; - - if (src == dst) - continue; - - intel_copy_bo(batch, bo[dst], bo[src], width*height*4); - bo_start_val[dst] = bo_start_val[src]; - - /* - check_bo(bo[dst], bo_start_val[dst]); - igt_info("%d: copy bo %d to %d\n", i, src, dst); - */ - } - - for (i = 0; i < count; i++) { - /* - igt_info("check %d\n", i); - */ - check_bo(fd, bo[i], bo_start_val[i]); - - drm_intel_bo_unreference(bo[i]); - bo[i] = NULL; - } - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_tiled_partial_pwrite_pread.c b/tests/gem_tiled_partial_pwrite_pread.c deleted file mode 100644 index 8dea82e4..00000000 --- a/tests/gem_tiled_partial_pwrite_pread.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test pwrite/pread consistency when touching partial" - " cachelines."); - -/* - * Testcase: pwrite/pread consistency when touching partial cachelines - * - * Some fancy new pwrite/pread optimizations clflush in-line while - * reading/writing. Check whether all required clflushes happen. - * - * Unfortunately really old mesa used unaligned pread/pwrite for s/w fallback - * rendering, so we need to check whether this works on tiled buffers, too. - * - */ - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; - -drm_intel_bo *scratch_bo; -drm_intel_bo *staging_bo; -drm_intel_bo *tiled_staging_bo; -unsigned long scratch_pitch; -#define BO_SIZE (32*4096) -uint32_t devid; -uint64_t mappable_gtt_limit; -int fd; - -static void -copy_bo(drm_intel_bo *src, int src_tiled, - drm_intel_bo *dst, int dst_tiled) -{ - unsigned long dst_pitch = scratch_pitch; - unsigned long src_pitch = scratch_pitch; - uint32_t cmd_bits = 0; - - /* dst is tiled ... */ - if (intel_gen(devid) >= 4 && dst_tiled) { - dst_pitch /= 4; - cmd_bits |= XY_SRC_COPY_BLT_DST_TILED; - } - - if (intel_gen(devid) >= 4 && dst_tiled) { - src_pitch /= 4; - cmd_bits |= XY_SRC_COPY_BLT_SRC_TILED; - } - - BLIT_COPY_BATCH_START(cmd_bits); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - dst_pitch); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(BO_SIZE/scratch_pitch << 16 | 1024); - OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(src_pitch); - OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -static void -blt_bo_fill(drm_intel_bo *tmp_bo, drm_intel_bo *bo, int val) -{ - uint8_t *gtt_ptr; - int i; - - drm_intel_gem_bo_map_gtt(tmp_bo); - gtt_ptr = tmp_bo->virtual; - - for (i = 0; i < BO_SIZE; i++) - gtt_ptr[i] = val; - - drm_intel_gem_bo_unmap_gtt(tmp_bo); - - if (bo->offset < mappable_gtt_limit && - (IS_G33(devid) || intel_gen(devid) >= 4)) - igt_trash_aperture(); - - copy_bo(tmp_bo, 0, bo, 1); -} - -#define MAX_BLT_SIZE 128 -#define ROUNDS 200 -uint8_t tmp[BO_SIZE]; -uint8_t compare_tmp[BO_SIZE]; - -static void test_partial_reads(void) -{ - int i, j; - - for (i = 0; i < ROUNDS; i++) { - int start, len; - int val = i % 256; - - blt_bo_fill(staging_bo, scratch_bo, i); - - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - drm_intel_bo_get_subdata(scratch_bo, start, len, tmp); - for (j = 0; j < len; j++) { - igt_assert_f(tmp[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - start + j, tmp[j], val); - } - - igt_progress("partial reads test: ", i, ROUNDS); - } -} - -static void test_partial_writes(void) -{ - int i, j; - - for (i = 0; i < ROUNDS; i++) { - int start, len; - int val = i % 256; - - blt_bo_fill(staging_bo, scratch_bo, i); - - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - memset(tmp, i + 63, BO_SIZE); - - drm_intel_bo_subdata(scratch_bo, start, len, tmp); - - copy_bo(scratch_bo, 1, tiled_staging_bo, 1); - drm_intel_bo_get_subdata(tiled_staging_bo, 0, BO_SIZE, - compare_tmp); - - for (j = 0; j < start; j++) { - igt_assert_f(compare_tmp[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - for (; j < start + len; j++) { - igt_assert_f(compare_tmp[j] == tmp[0], - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], i); - } - for (; j < BO_SIZE; j++) { - igt_assert_f(compare_tmp[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - drm_intel_gem_bo_unmap_gtt(staging_bo); - - igt_progress("partial writes test: ", i, ROUNDS); - } -} - -static void test_partial_read_writes(void) -{ - int i, j; - - for (i = 0; i < ROUNDS; i++) { - int start, len; - int val = i % 256; - - blt_bo_fill(staging_bo, scratch_bo, i); - - /* partial read */ - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - drm_intel_bo_get_subdata(scratch_bo, start, len, tmp); - for (j = 0; j < len; j++) { - igt_assert_f(tmp[j] == val, - "mismatch in read at %i, got: %i, expected: %i\n", - start + j, tmp[j], val); - } - - /* Change contents through gtt to make the pread cachelines - * stale. */ - val = (i + 17) % 256; - blt_bo_fill(staging_bo, scratch_bo, val); - - /* partial write */ - start = random() % BO_SIZE; - len = random() % (BO_SIZE-start) + 1; - - memset(tmp, i + 63, BO_SIZE); - - drm_intel_bo_subdata(scratch_bo, start, len, tmp); - - copy_bo(scratch_bo, 1, tiled_staging_bo, 1); - drm_intel_bo_get_subdata(tiled_staging_bo, 0, BO_SIZE, - compare_tmp); - - for (j = 0; j < start; j++) { - igt_assert_f(compare_tmp[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - for (; j < start + len; j++) { - igt_assert_f(compare_tmp[j] == tmp[0], - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], tmp[0]); - } - for (; j < BO_SIZE; j++) { - igt_assert_f(compare_tmp[j] == val, - "mismatch at %i, got: %i, expected: %i\n", - j, tmp[j], val); - } - drm_intel_gem_bo_unmap_gtt(staging_bo); - - igt_progress("partial read/writes test: ", i, ROUNDS); - } -} - -igt_main -{ - uint32_t tiling_mode = I915_TILING_X; - - igt_skip_on_simulation(); - - srandom(0xdeadbeef); - - igt_fixture { - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - devid = intel_get_drm_devid(fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - /* overallocate the buffers we're actually using because */ - scratch_bo = drm_intel_bo_alloc_tiled(bufmgr, "scratch bo", 1024, - BO_SIZE/4096, 4, - &tiling_mode, &scratch_pitch, 0); - igt_assert(tiling_mode == I915_TILING_X); - igt_assert(scratch_pitch == 4096); - staging_bo = drm_intel_bo_alloc(bufmgr, "staging bo", BO_SIZE, 4096); - tiled_staging_bo = drm_intel_bo_alloc_tiled(bufmgr, "scratch bo", 1024, - BO_SIZE/4096, 4, - &tiling_mode, - &scratch_pitch, 0); - - igt_init_aperture_trashers(bufmgr); - mappable_gtt_limit = gem_mappable_aperture_size(); - } - - igt_subtest("reads") - test_partial_reads(); - - igt_subtest("writes") - test_partial_writes(); - - igt_subtest("writes-after-reads") - test_partial_read_writes(); - - igt_fixture { - igt_cleanup_aperture_trashers(); - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gem_tiled_pread.c b/tests/gem_tiled_pread.c deleted file mode 100644 index fdc51733..00000000 --- a/tests/gem_tiled_pread.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * - */ - -/** @file gem_tiled_pread.c - * - * This is a test of pread's behavior on tiled objects with respect to the - * reported swizzling value. - * - * The goal is to exercise the slow_bit17_copy path for reading on bit17 - * machines, but will also be useful for catching swizzling value bugs on - * other systems. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - - -IGT_TEST_DESCRIPTION("Test pread behavior on tiled objects with respect to the" - " reported swizzling value."); - -#define WIDTH 512 -#define HEIGHT 512 -static uint32_t linear[WIDTH * HEIGHT]; - -#define PAGE_SIZE 4096 - -static int tile_width; -static int tile_height; -static int tile_size; - -static uint32_t -create_bo(int fd) -{ - uint32_t handle; - uint32_t *data; - int i; - - handle = gem_create(fd, sizeof(linear)); - gem_set_tiling(fd, handle, I915_TILING_X, WIDTH * sizeof(uint32_t)); - - /* Fill the BO with dwords starting at start_val */ - data = gem_mmap(fd, handle, sizeof(linear), PROT_READ | PROT_WRITE); - for (i = 0; i < WIDTH*HEIGHT; i++) - data[i] = i; - munmap(data, sizeof(linear)); - - return handle; -} - -static int -swizzle_bit(int bit, int offset) -{ - return (offset & (1 << bit)) >> (bit - 6); -} - -/* Translate from a swizzled offset in the tiled buffer to the corresponding - * value from the original linear buffer. - */ -static uint32_t -calculate_expected(int offset) -{ - int tile_off = offset & (tile_size - 1); - int tile_base = offset & -tile_size; - int tile_index = tile_base / tile_size; - int tiles_per_row = 4*WIDTH / tile_width; - - /* base x,y values from the tile (page) index. */ - int base_y = tile_index / tiles_per_row * tile_height; - int base_x = tile_index % tiles_per_row * (tile_width/4); - - /* x, y offsets within the tile */ - int tile_y = tile_off / tile_width; - int tile_x = (tile_off % tile_width) / 4; - - igt_debug("%3d, %3d, %3d,%3d\n", base_x, base_y, tile_x, tile_y); - return (base_y + tile_y) * WIDTH + base_x + tile_x; -} - -igt_simple_main -{ - int fd; - int i, iter = 100; - uint32_t tiling, swizzle; - uint32_t handle; - uint32_t devid; - - fd = drm_open_any(); - - handle = create_bo(fd); - gem_get_tiling(fd, handle, &tiling, &swizzle); - - devid = intel_get_drm_devid(fd); - - if (IS_GEN2(devid)) { - tile_height = 16; - tile_width = 128; - tile_size = 2048; - } else { - tile_height = 8; - tile_width = 512; - tile_size = PAGE_SIZE; - } - - /* Read a bunch of random subsets of the data and check that they come - * out right. - */ - for (i = 0; i < iter; i++) { - int size = WIDTH * HEIGHT * 4; - int offset = (random() % size) & ~3; - int len = (random() % size) & ~3; - int j; - - if (len == 0) - len = 4; - - if (offset + len > size) - len = size - offset; - - if (i == 0) { - offset = 0; - len = size; - } - - gem_read(fd, handle, offset, linear, len); - - /* Translate from offsets in the read buffer to the swizzled - * address that it corresponds to. This is the opposite of - * what Mesa does (calculate offset to be read given the linear - * offset it's looking for). - */ - for (j = offset; j < offset + len; j += 4) { - uint32_t expected_val, found_val; - int swizzled_offset; - const char *swizzle_str; - - switch (swizzle) { - case I915_BIT_6_SWIZZLE_NONE: - swizzled_offset = j; - swizzle_str = "none"; - break; - case I915_BIT_6_SWIZZLE_9: - swizzled_offset = j ^ - swizzle_bit(9, j); - swizzle_str = "bit9"; - break; - case I915_BIT_6_SWIZZLE_9_10: - swizzled_offset = j ^ - swizzle_bit(9, j) ^ - swizzle_bit(10, j); - swizzle_str = "bit9^10"; - break; - case I915_BIT_6_SWIZZLE_9_11: - swizzled_offset = j ^ - swizzle_bit(9, j) ^ - swizzle_bit(11, j); - swizzle_str = "bit9^11"; - break; - case I915_BIT_6_SWIZZLE_9_10_11: - swizzled_offset = j ^ - swizzle_bit(9, j) ^ - swizzle_bit(10, j) ^ - swizzle_bit(11, j); - swizzle_str = "bit9^10^11"; - break; - default: - igt_assert_f(0, "Bad swizzle bits; %d\n", - swizzle); - } - expected_val = calculate_expected(swizzled_offset); - found_val = linear[(j - offset) / 4]; - igt_assert_f(expected_val == found_val, - "Bad read [%d]: %d instead of %d at 0x%08x " - "for read from 0x%08x to 0x%08x, swizzle=%s\n", - i, found_val, expected_val, j, - offset, offset + len, - swizzle_str); - } - } - - close(fd); -} diff --git a/tests/gem_tiled_pread_pwrite.c b/tests/gem_tiled_pread_pwrite.c deleted file mode 100644 index 3d8fdc9f..00000000 --- a/tests/gem_tiled_pread_pwrite.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright © 2009 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: - * Eric Anholt <eric@anholt.net> - * - */ - -/** @file gem_tiled_pread_pwrite.c - * - * This is a test of pread's behavior on tiled objects with respect to the - * reported swizzling value. - * - * The goal is to exercise the slow_bit17_copy path for reading on bit17 - * machines, but will also be useful for catching swizzling value bugs on - * other systems. - */ - -/* - * Testcase: Test swizzling by testing pwrite does the inverse of pread - * - * Together with the explicit pread testcase, this should cover our swizzle - * handling. - * - * Note that this test will use swap in an effort to test all of ram. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Test swizzling by testing pwrite does the inverse of" - " pread."); - -#define WIDTH 512 -#define HEIGHT 512 -static uint32_t linear[WIDTH * HEIGHT]; -static uint32_t current_tiling_mode; - -#define PAGE_SIZE 4096 - -static uint32_t -create_bo_and_fill(int fd) -{ - uint32_t handle; - uint32_t *data; - int i; - - handle = gem_create(fd, sizeof(linear)); - gem_set_tiling(fd, handle, current_tiling_mode, WIDTH * sizeof(uint32_t)); - - /* Fill the BO with dwords starting at start_val */ - data = gem_mmap(fd, handle, sizeof(linear), PROT_READ | PROT_WRITE); - for (i = 0; i < WIDTH*HEIGHT; i++) - data[i] = i; - munmap(data, sizeof(linear)); - - return handle; -} - -static uint32_t -create_bo(int fd) -{ - uint32_t handle; - - handle = gem_create(fd, sizeof(linear)); - gem_set_tiling(fd, handle, current_tiling_mode, WIDTH * sizeof(uint32_t)); - - return handle; -} - -igt_simple_main -{ - int fd; - uint32_t *data; - int i, j; - uint32_t tiling, swizzle; - uint32_t handle, handle_target; - int count; - - fd = drm_open_any(); - count = SLOW_QUICK(intel_get_total_ram_mb() * 9 / 10, 8) ; - - for (i = 0; i < count/2; i++) { - current_tiling_mode = I915_TILING_X; - - handle = create_bo_and_fill(fd); - gem_get_tiling(fd, handle, &tiling, &swizzle); - - gem_read(fd, handle, 0, linear, sizeof(linear)); - - handle_target = create_bo(fd); - gem_write(fd, handle_target, 0, linear, sizeof(linear)); - - /* Check the target bo's contents. */ - data = gem_mmap(fd, handle_target, sizeof(linear), PROT_READ | PROT_WRITE); - for (j = 0; j < WIDTH*HEIGHT; j++) - igt_assert_f(data[j] == j, - "mismatch at %i: %i\n", - j, data[j]); - munmap(data, sizeof(linear)); - - /* Leak both bos so that we use all of system mem! */ - gem_madvise(fd, handle_target, I915_MADV_DONTNEED); - gem_madvise(fd, handle, I915_MADV_DONTNEED); - - igt_progress("gem_tiled_pread_pwrite: ", i, count/2); - } - - close(fd); -} diff --git a/tests/gem_tiled_swapping.c b/tests/gem_tiled_swapping.c deleted file mode 100644 index 2361dfcf..00000000 --- a/tests/gem_tiled_swapping.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/** @file gem_tiled_pread_pwrite.c - * - * This is a test of pread's behavior on tiled objects with respect to the - * reported swizzling value. - * - * The goal is to exercise the slow_bit17_copy path for reading on bit17 - * machines, but will also be useful for catching swizzling value bugs on - * other systems. - */ - -/* - * Testcase: Exercise swizzle code for swapping - * - * The swizzle checks in the swapin path are at a different place than the ones - * for pread/pwrite, so we need to check them separately. - * - * This test obviously needs swap present (and exits if none is detected). - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <pthread.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "igt_aux.h" -#include "igt_debugfs.h" - -IGT_TEST_DESCRIPTION("Exercise swizzle code for swapping."); - -#define WIDTH 512 -#define HEIGHT 512 -#define LINEAR_DWORDS (4 * WIDTH * HEIGHT) -static uint32_t current_tiling_mode; - -#define PAGE_SIZE 4096 -#define AVAIL_RAM 512 - -static uint32_t -create_bo(int fd) -{ - uint32_t handle; - uint32_t *data; - - handle = gem_create(fd, LINEAR_DWORDS); - gem_set_tiling(fd, handle, current_tiling_mode, WIDTH * sizeof(uint32_t)); - - data = gem_mmap(fd, handle, LINEAR_DWORDS, PROT_READ | PROT_WRITE); - if (data == NULL) { - gem_close(fd, handle); - return 0; - } - munmap(data, LINEAR_DWORDS); - - return handle; -} - -static void -fill_bo(int fd, uint32_t handle) -{ - uint32_t *data; - int i; - - data = gem_mmap(fd, handle, LINEAR_DWORDS, PROT_READ | PROT_WRITE); - igt_assert(data); - - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - for (i = 0; i < WIDTH*HEIGHT; i++) - data[i] = i; - munmap(data, LINEAR_DWORDS); -} - -static void -check_bo(int fd, uint32_t handle) -{ - uint32_t *data; - int j; - - data = gem_mmap(fd, handle, LINEAR_DWORDS, PROT_READ); - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, 0); - j = rand() % (WIDTH * HEIGHT); - igt_assert_f(data[j] == j, "mismatch at %i: %i\n", j, data[j]); - munmap(data, LINEAR_DWORDS); -} - -uint32_t *bo_handles; - -struct thread { - pthread_t thread; - int *idx_arr; - int fd, count; -}; - -static void *thread_run(void *data) -{ - struct thread *t = data; - int i; - - for (i = 0; i < t->count; i++) - check_bo(t->fd, bo_handles[t->idx_arr[i]]); - - return NULL; -} - -static void thread_init(struct thread *t, int fd, int count) -{ - int i; - - t->fd = fd; - t->count = count; - t->idx_arr = calloc(count, sizeof(int)); - igt_assert(t->idx_arr); - - for (i = 0; i < count; i++) - t->idx_arr[i] = i; - - igt_permute_array(t->idx_arr, count, igt_exchange_int); -} - -static void thread_fini(struct thread *t) -{ - free(t->idx_arr); -} - -static void check_memory_layout(void) -{ - FILE *tiling_debugfs_file; - char *line = NULL; - size_t sz = 0; - - tiling_debugfs_file = igt_debugfs_fopen("i915_swizzle_info", "r"); - igt_assert(tiling_debugfs_file); - - while (getline(&line, &sz, tiling_debugfs_file) > 0) { - if (strstr(line, "L-shaped") != 0) - continue; - - igt_skip("L-shaped memory configuration detected\n"); - } - - igt_debug("normal memory configuration detected, continuing\n"); -} - -igt_main -{ - struct thread *threads; - int fd, n, count, num_threads; - - igt_fixture { - size_t lock_size; - - current_tiling_mode = I915_TILING_X; - - intel_purge_vm_caches(); - - fd = drm_open_any(); - - check_memory_layout(); - - /* lock RAM, leaving only 512MB available */ - lock_size = max(0, intel_get_total_ram_mb() - AVAIL_RAM); - igt_lock_mem(lock_size); - - /* need slightly more than available memory */ - count = min(intel_get_total_ram_mb(), AVAIL_RAM) * 1.25; - bo_handles = calloc(count, sizeof(uint32_t)); - igt_assert(bo_handles); - - num_threads = gem_available_fences(fd); - threads = calloc(num_threads, sizeof(struct thread)); - igt_assert(threads); - - igt_info("Using %d 1MiB objects (available RAM: %ld/%ld, swap: %ld)\n", - count, - (long)intel_get_avail_ram_mb(), - (long)intel_get_total_ram_mb(), - (long)intel_get_total_swap_mb()); - intel_require_memory(count, 1024*1024, CHECK_RAM | CHECK_SWAP); - - for (n = 0; n < count; n++) { - bo_handles[n] = create_bo(fd); - /* Not enough mmap address space possible. */ - igt_require(bo_handles[n]); - } - } - - igt_subtest("non-threaded") { - for (n = 0; n < count; n++) - fill_bo(fd, bo_handles[n]); - - thread_init(&threads[0], fd, count); - thread_run(&threads[0]); - thread_run(&threads[0]); - thread_run(&threads[0]); - thread_fini(&threads[0]); - } - - /* Once more with threads */ - igt_subtest("threaded") { - for (n = 0; n < count; n++) - fill_bo(fd, bo_handles[n]); - - for (n = 0; n < num_threads; n++) - thread_init(&threads[n], fd, count); - - thread_run(&threads[0]); - for (n = 0; n < num_threads; n++) - pthread_create(&threads[n].thread, NULL, thread_run, &threads[n]); - for (n = 0; n < num_threads; n++) - pthread_join(threads[n].thread, NULL); - thread_run(&threads[0]); - - for (n = 0; n < num_threads; n++) - thread_fini(&threads[n]); - } - - close(fd); -} diff --git a/tests/gem_tiled_wb.c b/tests/gem_tiled_wb.c deleted file mode 100644 index b6efd6ee..00000000 --- a/tests/gem_tiled_wb.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright © 2009 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. - */ - -/** @file gem_tiled_wc.c - * - * This is a test of write-combining mmap's behavior on tiled objects - * with respect to the reported swizzling value. - * - * The goal is to exercise the complications that arise when using a linear - * view of a tiled object that is subject to hardware swizzling. This is - * useful to check that we are presenting the correct view of the object - * to userspace, and that userspace has to respect the swizzle. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("This is a test of write-combining mmap's behavior on" - " tiled objects with respect to the reported swizzling" - " value."); - -#define WIDTH 512 -#define HEIGHT 512 -#define SIZE (WIDTH*HEIGHT*sizeof(uint32_t)) - -#define PAGE_SIZE 4096 - -static int tile_width; -static int tile_height; -static int tile_size; - -static uint32_t -create_bo(int fd) -{ - uint32_t handle; - uint32_t *data; - int i; - - handle = gem_create(fd, SIZE); - gem_set_tiling(fd, handle, I915_TILING_X, WIDTH * sizeof(uint32_t)); - - /* Write throught the fence to tiled the data. - * We then manually detile on reading back through the mmap(wc). - */ - data = gem_mmap__gtt(fd, handle, SIZE, PROT_READ | PROT_WRITE); - for (i = 0; i < WIDTH*HEIGHT; i++) - data[i] = i; - munmap(data, SIZE); - - gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0); - return handle; -} - -static int -swizzle_bit(int bit, int offset) -{ - return (offset & (1 << bit)) >> (bit - 6); -} - -/* Translate from a swizzled offset in the tiled buffer to the corresponding - * value from the original linear buffer. - */ -static uint32_t -calculate_expected(int offset) -{ - int tile_off = offset & (tile_size - 1); - int tile_base = offset & -tile_size; - int tile_index = tile_base / tile_size; - int tiles_per_row = 4*WIDTH / tile_width; - - /* base x,y values from the tile (page) index. */ - int base_y = tile_index / tiles_per_row * tile_height; - int base_x = tile_index % tiles_per_row * (tile_width/4); - - /* x, y offsets within the tile */ - int tile_y = tile_off / tile_width; - int tile_x = (tile_off % tile_width) / 4; - - igt_debug("%3d, %3d, %3d,%3d\n", base_x, base_y, tile_x, tile_y); - return (base_y + tile_y) * WIDTH + base_x + tile_x; -} - -static void -get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle) -{ - struct drm_i915_gem_get_tiling2 { - uint32_t handle; - uint32_t tiling_mode; - uint32_t swizzle_mode; - uint32_t phys_swizzle_mode; - } arg; -#define DRM_IOCTL_I915_GEM_GET_TILING2 DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling2) - - memset(&arg, 0, sizeof(arg)); - arg.handle = handle; - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING2, &arg)); - igt_require(arg.phys_swizzle_mode == arg.swizzle_mode); - - *tiling = arg.tiling_mode; - *swizzle = arg.swizzle_mode; -} - -igt_simple_main -{ - int fd; - int i, iter = 100; - uint32_t tiling, swizzle; - uint32_t handle; - - fd = drm_open_any(); - - handle = create_bo(fd); - get_tiling(fd, handle, &tiling, &swizzle); - - if (IS_GEN2(intel_get_drm_devid(fd))) { - tile_height = 16; - tile_width = 128; - tile_size = 2048; - } else { - tile_height = 8; - tile_width = 512; - tile_size = PAGE_SIZE; - } - - /* Read a bunch of random subsets of the data and check that they come - * out right. - */ - for (i = 0; i < iter; i++) { - int size = WIDTH * HEIGHT * 4; - int offset = (random() % size) & ~3; - int len = (random() % size) & ~3; - int first_page, last_page; - uint32_t *linear; - int j; - - if (len == 0) - len = 4; - - if (offset + len > size) - len = size - offset; - - if (i == 0) { - offset = 0; - len = size; - } - - first_page = offset & ~(PAGE_SIZE-1); - last_page = (offset + len + PAGE_SIZE) & ~(PAGE_SIZE-1); - offset -= first_page; - - linear = gem_mmap__cpu(fd, handle, first_page, last_page - first_page, PROT_READ); - igt_assert(linear); - - - /* Translate from offsets in the read buffer to the swizzled - * address that it corresponds to. This is the opposite of - * what Mesa does (calculate offset to be read given the linear - * offset it's looking for). - */ - for (j = offset; j < offset + len; j += 4) { - uint32_t expected_val, found_val; - int swizzled_offset = j + first_page; - const char *swizzle_str; - - switch (swizzle) { - case I915_BIT_6_SWIZZLE_NONE: - swizzle_str = "none"; - break; - case I915_BIT_6_SWIZZLE_9: - swizzled_offset ^= - swizzle_bit(9, swizzled_offset); - swizzle_str = "bit9"; - break; - case I915_BIT_6_SWIZZLE_9_10: - swizzled_offset ^= - swizzle_bit(9, swizzled_offset) ^ - swizzle_bit(10, swizzled_offset); - swizzle_str = "bit9^10"; - break; - case I915_BIT_6_SWIZZLE_9_11: - swizzled_offset ^= - swizzle_bit(9, swizzled_offset) ^ - swizzle_bit(11, swizzled_offset); - swizzle_str = "bit9^11"; - break; - case I915_BIT_6_SWIZZLE_9_10_11: - swizzled_offset ^= - swizzle_bit(9, swizzled_offset) ^ - swizzle_bit(10, swizzled_offset) ^ - swizzle_bit(11, swizzled_offset); - swizzle_str = "bit9^10^11"; - break; - default: - igt_skip("unknown swizzling"); - break; - } - expected_val = calculate_expected(swizzled_offset); - found_val = linear[j / 4]; - igt_assert_f(expected_val == found_val, - "Bad read [%d]: %d instead of %d at 0x%08x " - "for read from 0x%08x to 0x%08x, swizzle=%s\n", - i, found_val, expected_val, j + first_page, - offset, offset + len, - swizzle_str); - } - munmap(linear, last_page - first_page); - } - - close(fd); -} diff --git a/tests/gem_tiled_wc.c b/tests/gem_tiled_wc.c deleted file mode 100644 index b0f7a655..00000000 --- a/tests/gem_tiled_wc.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright © 2009 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. - */ - -/** @file gem_tiled_wc.c - * - * This is a test of write-combining mmap's behavior on tiled objects - * with respect to the reported swizzling value. - * - * The goal is to exercise the complications that arise when using a linear - * view of a tiled object that is subject to hardware swizzling. This is - * useful to check that we are presenting the correct view of the object - * to userspace, and that userspace has to respect the swizzle. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -#define WIDTH 512 -#define HEIGHT 512 -#define SIZE (WIDTH*HEIGHT*sizeof(uint32_t)) - -#define PAGE_SIZE 4096 - -static int tile_width; -static int tile_height; -static int tile_size; - -static uint32_t -create_bo(int fd) -{ - uint32_t handle; - uint32_t *data; - int i; - - handle = gem_create(fd, SIZE); - gem_set_tiling(fd, handle, I915_TILING_X, WIDTH * sizeof(uint32_t)); - - /* Fill the BO with dwords starting at start_val */ - data = gem_mmap__gtt(fd, handle, SIZE, PROT_READ | PROT_WRITE); - for (i = 0; i < WIDTH*HEIGHT; i++) - data[i] = i; - munmap(data, SIZE); - - return handle; -} - -static int -swizzle_bit(int bit, int offset) -{ - return (offset & (1 << bit)) >> (bit - 6); -} - -/* Translate from a swizzled offset in the tiled buffer to the corresponding - * value from the original linear buffer. - */ -static uint32_t -calculate_expected(int offset) -{ - int tile_off = offset & (tile_size - 1); - int tile_base = offset & -tile_size; - int tile_index = tile_base / tile_size; - int tiles_per_row = 4*WIDTH / tile_width; - - /* base x,y values from the tile (page) index. */ - int base_y = tile_index / tiles_per_row * tile_height; - int base_x = tile_index % tiles_per_row * (tile_width/4); - - /* x, y offsets within the tile */ - int tile_y = tile_off / tile_width; - int tile_x = (tile_off % tile_width) / 4; - - igt_debug("%s(%d): %3d, %3d, %3d,%3d = %d\n", - __func__, offset, base_x, base_y, tile_x, tile_y, - (base_y + tile_y) * WIDTH + base_x + tile_x); - return (base_y + tile_y) * WIDTH + base_x + tile_x; -} - -static void -get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle) -{ - struct drm_i915_gem_get_tiling2 { - uint32_t handle; - uint32_t tiling_mode; - uint32_t swizzle_mode; - uint32_t phys_swizzle_mode; - } arg; -#define DRM_IOCTL_I915_GEM_GET_TILING2 DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling2) - - memset(&arg, 0, sizeof(arg)); - arg.handle = handle; - - do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING2, &arg)); - igt_require(arg.phys_swizzle_mode == arg.swizzle_mode); - - *tiling = arg.tiling_mode; - *swizzle = arg.swizzle_mode; -} - -igt_simple_main -{ - int fd; - int i, iter = 100; - uint32_t tiling, swizzle; - uint32_t handle; - - fd = drm_open_any(); - gem_require_mmap_wc(fd); - - handle = create_bo(fd); - get_tiling(fd, handle, &tiling, &swizzle); - - if (IS_GEN2(intel_get_drm_devid(fd))) { - tile_height = 16; - tile_width = 128; - tile_size = 2048; - } else { - tile_height = 8; - tile_width = 512; - tile_size = PAGE_SIZE; - } - - /* Read a bunch of random subsets of the data and check that they come - * out right. - */ - for (i = 0; i < iter; i++) { - int size = WIDTH * HEIGHT * 4; - int offset = (random() % size) & ~3; - int len = (random() % size) & ~3; - int first_page, last_page; - uint32_t *linear; - int j; - - if (len == 0) - len = 4; - - if (offset + len > size) - len = size - offset; - - if (i == 0) { - offset = 0; - len = size; - } - - first_page = offset & ~(PAGE_SIZE-1); - last_page = (offset + len + PAGE_SIZE) & ~(PAGE_SIZE-1); - - linear = gem_mmap__wc(fd, handle, first_page, last_page - first_page, PROT_READ); - igt_assert(linear); - - /* Translate from offsets in the read buffer to the swizzled - * address that it corresponds to. This is the opposite of - * what Mesa does (calculate offset to be read given the linear - * offset it's looking for). - */ - for (j = offset; j < offset + len; j += 4) { - uint32_t expected_val, found_val; - int swizzled_offset; - const char *swizzle_str; - - switch (swizzle) { - case I915_BIT_6_SWIZZLE_NONE: - swizzled_offset = j; - swizzle_str = "none"; - break; - case I915_BIT_6_SWIZZLE_9: - swizzled_offset = j ^ - swizzle_bit(9, j); - swizzle_str = "bit9"; - break; - case I915_BIT_6_SWIZZLE_9_10: - swizzled_offset = j ^ - swizzle_bit(9, j) ^ - swizzle_bit(10, j); - swizzle_str = "bit9^10"; - break; - case I915_BIT_6_SWIZZLE_9_11: - swizzled_offset = j ^ - swizzle_bit(9, j) ^ - swizzle_bit(11, j); - swizzle_str = "bit9^11"; - break; - case I915_BIT_6_SWIZZLE_9_10_11: - swizzled_offset = j ^ - swizzle_bit(9, j) ^ - swizzle_bit(10, j) ^ - swizzle_bit(11, j); - swizzle_str = "bit9^10^11"; - break; - default: - igt_skip("unknown swizzling"); - break; - } - igt_debug("Checking offset %d swizzled %s -> %d\n", - j, swizzle_str, swizzled_offset); - expected_val = calculate_expected(swizzled_offset); - found_val = linear[(j - first_page)/ 4]; - igt_assert_f(expected_val == found_val, - "Bad read [%d]: %d instead of %d at 0x%08x " - "for read from 0x%08x to 0x%08x, swizzle=%s\n", - i, found_val, expected_val, j, - offset, offset + len, - swizzle_str); - } - munmap(linear, last_page - first_page); - } - - close(fd); -} diff --git a/tests/gem_tiling_max_stride.c b/tests/gem_tiling_max_stride.c deleted file mode 100644 index fce1ac7d..00000000 --- a/tests/gem_tiling_max_stride.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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: - * Ville Syrjälä <ville.syrjala@linux.intel.com> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <limits.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Check that max fence stride works."); - -static void do_test_invalid_tiling(int fd, uint32_t handle, int tiling, int stride) -{ - igt_assert(__gem_set_tiling(fd, handle, tiling, tiling ? stride : 0) == -EINVAL); -} - -static void test_invalid_tiling(int fd, uint32_t handle, int stride) -{ - do_test_invalid_tiling(fd, handle, I915_TILING_X, stride); - do_test_invalid_tiling(fd, handle, I915_TILING_Y, stride); -} - -/** - * Testcase: Check that max fence stride works - */ - -igt_simple_main -{ - int fd; - uint32_t *ptr; - uint32_t *data; - uint32_t handle; - uint32_t stride; - uint32_t size; - uint32_t devid; - int i = 0, x, y; - int tile_width = 512; - int tile_height = 8; - - fd = drm_open_any(); - - devid = intel_get_drm_devid(fd); - - if (intel_gen(devid) >= 7) - stride = 256 * 1024; - else if (intel_gen(devid) >= 4) - stride = 128 * 1024; - else { - if (IS_GEN2(devid)) { - tile_width = 128; - tile_height = 16; - } - stride = 8 * 1024; - } - - size = stride * tile_height; - - data = malloc(size); - igt_assert(data); - - /* Fill each line with the line number */ - for (y = 0; y < tile_height; y++) { - for (x = 0; x < stride / 4; x++) - data[i++] = y; - } - - handle = gem_create(fd, size); - - ptr = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE); - igt_assert(ptr); - - test_invalid_tiling(fd, handle, 0); - test_invalid_tiling(fd, handle, 64); - test_invalid_tiling(fd, handle, stride - 1); - test_invalid_tiling(fd, handle, stride + 1); - test_invalid_tiling(fd, handle, stride + 127); - test_invalid_tiling(fd, handle, stride + 128); - test_invalid_tiling(fd, handle, stride + tile_width - 1); - test_invalid_tiling(fd, handle, stride + tile_width); - test_invalid_tiling(fd, handle, stride * 2); - test_invalid_tiling(fd, handle, INT_MAX); - test_invalid_tiling(fd, handle, UINT_MAX); - - gem_set_tiling(fd, handle, I915_TILING_X, stride); - - gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - - memcpy(ptr, data, size); - - gem_set_tiling(fd, handle, I915_TILING_NONE, 0); - - memcpy(data, ptr, size); - - /* Check that each tile contains the expected pattern */ - for (i = 0; i < size / 4; ) { - for (y = 0; y < tile_height; y++) { - for (x = 0; x < tile_width / 4; x++) { - igt_assert(y == data[i]); - i++; - } - } - } - - munmap(ptr, size); - - close(fd); -} diff --git a/tests/gem_unfence_active_buffers.c b/tests/gem_unfence_active_buffers.c deleted file mode 100644 index 125568ed..00000000 --- a/tests/gem_unfence_active_buffers.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright © 2012 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/** @file gem_unfence_active_buffers.c - * - * Testcase: Check for use-after free in the fence stealing code - * - * If we're stealing the fence of a active object where the active list is the - * only thing holding a reference, we need to be careful not to access the old - * object we're stealing the fence from after that reference has been dropped by - * retire_requests. - * - * Note that this needs slab poisoning enabled in the kernel to reliably hit the - * problem - the race window is too small. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <stdbool.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Check for use-after-free in the fence stealing code."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -uint32_t devid; - -#define TEST_SIZE (1024*1024) -#define TEST_STRIDE (4*1024) - -uint32_t data[TEST_SIZE/4]; - -igt_simple_main -{ - int i, ret, fd, num_fences; - drm_intel_bo *busy_bo, *test_bo; - uint32_t tiling = I915_TILING_X; - - igt_skip_on_simulation(); - - for (i = 0; i < 1024*256; i++) - data[i] = i; - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - devid = intel_get_drm_devid(fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - igt_info("filling ring\n"); - busy_bo = drm_intel_bo_alloc(bufmgr, "busy bo bo", 16*1024*1024, 4096); - - for (i = 0; i < 250; i++) { - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 2*1024*4); - OUT_BATCH(0 << 16 | 1024); - OUT_BATCH((2048) << 16 | (2048)); - OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(2*1024*4); - OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 6) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } - } - intel_batchbuffer_flush(batch); - - num_fences = gem_available_fences(fd); - igt_info("creating havoc on %i fences\n", num_fences); - - for (i = 0; i < num_fences*2; i++) { - test_bo = drm_intel_bo_alloc(bufmgr, "test_bo", - TEST_SIZE, 4096); - ret = drm_intel_bo_set_tiling(test_bo, &tiling, TEST_STRIDE); - igt_assert(ret == 0); - - drm_intel_bo_disable_reuse(test_bo); - - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - TEST_STRIDE); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH((1) << 16 | (1)); - OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(TEST_STRIDE); - OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - intel_batchbuffer_flush(batch); - igt_info("test bo offset: %#lx\n", test_bo->offset); - - drm_intel_bo_unreference(test_bo); - } - - /* launch a few batchs to ensure the damaged slab objects get reused. */ - for (i = 0; i < 10; i++) { - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 2*1024*4); - OUT_BATCH(0 << 16 | 1024); - OUT_BATCH((1) << 16 | (1)); - OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(2*1024*4); - OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 8) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } - } - intel_batchbuffer_flush(batch); -} diff --git a/tests/gem_unref_active_buffers.c b/tests/gem_unref_active_buffers.c deleted file mode 100644 index 8c8efaad..00000000 --- a/tests/gem_unref_active_buffers.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright © 2011 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/* - * Testcase: Unreferencing of active buffers - * - * Execs buffers and immediately unreferences them, hence the kernel active list - * will be the last one to hold a reference on them. Usually libdrm bo caching - * prevents that by keeping another reference. - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Test unreferencing of active buffers."); - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *load_bo; - -igt_simple_main -{ - int fd, i; - - igt_skip_on_simulation(); - - fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - /* don't enable buffer reuse!! */ - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - igt_assert(batch); - - /* put some load onto the gpu to keep the light buffers active for long - * enough */ - for (i = 0; i < 1000; i++) { - load_bo = drm_intel_bo_alloc(bufmgr, "target bo", 1024*4096, 4096); - igt_assert(load_bo); - - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 4096); - OUT_BATCH(0); /* dst x1,y1 */ - OUT_BATCH((1024 << 16) | 512); - OUT_RELOC_FENCED(load_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH((0 << 16) | 512); /* src x1, y1 */ - OUT_BATCH(4096); - OUT_RELOC_FENCED(load_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); - - drm_intel_bo_disable_reuse(load_bo); - drm_intel_bo_unreference(load_bo); - } - - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); -} diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c deleted file mode 100644 index 9217c2ac..00000000 --- a/tests/gem_userptr_blits.c +++ /dev/null @@ -1,1536 +0,0 @@ -/* - * Copyright © 2009-2014 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: - * Eric Anholt <eric@anholt.net> - * Chris Wilson <chris@chris-wilson.co.uk> - * Tvrtko Ursulin <tvrtko.ursulin@intel.com> - * - */ - -/** @file gem_userptr_blits.c - * - * This is a test of doing many blits using a mixture of normal system pages - * and uncached linear buffers, with a working set larger than the - * aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/mman.h> -#include <signal.h> -#include <pthread.h> -#include <time.h> - -#include "drm.h" -#include "i915_drm.h" - -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "ioctl_wrappers.h" - -#include "eviction_common.c" - -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - -#define LOCAL_I915_GEM_USERPTR 0x33 -#define LOCAL_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_USERPTR, struct local_i915_gem_userptr) -struct local_i915_gem_userptr { - uint64_t user_ptr; - uint64_t user_size; - uint32_t flags; -#define LOCAL_I915_USERPTR_READ_ONLY (1<<0) -#define LOCAL_I915_USERPTR_UNSYNCHRONIZED (1<<31) - uint32_t handle; -}; - -static uint32_t userptr_flags = LOCAL_I915_USERPTR_UNSYNCHRONIZED; - -#define WIDTH 512 -#define HEIGHT 512 - -static uint32_t linear[WIDTH*HEIGHT]; - -static void gem_userptr_test_unsynchronized(void) -{ - userptr_flags = LOCAL_I915_USERPTR_UNSYNCHRONIZED; -} - -static void gem_userptr_test_synchronized(void) -{ - userptr_flags = 0; -} - -static int gem_userptr(int fd, void *ptr, int size, int read_only, uint32_t *handle) -{ - struct local_i915_gem_userptr userptr; - int ret; - - memset(&userptr, 0, sizeof(userptr)); - userptr.user_ptr = (uintptr_t)ptr; - userptr.user_size = size; - userptr.flags = userptr_flags; - if (read_only) - userptr.flags |= LOCAL_I915_USERPTR_READ_ONLY; - - ret = drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr); - if (ret) - ret = errno; - igt_skip_on_f(ret == ENODEV && - (userptr_flags & LOCAL_I915_USERPTR_UNSYNCHRONIZED) == 0 && - !read_only, - "Skipping, synchronized mappings with no kernel CONFIG_MMU_NOTIFIER?"); - if (ret == 0) - *handle = userptr.handle; - - return ret; -} - - -static void gem_userptr_sync(int fd, uint32_t handle) -{ - gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); -} - -static void -copy(int fd, uint32_t dst, uint32_t src, unsigned int error) -{ - 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 ret, i=0; - - 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) - batch[i - 1] |= 8; - else - batch[i - 1] |= 6; - - batch[i++] = (3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - WIDTH*4; - 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) - 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) - 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 = 0; - 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 = 0; - reloc[1].offset = 7 * sizeof(batch[0]); - if (intel_gen(intel_get_drm_devid(fd)) >= 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; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - if (ret) - ret = errno; - - if (error == ~0) - igt_assert(ret != 0); - else - igt_assert(ret == error); - - gem_close(fd, handle); -} - -static int -blit(int fd, uint32_t dst, uint32_t src, uint32_t *all_bo, int n_bo) -{ - uint32_t batch[12]; - struct drm_i915_gem_relocation_entry reloc[2]; - struct drm_i915_gem_exec_object2 *obj; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - int n, ret, i=0; - - 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) - batch[i - 1] |= 8; - else - batch[i - 1] |= 6; - batch[i++] = (3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - WIDTH*4; - 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) - 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) - 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 = 0; - 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 = 0; - reloc[1].offset = 7 * sizeof(batch[0]); - if (intel_gen(intel_get_drm_devid(fd)) >= 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; - - obj = calloc(n_bo + 1, sizeof(*obj)); - for (n = 0; n < n_bo; n++) - obj[n].handle = all_bo[n]; - obj[n].handle = handle; - obj[n].relocation_count = 2; - obj[n].relocs_ptr = (uintptr_t)reloc; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = n_bo + 1; - 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; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - if (ret) - ret = errno; - - gem_close(fd, handle); - free(obj); - - return ret; -} - -static uint32_t -create_userptr(int fd, uint32_t val, uint32_t *ptr) -{ - uint32_t handle; - int i, ret; - - ret = gem_userptr(fd, ptr, sizeof(linear), 0, &handle); - igt_assert(ret == 0); - igt_assert(handle != 0); - - /* Fill the BO with dwords starting at val */ - for (i = 0; i < WIDTH*HEIGHT; i++) - ptr[i] = val++; - - return handle; -} - -static void **handle_ptr_map; -static unsigned *handle_size_map; -static unsigned int num_handle_map; - -static void reset_handle_ptr(void) -{ - if (num_handle_map == 0) - return; - - free(handle_ptr_map); - handle_ptr_map = NULL; - - free(handle_size_map); - handle_size_map = NULL; - - num_handle_map = 0; -} - -static void add_handle_ptr(uint32_t handle, void *ptr, int size) -{ - if (handle >= num_handle_map) { - int max = (4096 + handle) & -4096; - - handle_ptr_map = realloc(handle_ptr_map, - max * sizeof(void*)); - igt_assert(handle_ptr_map); - memset(handle_ptr_map + num_handle_map, 0, - (max - num_handle_map) * sizeof(void*)); - - handle_size_map = realloc(handle_size_map, - max * sizeof(unsigned)); - igt_assert(handle_size_map); - memset(handle_ptr_map + num_handle_map, 0, - (max - num_handle_map) * sizeof(unsigned)); - - num_handle_map = max; - } - - handle_ptr_map[handle] = ptr; - handle_size_map[handle] = size; -} - -static void *get_handle_ptr(uint32_t handle) -{ - igt_assert(handle < num_handle_map); - return handle_ptr_map[handle]; -} - -static void free_handle_ptr(uint32_t handle) -{ - igt_assert(handle < num_handle_map); - igt_assert(handle_ptr_map[handle]); - - munmap(handle_ptr_map[handle], handle_size_map[handle]); - handle_ptr_map[handle] = NULL; -} - -static uint32_t create_userptr_bo(int fd, int size) -{ - void *ptr; - uint32_t handle; - int ret; - - ptr = mmap(NULL, size, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_SHARED, - -1, 0); - igt_assert(ptr != MAP_FAILED); - - ret = gem_userptr(fd, (uint32_t *)ptr, size, 0, &handle); - igt_assert(ret == 0); - add_handle_ptr(handle, ptr, size); - - return handle; -} - -static void flink_userptr_bo(uint32_t old_handle, uint32_t new_handle) -{ - igt_assert(old_handle < num_handle_map); - igt_assert(handle_ptr_map[old_handle]); - - add_handle_ptr(new_handle, - handle_ptr_map[old_handle], - handle_size_map[old_handle]); -} - -static void clear(int fd, uint32_t handle, int size) -{ - void *ptr = get_handle_ptr(handle); - - igt_assert(ptr != NULL); - - memset(ptr, 0, size); -} - -static void free_userptr_bo(int fd, uint32_t handle) -{ - gem_close(fd, handle); - free_handle_ptr(handle); -} - -static uint32_t -create_bo(int fd, uint32_t val) -{ - uint32_t handle; - int i; - - handle = gem_create(fd, sizeof(linear)); - - /* Fill the BO with dwords starting at val */ - for (i = 0; i < WIDTH*HEIGHT; i++) - linear[i] = val++; - gem_write(fd, handle, 0, linear, sizeof(linear)); - - return handle; -} - -static void -check_cpu(uint32_t *ptr, uint32_t val) -{ - int i; - - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(ptr[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, ptr[i], i * 4); - val++; - } -} - -static void -check_gpu(int fd, uint32_t handle, uint32_t val) -{ - gem_read(fd, handle, 0, linear, sizeof(linear)); - check_cpu(linear, val); -} - -static int has_userptr(int fd) -{ - uint32_t handle = 0; - void *ptr; - uint32_t oldflags; - int ret; - - igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); - oldflags = userptr_flags; - gem_userptr_test_unsynchronized(); - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); - userptr_flags = oldflags; - if (ret != 0) { - free(ptr); - return 0; - } - - gem_close(fd, handle); - free(ptr); - - return handle != 0; -} - -static int test_input_checking(int fd) -{ - struct local_i915_gem_userptr userptr; - int ret; - - /* Invalid flags. */ - memset(&userptr, 0, sizeof(userptr)); - userptr.user_ptr = 0; - userptr.user_size = 0; - userptr.flags = ~0; - ret = drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr); - igt_assert(ret != 0); - - /* Too big. */ - memset(&userptr, 0, sizeof(userptr)); - userptr.user_ptr = 0; - userptr.user_size = ~0; - userptr.flags = 0; - ret = drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr); - igt_assert(ret != 0); - - /* Both wrong. */ - memset(&userptr, 0, sizeof(userptr)); - userptr.user_ptr = 0; - userptr.user_size = ~0; - userptr.flags = ~0; - ret = drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr); - igt_assert(ret != 0); - - return 0; -} - -static int test_access_control(int fd) -{ - igt_fork(child, 1) { - void *ptr; - int ret; - uint32_t handle; - - igt_drop_root(); - - /* CAP_SYS_ADMIN is needed for UNSYNCHRONIZED mappings. */ - gem_userptr_test_unsynchronized(); - - igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); - - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); - if (ret == 0) - gem_close(fd, handle); - free(ptr); - igt_assert(ret == EPERM); - } - - igt_waitchildren(); - - return 0; -} - -static int test_invalid_null_pointer(int fd) -{ - uint32_t handle; - int ret; - - /* NULL pointer. */ - ret = gem_userptr(fd, NULL, PAGE_SIZE, 0, &handle); - igt_assert(ret == 0); - - copy(fd, handle, handle, ~0); /* QQQ Precise errno? */ - gem_close(fd, handle); - - return 0; -} - -static int test_invalid_gtt_mapping(int fd) -{ - uint32_t handle, handle2; - void *ptr; - int ret; - - /* GTT mapping */ - handle = create_bo(fd, 0); - ptr = gem_mmap__gtt(fd, handle, sizeof(linear), PROT_READ | PROT_WRITE); - gem_close(fd, handle); - igt_assert(ptr != NULL); - igt_assert(((unsigned long)ptr & (PAGE_SIZE - 1)) == 0); - igt_assert((sizeof(linear) & (PAGE_SIZE - 1)) == 0); - - ret = gem_userptr(fd, ptr, sizeof(linear), 0, &handle2); - igt_assert(ret == 0); - copy(fd, handle2, handle2, ~0); /* QQQ Precise errno? */ - gem_close(fd, handle2); - - munmap(ptr, sizeof(linear)); - - return 0; -} - -#define PE_GTT_MAP 0x1 -#define PE_BUSY 0x2 -static void test_process_exit(int fd, int flags) -{ - if (flags & PE_GTT_MAP) - igt_require(gem_has_llc(fd)); - - igt_fork(child, 1) { - uint32_t handle; - - handle = create_userptr_bo(fd, sizeof(linear)); - - if (flags & PE_GTT_MAP) { - uint32_t *ptr = gem_mmap__gtt(fd, handle, sizeof(linear), PROT_READ | PROT_WRITE); - if (ptr) - *ptr = 0; - } - - if (flags & PE_BUSY) - copy(fd, handle, handle, 0); - } - igt_waitchildren(); -} - -static void test_forked_access(int fd) -{ - uint32_t handle1 = 0, handle2 = 0; - void *ptr1 = NULL, *ptr2 = NULL; - int ret; - - ret = posix_memalign(&ptr1, PAGE_SIZE, sizeof(linear)); -#ifdef MADV_DONTFORK - ret |= madvise(ptr1, sizeof(linear), MADV_DONTFORK); -#endif - ret |= gem_userptr(fd, ptr1, sizeof(linear), 0, &handle1); - igt_assert(ret == 0); - igt_assert(ptr1); - igt_assert(handle1); - - ret = posix_memalign(&ptr2, PAGE_SIZE, sizeof(linear)); -#ifdef MADV_DONTFORK - ret |= madvise(ptr2, sizeof(linear), MADV_DONTFORK); -#endif - ret |= gem_userptr(fd, ptr2, sizeof(linear), 0, &handle2); - igt_assert(ret == 0); - igt_assert(ptr2); - igt_assert(handle2); - - memset(ptr1, 0x1, sizeof(linear)); - memset(ptr2, 0x2, sizeof(linear)); - - igt_fork(child, 1) { - copy(fd, handle1, handle2, 0); - } - igt_waitchildren(); - - gem_userptr_sync(fd, handle1); - gem_userptr_sync(fd, handle2); - - gem_close(fd, handle1); - gem_close(fd, handle2); - - igt_assert(memcmp(ptr1, ptr2, sizeof(linear)) == 0); - -#ifdef MADV_DOFORK - ret = madvise(ptr1, sizeof(linear), MADV_DOFORK); - igt_assert(ret == 0); -#endif - free(ptr1); - -#ifdef MADV_DOFORK - ret = madvise(ptr2, sizeof(linear), MADV_DOFORK); - igt_assert(ret == 0); -#endif - free(ptr2); -} - -static int test_forbidden_ops(int fd) -{ - struct drm_i915_gem_pread gem_pread; - struct drm_i915_gem_pwrite gem_pwrite; - void *ptr; - int ret; - uint32_t handle; - char buf[PAGE_SIZE]; - - memset(&gem_pread, 0, sizeof(gem_pread)); - memset(&gem_pwrite, 0, sizeof(gem_pwrite)); - - igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); - - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); - igt_assert(ret == 0); - - /* pread/pwrite are not always forbidden, but when they - * are they should fail with EINVAL. - */ - - gem_pread.handle = handle; - gem_pread.offset = 0; - gem_pread.size = PAGE_SIZE; - gem_pread.data_ptr = (uintptr_t)buf; - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_PREAD, &gem_pread); - igt_assert(ret == 0 || errno == EINVAL); - - gem_pwrite.handle = handle; - gem_pwrite.offset = 0; - gem_pwrite.size = PAGE_SIZE; - gem_pwrite.data_ptr = (uintptr_t)buf; - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &gem_pwrite); - igt_assert(ret == 0 || errno == EINVAL); - gem_close(fd, handle); - free(ptr); - - return 0; -} - -static unsigned char counter; - -static void (* volatile orig_sigbus)(int sig, siginfo_t *info, void *param); -static volatile unsigned long sigbus_start; -static volatile long sigbus_cnt = -1; - -static void *umap(int fd, uint32_t handle) -{ - void *ptr; - - if (gem_has_llc(fd)) { - ptr = gem_mmap(fd, handle, sizeof(linear), PROT_READ | PROT_WRITE); - } else { - uint32_t tmp = gem_create(fd, sizeof(linear)); - copy(fd, tmp, handle, 0); - ptr = gem_mmap__cpu(fd, tmp, 0, sizeof(linear), PROT_READ); - gem_close(fd, tmp); - } - - return ptr; -} - -static void -check_bo(int fd1, uint32_t handle1, int is_userptr, int fd2, uint32_t handle2) -{ - unsigned char *ptr1, *ptr2; - unsigned long size = sizeof(linear); - - ptr2 = umap(fd2, handle2); - if (is_userptr) - ptr1 = is_userptr > 0 ? get_handle_ptr(handle1) : ptr2; - else - ptr1 = umap(fd1, handle1); - - igt_assert(ptr1); - igt_assert(ptr2); - - sigbus_start = (unsigned long)ptr2; - igt_assert(memcmp(ptr1, ptr2, sizeof(linear)) == 0); - - if (gem_has_llc(fd1)) { - counter++; - memset(ptr1, counter, size); - memset(ptr2, counter, size); - } - - if (!is_userptr) - munmap(ptr1, sizeof(linear)); - munmap(ptr2, sizeof(linear)); -} - -static int export_handle(int fd, uint32_t handle, int *outfd) -{ - struct drm_prime_handle args; - int ret; - - args.handle = handle; - args.flags = DRM_CLOEXEC; - args.fd = -1; - - ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); - if (ret) - ret = errno; - *outfd = args.fd; - - return ret; -} - -static void sigbus(int sig, siginfo_t *info, void *param) -{ - unsigned long ptr = (unsigned long)info->si_addr; - void *addr; - - if (ptr >= sigbus_start && - ptr < sigbus_start + sizeof(linear)) { - /* replace mapping to allow progress */ - munmap((void *)sigbus_start, sizeof(linear)); - addr = mmap((void *)sigbus_start, sizeof(linear), - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); - igt_assert((unsigned long)addr == sigbus_start); - memset(addr, counter, sizeof(linear)); - - sigbus_cnt++; - return; - } - - if (orig_sigbus) - orig_sigbus(sig, info, param); - igt_assert(0); -} - -static int test_dmabuf(void) -{ - int fd1, fd2; - uint32_t handle, handle_import; - int dma_buf_fd = -1; - int ret; - - fd1 = drm_open_any(); - - handle = create_userptr_bo(fd1, sizeof(linear)); - memset(get_handle_ptr(handle), counter, sizeof(linear)); - - ret = export_handle(fd1, handle, &dma_buf_fd); - if (userptr_flags & LOCAL_I915_USERPTR_UNSYNCHRONIZED && ret) { - igt_assert(ret == EINVAL || ret == ENODEV); - free_userptr_bo(fd1, handle); - close(fd1); - return 0; - } else { - igt_assert(ret == 0); - igt_assert(dma_buf_fd >= 0); - } - - fd2 = drm_open_any(); - handle_import = prime_fd_to_handle(fd2, dma_buf_fd); - check_bo(fd1, handle, 1, fd2, handle_import); - - /* close dma_buf, check whether nothing disappears. */ - close(dma_buf_fd); - check_bo(fd1, handle, 1, fd2, handle_import); - - /* destroy userptr object and expect SIGBUS */ - free_userptr_bo(fd1, handle); - close(fd1); - - if (gem_has_llc(fd2)) { - struct sigaction sigact, orig_sigact; - - memset(&sigact, 0, sizeof(sigact)); - sigact.sa_sigaction = sigbus; - sigact.sa_flags = SA_SIGINFO; - ret = sigaction(SIGBUS, &sigact, &orig_sigact); - igt_assert(ret == 0); - - orig_sigbus = orig_sigact.sa_sigaction; - - sigbus_cnt = 0; - check_bo(fd2, handle_import, -1, fd2, handle_import); - igt_assert(sigbus_cnt > 0); - - ret = sigaction(SIGBUS, &orig_sigact, NULL); - igt_assert(ret == 0); - } - - close(fd2); - reset_handle_ptr(); - - return 0; -} - -static int test_usage_restrictions(int fd) -{ - void *ptr; - int ret; - uint32_t handle; - - igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE * 2) == 0); - - /* Address not aligned. */ - ret = gem_userptr(fd, (char *)ptr + 1, PAGE_SIZE, 0, &handle); - igt_assert(ret != 0); - - /* Size not rounded to page size. */ - ret = gem_userptr(fd, ptr, PAGE_SIZE - 1, 0, &handle); - igt_assert(ret != 0); - - /* Both wrong. */ - ret = gem_userptr(fd, (char *)ptr + 1, PAGE_SIZE - 1, 0, &handle); - igt_assert(ret != 0); - - /* Read-only not supported. */ - ret = gem_userptr(fd, (char *)ptr, PAGE_SIZE, 1, &handle); - igt_assert(ret != 0); - - free(ptr); - - return 0; -} - -static int test_create_destroy(int fd, int time) -{ - struct timespec start, now; - uint32_t handle; - void *ptr; - int n; - - igt_fork_signal_helper(); - - clock_gettime(CLOCK_MONOTONIC, &start); - do { - for (n = 0; n < 1000; n++) { - igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); - - do_or_die(gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle)); - - gem_close(fd, handle); - free(ptr); - } - - clock_gettime(CLOCK_MONOTONIC, &now); - now.tv_sec -= time; - } while (now.tv_sec < start.tv_sec || - (now.tv_sec == start.tv_sec && now.tv_nsec < start.tv_nsec)); - - igt_stop_signal_helper(); - - return 0; -} - -static int test_coherency(int fd, int count) -{ - uint32_t *memory; - uint32_t *cpu, *cpu_val; - uint32_t *gpu, *gpu_val; - uint32_t start = 0; - int i, ret; - - intel_require_memory(count, sizeof(linear), CHECK_RAM); - igt_info("Using 2x%d 1MiB buffers\n", count); - - ret = posix_memalign((void **)&memory, PAGE_SIZE, count*sizeof(linear)); - igt_assert(ret == 0 && memory); - - gpu = malloc(sizeof(uint32_t)*count*4); - gpu_val = gpu + count; - cpu = gpu_val + count; - cpu_val = cpu + count; - - for (i = 0; i < count; i++) { - gpu[i] = create_bo(fd, start); - gpu_val[i] = start; - start += WIDTH*HEIGHT; - } - - for (i = 0; i < count; i++) { - cpu[i] = create_userptr(fd, start, memory+i*WIDTH*HEIGHT); - cpu_val[i] = start; - start += WIDTH*HEIGHT; - } - - igt_info("Verifying initialisation...\n"); - for (i = 0; i < count; i++) { - check_gpu(fd, gpu[i], gpu_val[i]); - check_cpu(memory+i*WIDTH*HEIGHT, cpu_val[i]); - } - - igt_info("Cyclic blits cpu->gpu, forward...\n"); - for (i = 0; i < count * 4; i++) { - int src = i % count; - int dst = (i + 1) % count; - - copy(fd, gpu[dst], cpu[src], 0); - gpu_val[dst] = cpu_val[src]; - } - for (i = 0; i < count; i++) - check_gpu(fd, gpu[i], gpu_val[i]); - - igt_info("Cyclic blits gpu->cpu, backward...\n"); - for (i = 0; i < count * 4; i++) { - int src = (i + 1) % count; - int dst = i % count; - - copy(fd, cpu[dst], gpu[src], 0); - cpu_val[dst] = gpu_val[src]; - } - for (i = 0; i < count; i++) { - gem_userptr_sync(fd, cpu[i]); - check_cpu(memory+i*WIDTH*HEIGHT, cpu_val[i]); - } - - igt_info("Random blits...\n"); - for (i = 0; i < count * 4; i++) { - int src = random() % count; - int dst = random() % count; - - if (random() & 1) { - copy(fd, gpu[dst], cpu[src], 0); - gpu_val[dst] = cpu_val[src]; - } else { - copy(fd, cpu[dst], gpu[src], 0); - cpu_val[dst] = gpu_val[src]; - } - } - for (i = 0; i < count; i++) { - check_gpu(fd, gpu[i], gpu_val[i]); - gem_close(fd, gpu[i]); - - gem_userptr_sync(fd, cpu[i]); - check_cpu(memory+i*WIDTH*HEIGHT, cpu_val[i]); - gem_close(fd, cpu[i]); - } - - free(gpu); - free(memory); - - return 0; -} - -static struct igt_eviction_test_ops fault_ops = { - .create = create_userptr_bo, - .flink = flink_userptr_bo, - .close = free_userptr_bo, - .copy = blit, - .clear = clear, -}; - -static int can_swap(void) -{ - unsigned long as, ram; - - /* Cannot swap if not enough address space */ - - /* FIXME: Improve check criteria. */ - if (sizeof(void*) < 8) - as = 3 * 1024; - else - as = 256 * 1024; /* Just a big number */ - - ram = intel_get_total_ram_mb(); - - if ((as - 128) < (ram - 256)) - return 0; - - return 1; -} - -static void test_forking_evictions(int fd, int size, int count, - unsigned flags) -{ - int trash_count; - int num_threads; - - trash_count = intel_get_total_ram_mb() * 11 / 10; - /* Use the fact test will spawn a number of child - * processes meaning swapping will be triggered system - * wide even if one process on it's own can't do it. - */ - num_threads = min(sysconf(_SC_NPROCESSORS_ONLN) * 4, 12); - trash_count /= num_threads; - if (count > trash_count) - count = trash_count; - - forking_evictions(fd, &fault_ops, size, count, trash_count, flags); - reset_handle_ptr(); -} - -static void test_swapping_evictions(int fd, int size, int count) -{ - int trash_count; - - igt_skip_on_f(!can_swap(), - "Not enough process address space for swapping tests.\n"); - - trash_count = intel_get_total_ram_mb() * 11 / 10; - - swapping_evictions(fd, &fault_ops, size, count, trash_count); - reset_handle_ptr(); -} - -static void test_minor_evictions(int fd, int size, int count) -{ - minor_evictions(fd, &fault_ops, size, count); - reset_handle_ptr(); -} - -static void test_major_evictions(int fd, int size, int count) -{ - major_evictions(fd, &fault_ops, size, count); - reset_handle_ptr(); -} - -static void test_overlap(int fd, int expected) -{ - char *ptr; - int ret; - uint32_t handle, handle2; - - igt_assert(posix_memalign((void *)&ptr, PAGE_SIZE, PAGE_SIZE * 3) == 0); - - ret = gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE, 0, &handle); - igt_assert(ret == 0); - - /* before, no overlap */ - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle2); - if (ret == 0) - gem_close(fd, handle2); - igt_assert(ret == 0); - - /* after, no overlap */ - ret = gem_userptr(fd, ptr + PAGE_SIZE * 2, PAGE_SIZE, 0, &handle2); - if (ret == 0) - gem_close(fd, handle2); - igt_assert(ret == 0); - - /* exactly overlapping */ - ret = gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE, 0, &handle2); - if (ret == 0) - gem_close(fd, handle2); - igt_assert(ret == 0 || ret == expected); - - /* start overlaps */ - ret = gem_userptr(fd, ptr, PAGE_SIZE * 2, 0, &handle2); - if (ret == 0) - gem_close(fd, handle2); - igt_assert(ret == 0 || ret == expected); - - /* end overlaps */ - ret = gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE * 2, 0, &handle2); - if (ret == 0) - gem_close(fd, handle2); - igt_assert(ret == 0 || ret == expected); - - /* subsumes */ - ret = gem_userptr(fd, ptr, PAGE_SIZE * 3, 0, &handle2); - if (ret == 0) - gem_close(fd, handle2); - igt_assert(ret == 0 || ret == expected); - - gem_close(fd, handle); - free(ptr); -} - -static void test_unmap(int fd, int expected) -{ - char *ptr, *bo_ptr; - const unsigned int num_obj = 3; - unsigned int i; - uint32_t bo[num_obj + 1]; - size_t map_size = sizeof(linear) * num_obj + (PAGE_SIZE - 1); - int ret; - - ptr = mmap(NULL, map_size, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - igt_assert(ptr != MAP_FAILED); - - bo_ptr = (char *)ALIGN((unsigned long)ptr, PAGE_SIZE); - - for (i = 0; i < num_obj; i++, bo_ptr += sizeof(linear)) { - ret = gem_userptr(fd, bo_ptr, sizeof(linear), 0, &bo[i]); - igt_assert(ret == 0); - } - - bo[num_obj] = create_bo(fd, 0); - - for (i = 0; i < num_obj; i++) - copy(fd, bo[num_obj], bo[i], 0); - - ret = munmap(ptr, map_size); - igt_assert(ret == 0); - - for (i = 0; i < num_obj; i++) - copy(fd, bo[num_obj], bo[i], expected); - - for (i = 0; i < (num_obj + 1); i++) - gem_close(fd, bo[i]); -} - -static void test_unmap_after_close(int fd) -{ - char *ptr, *bo_ptr; - const unsigned int num_obj = 3; - unsigned int i; - uint32_t bo[num_obj + 1]; - size_t map_size = sizeof(linear) * num_obj + (PAGE_SIZE - 1); - int ret; - - ptr = mmap(NULL, map_size, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - igt_assert(ptr != MAP_FAILED); - - bo_ptr = (char *)ALIGN((unsigned long)ptr, PAGE_SIZE); - - for (i = 0; i < num_obj; i++, bo_ptr += sizeof(linear)) { - ret = gem_userptr(fd, bo_ptr, sizeof(linear), 0, &bo[i]); - igt_assert(ret == 0); - } - - bo[num_obj] = create_bo(fd, 0); - - for (i = 0; i < num_obj; i++) - copy(fd, bo[num_obj], bo[i], 0); - - for (i = 0; i < (num_obj + 1); i++) - gem_close(fd, bo[i]); - - ret = munmap(ptr, map_size); - igt_assert(ret == 0); -} - -static void test_unmap_cycles(int fd, int expected) -{ - int i; - - for (i = 0; i < 1000; i++) - test_unmap(fd, expected); -} - -#define MM_STRESS_LOOPS 100000 - -struct stress_thread_data { - unsigned int stop; - int exit_code; -}; - -static void *mm_stress_thread(void *data) -{ - struct stress_thread_data *stdata = (struct stress_thread_data *)data; - void *ptr; - int ret; - - while (!stdata->stop) { - ptr = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (ptr == MAP_FAILED) { - stdata->exit_code = -EFAULT; - break; - } - ret = munmap(ptr, PAGE_SIZE); - if (ret) { - stdata->exit_code = errno; - break; - } - } - - return NULL; -} - -static void test_stress_mm(int fd) -{ - int ret; - pthread_t t; - unsigned int loops = MM_STRESS_LOOPS; - uint32_t handle; - void *ptr; - struct stress_thread_data stdata; - - memset(&stdata, 0, sizeof(stdata)); - - igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); - - ret = pthread_create(&t, NULL, mm_stress_thread, &stdata); - igt_assert(ret == 0); - - while (loops--) { - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); - igt_assert(ret == 0); - - gem_close(fd, handle); - } - - free(ptr); - - stdata.stop = 1; - ret = pthread_join(t, NULL); - igt_assert(ret == 0); - - igt_assert(stdata.exit_code == 0); -} - -struct userptr_close_thread_data { - int fd; - void *ptr; - bool overlap; - bool stop; - pthread_mutex_t mutex; -}; - -static void *mm_userptr_close_thread(void *data) -{ - struct userptr_close_thread_data *t = (struct userptr_close_thread_data *)data; - int num_handles = t->overlap ? 2 : 1; - - uint32_t handle[num_handles]; - - /* Be pedantic and enforce the required memory barriers */ - pthread_mutex_lock(&t->mutex); - while (!t->stop) { - pthread_mutex_unlock(&t->mutex); - for (int i = 0; i < num_handles; i++) - igt_assert(gem_userptr(t->fd, t->ptr, PAGE_SIZE, 0, &handle[i]) == 0); - for (int i = 0; i < num_handles; i++) - gem_close(t->fd, handle[i]); - pthread_mutex_lock(&t->mutex); - } - pthread_mutex_unlock(&t->mutex); - - return NULL; -} - -static void test_invalidate_close_race(int fd, bool overlap) -{ - pthread_t t; - unsigned int loops = MM_STRESS_LOOPS; - struct userptr_close_thread_data t_data; - - memset(&t_data, 0, sizeof(t_data)); - t_data.fd = fd; - t_data.overlap = overlap; - igt_assert(posix_memalign(&t_data.ptr, PAGE_SIZE, PAGE_SIZE) == 0); - pthread_mutex_init(&t_data.mutex, NULL); - - igt_assert(pthread_create(&t, NULL, mm_userptr_close_thread, &t_data) == 0); - - while (loops--) { - mprotect(t_data.ptr, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC); - mprotect(t_data.ptr, PAGE_SIZE, PROT_READ | PROT_WRITE); - } - - pthread_mutex_lock(&t_data.mutex); - t_data.stop = 1; - pthread_mutex_unlock(&t_data.mutex); - - pthread_join(t, NULL); - - pthread_mutex_destroy(&t_data.mutex); - free(t_data.ptr); -} - -unsigned int total_ram; -uint64_t aperture_size; -int fd, count; - - -int main(int argc, char **argv) -{ - int size = sizeof(linear); - - igt_subtest_init(argc, argv); - - igt_fixture { - int ret; - - fd = drm_open_any(); - igt_assert(fd >= 0); - - ret = has_userptr(fd); - igt_skip_on_f(ret == 0, "No userptr support - %s (%d)\n", - strerror(errno), ret); - - size = sizeof(linear); - - aperture_size = gem_aperture_size(fd); - igt_info("Aperture size is %lu MiB\n", (long)(aperture_size / (1024*1024))); - - if (argc > 1) - count = atoi(argv[1]); - if (count == 0) - count = 2 * aperture_size / (1024*1024) / 3; - - total_ram = intel_get_total_ram_mb(); - igt_info("Total RAM is %u MiB\n", total_ram); - - if (count > total_ram * 3 / 4) { - count = intel_get_total_ram_mb() * 3 / 4; - igt_info("Not enough RAM to run test, reducing buffer count.\n"); - } - } - - igt_subtest("input-checking") - test_input_checking(fd); - - igt_subtest("usage-restrictions") - test_usage_restrictions(fd); - - igt_subtest("invalid-null-pointer") - test_invalid_null_pointer(fd); - - igt_subtest("invalid-gtt-mapping") - test_invalid_gtt_mapping(fd); - - igt_subtest("forked-access") - test_forked_access(fd); - - igt_subtest("forbidden-operations") - test_forbidden_ops(fd); - - igt_info("Testing unsynchronized mappings...\n"); - gem_userptr_test_unsynchronized(); - - igt_subtest("create-destroy-unsync") - test_create_destroy(fd, 5); - - igt_subtest("unsync-overlap") - test_overlap(fd, 0); - - igt_subtest("unsync-unmap") - test_unmap(fd, 0); - - igt_subtest("unsync-unmap-cycles") - test_unmap_cycles(fd, 0); - - igt_subtest("unsync-unmap-after-close") - test_unmap_after_close(fd); - - igt_subtest("coherency-unsync") - test_coherency(fd, count); - - igt_subtest("dmabuf-unsync") - test_dmabuf(); - - for (unsigned flags = 0; flags < ALL_FORKING_EVICTIONS + 1; flags++) { - igt_subtest_f("forked-unsync%s%s%s-%s", - flags & FORKING_EVICTIONS_SWAPPING ? "-swapping" : "", - flags & FORKING_EVICTIONS_DUP_DRMFD ? "-multifd" : "", - flags & FORKING_EVICTIONS_MEMORY_PRESSURE ? - "-mempressure" : "", - flags & FORKING_EVICTIONS_INTERRUPTIBLE ? - "interruptible" : "normal") { - test_forking_evictions(fd, size, count, flags); - } - } - - igt_subtest("swapping-unsync-normal") - test_swapping_evictions(fd, size, count); - - igt_subtest("minor-unsync-normal") - test_minor_evictions(fd, size, count); - - igt_subtest("major-unsync-normal") { - size = 200 * 1024 * 1024; - count = (gem_aperture_size(fd) / size) + 2; - test_major_evictions(fd, size, count); - } - - igt_fixture { - size = sizeof(linear); - count = 2 * gem_aperture_size(fd) / (1024*1024) / 3; - if (count > total_ram * 3 / 4) - count = intel_get_total_ram_mb() * 3 / 4; - } - - igt_fork_signal_helper(); - - igt_subtest("swapping-unsync-interruptible") - test_swapping_evictions(fd, size, count); - - igt_subtest("minor-unsync-interruptible") - test_minor_evictions(fd, size, count); - - igt_subtest("major-unsync-interruptible") { - size = 200 * 1024 * 1024; - count = (gem_aperture_size(fd) / size) + 2; - test_major_evictions(fd, size, count); - } - - igt_stop_signal_helper(); - - igt_info("Testing synchronized mappings...\n"); - - igt_fixture { - size = sizeof(linear); - count = 2 * gem_aperture_size(fd) / (1024*1024) / 3; - if (count > total_ram * 3 / 4) - count = intel_get_total_ram_mb() * 3 / 4; - } - - gem_userptr_test_synchronized(); - - igt_subtest("process-exit") - test_process_exit(fd, 0); - - igt_subtest("process-exit-gtt") - test_process_exit(fd, PE_GTT_MAP); - - igt_subtest("process-exit-busy") - test_process_exit(fd, PE_BUSY); - - igt_subtest("process-exit-gtt-busy") - test_process_exit(fd, PE_GTT_MAP | PE_BUSY); - - igt_subtest("create-destroy-sync") - test_create_destroy(fd, 5); - - igt_subtest("sync-overlap") - test_overlap(fd, EINVAL); - - igt_subtest("sync-unmap") - test_unmap(fd, EFAULT); - - igt_subtest("sync-unmap-cycles") - test_unmap_cycles(fd, EFAULT); - - igt_subtest("sync-unmap-after-close") - test_unmap_after_close(fd); - - igt_subtest("stress-mm") - test_stress_mm(fd); - - igt_subtest("stress-mm-invalidate-close") - test_invalidate_close_race(fd, false); - - igt_subtest("stress-mm-invalidate-close-overlap") - test_invalidate_close_race(fd, true); - - igt_subtest("coherency-sync") - test_coherency(fd, count); - - igt_subtest("dmabuf-sync") - test_dmabuf(); - - for (unsigned flags = 0; flags < ALL_FORKING_EVICTIONS + 1; flags++) { - igt_subtest_f("forked-sync%s%s%s-%s", - flags & FORKING_EVICTIONS_SWAPPING ? "-swapping" : "", - flags & FORKING_EVICTIONS_DUP_DRMFD ? "-multifd" : "", - flags & FORKING_EVICTIONS_MEMORY_PRESSURE ? - "-mempressure" : "", - flags & FORKING_EVICTIONS_INTERRUPTIBLE ? - "interruptible" : "normal") { - test_forking_evictions(fd, size, count, flags); - } - } - - igt_subtest("swapping-normal-sync") - test_swapping_evictions(fd, size, count); - - igt_subtest("minor-normal-sync") - test_minor_evictions(fd, size, count); - - igt_subtest("major-normal-sync") { - size = 200 * 1024 * 1024; - count = (gem_aperture_size(fd) / size) + 2; - test_major_evictions(fd, size, count); - } - - igt_fixture { - size = 1024 * 1024; - count = 2 * gem_aperture_size(fd) / (1024*1024) / 3; - if (count > total_ram * 3 / 4) - count = intel_get_total_ram_mb() * 3 / 4; - } - - igt_fork_signal_helper(); - - igt_subtest("swapping-sync-interruptible") - test_swapping_evictions(fd, size, count); - - igt_subtest("minor-sync-interruptible") - test_minor_evictions(fd, size, count); - - igt_subtest("major-sync-interruptible") { - size = 200 * 1024 * 1024; - count = (gem_aperture_size(fd) / size) + 2; - test_major_evictions(fd, size, count); - } - - igt_stop_signal_helper(); - - igt_subtest("access-control") - test_access_control(fd); - - igt_exit(); -} diff --git a/tests/gem_wait.c b/tests/gem_wait.c deleted file mode 100644 index 46b381b9..00000000 --- a/tests/gem_wait.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright © 2012 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: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -#include <stdio.h> -#include <time.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -#define MSEC_PER_SEC 1000L -#define USEC_PER_MSEC 1000L -#define NSEC_PER_USEC 1000L -#define NSEC_PER_MSEC 1000000L -#define USEC_PER_SEC 1000000L -#define NSEC_PER_SEC 1000000000L - -#define ENOUGH_WORK_IN_SECONDS 2 -#define BUF_SIZE (8<<20) -#define BUF_PAGES ((8<<20)>>12) -drm_intel_bo *dst, *dst2; - -/* returns time diff in milliseconds */ -static int64_t -do_time_diff(struct timespec *end, struct timespec *start) -{ - int64_t ret; - ret = (MSEC_PER_SEC * difftime(end->tv_sec, start->tv_sec)) + - ((end->tv_nsec/NSEC_PER_MSEC) - (start->tv_nsec/NSEC_PER_MSEC)); - return ret; -} - -static int -gem_bo_wait_timeout(int fd, uint32_t handle, uint64_t *timeout_ns) -{ - struct drm_i915_gem_wait wait; - int ret; - - igt_assert(timeout_ns); - - wait.bo_handle = handle; - wait.timeout_ns = *timeout_ns; - wait.flags = 0; - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_WAIT, &wait); - *timeout_ns = wait.timeout_ns; - - return ret ? -errno : 0; -} - -static void blt_color_fill(struct intel_batchbuffer *batch, - drm_intel_bo *buf, - const unsigned int pages) -{ - const unsigned short height = pages/4; - const unsigned short width = 4096; - - COLOR_BLIT_COPY_BATCH_START(COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB); - OUT_BATCH((3 << 24) | /* 32 Bit Color */ - (0xF0 << 16) | /* Raster OP copy background register */ - 0); /* Dest pitch is 0 */ - OUT_BATCH(0); - OUT_BATCH(width << 16 | - height); - OUT_RELOC_FENCED(buf, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(rand()); /* random pattern */ - ADVANCE_BATCH(); -} - -static void render_timeout(int fd) -{ - drm_intel_bufmgr *bufmgr; - struct intel_batchbuffer *batch; - uint64_t timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC; - int ret; - const bool do_signals = true; /* signals will seem to make the operation - * use less process CPU time */ - bool done = false; - int i, iter = 1; - - igt_skip_on_simulation(); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - - dst = drm_intel_bo_alloc(bufmgr, "dst", BUF_SIZE, 4096); - dst2 = drm_intel_bo_alloc(bufmgr, "dst2", BUF_SIZE, 4096); - - igt_skip_on_f(gem_bo_wait_timeout(fd, dst->handle, &timeout) == -EINVAL, - "kernel doesn't support wait_timeout, skipping test\n"); - timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC; - - /* Figure out a rough number of fills required to consume 1 second of - * GPU work. - */ - do { - struct timespec start, end; - long diff; - -#ifndef CLOCK_MONOTONIC_RAW -#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC -#endif - - igt_assert(clock_gettime(CLOCK_MONOTONIC_RAW, &start) == 0); - for (i = 0; i < iter; i++) - blt_color_fill(batch, dst, BUF_PAGES); - intel_batchbuffer_flush(batch); - drm_intel_bo_wait_rendering(dst); - igt_assert(clock_gettime(CLOCK_MONOTONIC_RAW, &end) == 0); - - diff = do_time_diff(&end, &start); - igt_assert(diff >= 0); - - if ((diff / MSEC_PER_SEC) > ENOUGH_WORK_IN_SECONDS) - done = true; - else - iter <<= 1; - } while (!done && iter < 1000000); - - igt_assert_lt(iter, 1000000); - - igt_info("%d iters is enough work\n", iter); - gem_quiescent_gpu(fd); - if (do_signals) - igt_fork_signal_helper(); - - /* We should be able to do half as much work in the same amount of time, - * but because we might schedule almost twice as much as required, we - * might accidentally time out. Hence add some fudge. */ - for (i = 0; i < iter/3; i++) - blt_color_fill(batch, dst2, BUF_PAGES); - - intel_batchbuffer_flush(batch); - igt_assert(gem_bo_busy(fd, dst2->handle) == true); - - igt_assert_eq(gem_bo_wait_timeout(fd, dst2->handle, &timeout), 0); - igt_assert(gem_bo_busy(fd, dst2->handle) == false); - 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); - } - - /* check that polling with timeout=0 works. */ - timeout = 0; - igt_assert_eq(gem_bo_wait_timeout(fd, dst2->handle, &timeout), 0); - igt_assert_eq(timeout, 0); - - /* Now check that we correctly time out, twice the auto-tune load should - * be good enough. */ - timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC; - for (i = 0; i < iter*2; i++) - blt_color_fill(batch, dst2, BUF_PAGES); - - intel_batchbuffer_flush(batch); - - ret = gem_bo_wait_timeout(fd, dst2->handle, &timeout); - igt_assert_eq(ret, -ETIME); - igt_assert_eq(timeout, 0); - igt_assert(gem_bo_busy(fd, dst2->handle) == true); - - /* check that polling with timeout=0 works. */ - timeout = 0; - igt_assert_eq(gem_bo_wait_timeout(fd, dst2->handle, &timeout), -ETIME); - igt_assert_eq(timeout, 0); - - - if (do_signals) - igt_stop_signal_helper(); - drm_intel_bo_unreference(dst2); - drm_intel_bo_unreference(dst); - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); -} - -static void invalid_flags(int fd) -{ - struct drm_i915_gem_wait wait; - int ret; - uint32_t handle; - - handle = gem_create(fd, 4096); - - wait.bo_handle = handle; - wait.timeout_ns = 1; - wait.flags = 0xffffffff; - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_WAIT, &wait); - - igt_assert(ret != 0 && errno == EINVAL); - - gem_close(fd, handle); -} - -static void invalid_buf(int fd) -{ - struct drm_i915_gem_wait wait; - int ret; - - wait.bo_handle = 0; - wait.timeout_ns = 1; - wait.flags = 0; - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_WAIT, &wait); - - igt_assert(ret != 0 && errno == ENOENT); -} - -int drm_fd; - -igt_main -{ - igt_fixture - drm_fd = drm_open_any(); - - igt_subtest("render_timeout") - render_timeout(drm_fd); - - igt_subtest("invalid-flags") - invalid_flags(drm_fd); - - igt_subtest("invalid-buf") - invalid_buf(drm_fd); - - igt_fixture - close(drm_fd); -} diff --git a/tests/gem_workarounds.c b/tests/gem_workarounds.c deleted file mode 100644 index 0e3613f3..00000000 --- a/tests/gem_workarounds.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright © 2014 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: - * Arun Siluvery <arun.siluvery@linux.intel.com> - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <time.h> -#include <signal.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_gt.h" -#include "igt_aux.h" -#include "intel_chipset.h" -#include "intel_io.h" - -enum operation { - GPU_RESET = 0x01, - SUSPEND_RESUME = 0x02, - SIMPLE_READ = 0x03, -}; - -struct intel_wa_reg { - uint32_t addr; - uint32_t value; - uint32_t mask; -}; - -static int drm_fd; -static uint32_t devid; -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static int num_wa_regs; - -static struct intel_wa_reg *wa_regs; - -static void wait_gpu(void) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec; - uint32_t b[2] = {MI_BATCH_BUFFER_END}; - - memset(&gem_exec, 0, sizeof(gem_exec)); - gem_exec.handle = gem_create(drm_fd, 4096); - gem_write(drm_fd, gem_exec.handle, 0, b, sizeof(b)); - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)&gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_len = sizeof(b); - - drmIoctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - - gem_sync(drm_fd, gem_exec.handle); - - gem_close(drm_fd, gem_exec.handle); -} - -static void test_hang_gpu(void) -{ - int retry_count = 30; - enum stop_ring_flags flags; - - igt_assert(retry_count); - igt_set_stop_rings(STOP_RING_DEFAULTS); - - wait_gpu(); - - while(retry_count--) { - flags = igt_get_stop_rings(); - if (flags == 0) - break; - igt_info("gpu hang not yet cleared, retries left %d\n", retry_count); - sleep(1); - } - - flags = igt_get_stop_rings(); - if (flags) - igt_set_stop_rings(STOP_RING_NONE); -} - -static void test_suspend_resume(void) -{ - igt_info("Suspending the device ...\n"); - igt_system_suspend_autoresume(); -} - -static int workaround_fail_count(void) -{ - int i, fail_count = 0; - - intel_register_access_init(intel_get_pci_device(), 0); - - /* There is a small delay after coming ot of rc6 to the correct - render context values will get loaded by hardware (bdw,chv). - This here ensures that we have the correct context loaded before - we start to read values */ - wait_gpu(); - - igt_debug("Address\tval\t\tmask\t\tread\t\tresult\n"); - - for (i = 0; i < num_wa_regs; ++i) { - const uint32_t val = intel_register_read(wa_regs[i].addr); - const bool ok = (wa_regs[i].value & wa_regs[i].mask) == - (val & wa_regs[i].mask); - - igt_debug("0x%05X\t0x%08X\t0x%08X\t0x%08X\t%s\n", - wa_regs[i].addr, wa_regs[i].value, wa_regs[i].mask, - val, ok ? "OK" : "FAIL"); - - if (!ok) { - igt_warn("0x%05X\t0x%08X\t0x%08X\t0x%08X\t%s\n", - wa_regs[i].addr, wa_regs[i].value, - wa_regs[i].mask, - val, ok ? "OK" : "FAIL"); - fail_count++; - } - } - - intel_register_access_fini(); - - return fail_count; -} - -static void check_workarounds(enum operation op) -{ - igt_assert(workaround_fail_count() == 0); - - switch (op) { - case GPU_RESET: - test_hang_gpu(); - break; - - case SUSPEND_RESUME: - test_suspend_resume(); - break; - - case SIMPLE_READ: - return; - - default: - igt_assert(0); - } - - igt_assert(workaround_fail_count() == 0); -} - -igt_main -{ - igt_fixture { - int i; - int fd; - int ret; - FILE *file; - char *line = NULL; - size_t line_size; - - drm_fd = drm_open_any(); - - bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096); - devid = intel_get_drm_devid(drm_fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - fd = igt_debugfs_open("i915_wa_registers", O_RDONLY); - igt_assert(fd >= 0); - - file = fdopen(fd, "r"); - igt_assert(file > 0); - - ret = getline(&line, &line_size, file); - igt_assert(ret > 0); - sscanf(line, "Workarounds applied: %d", &num_wa_regs); - - if (IS_BROADWELL(devid) || - IS_CHERRYVIEW(devid)) - igt_assert(num_wa_regs > 0); - else - igt_assert(num_wa_regs >= 0); - - wa_regs = malloc(num_wa_regs * sizeof(*wa_regs)); - - i = 0; - while(getline(&line, &line_size, file) > 0) { - sscanf(line, "0x%X: 0x%08X, mask: 0x%08X", - &wa_regs[i].addr, &wa_regs[i].value, - &wa_regs[i].mask); - ++i; - } - - free(line); - fclose(file); - close(fd); - } - - igt_subtest("read") - check_workarounds(SIMPLE_READ); - - igt_subtest("reset") - check_workarounds(GPU_RESET); - - igt_subtest("suspend-resume") - check_workarounds(SUSPEND_RESUME); - - igt_fixture { - free(wa_regs); - close(drm_fd); - } -} diff --git a/tests/gem_write_read_ring_switch.c b/tests/gem_write_read_ring_switch.c deleted file mode 100644 index da579dac..00000000 --- a/tests/gem_write_read_ring_switch.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <drm.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_io.h" -#include "i830_reg.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Check read/write syncpoints when switching rings."); - -#define LOCAL_I915_EXEC_VEBOX (4<<0) - -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static drm_intel_bo *load_bo, *target_bo, *dummy_bo; -int fd; - -/* Testcase: check read/write syncpoints when switching rings - * - * We've had a bug where the syncpoint for the last write was mangled after a - * ring switch using semaphores. This resulted in cpu reads returning before the - * write actually completed. This test exercises this. - */ - -#define COLOR 0xffffffff -static void run_test(int ring) -{ - uint32_t *ptr; - int i; - - gem_require_ring(fd, ring); - /* Testing render only makes sense with separate blt. */ - if (ring == I915_EXEC_RENDER) - gem_require_ring(fd, I915_EXEC_BLT); - - target_bo = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096); - igt_assert(target_bo); - - /* Need to map first so that we can do our own domain mangement with - * set_domain. */ - drm_intel_bo_map(target_bo, 0); - ptr = target_bo->virtual; - igt_assert(*ptr == 0); - - /* put some load onto the gpu to keep the light buffers active for long - * enough */ - for (i = 0; i < 1000; i++) { - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - 4096); - OUT_BATCH(0); /* dst x1,y1 */ - OUT_BATCH((1024 << 16) | 512); - OUT_RELOC_FENCED(load_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH((0 << 16) | 512); /* src x1, y1 */ - OUT_BATCH(4096); - OUT_RELOC_FENCED(load_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - } - - COLOR_BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xff << 16) | - 128); - OUT_BATCH(0); /* dst x1,y1 */ - OUT_BATCH((1 << 16) | 1); - OUT_RELOC_FENCED(target_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(COLOR); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); - - /* Emit an empty batch so that signalled seqno on the target ring > - * signalled seqnoe on the blt ring. This is required to hit the bug. */ - BEGIN_BATCH(2, 0); - OUT_BATCH(MI_NOOP); - OUT_BATCH(MI_NOOP); - ADVANCE_BATCH(); - intel_batchbuffer_flush_on_ring(batch, ring); - - /* For the ring->ring sync it's important to only emit a read reloc, for - * otherwise the obj->last_write_seqno will be updated. */ - 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_bo, I915_GEM_DOMAIN_RENDER, 0, 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_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - OUT_BATCH(MI_NOOP | (1<<22) | (0xf)); - ADVANCE_BATCH(); - } - intel_batchbuffer_flush_on_ring(batch, ring); - - gem_set_domain(fd, target_bo->handle, I915_GEM_DOMAIN_GTT, 0); - igt_assert(*ptr == COLOR); - drm_intel_bo_unmap(target_bo); - - drm_intel_bo_unreference(target_bo); -} - -igt_main -{ - static const struct { - const char *name; - int ring; - } tests[] = { - { "blt2render", I915_EXEC_RENDER }, - { "blt2bsd", I915_EXEC_BSD }, - { "blt2vebox", LOCAL_I915_EXEC_VEBOX }, - }; - int i; - - igt_skip_on_simulation(); - - igt_fixture { - fd = drm_open_any(); - - /* Test requires MI_FLUSH_DW and MI_COND_BATCH_BUFFER_END */ - igt_require(intel_gen(intel_get_drm_devid(fd)) >= 6); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - igt_assert(bufmgr); - /* don't enable buffer reuse!! */ - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - igt_assert(batch); - - dummy_bo = drm_intel_bo_alloc(bufmgr, "dummy bo", 4096, 4096); - igt_assert(dummy_bo); - - load_bo = drm_intel_bo_alloc(bufmgr, "load bo", 1024*4096, 4096); - igt_assert(load_bo); - } - - for (i = 0; i < ARRAY_SIZE(tests); i++) { - igt_subtest(tests[i].name) - run_test(tests[i].ring); - } - - igt_fork_signal_helper(); - for (i = 0; i < ARRAY_SIZE(tests); i++) { - igt_subtest_f("%s-interruptible", tests[i].name) - run_test(tests[i].ring); - } - igt_stop_signal_helper(); - - igt_fixture { - drm_intel_bufmgr_destroy(bufmgr); - - close(fd); - } -} diff --git a/tests/gen3_mixed_blits.c b/tests/gen3_mixed_blits.c deleted file mode 100644 index 2d41cb4e..00000000 --- a/tests/gen3_mixed_blits.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/** @file gen3_linear_render_blits.c - * - * This is a test of doing many blits, with a working set - * larger than the aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -#include "i915_reg.h" -#include "i915_3d.h" - -#define WIDTH (512) -#define HEIGHT (512) - -static inline uint32_t pack_float(float f) -{ - union { - uint32_t dw; - float f; - } u; - u.f = f; - return u.dw; -} - -static uint32_t fill_reloc(struct drm_i915_gem_relocation_entry *reloc, - uint32_t offset, - uint32_t handle, - uint32_t read_domain, - uint32_t write_domain) -{ - reloc->target_handle = handle; - reloc->delta = 0; - reloc->offset = offset * sizeof(uint32_t); - reloc->presumed_offset = 0; - reloc->read_domains = read_domain; - reloc->write_domain = write_domain; - - return reloc->presumed_offset + reloc->delta; -} - -static void -render_copy(int fd, - uint32_t dst, int dst_tiling, - uint32_t src, int src_tiling, - int use_fence) -{ - uint32_t batch[1024], *b = batch; - struct drm_i915_gem_relocation_entry reloc[2], *r = reloc; - struct drm_i915_gem_exec_object2 obj[3]; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - uint32_t tiling_bits; - int ret; - - /* invariant state */ - *b++ = (_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); - *b++ = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | - IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) | - IAB_MODIFY_SRC_FACTOR | - (BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) | - IAB_MODIFY_DST_FACTOR | - (BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT)); - *b++ = (_3DSTATE_DFLT_DIFFUSE_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_SPEC_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_Z_CMD); - *b++ = (0); - *b++ = (_3DSTATE_COORD_SET_BINDINGS | - CSB_TCB(0, 0) | - CSB_TCB(1, 1) | - CSB_TCB(2, 2) | - CSB_TCB(3, 3) | - CSB_TCB(4, 4) | - CSB_TCB(5, 5) | - CSB_TCB(6, 6) | - CSB_TCB(7, 7)); - *b++ = (_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | - ENABLE_TEXKILL_3D_4D | - TEXKILL_4D); - *b++ = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) | - ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff)); - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | 2); - *b++ = (0x00000000); /* Disable texture coordinate wrap-shortest */ - *b++ = ((1 << S4_POINT_WIDTH_SHIFT) | - S4_LINE_WIDTH_ONE | - S4_CULLMODE_NONE | - S4_VFMT_XY); - *b++ = (0x00000000); /* Stencil. */ - *b++ = (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - *b++ = (_3DSTATE_SCISSOR_RECT_0_CMD); - *b++ = (0); - *b++ = (0); - *b++ = (_3DSTATE_DEPTH_SUBRECT_DISABLE); - *b++ = (_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ - *b++ = (0); - *b++ = (_3DSTATE_STIPPLE); - *b++ = (0x00000000); - *b++ = (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); - - /* samler state */ - if (use_fence) { - tiling_bits = MS3_USE_FENCE_REGS; - } else { - tiling_bits = 0; - if (src_tiling != I915_TILING_NONE) - tiling_bits = MS3_TILED_SURFACE; - if (src_tiling == I915_TILING_Y) - tiling_bits |= MS3_TILE_WALK; - } - -#define TEX_COUNT 1 - *b++ = (_3DSTATE_MAP_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b = fill_reloc(r++, b-batch, src, I915_GEM_DOMAIN_SAMPLER, 0); b++; - *b++ = (MAPSURF_32BIT | MT_32BIT_ARGB8888 | tiling_bits | - (HEIGHT - 1) << MS3_HEIGHT_SHIFT | - (WIDTH - 1) << MS3_WIDTH_SHIFT); - *b++ = ((WIDTH-1) << MS4_PITCH_SHIFT); - - *b++ = (_3DSTATE_SAMPLER_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b++ = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT | - FILTER_NEAREST << SS2_MAG_FILTER_SHIFT | - FILTER_NEAREST << SS2_MIN_FILTER_SHIFT); - *b++ = (TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT | - TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT | - 0 << SS3_TEXTUREMAP_INDEX_SHIFT); - *b++ = (0x00000000); - - /* render target state */ - if (use_fence) { - tiling_bits = BUF_3D_USE_FENCE; - } else { - tiling_bits = 0; - if (dst_tiling != I915_TILING_NONE) - tiling_bits = BUF_3D_TILED_SURFACE; - if (dst_tiling == I915_TILING_Y) - tiling_bits |= BUF_3D_TILE_WALK_Y; - } - *b++ = (_3DSTATE_BUF_INFO_CMD); - *b++ = (BUF_3D_ID_COLOR_BACK | tiling_bits | WIDTH*4); - *b = fill_reloc(r++, b-batch, dst, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); - b++; - - *b++ = (_3DSTATE_DST_BUF_VARS_CMD); - *b++ = (COLR_BUF_ARGB8888 | - DSTORG_HORT_BIAS(0x8) | - DSTORG_VERT_BIAS(0x8)); - - /* draw rect is unconditional */ - *b++ = (_3DSTATE_DRAW_RECT_CMD); - *b++ = (0x00000000); - *b++ = (0x00000000); /* ymin, xmin */ - *b++ = (DRAW_YMAX(HEIGHT - 1) | - DRAW_XMAX(WIDTH - 1)); - /* yorig, xorig (relate to color buffer?) */ - *b++ = (0x00000000); - - /* texfmt */ - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) | 2); - *b++ = ((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT)); - *b++ = (~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D)); - *b++ = (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE | - BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | - BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | - BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT); - - /* pixel shader */ - *b++ = (_3DSTATE_PIXEL_SHADER_PROGRAM | (1 + 3*3 - 2)); - /* decl FS_T0 */ - *b++ = (D0_DCL | - REG_TYPE(FS_T0) << D0_TYPE_SHIFT | - REG_NR(FS_T0) << D0_NR_SHIFT | - ((REG_TYPE(FS_T0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* decl FS_S0 */ - *b++ = (D0_DCL | - (REG_TYPE(FS_S0) << D0_TYPE_SHIFT) | - (REG_NR(FS_S0) << D0_NR_SHIFT) | - ((REG_TYPE(FS_S0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* texld(FS_OC, FS_S0, FS_T0 */ - *b++ = (T0_TEXLD | - (REG_TYPE(FS_OC) << T0_DEST_TYPE_SHIFT) | - (REG_NR(FS_OC) << T0_DEST_NR_SHIFT) | - (REG_NR(FS_S0) << T0_SAMPLER_NR_SHIFT)); - *b++ = ((REG_TYPE(FS_T0) << T1_ADDRESS_REG_TYPE_SHIFT) | - (REG_NR(FS_T0) << T1_ADDRESS_REG_NR_SHIFT)); - *b++ = (0); - - *b++ = (PRIM3D_RECTLIST | (3*4 - 1)); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - - *b++ = MI_BATCH_BUFFER_END; - if ((b - batch) & 1) - *b++ = 0; - - igt_assert(b - batch <= 1024); - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0])); - - igt_assert(r-reloc == 2); - - tiling_bits = 0; - if (use_fence) - tiling_bits = EXEC_OBJECT_NEEDS_FENCE; - - obj[0].handle = dst; - obj[0].relocation_count = 0; - obj[0].relocs_ptr = 0; - obj[0].alignment = 0; - obj[0].offset = 0; - obj[0].flags = tiling_bits; - obj[0].rsvd1 = 0; - obj[0].rsvd2 = 0; - - obj[1].handle = src; - obj[1].relocation_count = 0; - obj[1].relocs_ptr = 0; - obj[1].alignment = 0; - obj[1].offset = 0; - obj[1].flags = tiling_bits; - obj[1].rsvd1 = 0; - obj[1].rsvd2 = 0; - - obj[2].handle = handle; - obj[2].relocation_count = 2; - obj[2].relocs_ptr = (uintptr_t)reloc; - obj[2].alignment = 0; - obj[2].offset = 0; - obj[2].flags = 0; - obj[2].rsvd1 = obj[2].rsvd2 = 0; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = 3; - exec.batch_start_offset = 0; - exec.batch_len = (b-batch)*sizeof(batch[0]); - exec.DR1 = exec.DR4 = 0; - exec.num_cliprects = 0; - exec.cliprects_ptr = 0; - exec.flags = 0; - i915_execbuffer2_set_context_id(exec, 0); - exec.rsvd2 = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - while (ret && errno == EBUSY) { - drmCommandNone(fd, DRM_I915_GEM_THROTTLE); - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - } - igt_assert(ret == 0); - - gem_close(fd, handle); -} - -static void blt_copy(int fd, uint32_t dst, uint32_t src) -{ - uint32_t batch[1024], *b = batch; - struct drm_i915_gem_relocation_entry reloc[2], *r = reloc; - struct drm_i915_gem_exec_object2 obj[3]; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - int ret; - - *b++ = (XY_SRC_COPY_BLT_CMD | - XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB | 6); - *b++ = 3 << 24 | 0xcc << 16 | WIDTH * 4; - *b++ = 0; - *b++ = HEIGHT << 16 | WIDTH; - *b = fill_reloc(r++, b-batch, dst, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); b++; - *b++ = 0; - *b++ = WIDTH*4; - *b = fill_reloc(r++, b-batch, src, I915_GEM_DOMAIN_RENDER, 0); b++; - - *b++ = MI_BATCH_BUFFER_END; - if ((b - batch) & 1) - *b++ = 0; - - igt_assert(b - batch <= 1024); - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0])); - - igt_assert(r-reloc == 2); - - obj[0].handle = dst; - obj[0].relocation_count = 0; - obj[0].relocs_ptr = 0; - obj[0].alignment = 0; - obj[0].offset = 0; - obj[0].flags = EXEC_OBJECT_NEEDS_FENCE; - obj[0].rsvd1 = 0; - obj[0].rsvd2 = 0; - - obj[1].handle = src; - obj[1].relocation_count = 0; - obj[1].relocs_ptr = 0; - obj[1].alignment = 0; - obj[1].offset = 0; - obj[1].flags = EXEC_OBJECT_NEEDS_FENCE; - obj[1].rsvd1 = 0; - obj[1].rsvd2 = 0; - - obj[2].handle = handle; - obj[2].relocation_count = 2; - obj[2].relocs_ptr = (uintptr_t)reloc; - obj[2].alignment = 0; - obj[2].offset = 0; - obj[2].flags = 0; - obj[2].rsvd1 = obj[2].rsvd2 = 0; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = 3; - exec.batch_start_offset = 0; - exec.batch_len = (b-batch)*sizeof(batch[0]); - exec.DR1 = exec.DR4 = 0; - exec.num_cliprects = 0; - exec.cliprects_ptr = 0; - exec.flags = 0; - i915_execbuffer2_set_context_id(exec, 0); - exec.rsvd2 = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - while (ret && errno == EBUSY) { - drmCommandNone(fd, DRM_I915_GEM_THROTTLE); - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - } - igt_assert(ret == 0); - - gem_close(fd, handle); -} - - -static void -copy(int fd, - uint32_t dst, int dst_tiling, - uint32_t src, int src_tiling) -{ -retry: - switch (random() % 3) { - case 0: render_copy(fd, dst, dst_tiling, src, src_tiling, 0); break; - case 1: render_copy(fd, dst, dst_tiling, src, src_tiling, 1); break; - case 2: if (dst_tiling == I915_TILING_Y || src_tiling == I915_TILING_Y) - goto retry; - blt_copy(fd, dst, src); - break; - } -} - -static uint32_t -create_bo(int fd, uint32_t val, int tiling) -{ - uint32_t handle; - uint32_t *v; - int i; - - handle = gem_create(fd, WIDTH*HEIGHT*4); - gem_set_tiling(fd, handle, tiling, WIDTH*4); - - /* Fill the BO with dwords starting at val */ - v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ | PROT_WRITE); - igt_assert(v); - for (i = 0; i < WIDTH*HEIGHT; i++) - v[i] = val++; - munmap(v, WIDTH*HEIGHT*4); - - return handle; -} - -static void -check_bo(int fd, uint32_t handle, uint32_t val) -{ - uint32_t *v; - int i; - - v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ); - igt_assert(v); - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(v[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, v[i], i * 4); - val++; - } - munmap(v, WIDTH*HEIGHT*4); -} - -int main(int argc, char **argv) -{ - uint32_t *handle, *tiling, *start_val; - uint32_t start = 0; - int i, fd, count; - - igt_simple_init(argc, argv); - - fd = drm_open_any(); - - igt_require(IS_GEN3(intel_get_drm_devid(fd))); - - count = 0; - if (argc > 1) - count = atoi(argv[1]); - if (count == 0) - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - igt_info("Using %d 1MiB buffers\n", count); - - handle = malloc(sizeof(uint32_t)*count*3); - tiling = handle + count; - start_val = tiling + count; - - for (i = 0; i < count; i++) { - handle[i] = create_bo(fd, start, tiling[i] = i % 3); - start_val[i] = start; - start += 1024 * 1024 / 4; - } - - igt_info("Verifying initialisation..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Cyclic blits, forward..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = i % count; - int dst = (i + 1) % count; - - copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Cyclic blits, backward..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = (i + 1) % count; - int dst = i % count; - - copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Random blits..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = random() % count; - int dst = random() % count; - - while (src == dst) - dst = random() % count; - - copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_exit(); -} diff --git a/tests/gen3_render_linear_blits.c b/tests/gen3_render_linear_blits.c deleted file mode 100644 index 9bf9c306..00000000 --- a/tests/gen3_render_linear_blits.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/** @file gen3_linear_render_blits.c - * - * This is a test of doing many blits, with a working set - * larger than the aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -#include "i915_reg.h" -#include "i915_3d.h" - -#define WIDTH 512 -#define HEIGHT 512 - -static uint32_t linear[WIDTH*HEIGHT]; - -static inline uint32_t pack_float(float f) -{ - union { - uint32_t dw; - float f; - } u; - u.f = f; - return u.dw; -} - -static uint32_t fill_reloc(struct drm_i915_gem_relocation_entry *reloc, - uint32_t offset, - uint32_t handle, - uint32_t read_domain, - uint32_t write_domain) -{ - reloc->target_handle = handle; - reloc->delta = 0; - reloc->offset = offset * sizeof(uint32_t); - reloc->presumed_offset = 0; - reloc->read_domains = read_domain; - reloc->write_domain = write_domain; - - return reloc->presumed_offset + reloc->delta; -} - -static void -copy(int fd, uint32_t dst, uint32_t src) -{ - uint32_t batch[1024], *b = batch; - struct drm_i915_gem_relocation_entry reloc[2], *r = reloc; - struct drm_i915_gem_exec_object2 obj[3]; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - int ret; - - /* invariant state */ - *b++ = (_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); - *b++ = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | - IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) | - IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << - IAB_SRC_FACTOR_SHIFT) | - IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << - IAB_DST_FACTOR_SHIFT)); - *b++ = (_3DSTATE_DFLT_DIFFUSE_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_SPEC_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_Z_CMD); - *b++ = (0); - *b++ = (_3DSTATE_COORD_SET_BINDINGS | - CSB_TCB(0, 0) | - CSB_TCB(1, 1) | - CSB_TCB(2, 2) | - CSB_TCB(3, 3) | - CSB_TCB(4, 4) | - CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); - *b++ = (_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); - *b++ = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) | - ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff)); - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | 2); - *b++ = (0x00000000); /* Disable texture coordinate wrap-shortest */ - *b++ = ((1 << S4_POINT_WIDTH_SHIFT) | - S4_LINE_WIDTH_ONE | - S4_CULLMODE_NONE | - S4_VFMT_XY); - *b++ = (0x00000000); /* Stencil. */ - *b++ = (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - *b++ = (_3DSTATE_SCISSOR_RECT_0_CMD); - *b++ = (0); - *b++ = (0); - *b++ = (_3DSTATE_DEPTH_SUBRECT_DISABLE); - *b++ = (_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ - *b++ = (0); - *b++ = (_3DSTATE_STIPPLE); - *b++ = (0x00000000); - *b++ = (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); - - /* samler state */ -#define TEX_COUNT 1 - *b++ = (_3DSTATE_MAP_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b = fill_reloc(r++, b-batch, src, I915_GEM_DOMAIN_SAMPLER, 0); b++; - *b++ = (MAPSURF_32BIT | MT_32BIT_ARGB8888 | - (HEIGHT - 1) << MS3_HEIGHT_SHIFT | - (WIDTH - 1) << MS3_WIDTH_SHIFT); - *b++ = ((WIDTH-1) << MS4_PITCH_SHIFT); - - *b++ = (_3DSTATE_SAMPLER_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b++ = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT | - FILTER_NEAREST << SS2_MAG_FILTER_SHIFT | - FILTER_NEAREST << SS2_MIN_FILTER_SHIFT); - *b++ = (TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT | - TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT | - 0 << SS3_TEXTUREMAP_INDEX_SHIFT); - *b++ = (0x00000000); - - /* render target state */ - *b++ = (_3DSTATE_BUF_INFO_CMD); - *b++ = (BUF_3D_ID_COLOR_BACK | WIDTH*4); - *b = fill_reloc(r++, b-batch, dst, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); - b++; - - *b++ = (_3DSTATE_DST_BUF_VARS_CMD); - *b++ = (COLR_BUF_ARGB8888 | - DSTORG_HORT_BIAS(0x8) | - DSTORG_VERT_BIAS(0x8)); - - /* draw rect is unconditional */ - *b++ = (_3DSTATE_DRAW_RECT_CMD); - *b++ = (0x00000000); - *b++ = (0x00000000); /* ymin, xmin */ - *b++ = (DRAW_YMAX(HEIGHT - 1) | - DRAW_XMAX(WIDTH - 1)); - /* yorig, xorig (relate to color buffer?) */ - *b++ = (0x00000000); - - /* texfmt */ - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) | 2); - *b++ = ((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT)); - *b++ = (~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D)); - *b++ = (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE | - BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | - BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | - BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT); - - /* pixel shader */ - *b++ = (_3DSTATE_PIXEL_SHADER_PROGRAM | (1 + 3*3 - 2)); - /* decl FS_T0 */ - *b++ = (D0_DCL | - REG_TYPE(FS_T0) << D0_TYPE_SHIFT | - REG_NR(FS_T0) << D0_NR_SHIFT | - ((REG_TYPE(FS_T0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* decl FS_S0 */ - *b++ = (D0_DCL | - (REG_TYPE(FS_S0) << D0_TYPE_SHIFT) | - (REG_NR(FS_S0) << D0_NR_SHIFT) | - ((REG_TYPE(FS_S0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* texld(FS_OC, FS_S0, FS_T0 */ - *b++ = (T0_TEXLD | - (REG_TYPE(FS_OC) << T0_DEST_TYPE_SHIFT) | - (REG_NR(FS_OC) << T0_DEST_NR_SHIFT) | - (REG_NR(FS_S0) << T0_SAMPLER_NR_SHIFT)); - *b++ = ((REG_TYPE(FS_T0) << T1_ADDRESS_REG_TYPE_SHIFT) | - (REG_NR(FS_T0) << T1_ADDRESS_REG_NR_SHIFT)); - *b++ = (0); - - *b++ = (PRIM3D_RECTLIST | (3*4 - 1)); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - - *b++ = MI_BATCH_BUFFER_END; - if ((b - batch) & 1) - *b++ = 0; - - igt_assert(b - batch <= 1024); - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0])); - - igt_assert(r-reloc == 2); - - obj[0].handle = dst; - obj[0].relocation_count = 0; - obj[0].relocs_ptr = 0; - obj[0].alignment = 0; - obj[0].offset = 0; - obj[0].flags = 0; - obj[0].rsvd1 = 0; - obj[0].rsvd2 = 0; - - obj[1].handle = src; - obj[1].relocation_count = 0; - obj[1].relocs_ptr = 0; - obj[1].alignment = 0; - obj[1].offset = 0; - obj[1].flags = 0; - obj[1].rsvd1 = 0; - obj[1].rsvd2 = 0; - - obj[2].handle = handle; - obj[2].relocation_count = 2; - obj[2].relocs_ptr = (uintptr_t)reloc; - obj[2].alignment = 0; - obj[2].offset = 0; - obj[2].flags = 0; - obj[2].rsvd1 = obj[2].rsvd2 = 0; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = 3; - exec.batch_start_offset = 0; - exec.batch_len = (b-batch)*sizeof(batch[0]); - exec.DR1 = exec.DR4 = 0; - exec.num_cliprects = 0; - exec.cliprects_ptr = 0; - exec.flags = 0; - i915_execbuffer2_set_context_id(exec, 0); - exec.rsvd2 = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - while (ret && errno == EBUSY) { - drmCommandNone(fd, DRM_I915_GEM_THROTTLE); - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - } - igt_assert(ret == 0); - - gem_close(fd, handle); -} - -static uint32_t -create_bo(int fd, uint32_t val) -{ - uint32_t handle; - int i; - - handle = gem_create(fd, sizeof(linear)); - - /* Fill the BO with dwords starting at val */ - for (i = 0; i < WIDTH*HEIGHT; i++) - linear[i] = val++; - gem_write(fd, handle, 0, linear, sizeof(linear)); - - return handle; -} - -static void -check_bo(int fd, uint32_t handle, uint32_t val) -{ - int i; - - gem_read(fd, handle, 0, linear, sizeof(linear)); - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(linear[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, linear[i], i * 4); - val++; - } -} - -int main(int argc, char **argv) -{ - uint32_t *handle, *start_val; - uint32_t start = 0; - int i, fd, count; - - igt_simple_init(argc, argv); - - fd = drm_open_any(); - - igt_require(IS_GEN3(intel_get_drm_devid(fd))); - - count = 0; - if (argc > 1) - count = atoi(argv[1]); - if (count == 0) - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - igt_info("Using %d 1MiB buffers\n", count); - - handle = malloc(sizeof(uint32_t)*count*2); - start_val = handle + count; - - for (i = 0; i < count; i++) { - handle[i] = create_bo(fd, start); - start_val[i] = start; - start += 1024 * 1024 / 4; - } - - igt_info("Verifying initialisation...\n"); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Cyclic blits, forward...\n"); - for (i = 0; i < count * 4; i++) { - int src = i % count; - int dst = (i + 1) % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Cyclic blits, backward...\n"); - for (i = 0; i < count * 4; i++) { - int src = (i + 1) % count; - int dst = i % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Random blits...\n"); - for (i = 0; i < count * 4; i++) { - int src = random() % count; - int dst = random() % count; - - if (src == dst) - continue; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_exit(); -} diff --git a/tests/gen3_render_mixed_blits.c b/tests/gen3_render_mixed_blits.c deleted file mode 100644 index bdfd66f6..00000000 --- a/tests/gen3_render_mixed_blits.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/** @file gen3_linear_render_blits.c - * - * This is a test of doing many blits, with a working set - * larger than the aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -#include "i915_reg.h" -#include "i915_3d.h" - -#define WIDTH 512 -#define HEIGHT 512 - -static inline uint32_t pack_float(float f) -{ - union { - uint32_t dw; - float f; - } u; - u.f = f; - return u.dw; -} - -static uint32_t fill_reloc(struct drm_i915_gem_relocation_entry *reloc, - uint32_t offset, - uint32_t handle, - uint32_t read_domain, - uint32_t write_domain) -{ - reloc->target_handle = handle; - reloc->delta = 0; - reloc->offset = offset * sizeof(uint32_t); - reloc->presumed_offset = 0; - reloc->read_domains = read_domain; - reloc->write_domain = write_domain; - - return reloc->presumed_offset + reloc->delta; -} - -static void -copy(int fd, - uint32_t dst, int dst_tiling, - uint32_t src, int src_tiling) -{ - uint32_t batch[1024], *b = batch; - struct drm_i915_gem_relocation_entry reloc[2], *r = reloc; - struct drm_i915_gem_exec_object2 obj[3]; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - uint32_t tiling_bits; - int ret; - - /* invariant state */ - *b++ = (_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); - *b++ = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | - IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) | - IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << - IAB_SRC_FACTOR_SHIFT) | - IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << - IAB_DST_FACTOR_SHIFT)); - *b++ = (_3DSTATE_DFLT_DIFFUSE_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_SPEC_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_Z_CMD); - *b++ = (0); - *b++ = (_3DSTATE_COORD_SET_BINDINGS | - CSB_TCB(0, 0) | - CSB_TCB(1, 1) | - CSB_TCB(2, 2) | - CSB_TCB(3, 3) | - CSB_TCB(4, 4) | - CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); - *b++ = (_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); - *b++ = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) | - ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff)); - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | 2); - *b++ = (0x00000000); /* Disable texture coordinate wrap-shortest */ - *b++ = ((1 << S4_POINT_WIDTH_SHIFT) | - S4_LINE_WIDTH_ONE | - S4_CULLMODE_NONE | - S4_VFMT_XY); - *b++ = (0x00000000); /* Stencil. */ - *b++ = (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - *b++ = (_3DSTATE_SCISSOR_RECT_0_CMD); - *b++ = (0); - *b++ = (0); - *b++ = (_3DSTATE_DEPTH_SUBRECT_DISABLE); - *b++ = (_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ - *b++ = (0); - *b++ = (_3DSTATE_STIPPLE); - *b++ = (0x00000000); - *b++ = (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); - - /* samler state */ - tiling_bits = 0; - if (src_tiling != I915_TILING_NONE) - tiling_bits = MS3_TILED_SURFACE; - if (src_tiling == I915_TILING_Y) - tiling_bits |= MS3_TILE_WALK; - -#define TEX_COUNT 1 - *b++ = (_3DSTATE_MAP_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b = fill_reloc(r++, b-batch, src, I915_GEM_DOMAIN_SAMPLER, 0); b++; - *b++ = (MAPSURF_32BIT | MT_32BIT_ARGB8888 | tiling_bits | - (HEIGHT - 1) << MS3_HEIGHT_SHIFT | - (WIDTH - 1) << MS3_WIDTH_SHIFT); - *b++ = ((WIDTH-1) << MS4_PITCH_SHIFT); - - *b++ = (_3DSTATE_SAMPLER_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b++ = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT | - FILTER_NEAREST << SS2_MAG_FILTER_SHIFT | - FILTER_NEAREST << SS2_MIN_FILTER_SHIFT); - *b++ = (TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT | - TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT | - 0 << SS3_TEXTUREMAP_INDEX_SHIFT); - *b++ = (0x00000000); - - /* render target state */ - tiling_bits = 0; - if (dst_tiling != I915_TILING_NONE) - tiling_bits = BUF_3D_TILED_SURFACE; - if (dst_tiling == I915_TILING_Y) - tiling_bits |= BUF_3D_TILE_WALK_Y; - *b++ = (_3DSTATE_BUF_INFO_CMD); - *b++ = (BUF_3D_ID_COLOR_BACK | tiling_bits | WIDTH*4); - *b = fill_reloc(r++, b-batch, dst, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); - b++; - - *b++ = (_3DSTATE_DST_BUF_VARS_CMD); - *b++ = (COLR_BUF_ARGB8888 | - DSTORG_HORT_BIAS(0x8) | - DSTORG_VERT_BIAS(0x8)); - - /* draw rect is unconditional */ - *b++ = (_3DSTATE_DRAW_RECT_CMD); - *b++ = (0x00000000); - *b++ = (0x00000000); /* ymin, xmin */ - *b++ = (DRAW_YMAX(HEIGHT - 1) | - DRAW_XMAX(WIDTH - 1)); - /* yorig, xorig (relate to color buffer?) */ - *b++ = (0x00000000); - - /* texfmt */ - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) | 2); - *b++ = ((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT)); - *b++ = (~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D)); - *b++ = (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE | - BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | - BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | - BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT); - - /* pixel shader */ - *b++ = (_3DSTATE_PIXEL_SHADER_PROGRAM | (1 + 3*3 - 2)); - /* decl FS_T0 */ - *b++ = (D0_DCL | - REG_TYPE(FS_T0) << D0_TYPE_SHIFT | - REG_NR(FS_T0) << D0_NR_SHIFT | - ((REG_TYPE(FS_T0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* decl FS_S0 */ - *b++ = (D0_DCL | - (REG_TYPE(FS_S0) << D0_TYPE_SHIFT) | - (REG_NR(FS_S0) << D0_NR_SHIFT) | - ((REG_TYPE(FS_S0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* texld(FS_OC, FS_S0, FS_T0 */ - *b++ = (T0_TEXLD | - (REG_TYPE(FS_OC) << T0_DEST_TYPE_SHIFT) | - (REG_NR(FS_OC) << T0_DEST_NR_SHIFT) | - (REG_NR(FS_S0) << T0_SAMPLER_NR_SHIFT)); - *b++ = ((REG_TYPE(FS_T0) << T1_ADDRESS_REG_TYPE_SHIFT) | - (REG_NR(FS_T0) << T1_ADDRESS_REG_NR_SHIFT)); - *b++ = (0); - - *b++ = (PRIM3D_RECTLIST | (3*4 - 1)); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - - *b++ = MI_BATCH_BUFFER_END; - if ((b - batch) & 1) - *b++ = 0; - - igt_assert(b - batch <= 1024); - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0])); - - igt_assert(r-reloc == 2); - - obj[0].handle = dst; - obj[0].relocation_count = 0; - obj[0].relocs_ptr = 0; - obj[0].alignment = 0; - obj[0].offset = 0; - obj[0].flags = 0; - obj[0].rsvd1 = 0; - obj[0].rsvd2 = 0; - - obj[1].handle = src; - obj[1].relocation_count = 0; - obj[1].relocs_ptr = 0; - obj[1].alignment = 0; - obj[1].offset = 0; - obj[1].flags = 0; - obj[1].rsvd1 = 0; - obj[1].rsvd2 = 0; - - obj[2].handle = handle; - obj[2].relocation_count = 2; - obj[2].relocs_ptr = (uintptr_t)reloc; - obj[2].alignment = 0; - obj[2].offset = 0; - obj[2].flags = 0; - obj[2].rsvd1 = obj[2].rsvd2 = 0; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = 3; - exec.batch_start_offset = 0; - exec.batch_len = (b-batch)*sizeof(batch[0]); - exec.DR1 = exec.DR4 = 0; - exec.num_cliprects = 0; - exec.cliprects_ptr = 0; - exec.flags = 0; - i915_execbuffer2_set_context_id(exec, 0); - exec.rsvd2 = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - while (ret && errno == EBUSY) { - drmCommandNone(fd, DRM_I915_GEM_THROTTLE); - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - } - igt_assert(ret == 0); - - gem_close(fd, handle); -} - -static uint32_t -create_bo(int fd, uint32_t val, int tiling) -{ - uint32_t handle; - uint32_t *v; - int i; - - handle = gem_create(fd, WIDTH*HEIGHT*4); - gem_set_tiling(fd, handle, tiling, WIDTH*4); - - /* Fill the BO with dwords starting at val */ - v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ | PROT_WRITE); - igt_assert(v); - for (i = 0; i < WIDTH*HEIGHT; i++) - v[i] = val++; - munmap(v, WIDTH*HEIGHT*4); - - return handle; -} - -static void -check_bo(int fd, uint32_t handle, uint32_t val) -{ - uint32_t *v; - int i; - - v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ); - igt_assert(v); - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(v[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, v[i], i * 4); - val++; - } - munmap(v, WIDTH*HEIGHT*4); -} - -int main(int argc, char **argv) -{ - uint32_t *handle, *tiling, *start_val; - uint32_t start = 0; - int i, fd, count; - - igt_simple_init(argc, argv); - - fd = drm_open_any(); - - igt_require(IS_GEN3(intel_get_drm_devid(fd))); - - count = 0; - if (argc > 1) - count = atoi(argv[1]); - if (count == 0) - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - igt_info("Using %d 1MiB buffers\n", count); - - handle = malloc(sizeof(uint32_t)*count*3); - tiling = handle + count; - start_val = tiling + count; - - for (i = 0; i < count; i++) { - handle[i] = create_bo(fd, start, tiling[i] = i % 3); - start_val[i] = start; - start += 1024 * 1024 / 4; - } - - igt_info("Verifying initialisation..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Cyclic blits, forward..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = i % count; - int dst = (i + 1) % count; - - copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Cyclic blits, backward..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = (i + 1) % count; - int dst = i % count; - - copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Random blits..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = random() % count; - int dst = random() % count; - - while (src == dst) - dst = random() % count; - - copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_exit(); -} diff --git a/tests/gen3_render_tiledx_blits.c b/tests/gen3_render_tiledx_blits.c deleted file mode 100644 index 92a77f21..00000000 --- a/tests/gen3_render_tiledx_blits.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/** @file gen3_linear_render_blits.c - * - * This is a test of doing many blits, with a working set - * larger than the aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -#include "i915_reg.h" -#include "i915_3d.h" - -#define WIDTH 512 -#define HEIGHT 512 - -static inline uint32_t pack_float(float f) -{ - union { - uint32_t dw; - float f; - } u; - u.f = f; - return u.dw; -} - -static uint32_t fill_reloc(struct drm_i915_gem_relocation_entry *reloc, - uint32_t offset, - uint32_t handle, - uint32_t read_domain, - uint32_t write_domain) -{ - reloc->target_handle = handle; - reloc->delta = 0; - reloc->offset = offset * sizeof(uint32_t); - reloc->presumed_offset = 0; - reloc->read_domains = read_domain; - reloc->write_domain = write_domain; - - return reloc->presumed_offset + reloc->delta; -} - -static void -copy(int fd, uint32_t dst, uint32_t src) -{ - uint32_t batch[1024], *b = batch; - struct drm_i915_gem_relocation_entry reloc[2], *r = reloc; - struct drm_i915_gem_exec_object2 obj[3]; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - int ret; - - /* invariant state */ - *b++ = (_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); - *b++ = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | - IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) | - IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << - IAB_SRC_FACTOR_SHIFT) | - IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << - IAB_DST_FACTOR_SHIFT)); - *b++ = (_3DSTATE_DFLT_DIFFUSE_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_SPEC_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_Z_CMD); - *b++ = (0); - *b++ = (_3DSTATE_COORD_SET_BINDINGS | - CSB_TCB(0, 0) | - CSB_TCB(1, 1) | - CSB_TCB(2, 2) | - CSB_TCB(3, 3) | - CSB_TCB(4, 4) | - CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); - *b++ = (_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); - *b++ = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) | - ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff)); - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | 2); - *b++ = (0x00000000); /* Disable texture coordinate wrap-shortest */ - *b++ = ((1 << S4_POINT_WIDTH_SHIFT) | - S4_LINE_WIDTH_ONE | - S4_CULLMODE_NONE | - S4_VFMT_XY); - *b++ = (0x00000000); /* Stencil. */ - *b++ = (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - *b++ = (_3DSTATE_SCISSOR_RECT_0_CMD); - *b++ = (0); - *b++ = (0); - *b++ = (_3DSTATE_DEPTH_SUBRECT_DISABLE); - *b++ = (_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ - *b++ = (0); - *b++ = (_3DSTATE_STIPPLE); - *b++ = (0x00000000); - *b++ = (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); - - /* samler state */ -#define TEX_COUNT 1 - *b++ = (_3DSTATE_MAP_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b = fill_reloc(r++, b-batch, src, I915_GEM_DOMAIN_SAMPLER, 0); b++; - *b++ = (MAPSURF_32BIT | MT_32BIT_ARGB8888 | - MS3_TILED_SURFACE | - (HEIGHT - 1) << MS3_HEIGHT_SHIFT | - (WIDTH - 1) << MS3_WIDTH_SHIFT); - *b++ = ((WIDTH-1) << MS4_PITCH_SHIFT); - - *b++ = (_3DSTATE_SAMPLER_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b++ = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT | - FILTER_NEAREST << SS2_MAG_FILTER_SHIFT | - FILTER_NEAREST << SS2_MIN_FILTER_SHIFT); - *b++ = (TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT | - TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT | - 0 << SS3_TEXTUREMAP_INDEX_SHIFT); - *b++ = (0x00000000); - - /* render target state */ - *b++ = (_3DSTATE_BUF_INFO_CMD); - *b++ = (BUF_3D_ID_COLOR_BACK | BUF_3D_TILED_SURFACE | WIDTH*4); - *b = fill_reloc(r++, b-batch, dst, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); - b++; - - *b++ = (_3DSTATE_DST_BUF_VARS_CMD); - *b++ = (COLR_BUF_ARGB8888 | - DSTORG_HORT_BIAS(0x8) | - DSTORG_VERT_BIAS(0x8)); - - /* draw rect is unconditional */ - *b++ = (_3DSTATE_DRAW_RECT_CMD); - *b++ = (0x00000000); - *b++ = (0x00000000); /* ymin, xmin */ - *b++ = (DRAW_YMAX(HEIGHT - 1) | - DRAW_XMAX(WIDTH - 1)); - /* yorig, xorig (relate to color buffer?) */ - *b++ = (0x00000000); - - /* texfmt */ - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) | 2); - *b++ = ((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT)); - *b++ = (~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D)); - *b++ = (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE | - BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | - BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | - BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT); - - /* pixel shader */ - *b++ = (_3DSTATE_PIXEL_SHADER_PROGRAM | (1 + 3*3 - 2)); - /* decl FS_T0 */ - *b++ = (D0_DCL | - REG_TYPE(FS_T0) << D0_TYPE_SHIFT | - REG_NR(FS_T0) << D0_NR_SHIFT | - ((REG_TYPE(FS_T0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* decl FS_S0 */ - *b++ = (D0_DCL | - (REG_TYPE(FS_S0) << D0_TYPE_SHIFT) | - (REG_NR(FS_S0) << D0_NR_SHIFT) | - ((REG_TYPE(FS_S0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* texld(FS_OC, FS_S0, FS_T0 */ - *b++ = (T0_TEXLD | - (REG_TYPE(FS_OC) << T0_DEST_TYPE_SHIFT) | - (REG_NR(FS_OC) << T0_DEST_NR_SHIFT) | - (REG_NR(FS_S0) << T0_SAMPLER_NR_SHIFT)); - *b++ = ((REG_TYPE(FS_T0) << T1_ADDRESS_REG_TYPE_SHIFT) | - (REG_NR(FS_T0) << T1_ADDRESS_REG_NR_SHIFT)); - *b++ = (0); - - *b++ = (PRIM3D_RECTLIST | (3*4 - 1)); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - - *b++ = MI_BATCH_BUFFER_END; - if ((b - batch) & 1) - *b++ = 0; - - igt_assert(b - batch <= 1024); - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0])); - - igt_assert(r-reloc == 2); - - obj[0].handle = dst; - obj[0].relocation_count = 0; - obj[0].relocs_ptr = 0; - obj[0].alignment = 0; - obj[0].offset = 0; - obj[0].flags = 0; - obj[0].rsvd1 = 0; - obj[0].rsvd2 = 0; - - obj[1].handle = src; - obj[1].relocation_count = 0; - obj[1].relocs_ptr = 0; - obj[1].alignment = 0; - obj[1].offset = 0; - obj[1].flags = 0; - obj[1].rsvd1 = 0; - obj[1].rsvd2 = 0; - - obj[2].handle = handle; - obj[2].relocation_count = 2; - obj[2].relocs_ptr = (uintptr_t)reloc; - obj[2].alignment = 0; - obj[2].offset = 0; - obj[2].flags = 0; - obj[2].rsvd1 = obj[2].rsvd2 = 0; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = 3; - exec.batch_start_offset = 0; - exec.batch_len = (b-batch)*sizeof(batch[0]); - exec.DR1 = exec.DR4 = 0; - exec.num_cliprects = 0; - exec.cliprects_ptr = 0; - exec.flags = 0; - i915_execbuffer2_set_context_id(exec, 0); - exec.rsvd2 = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - while (ret && errno == EBUSY) { - drmCommandNone(fd, DRM_I915_GEM_THROTTLE); - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - } - igt_assert(ret == 0); - - gem_close(fd, handle); -} - -static uint32_t -create_bo(int fd, uint32_t val) -{ - uint32_t handle; - uint32_t *v; - int i; - - handle = gem_create(fd, WIDTH*HEIGHT*4); - gem_set_tiling(fd, handle, I915_TILING_X, WIDTH*4); - - /* Fill the BO with dwords starting at val */ - v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ | PROT_WRITE); - igt_assert(v); - for (i = 0; i < WIDTH*HEIGHT; i++) - v[i] = val++; - munmap(v, WIDTH*HEIGHT*4); - - return handle; -} - -static void -check_bo(int fd, uint32_t handle, uint32_t val) -{ - uint32_t *v; - int i; - - v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ); - igt_assert(v); - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(v[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, v[i], i * 4); - val++; - } - munmap(v, WIDTH*HEIGHT*4); -} - -int main(int argc, char **argv) -{ - uint32_t *handle, *start_val; - uint32_t start = 0; - int i, fd, count; - - igt_simple_init(argc, argv); - - fd = drm_open_any(); - - igt_require(IS_GEN3(intel_get_drm_devid(fd))); - - count = 0; - if (argc > 1) - count = atoi(argv[1]); - if (count == 0) - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - igt_info("Using %d 1MiB buffers\n", count); - - handle = malloc(sizeof(uint32_t)*count*2); - start_val = handle + count; - - for (i = 0; i < count; i++) { - handle[i] = create_bo(fd, start); - start_val[i] = start; - start += 1024 * 1024 / 4; - } - - igt_info("Verifying initialisation...\n"); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Cyclic blits, forward...\n"); - for (i = 0; i < count * 4; i++) { - int src = i % count; - int dst = (i + 1) % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Cyclic blits, backward...\n"); - for (i = 0; i < count * 4; i++) { - int src = (i + 1) % count; - int dst = i % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_info("Random blits...\n"); - for (i = 0; i < count * 4; i++) { - int src = random() % count; - int dst = random() % count; - - if (src == dst) - continue; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - - igt_exit(); -} diff --git a/tests/gen3_render_tiledy_blits.c b/tests/gen3_render_tiledy_blits.c deleted file mode 100644 index 8927c0b4..00000000 --- a/tests/gen3_render_tiledy_blits.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright © 2011 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/** @file gen3_linear_render_blits.c - * - * This is a test of doing many blits, with a working set - * larger than the aperture size. - * - * The goal is to simply ensure the basics work. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -#include "i915_reg.h" -#include "i915_3d.h" - -#define WIDTH 512 -#define HEIGHT 512 - -static inline uint32_t pack_float(float f) -{ - union { - uint32_t dw; - float f; - } u; - u.f = f; - return u.dw; -} - -static uint32_t fill_reloc(struct drm_i915_gem_relocation_entry *reloc, - uint32_t offset, - uint32_t handle, - uint32_t read_domain, - uint32_t write_domain) -{ - reloc->target_handle = handle; - reloc->delta = 0; - reloc->offset = offset * sizeof(uint32_t); - reloc->presumed_offset = 0; - reloc->read_domains = read_domain; - reloc->write_domain = write_domain; - - return reloc->presumed_offset + reloc->delta; -} - -static void -copy(int fd, uint32_t dst, uint32_t src) -{ - uint32_t batch[1024], *b = batch; - struct drm_i915_gem_relocation_entry reloc[2], *r = reloc; - struct drm_i915_gem_exec_object2 obj[3]; - struct drm_i915_gem_execbuffer2 exec; - uint32_t handle; - int ret; - - /* invariant state */ - *b++ = (_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); - *b++ = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | - IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) | - IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << - IAB_SRC_FACTOR_SHIFT) | - IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << - IAB_DST_FACTOR_SHIFT)); - *b++ = (_3DSTATE_DFLT_DIFFUSE_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_SPEC_CMD); - *b++ = (0); - *b++ = (_3DSTATE_DFLT_Z_CMD); - *b++ = (0); - *b++ = (_3DSTATE_COORD_SET_BINDINGS | - CSB_TCB(0, 0) | - CSB_TCB(1, 1) | - CSB_TCB(2, 2) | - CSB_TCB(3, 3) | - CSB_TCB(4, 4) | - CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); - *b++ = (_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); - *b++ = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) | - ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff)); - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | 2); - *b++ = (0x00000000); /* Disable texture coordinate wrap-shortest */ - *b++ = ((1 << S4_POINT_WIDTH_SHIFT) | - S4_LINE_WIDTH_ONE | - S4_CULLMODE_NONE | - S4_VFMT_XY); - *b++ = (0x00000000); /* Stencil. */ - *b++ = (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - *b++ = (_3DSTATE_SCISSOR_RECT_0_CMD); - *b++ = (0); - *b++ = (0); - *b++ = (_3DSTATE_DEPTH_SUBRECT_DISABLE); - *b++ = (_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ - *b++ = (0); - *b++ = (_3DSTATE_STIPPLE); - *b++ = (0x00000000); - *b++ = (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); - - /* samler state */ -#define TEX_COUNT 1 - *b++ = (_3DSTATE_MAP_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b = fill_reloc(r++, b-batch, src, I915_GEM_DOMAIN_SAMPLER, 0); b++; - *b++ = (MAPSURF_32BIT | MT_32BIT_ARGB8888 | - MS3_TILED_SURFACE | MS3_TILE_WALK | - (HEIGHT - 1) << MS3_HEIGHT_SHIFT | - (WIDTH - 1) << MS3_WIDTH_SHIFT); - *b++ = ((WIDTH-1) << MS4_PITCH_SHIFT); - - *b++ = (_3DSTATE_SAMPLER_STATE | (3 * TEX_COUNT)); - *b++ = ((1 << TEX_COUNT) - 1); - *b++ = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT | - FILTER_NEAREST << SS2_MAG_FILTER_SHIFT | - FILTER_NEAREST << SS2_MIN_FILTER_SHIFT); - *b++ = (TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT | - TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT | - 0 << SS3_TEXTUREMAP_INDEX_SHIFT); - *b++ = (0x00000000); - - /* render target state */ - *b++ = (_3DSTATE_BUF_INFO_CMD); - *b++ = (BUF_3D_ID_COLOR_BACK | BUF_3D_TILED_SURFACE | BUF_3D_TILE_WALK_Y | WIDTH*4); - *b = fill_reloc(r++, b-batch, dst, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); - b++; - - *b++ = (_3DSTATE_DST_BUF_VARS_CMD); - *b++ = (COLR_BUF_ARGB8888 | - DSTORG_HORT_BIAS(0x8) | - DSTORG_VERT_BIAS(0x8)); - - /* draw rect is unconditional */ - *b++ = (_3DSTATE_DRAW_RECT_CMD); - *b++ = (0x00000000); - *b++ = (0x00000000); /* ymin, xmin */ - *b++ = (DRAW_YMAX(HEIGHT - 1) | - DRAW_XMAX(WIDTH - 1)); - /* yorig, xorig (relate to color buffer?) */ - *b++ = (0x00000000); - - /* texfmt */ - *b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) | 2); - *b++ = ((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT)); - *b++ = (~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D)); - *b++ = (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE | - BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | - BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | - BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT); - - /* pixel shader */ - *b++ = (_3DSTATE_PIXEL_SHADER_PROGRAM | (1 + 3*3 - 2)); - /* decl FS_T0 */ - *b++ = (D0_DCL | - REG_TYPE(FS_T0) << D0_TYPE_SHIFT | - REG_NR(FS_T0) << D0_NR_SHIFT | - ((REG_TYPE(FS_T0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* decl FS_S0 */ - *b++ = (D0_DCL | - (REG_TYPE(FS_S0) << D0_TYPE_SHIFT) | - (REG_NR(FS_S0) << D0_NR_SHIFT) | - ((REG_TYPE(FS_S0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); - *b++ = (0); - *b++ = (0); - /* texld(FS_OC, FS_S0, FS_T0 */ - *b++ = (T0_TEXLD | - (REG_TYPE(FS_OC) << T0_DEST_TYPE_SHIFT) | - (REG_NR(FS_OC) << T0_DEST_NR_SHIFT) | - (REG_NR(FS_S0) << T0_SAMPLER_NR_SHIFT)); - *b++ = ((REG_TYPE(FS_T0) << T1_ADDRESS_REG_TYPE_SHIFT) | - (REG_NR(FS_T0) << T1_ADDRESS_REG_NR_SHIFT)); - *b++ = (0); - - *b++ = (PRIM3D_RECTLIST | (3*4 - 1)); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(WIDTH); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - *b++ = pack_float(0); - *b++ = pack_float(HEIGHT); - - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - *b++ = pack_float(0); - - *b++ = MI_BATCH_BUFFER_END; - if ((b - batch) & 1) - *b++ = 0; - - igt_assert(b - batch <= 1024); - handle = gem_create(fd, 4096); - gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0])); - - igt_assert(r-reloc == 2); - - obj[0].handle = dst; - obj[0].relocation_count = 0; - obj[0].relocs_ptr = 0; - obj[0].alignment = 0; - obj[0].offset = 0; - obj[0].flags = 0; - obj[0].rsvd1 = 0; - obj[0].rsvd2 = 0; - - obj[1].handle = src; - obj[1].relocation_count = 0; - obj[1].relocs_ptr = 0; - obj[1].alignment = 0; - obj[1].offset = 0; - obj[1].flags = 0; - obj[1].rsvd1 = 0; - obj[1].rsvd2 = 0; - - obj[2].handle = handle; - obj[2].relocation_count = 2; - obj[2].relocs_ptr = (uintptr_t)reloc; - obj[2].alignment = 0; - obj[2].offset = 0; - obj[2].flags = 0; - obj[2].rsvd1 = obj[2].rsvd2 = 0; - - exec.buffers_ptr = (uintptr_t)obj; - exec.buffer_count = 3; - exec.batch_start_offset = 0; - exec.batch_len = (b-batch)*sizeof(batch[0]); - exec.DR1 = exec.DR4 = 0; - exec.num_cliprects = 0; - exec.cliprects_ptr = 0; - exec.flags = 0; - i915_execbuffer2_set_context_id(exec, 0); - exec.rsvd2 = 0; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - while (ret && errno == EBUSY) { - drmCommandNone(fd, DRM_I915_GEM_THROTTLE); - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec); - } - igt_assert(ret == 0); - - gem_close(fd, handle); -} - -static uint32_t -create_bo(int fd, uint32_t val) -{ - uint32_t handle; - uint32_t *v; - int i; - - handle = gem_create(fd, WIDTH*HEIGHT*4); - gem_set_tiling(fd, handle, I915_TILING_Y, WIDTH*4); - - /* Fill the BO with dwords starting at val */ - v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ | PROT_WRITE); - igt_assert(v); - for (i = 0; i < WIDTH*HEIGHT; i++) - v[i] = val++; - munmap(v, WIDTH*HEIGHT*4); - - return handle; -} - -static void -check_bo(int fd, uint32_t handle, uint32_t val) -{ - uint32_t *v; - int i; - - v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ); - igt_assert(v); - for (i = 0; i < WIDTH*HEIGHT; i++) { - igt_assert_f(v[i] == val, - "Expected 0x%08x, found 0x%08x " - "at offset 0x%08x\n", - val, v[i], i * 4); - val++; - } - munmap(v, WIDTH*HEIGHT*4); -} - -int main(int argc, char **argv) -{ - uint32_t *handle, *start_val; - uint32_t start = 0; - int i, fd, count; - - igt_simple_init(argc, argv); - - fd = drm_open_any(); - - igt_require(IS_GEN3(intel_get_drm_devid(fd))); - - count = 0; - if (argc > 1) - count = atoi(argv[1]); - if (count == 0) - count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; - igt_info("Using %d 1MiB buffers\n", count); - - handle = malloc(sizeof(uint32_t)*count*2); - start_val = handle + count; - - for (i = 0; i < count; i++) { - handle[i] = create_bo(fd, start); - start_val[i] = start; - start += 1024 * 1024 / 4; - } - - igt_info("Verifying initialisation..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Cyclic blits, forward..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = i % count; - int dst = (i + 1) % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Cyclic blits, backward..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = (i + 1) % count; - int dst = i % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_info("Random blits..."); fflush(stdout); - for (i = 0; i < count * 32; i++) { - int src = random() % count; - int dst = random() % count; - - while (src == dst) - dst = random() % count; - - copy(fd, handle[dst], handle[src]); - start_val[dst] = start_val[src]; - } - igt_info("verifying..."); fflush(stdout); - for (i = 0; i < count; i++) - check_bo(fd, handle[i], start_val[i]); - igt_info("done\n"); - - igt_exit(); -} diff --git a/tests/gen7_forcewake_mt.c b/tests/gen7_forcewake_mt.c deleted file mode 100644 index 01299c52..00000000 --- a/tests/gen7_forcewake_mt.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright © 2014 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: - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -/* - * Testcase: Exercise a suspect workaround required for FORCEWAKE_MT - * - */ - -#include <sys/types.h> -#include <pthread.h> -#include <string.h> - -#include "drm.h" -#include "ioctl_wrappers.h" -#include "i915_pciids.h" -#include "drmtest.h" -#include "intel_io.h" -#include "intel_chipset.h" - -IGT_TEST_DESCRIPTION("Exercise a suspect workaround required for" - " FORCEWAKE_MT."); - -#define FORCEWAKE_MT 0xa188 - -struct thread { - pthread_t thread; - void *mmio; - int fd; - int bit; -}; - -static const struct pci_id_match match[] = { - INTEL_IVB_D_IDS(NULL), - INTEL_IVB_M_IDS(NULL), - - INTEL_HSW_D_IDS(NULL), - INTEL_HSW_M_IDS(NULL), - - { 0, 0, 0 }, -}; - -static struct pci_device *__igfx_get(void) -{ - struct pci_device *dev; - - if (pci_system_init()) - return 0; - - dev = pci_device_find_by_slot(0, 0, 2, 0); - if (dev == NULL || dev->vendor_id != 0x8086) { - struct pci_device_iterator *iter; - - iter = pci_id_match_iterator_create(match); - if (!iter) - return 0; - - dev = pci_device_next(iter); - pci_iterator_destroy(iter); - } - - return dev; -} - -static void *igfx_get_mmio(void) -{ - struct pci_device *pci = __igfx_get(); - int error; - - igt_skip_on(pci == NULL); - igt_skip_on(intel_gen(pci->device_id) != 7); - - error = pci_device_probe(pci); - igt_assert(error == 0); - - error = pci_device_map_range(pci, - pci->regions[0].base_addr, - 2*1024*1024, - PCI_DEV_MAP_FLAG_WRITABLE, - &mmio); - igt_assert(error == 0); - igt_assert(mmio != NULL); - - return mmio; -} - -static void *thread(void *arg) -{ - struct thread *t = arg; - uint32_t *forcewake_mt = (uint32_t *)((char *)t->mmio + FORCEWAKE_MT); - uint32_t bit = 1 << t->bit; - - while (1) { - *forcewake_mt = bit << 16 | bit; - igt_assert(*forcewake_mt & bit); - *forcewake_mt = bit << 16; - igt_assert((*forcewake_mt & bit) == 0); - } - - return NULL; -} - -#define MI_STORE_REGISTER_MEM (0x24<<23) - -igt_simple_main -{ - struct thread t[16]; - int i; - - t[0].fd = drm_open_any(); - t[0].mmio = igfx_get_mmio(); - - for (i = 2; i < 16; i++) { - t[i] = t[0]; - t[i].bit = i; - pthread_create(&t[i].thread, NULL, thread, &t[i]); - } - - sleep(2); - - for (i = 0; i < 1000; i++) { - uint32_t *p; - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec[2]; - struct drm_i915_gem_relocation_entry reloc[2]; - uint32_t b[] = { - MI_LOAD_REGISTER_IMM, - FORCEWAKE_MT, - 2 << 16 | 2, - MI_STORE_REGISTER_MEM | 1, - FORCEWAKE_MT, - 0, // to be patched - MI_LOAD_REGISTER_IMM, - FORCEWAKE_MT, - 2 << 16, - MI_STORE_REGISTER_MEM | 1, - FORCEWAKE_MT, - 1 * sizeof(uint32_t), // to be patched - MI_BATCH_BUFFER_END, - 0 - }; - - memset(exec, 0, sizeof(exec)); - exec[1].handle = gem_create(t[0].fd, 4096); - exec[1].relocation_count = 2; - exec[1].relocs_ptr = (uintptr_t)reloc; - gem_write(t[0].fd, exec[1].handle, 0, b, sizeof(b)); - exec[0].handle = gem_create(t[0].fd, 4096); - - reloc[0].offset = 5 * sizeof(uint32_t); - reloc[0].delta = 0; - reloc[0].target_handle = exec[0].handle; - reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; - reloc[0].presumed_offset = 0; - - reloc[1].offset = 11 * sizeof(uint32_t); - reloc[1].delta = 1 * sizeof(uint32_t); - reloc[1].target_handle = exec[0].handle; - reloc[1].read_domains = I915_GEM_DOMAIN_RENDER; - reloc[1].write_domain = I915_GEM_DOMAIN_RENDER; - reloc[1].presumed_offset = 0; - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)&exec; - execbuf.buffer_count = 2; - execbuf.batch_len = sizeof(b); - execbuf.flags = I915_EXEC_SECURE; - - gem_execbuf(t[0].fd, &execbuf); - gem_sync(t[0].fd, exec[1].handle); - - p = gem_mmap(t[0].fd, exec[0].handle, 4096, PROT_READ); - - igt_info("[%d]={ %08x %08x }\n", i, p[0], p[1]); - igt_assert(p[0] & 2); - igt_assert((p[1] & 2) == 0); - - munmap(p, 4096); - gem_close(t[0].fd, exec[0].handle); - gem_close(t[0].fd, exec[1].handle); - - usleep(1000); - } -} diff --git a/tests/kms_3d.c b/tests/kms_3d.c deleted file mode 100644 index 6588d9d2..00000000 --- a/tests/kms_3d.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright © 2014 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. - * - */ - -#include "igt_core.h" -#include "igt_kms.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Tests 3D mode setting."); - -igt_simple_main -{ - int drm_fd; - drmModeRes *res; - drmModeConnector *connector; - unsigned char *edid; - size_t length; - int mode_count, connector_id; - - drm_fd = drm_open_any_master(); - res = drmModeGetResources(drm_fd); - - igt_assert(drmSetClientCap(drm_fd, DRM_CLIENT_CAP_STEREO_3D, 1) >= 0); - - /* find an hdmi connector */ - for (int i = 0; i < res->count_connectors; i++) { - - connector = drmModeGetConnector(drm_fd, res->connectors[i]); - - if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA && - connector->connection == DRM_MODE_DISCONNECTED) - break; - - drmModeFreeConnector(connector); - - connector = NULL; - } - igt_require(connector); - - kmstest_edid_add_3d(igt_kms_get_base_edid(), EDID_LENGTH, &edid, - &length); - - kmstest_force_edid(drm_fd, connector, edid, length); - if (!kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_ON)) - igt_skip("Could not force connector on\n"); - - connector_id = connector->connector_id; - - /* check for 3D modes */ - mode_count = 0; - connector = drmModeGetConnector(drm_fd, connector_id); - for (int i = 0; i < connector->count_modes; i++) { - if (connector->modes[i].flags & DRM_MODE_FLAG_3D_MASK) - mode_count++; - } - - igt_assert(mode_count == 15); - - /* set 3D modes */ - igt_info("Testing:\n"); - for (int i = 0; i < connector->count_modes; i++) { - int fb_id; - struct kmstest_connector_config config; - int crtc_mask = -1; - int ret; - - if (!(connector->modes[i].flags & DRM_MODE_FLAG_3D_MASK)) - continue; - - /* create a configuration */ - ret = kmstest_get_connector_config(drm_fd, connector_id, - crtc_mask, &config); - if (ret != true) { - igt_info("Error creating configuration for:\n "); - kmstest_dump_mode(&connector->modes[i]); - - continue; - } - - igt_info(" "); - kmstest_dump_mode(&connector->modes[i]); - - /* create stereo framebuffer */ - fb_id = igt_create_stereo_fb(drm_fd, &connector->modes[i], - igt_bpp_depth_to_drm_format(32, 32), - I915_TILING_NONE); - - ret = drmModeSetCrtc(drm_fd, config.crtc->crtc_id, fb_id, 0, 0, - &connector->connector_id, 1, - &connector->modes[i]); - - igt_assert(ret == 0); - } - - kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_UNSPECIFIED); - kmstest_force_edid(drm_fd, connector, NULL, 0); - - drmModeFreeConnector(connector); - free(edid); - - igt_exit(); -} diff --git a/tests/kms_addfb.c b/tests/kms_addfb.c deleted file mode 100644 index 756589e9..00000000 --- a/tests/kms_addfb.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "drm_fourcc.h" - -uint32_t gem_bo; -uint32_t gem_bo_small; - -static void pitch_tests(int fd) -{ - struct drm_mode_fb_cmd2 f = {}; - int bad_pitches[] = { 0, 32, 63, 128, 256, 256*4, 999, 64*1024 }; - int i; - - f.width = 512; - f.height = 512; - f.pixel_format = DRM_FORMAT_XRGB8888; - f.pitches[0] = 1024*4; - - igt_fixture { - gem_bo = gem_create(fd, 1024*1024*4); - igt_assert(gem_bo); - } - - igt_subtest("no-handle") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == -1 && - errno == EINVAL); - } - - f.handles[0] = gem_bo; - igt_subtest("normal") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &f.fb_id) == 0); - f.fb_id = 0; - } - - for (i = 0; i < ARRAY_SIZE(bad_pitches); i++) { - igt_subtest_f("bad-pitch-%i", bad_pitches[i]) { - f.pitches[0] = bad_pitches[i]; - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == -1 && - errno == EINVAL); - } - } - - igt_fixture - gem_set_tiling(fd, gem_bo, I915_TILING_X, 1024*4); - f.pitches[0] = 1024*4; - - igt_subtest("X-tiled") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &f.fb_id) == 0); - f.fb_id = 0; - } - - igt_subtest("framebuffer-vs-set-tiling") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0); - igt_assert(__gem_set_tiling(fd, gem_bo, I915_TILING_X, 512*4) == -EBUSY); - igt_assert(__gem_set_tiling(fd, gem_bo, I915_TILING_X, 1024*4) == -EBUSY); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &f.fb_id) == 0); - f.fb_id = 0; - } - - f.pitches[0] = 512*4; - igt_subtest("tile-pitch-mismatch") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == -1 && - errno == EINVAL); - } - - igt_fixture - gem_set_tiling(fd, gem_bo, I915_TILING_Y, 1024*4); - f.pitches[0] = 1024*4; - igt_subtest("Y-tiled") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == -1 && - errno == EINVAL); - } - - igt_fixture - gem_close(fd, gem_bo); -} - -static void size_tests(int fd) -{ - struct drm_mode_fb_cmd2 f = {}; - struct drm_mode_fb_cmd2 f_16 = {}; - struct drm_mode_fb_cmd2 f_8 = {}; - - f.width = 1024; - f.height = 1024; - f.pixel_format = DRM_FORMAT_XRGB8888; - f.pitches[0] = 1024*4; - - f_16.width = 1024; - f_16.height = 1024*2; - f_16.pixel_format = DRM_FORMAT_RGB565; - f_16.pitches[0] = 1024*2; - - f_8.width = 1024*2; - f_8.height = 1024*2; - f_8.pixel_format = DRM_FORMAT_C8; - f_8.pitches[0] = 1024*2; - - igt_fixture { - gem_bo = gem_create(fd, 1024*1024*4); - igt_assert(gem_bo); - gem_bo_small = gem_create(fd, 1024*1024*4 - 4096); - igt_assert(gem_bo_small); - } - - f.handles[0] = gem_bo; - f_16.handles[0] = gem_bo; - f_8.handles[0] = gem_bo; - - igt_subtest("size-max") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &f.fb_id) == 0); - f.fb_id = 0; - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f_16) == 0); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &f_16.fb_id) == 0); - f.fb_id = 0; - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f_8) == 0); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &f_8.fb_id) == 0); - f.fb_id = 0; - } - - f.width++; - f_16.width++; - f_8.width++; - igt_subtest("too-wide") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == -1 && - errno == EINVAL); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f_16) == -1 && - errno == EINVAL); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f_8) == -1 && - errno == EINVAL); - } - f.width--; - f_16.width--; - f_8.width--; - f.height++; - f_16.height++; - f_8.height++; - igt_subtest("too-high") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == -1 && - errno == EINVAL); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f_16) == -1 && - errno == EINVAL); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f_8) == -1 && - errno == EINVAL); - } - - f.handles[0] = gem_bo_small; - igt_subtest("bo-too-small") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == -1 && - errno == EINVAL); - } - - /* Just to check that the parameters would work. */ - f.height = 1020; - igt_subtest("small-bo") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0); - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &f.fb_id) == 0); - f.fb_id = 0; - } - - igt_fixture - gem_set_tiling(fd, gem_bo_small, I915_TILING_X, 1024*4); - - igt_subtest("bo-too-small-due-to-tiling") { - igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == -1 && - errno == EINVAL); - } - - - igt_fixture { - gem_close(fd, gem_bo); - gem_close(fd, gem_bo_small); - } -} - -int fd; - -igt_main -{ - igt_fixture - fd = drm_open_any_master(); - - pitch_tests(fd); - - size_tests(fd); - - igt_fixture - close(fd); -} diff --git a/tests/kms_cursor_crc.c b/tests/kms_cursor_crc.c deleted file mode 100644 index 64fea122..00000000 --- a/tests/kms_cursor_crc.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * 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. - * - */ - -#include <errno.h> -#include <limits.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION( - "Use the display CRC support to validate cursor plane functionality. " - "The test will position the cursor plane either fully onscreen, " - "partially onscreen, or fully offscreen, using either a fully opaque " - "or fully transparent surface. In each case it then reads the PF CRC " - "and compares it with the CRC value obtained when the cursor plane " - "was disabled."); - -#ifndef DRM_CAP_CURSOR_WIDTH -#define DRM_CAP_CURSOR_WIDTH 0x8 -#endif -#ifndef DRM_CAP_CURSOR_HEIGHT -#define DRM_CAP_CURSOR_HEIGHT 0x9 -#endif - -typedef struct { - int drm_fd; - igt_display_t display; - struct igt_fb primary_fb; - struct igt_fb fb; - igt_output_t *output; - enum pipe pipe; - igt_crc_t ref_crc; - int left, right, top, bottom; - int screenw, screenh; - int curw, curh; /* cursor size */ - int cursor_max_w, cursor_max_h; - igt_pipe_crc_t *pipe_crc; - uint32_t devid; -} data_t; - -static void draw_cursor(cairo_t *cr, int x, int y, int cw, int ch) -{ - int wl, wr, ht, hb; - - /* deal with odd cursor width/height */ - wl = cw / 2; - wr = (cw + 1) / 2; - ht = ch / 2; - hb = (ch + 1) / 2; - - /* Cairo doesn't like to be fed numbers that are too wild */ - if ((x < SHRT_MIN) || (x > SHRT_MAX) || (y < SHRT_MIN) || (y > SHRT_MAX)) - return; - cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); - /* 4 color rectangles in the corners, RGBY */ - igt_paint_color_alpha(cr, x, y, wl, ht, 1.0, 0.0, 0.0, 1.0); - igt_paint_color_alpha(cr, x + wl, y, wr, ht, 0.0, 1.0, 0.0, 1.0); - igt_paint_color_alpha(cr, x, y + ht, wl, hb, 0.0, 0.0, 1.0, 1.0); - igt_paint_color_alpha(cr, x + wl, y + ht, wr, hb, 0.5, 0.5, 0.5, 1.0); -} - -static void cursor_enable(data_t *data) -{ - igt_output_t *output = data->output; - igt_plane_t *cursor; - - cursor = igt_output_get_plane(output, IGT_PLANE_CURSOR); - igt_plane_set_fb(cursor, &data->fb); - igt_plane_set_size(cursor, data->curw, data->curh); -} - -static void cursor_disable(data_t *data) -{ - igt_output_t *output = data->output; - igt_plane_t *cursor; - - cursor = igt_output_get_plane(output, IGT_PLANE_CURSOR); - igt_plane_set_fb(cursor, NULL); -} - - -static void do_single_test(data_t *data, int x, int y) -{ - igt_display_t *display = &data->display; - igt_pipe_crc_t *pipe_crc = data->pipe_crc; - igt_crc_t crc, ref_crc; - igt_plane_t *cursor; - cairo_t *cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); - - igt_print_activity(); - - /* Hardware test */ - igt_paint_test_pattern(cr, data->screenw, data->screenh); - cursor_enable(data); - cursor = igt_output_get_plane(data->output, IGT_PLANE_CURSOR); - igt_plane_set_position(cursor, x, y); - igt_display_commit(display); - igt_wait_for_vblank(data->drm_fd, data->pipe); - igt_pipe_crc_collect_crc(pipe_crc, &crc); - cursor_disable(data); - igt_display_commit(display); - - /* Now render the same in software and collect crc */ - draw_cursor(cr, x, y, data->curw, data->curh); - igt_display_commit(display); - igt_wait_for_vblank(data->drm_fd, data->pipe); - igt_pipe_crc_collect_crc(pipe_crc, &ref_crc); - /* Clear screen afterwards */ - igt_paint_color(cr, 0, 0, data->screenw, data->screenh, - 0.0, 0.0, 0.0); - - igt_assert(igt_crc_equal(&crc, &ref_crc)); -} - -static void do_fail_test(data_t *data, int x, int y, int expect) -{ - igt_display_t *display = &data->display; - igt_plane_t *cursor; - cairo_t *cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); - int ret; - - igt_print_activity(); - - /* Hardware test */ - igt_paint_test_pattern(cr, data->screenw, data->screenh); - cursor_enable(data); - cursor = igt_output_get_plane(data->output, IGT_PLANE_CURSOR); - igt_plane_set_position(cursor, x, y); - ret = igt_display_try_commit2(display, COMMIT_LEGACY); - - igt_plane_set_position(cursor, 0, 0); - cursor_disable(data); - igt_display_commit(display); - - igt_assert(ret == expect); -} - -static void do_test(data_t *data, - int left, int right, int top, int bottom) -{ - do_single_test(data, left, top); - do_single_test(data, right, top); - do_single_test(data, right, bottom); - do_single_test(data, left, bottom); -} - -static void test_crc_onscreen(data_t *data) -{ - int left = data->left; - int right = data->right; - int top = data->top; - int bottom = data->bottom; - int cursor_w = data->curw; - int cursor_h = data->curh; - - /* fully inside */ - do_test(data, left, right, top, bottom); - - /* 2 pixels inside */ - do_test(data, left - (cursor_w-2), right + (cursor_w-2), top , bottom ); - do_test(data, left , right , top - (cursor_h-2), bottom + (cursor_h-2)); - do_test(data, left - (cursor_w-2), right + (cursor_w-2), top - (cursor_h-2), bottom + (cursor_h-2)); - - /* 1 pixel inside */ - do_test(data, left - (cursor_w-1), right + (cursor_w-1), top , bottom ); - do_test(data, left , right , top - (cursor_h-1), bottom + (cursor_h-1)); - do_test(data, left - (cursor_w-1), right + (cursor_w-1), top - (cursor_h-1), bottom + (cursor_h-1)); -} - -static void test_crc_offscreen(data_t *data) -{ - int left = data->left; - int right = data->right; - int top = data->top; - int bottom = data->bottom; - int cursor_w = data->curw; - int cursor_h = data->curh; - - /* fully outside */ - do_test(data, left - (cursor_w), right + (cursor_w), top , bottom ); - do_test(data, left , right , top - (cursor_h), bottom + (cursor_h)); - do_test(data, left - (cursor_w), right + (cursor_w), top - (cursor_h), bottom + (cursor_h)); - - /* fully outside by 1 extra pixels */ - do_test(data, left - (cursor_w+1), right + (cursor_w+1), top , bottom ); - do_test(data, left , right , top - (cursor_h+1), bottom + (cursor_h+1)); - do_test(data, left - (cursor_w+1), right + (cursor_w+1), top - (cursor_h+1), bottom + (cursor_h+1)); - - /* fully outside by 2 extra pixels */ - do_test(data, left - (cursor_w+2), right + (cursor_w+2), top , bottom ); - do_test(data, left , right , top - (cursor_h+2), bottom + (cursor_h+2)); - do_test(data, left - (cursor_w+2), right + (cursor_w+2), top - (cursor_h+2), bottom + (cursor_h+2)); - - /* fully outside by a lot of extra pixels */ - do_test(data, left - (cursor_w+512), right + (cursor_w+512), top , bottom ); - do_test(data, left , right , top - (cursor_h+512), bottom + (cursor_h+512)); - do_test(data, left - (cursor_w+512), right + (cursor_w+512), top - (cursor_h+512), bottom + (cursor_h+512)); - - /* go nuts */ - do_test(data, INT_MIN, INT_MAX - cursor_w, INT_MIN, INT_MAX - cursor_h); - do_test(data, SHRT_MIN, SHRT_MAX, SHRT_MIN, SHRT_MAX); - - /* Make sure we get -ERANGE on integer overflow */ - do_fail_test(data, INT_MAX - cursor_w + 1, INT_MAX - cursor_h + 1, -ERANGE); -} - -static void test_crc_sliding(data_t *data) -{ - int i; - - /* Make sure cursor moves smoothly and pixel-by-pixel, and that there are - * no alignment issues. Horizontal, vertical and diagonal test. - */ - for (i = 0; i < 16; i++) { - do_single_test(data, i, 0); - do_single_test(data, 0, i); - do_single_test(data, i, i); - } -} - -static void test_crc_random(data_t *data) -{ - int i; - - /* Random cursor placement */ - for (i = 0; i < 50; i++) { - int x = rand() % (data->screenw + data->curw * 2) - data->curw; - int y = rand() % (data->screenh + data->curh * 2) - data->curh; - do_single_test(data, x, y); - } -} - -static bool prepare_crtc(data_t *data, igt_output_t *output, - int cursor_w, int cursor_h) -{ - drmModeModeInfo *mode; - igt_display_t *display = &data->display; - igt_plane_t *primary; - - /* select the pipe we want to use */ - igt_output_set_pipe(output, data->pipe); - cursor_disable(data); - igt_display_commit(display); - - if (!output->valid) { - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(display); - return false; - } - - /* create and set the primary plane fb */ - mode = igt_output_get_mode(output); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - 0.0, 0.0, 0.0, - &data->primary_fb); - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - igt_plane_set_fb(primary, &data->primary_fb); - - igt_display_commit(display); - - /* create the pipe_crc object for this pipe */ - if (data->pipe_crc) - igt_pipe_crc_free(data->pipe_crc); - - data->pipe_crc = igt_pipe_crc_new(data->pipe, - INTEL_PIPE_CRC_SOURCE_AUTO); - - /* x/y position where the cursor is still fully visible */ - data->left = 0; - data->right = mode->hdisplay - cursor_w; - data->top = 0; - data->bottom = mode->vdisplay - cursor_h; - data->screenw = mode->hdisplay; - data->screenh = mode->vdisplay; - data->curw = cursor_w; - data->curh = cursor_h; - - /* make sure cursor is disabled */ - cursor_disable(data); - igt_wait_for_vblank(data->drm_fd, data->pipe); - - /* get reference crc w/o cursor */ - igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc); - - return true; -} - -static void cleanup_crtc(data_t *data, igt_output_t *output) -{ - igt_display_t *display = &data->display; - igt_plane_t *primary; - - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = NULL; - - igt_remove_fb(data->drm_fd, &data->primary_fb); - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - igt_plane_set_fb(primary, NULL); - - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(display); -} - -static void run_test(data_t *data, void (*testfunc)(data_t *), int cursor_w, int cursor_h) -{ - igt_display_t *display = &data->display; - igt_output_t *output; - enum pipe p; - int valid_tests = 0; - - igt_require(cursor_w <= data->cursor_max_w && - cursor_h <= data->cursor_max_h); - - for_each_connected_output(display, output) { - data->output = output; - for_each_pipe(display, p) { - data->pipe = p; - - if (!prepare_crtc(data, output, cursor_w, cursor_h)) - continue; - - valid_tests++; - - igt_info("Beginning %s on pipe %s, connector %s\n", - igt_subtest_name(), - kmstest_pipe_name(data->pipe), - igt_output_name(output)); - - testfunc(data); - - igt_info("\n%s on pipe %s, connector %s: PASSED\n\n", - igt_subtest_name(), - kmstest_pipe_name(data->pipe), - igt_output_name(output)); - - /* cleanup what prepare_crtc() has done */ - cleanup_crtc(data, output); - } - } - - igt_require_f(valid_tests, "no valid crtc/connector combinations found\n"); -} - -static void create_cursor_fb(data_t *data, int cur_w, int cur_h) -{ - cairo_t *cr; - uint32_t fb_id; - - /* - * Make the FB slightly taller and leave the extra - * line opaque white, so that we can see that the - * hardware won't scan beyond what it should (esp. - * with non-square cursors). - */ - fb_id = igt_create_color_fb(data->drm_fd, cur_w, cur_h + 1, - DRM_FORMAT_ARGB8888, I915_TILING_NONE, - 1.0, 1.0, 1.0, - &data->fb); - - igt_assert(fb_id); - - cr = igt_get_cairo_ctx(data->drm_fd, &data->fb); - draw_cursor(cr, 0, 0, cur_w, cur_h); - igt_assert(cairo_status(cr) == 0); -} - -static bool has_nonsquare_cursors(uint32_t devid) -{ - /* - * Test non-square cursors a bit on the platforms - * that support such things. - */ - return devid == PCI_CHIP_845_G || devid == PCI_CHIP_I865_G; -} - -static void test_cursor_size(data_t *data) -{ - igt_display_t *display = &data->display; - igt_pipe_crc_t *pipe_crc = data->pipe_crc; - igt_crc_t crc[10], ref_crc; - cairo_t *cr; - uint32_t fb_id; - int i, size; - int cursor_max_size = data->cursor_max_w; - int ret; - - /* Create a maximum size cursor, then change the size in flight to - * smaller ones to see that the size is applied correctly - */ - fb_id = igt_create_fb(data->drm_fd, cursor_max_size, cursor_max_size, - DRM_FORMAT_ARGB8888, I915_TILING_NONE, &data->fb); - igt_assert(fb_id); - - /* Use a solid white rectangle as the cursor */ - cr = igt_get_cairo_ctx(data->drm_fd, &data->fb); - igt_paint_color_alpha(cr, 0, 0, cursor_max_size, cursor_max_size, 1.0, 1.0, 1.0, 1.0); - - /* Hardware test loop */ - cursor_enable(data); - ret = drmModeMoveCursor(data->drm_fd, data->output->config.crtc->crtc_id, 0, 0); - igt_assert(ret == 0); - for (i = 0, size = cursor_max_size; size >= 64; size /= 2, i++) { - /* Change size in flight: */ - ret = drmModeSetCursor(data->drm_fd, data->output->config.crtc->crtc_id, - data->fb.gem_handle, size, size); - igt_assert(ret == 0); - igt_wait_for_vblank(data->drm_fd, data->pipe); - igt_pipe_crc_collect_crc(pipe_crc, &crc[i]); - } - cursor_disable(data); - /* Software test loop */ - cr = igt_get_cairo_ctx(data->drm_fd, &data->primary_fb); - for (i = 0, size = cursor_max_size; size >= 64; size /= 2, i++) { - /* Now render the same in software and collect crc */ - igt_paint_color_alpha(cr, 0, 0, size, size, 1.0, 1.0, 1.0, 1.0); - igt_display_commit(display); - igt_wait_for_vblank(data->drm_fd, data->pipe); - igt_pipe_crc_collect_crc(pipe_crc, &ref_crc); - /* Clear screen afterwards */ - igt_paint_color(cr, 0, 0, data->screenw, data->screenh, - 0.0, 0.0, 0.0); - igt_assert(igt_crc_equal(&crc[i], &ref_crc)); - } -} - -static void run_test_generic(data_t *data) -{ - int cursor_size; - for (cursor_size = 64; cursor_size <= 512; cursor_size *= 2) { - int w = cursor_size; - int h = cursor_size; - - igt_fixture - create_cursor_fb(data, w, h); - - /* Using created cursor FBs to test cursor support */ - igt_subtest_f("cursor-%dx%d-onscreen", w, h) - run_test(data, test_crc_onscreen, w, h); - igt_subtest_f("cursor-%dx%d-offscreen", w, h) - run_test(data, test_crc_offscreen, w, h); - igt_subtest_f("cursor-%dx%d-sliding", w, h) - run_test(data, test_crc_sliding, w, h); - igt_subtest_f("cursor-%dx%d-random", w, h) - run_test(data, test_crc_random, w, h); - - igt_fixture - igt_remove_fb(data->drm_fd, &data->fb); - - /* - * Test non-square cursors a bit on the platforms - * that support such things. And make it a bit more - * interesting by using a non-pot height. - */ - h /= 3; - - igt_fixture - create_cursor_fb(data, w, h); - - /* Using created cursor FBs to test cursor support */ - igt_subtest_f("cursor-%dx%d-onscreen", w, h) { - igt_require(has_nonsquare_cursors(data->devid)); - run_test(data, test_crc_onscreen, w, h); - } - igt_subtest_f("cursor-%dx%d-offscreen", w, h) { - igt_require(has_nonsquare_cursors(data->devid)); - run_test(data, test_crc_offscreen, w, h); - } - igt_subtest_f("cursor-%dx%d-sliding", w, h) { - igt_require(has_nonsquare_cursors(data->devid)); - run_test(data, test_crc_sliding, w, h); - } - igt_subtest_f("cursor-%dx%d-random", w, h) { - igt_require(has_nonsquare_cursors(data->devid)); - run_test(data, test_crc_random, w, h); - } - - igt_fixture - igt_remove_fb(data->drm_fd, &data->fb); - } -} - -static data_t data; - -igt_main -{ - uint64_t cursor_width = 64, cursor_height = 64; - int ret; - - igt_skip_on_simulation(); - - igt_fixture { - data.drm_fd = drm_open_any_master(); - - data.devid = intel_get_drm_devid(data.drm_fd); - - ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_WIDTH, &cursor_width); - igt_assert(ret == 0 || errno == EINVAL); - /* Not making use of cursor_height since it is same as width, still reading */ - ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height); - igt_assert(ret == 0 || errno == EINVAL); - - /* We assume width and height are same so max is assigned width */ - igt_assert_eq(cursor_width, cursor_height); - - kmstest_set_vt_graphics_mode(); - - igt_require_pipe_crc(); - - igt_display_init(&data.display, data.drm_fd); - } - - data.cursor_max_w = cursor_width; - data.cursor_max_h = cursor_height; - - igt_subtest_f("cursor-size-change") - run_test(&data, test_cursor_size, cursor_width, cursor_height); - - run_test_generic(&data); - - igt_fixture { - igt_display_fini(&data.display); - } -} diff --git a/tests/kms_fbc_crc.c b/tests/kms_fbc_crc.c deleted file mode 100644 index 32c3d989..00000000 --- a/tests/kms_fbc_crc.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * 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. - * - */ - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "intel_chipset.h" -#include "intel_batchbuffer.h" -#include "ioctl_wrappers.h" - -IGT_TEST_DESCRIPTION( - "Performs various write operations to the scanout buffer while FBC is " - "enabled. CRC checks will be used to make sure the modifications to scanout " - "buffer are detected."); - -enum test_mode { - TEST_PAGE_FLIP, - TEST_MMAP_CPU, - TEST_MMAP_GTT, - TEST_BLT, - TEST_RENDER, - TEST_CONTEXT, - TEST_PAGE_FLIP_AND_MMAP_CPU, - TEST_PAGE_FLIP_AND_MMAP_GTT, - TEST_PAGE_FLIP_AND_BLT, - TEST_PAGE_FLIP_AND_RENDER, - TEST_PAGE_FLIP_AND_CONTEXT, -}; - -typedef struct { - int drm_fd; - igt_crc_t ref_crc[2]; - igt_pipe_crc_t *pipe_crc; - drm_intel_bufmgr *bufmgr; - drm_intel_context *ctx[2]; - uint32_t devid; - uint32_t handle[2]; - igt_display_t display; - igt_output_t *output; - enum pipe pipe; - igt_plane_t *primary; - struct igt_fb fb[2]; - uint32_t fb_id[2]; -} data_t; - -static const char *test_mode_str(enum test_mode mode) -{ - static const char * const test_modes[] = { - [TEST_PAGE_FLIP] = "page_flip", - [TEST_MMAP_CPU] = "mmap_cpu", - [TEST_MMAP_GTT] = "mmap_gtt", - [TEST_BLT] = "blt", - [TEST_RENDER] = "render", - [TEST_CONTEXT] = "context", - [TEST_PAGE_FLIP_AND_MMAP_CPU] = "page_flip_and_mmap_cpu", - [TEST_PAGE_FLIP_AND_MMAP_GTT] = "page_flip_and_mmap_gtt", - [TEST_PAGE_FLIP_AND_BLT] = "page_flip_and_blt", - [TEST_PAGE_FLIP_AND_RENDER] = "page_flip_and_render", - [TEST_PAGE_FLIP_AND_CONTEXT] = "page_flip_and_context", - }; - - return test_modes[mode]; -} - -static void fill_blt(data_t *data, - uint32_t handle, - struct igt_fb *fb, - unsigned char color) -{ - drm_intel_bo *dst = gem_handle_to_libdrm_bo(data->bufmgr, - data->drm_fd, - "", handle); - struct intel_batchbuffer *batch; - unsigned flags; - int pitch; - - batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(batch); - - pitch = fb->stride; - flags = XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB; - if (fb->tiling && batch->gen >= 4) { - flags |= XY_COLOR_BLT_TILED; - pitch /= 4; - } - - COLOR_BLIT_COPY_BATCH_START(flags); - OUT_BATCH(3 << 24 | 0xf0 << 16 | pitch); - OUT_BATCH(0); - OUT_BATCH(fb->height << 16 | fb->width); - OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(color); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); - intel_batchbuffer_free(batch); - - gem_bo_busy(data->drm_fd, handle); -} - -static void scratch_buf_init(struct igt_buf *buf, drm_intel_bo *bo) -{ - buf->bo = bo; - buf->stride = 4096; - buf->tiling = I915_TILING_X; - buf->size = 4096; -} - -static void exec_nop(data_t *data, uint32_t handle, drm_intel_context *context) -{ - drm_intel_bo *dst; - struct intel_batchbuffer *batch; - - dst = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle); - igt_assert(dst); - - batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(batch); - - /* add the reloc to make sure the kernel will think we write to dst */ - BEGIN_BATCH(4, 1); - OUT_BATCH(MI_BATCH_BUFFER_END); - OUT_BATCH(MI_NOOP); - OUT_RELOC(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(MI_NOOP); - ADVANCE_BATCH(); - - intel_batchbuffer_flush_with_context(batch, context); - intel_batchbuffer_free(batch); -} - -static void fill_render(data_t *data, uint32_t handle, - drm_intel_context *context, unsigned char color) -{ - drm_intel_bo *src, *dst; - struct intel_batchbuffer *batch; - struct igt_buf src_buf, dst_buf; - const uint8_t buf[4] = { color, color, color, color }; - igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(data->devid); - - igt_skip_on(!rendercopy); - - dst = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle); - igt_assert(dst); - - src = drm_intel_bo_alloc(data->bufmgr, "", 4096, 4096); - igt_assert(src); - - gem_write(data->drm_fd, src->handle, 0, buf, 4); - - scratch_buf_init(&src_buf, src); - scratch_buf_init(&dst_buf, dst); - - batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(batch); - - rendercopy(batch, context, - &src_buf, 0, 0, 1, 1, - &dst_buf, 0, 0); - - intel_batchbuffer_free(batch); - - gem_bo_busy(data->drm_fd, handle); -} - -static bool fbc_enabled(data_t *data) -{ - FILE *status; - char str[64] = {}; - - status = igt_debugfs_fopen("i915_fbc_status", "r"); - igt_assert(status); - - fread(str, sizeof(str) - 1, 1, status); - fclose(status); - return strstr(str, "FBC enabled") != NULL; -} - -static void test_crc(data_t *data, enum test_mode mode) -{ - uint32_t crtc_id = data->output->config.crtc->crtc_id; - igt_pipe_crc_t *pipe_crc = data->pipe_crc; - igt_crc_t *crcs = NULL; - uint32_t handle = data->handle[0]; - - igt_assert(fbc_enabled(data)); - - if (mode >= TEST_PAGE_FLIP_AND_MMAP_CPU) { - handle = data->handle[1]; - igt_assert(drmModePageFlip(data->drm_fd, crtc_id, - data->fb_id[1], 0, NULL) == 0); - usleep(300000); - - igt_assert(fbc_enabled(data)); - } - - switch (mode) { - void *ptr; - case TEST_PAGE_FLIP: - igt_assert(drmModePageFlip(data->drm_fd, crtc_id, - data->fb_id[1], 0, NULL) == 0); - break; - case TEST_MMAP_CPU: - case TEST_PAGE_FLIP_AND_MMAP_CPU: - ptr = gem_mmap__cpu(data->drm_fd, handle, 0, 4096, PROT_WRITE); - gem_set_domain(data->drm_fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); - memset(ptr, 0xff, 4); - munmap(ptr, 4096); - gem_sw_finish(data->drm_fd, handle); - break; - case TEST_MMAP_GTT: - case TEST_PAGE_FLIP_AND_MMAP_GTT: - ptr = gem_mmap__gtt(data->drm_fd, handle, 4096, PROT_WRITE); - gem_set_domain(data->drm_fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - memset(ptr, 0xff, 4); - munmap(ptr, 4096); - break; - case TEST_BLT: - case TEST_PAGE_FLIP_AND_BLT: - fill_blt(data, handle, data->fb, ~0); - break; - case TEST_RENDER: - case TEST_CONTEXT: - case TEST_PAGE_FLIP_AND_RENDER: - case TEST_PAGE_FLIP_AND_CONTEXT: - fill_render(data, handle, - (mode == TEST_CONTEXT || mode == TEST_PAGE_FLIP_AND_CONTEXT) ? - data->ctx[1] : NULL, 0xff); - break; - } - - /* - * Make sure we're looking at new data (two vblanks - * to leave some leeway for the kernel if we ever do - * some kind of delayed FBC disable for GTT mmaps. - */ - igt_wait_for_vblank(data->drm_fd, data->pipe); - igt_wait_for_vblank(data->drm_fd, data->pipe); - - igt_pipe_crc_start(pipe_crc); - igt_pipe_crc_get_crcs(pipe_crc, 1, &crcs); - igt_pipe_crc_stop(pipe_crc); - igt_assert(!igt_crc_equal(&crcs[0], &data->ref_crc[0])); - if (mode == TEST_PAGE_FLIP) - igt_assert(igt_crc_equal(&crcs[0], &data->ref_crc[1])); - else - igt_assert(!igt_crc_equal(&crcs[0], &data->ref_crc[1])); - free(crcs); - - /* - * Allow time for FBC to kick in again if it - * got disabled during dirtyfb or page flip. - */ - usleep(300000); - - igt_assert(fbc_enabled(data)); - - igt_pipe_crc_start(pipe_crc); - igt_pipe_crc_get_crcs(pipe_crc, 1, &crcs); - igt_pipe_crc_stop(pipe_crc); - igt_assert(!igt_crc_equal(&crcs[0], &data->ref_crc[0])); - if (mode == TEST_PAGE_FLIP) - igt_assert(igt_crc_equal(&crcs[0], &data->ref_crc[1])); - else - igt_assert(!igt_crc_equal(&crcs[0], &data->ref_crc[1])); - free(crcs); -} - -static bool prepare_crtc(data_t *data) -{ - igt_display_t *display = &data->display; - igt_output_t *output = data->output; - - /* select the pipe we want to use */ - igt_output_set_pipe(output, data->pipe); - igt_display_commit(display); - - if (!output->valid) { - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(display); - return false; - } - - return true; -} - -static bool prepare_test(data_t *data, enum test_mode test_mode) -{ - igt_display_t *display = &data->display; - igt_output_t *output = data->output; - drmModeModeInfo *mode; - igt_pipe_crc_t *pipe_crc; - igt_crc_t *crcs = NULL; - - data->primary = igt_output_get_plane(data->output, IGT_PLANE_PRIMARY); - mode = igt_output_get_mode(data->output); - - data->fb_id[0] = igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_X, - 0.0, 0.0, 0.0, &data->fb[0]); - igt_assert(data->fb_id[0]); - data->fb_id[1] = igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_X, - 0.1, 0.1, 0.1, - &data->fb[1]); - igt_assert(data->fb_id[1]); - - data->handle[0] = data->fb[0].gem_handle; - data->handle[1] = data->fb[1].gem_handle; - - /* scanout = fb[1] */ - igt_plane_set_fb(data->primary, &data->fb[1]); - igt_display_commit(display); - usleep(300000); - - if (!fbc_enabled(data)) { - igt_info("FBC not enabled\n"); - - igt_plane_set_fb(data->primary, NULL); - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(display); - - igt_remove_fb(data->drm_fd, &data->fb[0]); - igt_remove_fb(data->drm_fd, &data->fb[1]); - return false; - } - - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = NULL; - - pipe_crc = igt_pipe_crc_new(data->pipe, - INTEL_PIPE_CRC_SOURCE_AUTO); - - data->pipe_crc = pipe_crc; - - igt_wait_for_vblank(data->drm_fd, data->pipe); - - /* get reference crc for fb[1] */ - igt_pipe_crc_start(pipe_crc); - igt_pipe_crc_get_crcs(pipe_crc, 1, &crcs); - data->ref_crc[1] = crcs[0]; - igt_pipe_crc_stop(pipe_crc); - free(crcs); - - if (test_mode == TEST_CONTEXT || test_mode == TEST_PAGE_FLIP_AND_CONTEXT) { - data->ctx[0] = drm_intel_gem_context_create(data->bufmgr); - igt_assert(data->ctx[0]); - data->ctx[1] = drm_intel_gem_context_create(data->bufmgr); - igt_assert(data->ctx[1]); - - /* - * Disable FBC RT address for both contexts - * (by "rendering" to a non-scanout buffer). - */ - exec_nop(data, data->handle[0], data->ctx[1]); - exec_nop(data, data->handle[0], data->ctx[0]); - exec_nop(data, data->handle[0], data->ctx[1]); - exec_nop(data, data->handle[0], data->ctx[0]); - } - - /* scanout = fb[0] */ - igt_plane_set_fb(data->primary, &data->fb[0]); - igt_display_commit(display); - usleep(300000); - - igt_assert(fbc_enabled(data)); - - if (test_mode == TEST_CONTEXT || test_mode == TEST_PAGE_FLIP_AND_CONTEXT) { - /* - * make ctx[0] FBC RT address point to fb[0], ctx[1] - * FBC RT address is left as disabled. - */ - exec_nop(data, data->fb[0].gem_handle, data->ctx[0]); - } - - igt_wait_for_vblank(data->drm_fd, data->pipe); - - /* get reference crc for fb[0] */ - igt_pipe_crc_start(pipe_crc); - igt_pipe_crc_get_crcs(pipe_crc, 1, &crcs); - data->ref_crc[0] = crcs[0]; - igt_pipe_crc_stop(pipe_crc); - free(crcs); - - return true; -} - -static void finish_crtc(data_t *data, enum test_mode mode) -{ - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = NULL; - - if (mode == TEST_CONTEXT || mode == TEST_PAGE_FLIP_AND_CONTEXT) { - drm_intel_gem_context_destroy(data->ctx[0]); - drm_intel_gem_context_destroy(data->ctx[1]); - } - - igt_plane_set_fb(data->primary, NULL); - igt_output_set_pipe(data->output, PIPE_ANY); - igt_display_commit(&data->display); - - igt_remove_fb(data->drm_fd, &data->fb[0]); - igt_remove_fb(data->drm_fd, &data->fb[1]); -} - -static void reset_display(data_t *data) -{ - igt_display_t *display = &data->display; - - for_each_connected_output(display, data->output) { - if (data->output->valid) { - data->primary = igt_output_get_plane(data->output, IGT_PLANE_PRIMARY); - igt_plane_set_fb(data->primary, NULL); - } - igt_output_set_pipe(data->output, PIPE_ANY); - } -} - -static void run_test(data_t *data, enum test_mode mode) -{ - igt_display_t *display = &data->display; - int valid_tests = 0; - - if (mode == TEST_CONTEXT || mode == TEST_PAGE_FLIP_AND_CONTEXT) { - drm_intel_context *ctx = drm_intel_gem_context_create(data->bufmgr); - igt_require(ctx); - drm_intel_gem_context_destroy(ctx); - } - - reset_display(data); - - for_each_connected_output(display, data->output) { - for_each_pipe(display, data->pipe) { - if (!prepare_crtc(data)) - continue; - - igt_info("Beginning %s on pipe %s, connector %s\n", - igt_subtest_name(), - kmstest_pipe_name(data->pipe), - igt_output_name(data->output)); - - if (!prepare_test(data, mode)) { - igt_info("%s on pipe %s, connector %s: SKIPPED\n", - igt_subtest_name(), - kmstest_pipe_name(data->pipe), - igt_output_name(data->output)); - continue; - } - - valid_tests++; - - test_crc(data, mode); - - igt_info("%s on pipe %s, connector %s: PASSED\n", - igt_subtest_name(), - kmstest_pipe_name(data->pipe), - igt_output_name(data->output)); - - finish_crtc(data, mode); - } - } - - igt_require_f(valid_tests, "no valid crtc/connector combinations found\n"); -} - -igt_main -{ - data_t data = {}; - enum test_mode mode; - - igt_skip_on_simulation(); - - igt_fixture { - char buf[64]; - FILE *status; - - data.drm_fd = drm_open_any_master(); - kmstest_set_vt_graphics_mode(); - - data.devid = intel_get_drm_devid(data.drm_fd); - - igt_require_pipe_crc(); - - status = igt_debugfs_fopen("i915_fbc_status", "r"); - igt_require_f(status, "No i915_fbc_status found\n"); - fread(buf, sizeof(buf), 1, status); - fclose(status); - buf[sizeof(buf) - 1] = '\0'; - igt_require_f(!strstr(buf, "unsupported by this chipset") && - !strstr(buf, "disabled per module param") && - !strstr(buf, "disabled per chip default"), - "FBC not supported/enabled\n"); - - data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096); - igt_assert(data.bufmgr); - drm_intel_bufmgr_gem_enable_reuse(data.bufmgr); - - igt_display_init(&data.display, data.drm_fd); - } - - for (mode = TEST_PAGE_FLIP; mode <= TEST_PAGE_FLIP_AND_CONTEXT; mode++) { - igt_subtest_f("%s", test_mode_str(mode)) { - run_test(&data, mode); - } - } - - igt_fixture { - drm_intel_bufmgr_destroy(data.bufmgr); - igt_display_fini(&data.display); - } -} diff --git a/tests/kms_fence_pin_leak.c b/tests/kms_fence_pin_leak.c deleted file mode 100644 index 7f530e65..00000000 --- a/tests/kms_fence_pin_leak.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright © 2014 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. - * - */ - -#include <errno.h> -#include <limits.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "ioctl_wrappers.h" -#include "intel_chipset.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION("Exercises full ppgtt fence pin_count leak in the " - "kernel."); - -typedef struct { - int drm_fd; - uint32_t devid; - drm_intel_bufmgr *bufmgr; - igt_display_t display; - drm_intel_bo *bos[64]; /* >= num fence registers */ -} data_t; - -static void exec_nop(data_t *data, uint32_t handle, drm_intel_context *context) -{ - drm_intel_bo *dst; - struct intel_batchbuffer *batch; - - dst = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle); - igt_assert(dst); - - batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(batch); - - /* add the reloc to make sure the kernel will think we write to dst */ - BEGIN_BATCH(4, 1); - OUT_BATCH(MI_BATCH_BUFFER_END); - OUT_BATCH(MI_NOOP); - OUT_RELOC(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(MI_NOOP); - ADVANCE_BATCH(); - - intel_batchbuffer_flush_with_context(batch, context); - intel_batchbuffer_free(batch); - - drm_intel_bo_unreference(dst); -} - -static void alloc_fence_objs(data_t *data) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(data->bos); i++) { - drm_intel_bo *bo; - - bo = drm_intel_bo_alloc(data->bufmgr, "fence bo", 4096, 4096); - igt_assert(bo); - gem_set_tiling(data->drm_fd, bo->handle, I915_TILING_X, 512); - - data->bos[i] = bo; - } -} - -static void touch_fences(data_t *data) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(data->bos); i++) { - uint32_t handle = data->bos[i]->handle; - void *ptr; - - ptr = gem_mmap__gtt(data->drm_fd, handle, 4096, PROT_WRITE); - gem_set_domain(data->drm_fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - memset(ptr, 0, 4); - munmap(ptr, 4096); - } -} - -static void free_fence_objs(data_t *data) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(data->bos); i++) - drm_intel_bo_unreference(data->bos[i]); -} - -static bool run_single_test(data_t *data, enum pipe pipe, igt_output_t *output) -{ - igt_display_t *display = &data->display; - drmModeModeInfo *mode; - igt_plane_t *primary; - struct igt_fb fb[2]; - int i; - - igt_output_set_pipe(output, pipe); - igt_display_commit(display); - - if (!output->valid) { - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(display); - return false; - } - - mode = igt_output_get_mode(output); - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_X, /* need a fence so must be tiled */ - 0.0, 0.0, 0.0, - &fb[0]); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_X, /* need a fence so must be tiled */ - 0.0, 0.0, 0.0, - &fb[1]); - - igt_plane_set_fb(primary, &fb[0]); - igt_display_commit(display); - - for (i = 0; i < 64; i++) { - drm_intel_context *ctx; - - /* - * Link fb.gem_handle to the ppgtt vm of ctx so that the context - * destruction will unbind the obj from the ppgtt vm in question. - */ - ctx = drm_intel_gem_context_create(data->bufmgr); - igt_assert(ctx); - exec_nop(data, fb[i&1].gem_handle, ctx); - drm_intel_gem_context_destroy(ctx); - - /* Force a context switch to make sure ctx gets destroyed for real. */ - exec_nop(data, fb[i&1].gem_handle, NULL); - - gem_sync(data->drm_fd, fb[i&1].gem_handle); - - /* - * Make only the current fb has a fence and - * the next fb will pick a new fence. Assuming - * all fences are associated with an object, the - * kernel will always pick a fence with pin_count==0. - */ - touch_fences(data); - - /* - * Pin the new buffer and unpin the old buffer from display. If - * the kernel is buggy the ppgtt unbind will have dropped the - * fence for the old buffer, and now the display code will try - * to unpin only to find no fence there. So the pin_count will leak. - */ - igt_plane_set_fb(primary, &fb[!(i&1)]); - igt_display_commit(display); - - igt_print_activity(); - } - - igt_plane_set_fb(primary, NULL); - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(display); - - igt_remove_fb(data->drm_fd, &fb[1]); - igt_remove_fb(data->drm_fd, &fb[0]); - - igt_info("\n"); - - return true; -} - -static void run_test(data_t *data) -{ - igt_display_t *display = &data->display; - igt_output_t *output; - enum pipe p; - - for_each_connected_output(display, output) { - for_each_pipe(display, p) { - if (run_single_test(data, p, output)) - return; /* one time ought to be enough */ - } - } - - igt_skip("no valid crtc/connector combinations found\n"); -} - -igt_simple_main -{ - drm_intel_context *ctx; - data_t data = {}; - - igt_skip_on_simulation(); - - data.drm_fd = drm_open_any_master(); - - data.devid = intel_get_drm_devid(data.drm_fd); - - kmstest_set_vt_graphics_mode(); - - data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096); - igt_assert(data.bufmgr); - drm_intel_bufmgr_gem_enable_reuse(data.bufmgr); - - igt_display_init(&data.display, data.drm_fd); - - ctx = drm_intel_gem_context_create(data.bufmgr); - igt_require(ctx); - drm_intel_gem_context_destroy(ctx); - - alloc_fence_objs(&data); - - run_test(&data); - - free_fence_objs(&data); - - drm_intel_bufmgr_destroy(data.bufmgr); - igt_display_fini(&data.display); -} diff --git a/tests/kms_flip.c b/tests/kms_flip.c deleted file mode 100644 index cae02e9b..00000000 --- a/tests/kms_flip.c +++ /dev/null @@ -1,1763 +0,0 @@ -/* - * Copyright 2012 Intel Corporation - * Jesse Barnes <jesse.barnes@intel.com> - * - * 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 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <cairo.h> -#include <errno.h> -#include <fcntl.h> -#include <math.h> -#include <stdint.h> -#include <unistd.h> -#include <sys/poll.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#ifdef HAVE_LINUX_KD_H -#include <linux/kd.h> -#elif HAVE_SYS_KD_H -#include <sys/kd.h> -#endif -#include <time.h> -#include <pthread.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_chipset.h" -#include "intel_batchbuffer.h" -#include "igt_kms.h" -#include "igt_aux.h" -#include "igt_gt.h" - -#define TEST_DPMS (1 << 0) -#define TEST_WITH_DUMMY_BCS (1 << 1) -#define TEST_WITH_DUMMY_RCS (1 << 2) -#define TEST_PAN (1 << 3) -#define TEST_MODESET (1 << 4) -#define TEST_CHECK_TS (1 << 5) -#define TEST_EBUSY (1 << 6) -#define TEST_EINVAL (1 << 7) -#define TEST_FLIP (1 << 8) -#define TEST_VBLANK (1 << 9) -#define TEST_VBLANK_BLOCK (1 << 10) -#define TEST_VBLANK_ABSOLUTE (1 << 11) -#define TEST_VBLANK_EXPIRED_SEQ (1 << 12) -#define TEST_FB_RECREATE (1 << 13) -#define TEST_RMFB (1 << 14) -#define TEST_HANG (1 << 15) -#define TEST_NOEVENT (1 << 16) -#define TEST_FB_BAD_TILING (1 << 17) -#define TEST_SINGLE_BUFFER (1 << 18) -#define TEST_DPMS_OFF (1 << 19) -#define TEST_NO_2X_OUTPUT (1 << 20) -#define TEST_DPMS_OFF_OTHERS (1 << 21) -#define TEST_ENOENT (1 << 22) -#define TEST_FENCE_STRESS (1 << 23) -#define TEST_VBLANK_RACE (1 << 24) -#define TEST_RPM (1 << 25) -#define TEST_SUSPEND (1 << 26) -#define TEST_TS_CONT (1 << 27) -#define TEST_BO_TOOBIG (1 << 28) -#define TEST_HANG_ONCE (1 << 29) - -#define EVENT_FLIP (1 << 0) -#define EVENT_VBLANK (1 << 1) - -#ifndef DRM_CAP_TIMESTAMP_MONOTONIC -#define DRM_CAP_TIMESTAMP_MONOTONIC 6 -#endif - -#define USEC_PER_SEC 1000000L -#define NSEC_PER_SEC 1000000000L - -drmModeRes *resources; -int drm_fd; -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -uint32_t devid; -int test_time = 3; -static bool monotonic_timestamp; -static pthread_t vblank_wait_thread; - -static drmModeConnector *last_connector; - -uint32_t *fb_ptr; - -struct type_name { - int type; - const char *name; -}; - -struct event_state { - const char *name; - - /* - * Event data for the last event that has already passed our check. - * Updated using the below current_* vars in update_state(). - */ - struct timeval last_ts; /* kernel reported timestamp */ - struct timeval last_received_ts; /* the moment we received it */ - unsigned int last_seq; /* kernel reported seq. num */ - - /* - * Event data for for the current event that we just received and - * going to check for validity. Set in event_handler(). - */ - struct timeval current_ts; /* kernel reported timestamp */ - struct timeval current_received_ts; /* the moment we received it */ - unsigned int current_seq; /* kernel reported seq. num */ - - int count; /* # of events of this type */ - - /* Step between the current and next 'target' sequence number. */ - int seq_step; -}; - -struct test_output { - int mode_valid; - drmModeModeInfo kmode[4]; - drmModeEncoder *kencoder[4]; - drmModeConnector *kconnector[4]; - uint32_t _connector[4]; - uint32_t _crtc[4]; - int count; /* 1:1 mapping between crtc:connector */ - int flags; - int pipe; /* primary pipe for vblank */ - unsigned int current_fb_id; - unsigned int fb_width; - unsigned int fb_height; - unsigned int fb_ids[3]; - int bpp, depth; - struct igt_fb fb_info[3]; - - struct event_state flip_state; - struct event_state vblank_state; - /* Overall step between each round */ - int seq_step; - unsigned int pending_events; - int flip_count; -}; - - -static unsigned long gettime_us(void) -{ - struct timespec ts; - - clock_gettime(CLOCK_MONOTONIC, &ts); - - return ts.tv_sec * 1000000 + ts.tv_nsec / 1000; -} - -static int calibrate_dummy_load(struct test_output *o, - const char *ring_name, - int (*emit)(struct test_output *o, int limit, int timeout)) -{ - unsigned long start; - int ops = 1; - - start = gettime_us(); - - do { - unsigned long diff; - int ret; - - ret = emit(o, (ops+1)/2, 10); - diff = gettime_us() - start; - - if (ret || diff / USEC_PER_SEC >= 1) - break; - - ops += ops; - } while (ops < 100000); - - igt_debug("%s dummy load calibrated: %d operations / second\n", - ring_name, ops); - - return ops; -} - -static void blit_copy(drm_intel_bo *dst, drm_intel_bo *src, - unsigned int width, unsigned int height, - unsigned int dst_pitch, unsigned int src_pitch) -{ - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - dst_pitch); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(height << 16 | width); - OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(src_pitch); - OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - - if (batch->gen >= 6) { - BEGIN_BATCH(3, 0); - OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - ADVANCE_BATCH(); - } -} - -static int _emit_dummy_load__bcs(struct test_output *o, int limit, int timeout) -{ - int i, ret = 0; - drm_intel_bo *src_bo, *dst_bo, *fb_bo; - struct igt_fb *fb_info = &o->fb_info[o->current_fb_id]; - - src_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096); - igt_assert(src_bo); - - dst_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096); - igt_assert(dst_bo); - - fb_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle); - igt_assert(fb_bo); - - for (i = 0; i < limit; i++) { - blit_copy(dst_bo, src_bo, - 2048, 2048, - 2048*4, 2048*4); - - igt_swap(src_bo, dst_bo); - } - blit_copy(fb_bo, src_bo, - min(o->fb_width, 2048), min(o->fb_height, 2048), - fb_info->stride, 2048*4); - intel_batchbuffer_flush(batch); - - if (timeout > 0) - ret = drm_intel_gem_bo_wait(fb_bo, timeout * NSEC_PER_SEC); - - drm_intel_bo_unreference(src_bo); - drm_intel_bo_unreference(dst_bo); - drm_intel_bo_unreference(fb_bo); - - return ret; -} - -static void emit_dummy_load__bcs(struct test_output *o, int seconds) -{ - static int ops_per_sec; - - if (ops_per_sec == 0) - ops_per_sec = calibrate_dummy_load(o, "bcs", - _emit_dummy_load__bcs); - - _emit_dummy_load__bcs(o, seconds * ops_per_sec, 0); -} - -static void emit_fence_stress(struct test_output *o) -{ - const int num_fences = gem_available_fences(drm_fd); - struct igt_fb *fb_info = &o->fb_info[o->current_fb_id]; - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 *exec; - uint32_t buf[2] = { MI_BATCH_BUFFER_END, 0 }; - drm_intel_bo **bo; - int i; - - bo = calloc(sizeof(*bo), num_fences); - exec = calloc(sizeof(*exec), num_fences+1); - for (i = 0; i < num_fences - 1; i++) { - uint32_t tiling = I915_TILING_X; - unsigned long pitch = 0; - bo[i] = drm_intel_bo_alloc_tiled(bufmgr, - "X tiled bo", 1024, 1024, 4, - &tiling, &pitch, 0); - exec[i].handle = bo[i]->handle; - exec[i].flags = EXEC_OBJECT_NEEDS_FENCE; - } - exec[i].handle = fb_info->gem_handle; - exec[i].flags = EXEC_OBJECT_NEEDS_FENCE; - exec[++i].handle = gem_create(drm_fd, 4096); - gem_write(drm_fd, exec[i].handle, 0, buf, sizeof(buf)); - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)exec; - execbuf.buffer_count = i + 1; - execbuf.batch_len = sizeof(buf); - if (HAS_BLT_RING(intel_get_drm_devid(drm_fd))) - execbuf.flags = I915_EXEC_BLT; - - gem_execbuf(drm_fd, &execbuf); - - gem_close(drm_fd, exec[i].handle); - for (i = 0; i < num_fences - 1; i++) - drm_intel_bo_unreference(bo[i]); - free(bo); - free(exec); -} - -static int _emit_dummy_load__rcs(struct test_output *o, int limit, int timeout) -{ - const struct igt_fb *fb_info = &o->fb_info[o->current_fb_id]; - igt_render_copyfunc_t copyfunc; - struct igt_buf sb[3], *src, *dst, *fb; - int i, ret = 0; - - copyfunc = igt_get_render_copyfunc(devid); - if (copyfunc == NULL) - return _emit_dummy_load__bcs(o, limit, timeout); - - sb[0].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096); - igt_assert(sb[0].bo); - sb[0].size = sb[0].bo->size; - sb[0].tiling = I915_TILING_NONE; - sb[0].data = NULL; - sb[0].num_tiles = sb[0].bo->size; - sb[0].stride = 4 * 2048; - - sb[1].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096); - igt_assert(sb[1].bo); - sb[1].size = sb[1].bo->size; - sb[1].tiling = I915_TILING_NONE; - sb[1].data = NULL; - sb[1].num_tiles = sb[1].bo->size; - sb[1].stride = 4 * 2048; - - sb[2].bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle); - igt_assert(sb[2].bo); - sb[2].size = sb[2].bo->size; - sb[2].tiling = fb_info->tiling; - sb[2].data = NULL; - sb[2].num_tiles = sb[2].bo->size; - sb[2].stride = fb_info->stride; - - src = &sb[0]; - dst = &sb[1]; - fb = &sb[2]; - - for (i = 0; i < limit; i++) { - copyfunc(batch, NULL, - src, 0, 0, - 2048, 2048, - dst, 0, 0); - - igt_swap(src, dst); - } - copyfunc(batch, NULL, - src, 0, 0, - min(o->fb_width, 2048), min(o->fb_height, 2048), - fb, 0, 0); - intel_batchbuffer_flush(batch); - - if (timeout > 0) - ret = drm_intel_gem_bo_wait(fb->bo, timeout * NSEC_PER_SEC); - - drm_intel_bo_unreference(sb[0].bo); - drm_intel_bo_unreference(sb[1].bo); - drm_intel_bo_unreference(sb[2].bo); - - return ret; -} - -static void emit_dummy_load__rcs(struct test_output *o, int seconds) -{ - static int ops_per_sec; - - if (ops_per_sec == 0) - ops_per_sec = calibrate_dummy_load(o, "rcs", - _emit_dummy_load__rcs); - - _emit_dummy_load__bcs(o, seconds * ops_per_sec, 0); -} - -static void dpms_off_other_outputs(struct test_output *o) -{ - int i, n; - drmModeConnector *connector; - uint32_t connector_id; - - for (i = 0; i < resources->count_connectors; i++) { - connector_id = resources->connectors[i]; - - for (n = 0; n < o->count; n++) { - if (connector_id == o->kconnector[n]->connector_id) - goto next; - } - - connector = drmModeGetConnector(drm_fd, connector_id); - - kmstest_set_connector_dpms(drm_fd, connector, DRM_MODE_DPMS_ON); - kmstest_set_connector_dpms(drm_fd, connector, DRM_MODE_DPMS_OFF); - - drmModeFreeConnector(connector); -next: - ; - } -} - -static void set_dpms(struct test_output *o, int mode) -{ - for (int n = 0; n < o->count; n++) - kmstest_set_connector_dpms(drm_fd, o->kconnector[n], mode); -} - -static void set_flag(unsigned int *v, unsigned int flag) -{ - igt_assert(!(*v & flag)); - *v |= flag; -} - -static void clear_flag(unsigned int *v, unsigned int flag) -{ - igt_assert(*v & flag); - *v &= ~flag; -} - -static int do_page_flip(struct test_output *o, uint32_t fb_id, bool event) -{ - int n, ret = 0; - - o->flip_count = 0; - - for (n = 0; ret == 0 && n < o->count; n++) - ret = drmModePageFlip(drm_fd, o->_crtc[n], fb_id, - event ? DRM_MODE_PAGE_FLIP_EVENT : 0, - event ? (void *)((unsigned long)o | (n==0)) : NULL); - - if (ret == 0 && event) - set_flag(&o->pending_events, EVENT_FLIP); - - return ret; -} - -struct vblank_reply { - unsigned int sequence; - struct timeval ts; -}; - -static int __wait_for_vblank(unsigned int flags, int crtc_idx, - int target_seq, unsigned long ret_data, - struct vblank_reply *reply) -{ - drmVBlank wait_vbl; - int ret; - unsigned crtc_idx_mask; - bool event = !(flags & TEST_VBLANK_BLOCK); - - memset(&wait_vbl, 0, sizeof(wait_vbl)); - - crtc_idx_mask = crtc_idx << DRM_VBLANK_HIGH_CRTC_SHIFT; - igt_assert(!(crtc_idx_mask & ~DRM_VBLANK_HIGH_CRTC_MASK)); - - wait_vbl.request.type = crtc_idx_mask; - if (flags & TEST_VBLANK_ABSOLUTE) - wait_vbl.request.type |= DRM_VBLANK_ABSOLUTE; - else - wait_vbl.request.type |= DRM_VBLANK_RELATIVE; - if (event) { - wait_vbl.request.type |= DRM_VBLANK_EVENT; - wait_vbl.request.signal = ret_data; - } - wait_vbl.request.sequence = target_seq; - - ret = drmWaitVBlank(drm_fd, &wait_vbl); - - if (ret == 0) { - reply->ts.tv_sec = wait_vbl.reply.tval_sec; - reply->ts.tv_usec = wait_vbl.reply.tval_usec; - reply->sequence = wait_vbl.reply.sequence; - } else - ret = -errno; - - return ret; -} - -static int do_wait_for_vblank(struct test_output *o, int pipe_id, - int target_seq, struct vblank_reply *reply) -{ - int ret; - unsigned flags = o->flags; - - /* Absolute waits only works once we have a frame counter. */ - if (!(o->vblank_state.count > 0)) - flags &= ~TEST_VBLANK_ABSOLUTE; - - ret = __wait_for_vblank(flags, pipe_id, target_seq, (unsigned long)o, - reply); - if (ret == 0 && !(o->flags & TEST_VBLANK_BLOCK)) - set_flag(&o->pending_events, EVENT_VBLANK); - - return ret; -} - -static bool -analog_tv_connector(struct test_output *o) -{ - uint32_t connector_type = o->kconnector[0]->connector_type; - - return connector_type == DRM_MODE_CONNECTOR_TV || - connector_type == DRM_MODE_CONNECTOR_9PinDIN || - connector_type == DRM_MODE_CONNECTOR_SVIDEO || - connector_type == DRM_MODE_CONNECTOR_Composite; -} - -static void event_handler(struct event_state *es, unsigned int frame, - unsigned int sec, unsigned int usec) -{ - struct timeval now; - - if (monotonic_timestamp) { - struct timespec ts; - - clock_gettime(CLOCK_MONOTONIC, &ts); - now.tv_sec = ts.tv_sec; - now.tv_usec = ts.tv_nsec / 1000; - } else { - gettimeofday(&now, NULL); - } - es->current_received_ts = now; - - es->current_ts.tv_sec = sec; - es->current_ts.tv_usec = usec; - es->current_seq = frame; -} - -static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *data) -{ - int primary = (unsigned long)data & 1; - struct test_output *o = (void *)((unsigned long)data & ~ 1); - - if (++o->flip_count == o->count) - clear_flag(&o->pending_events, EVENT_FLIP); - if (primary) - event_handler(&o->flip_state, frame, sec, usec); -} - -static double frame_time(struct test_output *o) -{ - return 1000.0 * 1000.0 / o->kmode[0].vrefresh; -} - -static void *vblank_wait_thread_func(void *data) -{ - struct test_output *o = data; - struct vblank_reply reply; - int i; - - for (i = 0; i < 32; i++) { - unsigned long start = gettime_us(); - __wait_for_vblank(TEST_VBLANK_BLOCK, o->pipe, 20, (unsigned long)o, &reply); - if (gettime_us() - start > 2 * frame_time(o)) - return (void*)1; - } - - return 0; -} - -static void spawn_vblank_wait_thread(struct test_output *o) -{ - igt_assert(pthread_create(&vblank_wait_thread, NULL, - vblank_wait_thread_func, o) == 0); -} - -static void join_vblank_wait_thread(void) -{ - igt_assert(pthread_join(vblank_wait_thread, NULL) == 0); -} - -static void fixup_premature_vblank_ts(struct test_output *o, - struct event_state *es) -{ - /* - * In case a power off event preempts the completion of a - * wait-for-vblank event the kernel will return a wf-vblank event with - * a zeroed-out timestamp. In order that check_state() doesn't - * complain replace this ts with a valid ts. As we can't calculate the - * exact timestamp, just use the time we received the event. - */ - struct timeval tv; - - if (!(o->flags & (TEST_DPMS | TEST_MODESET))) - return; - - if (o->vblank_state.current_ts.tv_sec != 0 || - o->vblank_state.current_ts.tv_usec != 0) - return; - - tv.tv_sec = 0; - tv.tv_usec = 1; - timersub(&es->current_received_ts, &tv, &es->current_ts); -} - -static void vblank_handler(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *data) -{ - struct test_output *o = data; - - clear_flag(&o->pending_events, EVENT_VBLANK); - event_handler(&o->vblank_state, frame, sec, usec); - fixup_premature_vblank_ts(o, &o->vblank_state); -} - -static void check_state(struct test_output *o, struct event_state *es) -{ - struct timeval diff; - double usec_interflip; - - timersub(&es->current_ts, &es->current_received_ts, &diff); - if (!analog_tv_connector(o)) { - igt_assert_f(diff.tv_sec < 0 || (diff.tv_sec == 0 && diff.tv_usec <= 2000), - "%s ts delayed for too long: %is, %iusec\n", - es->name, (int)diff.tv_sec, (int)diff.tv_usec); - - } - - if (es->count == 0) - return; - - timersub(&es->current_ts, &es->last_received_ts, &diff); - igt_assert_f(timercmp(&es->last_received_ts, &es->current_ts, <), - "%s ts before the %s was issued!\n" - "timerdiff %is, %ius\n", - es->name, es->name, - (int) diff.tv_sec, (int) diff.tv_usec); - - /* check only valid if no modeset happens in between, that increments by - * (1 << 23) on each step. This bounding matches the one in - * DRM_IOCTL_WAIT_VBLANK. */ - if (!(o->flags & (TEST_DPMS | TEST_MODESET))) - igt_assert_f(es->current_seq - (es->last_seq + o->seq_step) <= 1UL << 23, - "unexpected %s seq %u, should be >= %u\n", - es->name, es->current_seq, es->last_seq + o->seq_step); - - /* Check that the vblank frame didn't wrap unexpectedly. */ - if (o->flags & TEST_TS_CONT) { - /* Ignore seq_step here since vblank waits time out immediately - * when we kill the crtc. */ - igt_assert_f(es->current_seq - es->last_seq >= 0, - "unexpected %s seq %u, should be >= %u\n", - es->name, es->current_seq, es->last_seq); - igt_assert_f(es->current_seq - es->last_seq <= 100, - "unexpected %s seq %u, should be < %u\n", - es->name, es->current_seq, es->last_seq + 100); - - igt_debug("testing ts continuity: Current frame %u, old frame %u\n", - es->current_seq, es->last_seq); - } - - if ((o->flags & TEST_CHECK_TS) && (!analog_tv_connector(o))) { - timersub(&es->current_ts, &es->last_ts, &diff); - usec_interflip = (double)o->seq_step * frame_time(o); - - igt_assert_f(fabs((((double) diff.tv_usec) - usec_interflip) / - usec_interflip) <= 0.005, - "inter-%s ts jitter: %is, %ius\n", - es->name, (int) diff.tv_sec, (int) diff.tv_usec); - - igt_assert_f(es->current_seq == es->last_seq + o->seq_step, - "unexpected %s seq %u, expected %u\n", - es->name, es->current_seq, - es->last_seq + o->seq_step); - } -} - -static void check_state_correlation(struct test_output *o, - struct event_state *es1, - struct event_state *es2) -{ - struct timeval tv_diff; - double ftime; - double usec_diff; - int seq_diff; - - if (es1->count == 0 || es2->count == 0) - return; - - timersub(&es2->current_ts, &es1->current_ts, &tv_diff); - usec_diff = tv_diff.tv_sec * 1000 * 1000 + tv_diff.tv_usec; - - seq_diff = es2->current_seq - es1->current_seq; - ftime = frame_time(o); - usec_diff -= seq_diff * ftime; - - igt_assert_f(fabs(usec_diff) / ftime <= 0.005, - "timestamp mismatch between %s and %s (diff %.4f sec)\n", - es1->name, es2->name, usec_diff / 1000 / 1000); -} - -static void check_all_state(struct test_output *o, - unsigned int completed_events) -{ - bool flip, vblank; - - flip = completed_events & EVENT_FLIP; - vblank = completed_events & EVENT_VBLANK; - - if (flip) - check_state(o, &o->flip_state); - if (vblank) - check_state(o, &o->vblank_state); - - /* FIXME: Correlation check is broken. */ - if (flip && vblank && 0) - check_state_correlation(o, &o->flip_state, &o->vblank_state); -} - -static void recreate_fb(struct test_output *o) -{ - drmModeFBPtr r; - struct igt_fb *fb_info = &o->fb_info[o->current_fb_id]; - uint32_t new_fb_id; - - /* Call rmfb/getfb/addfb to ensure those don't introduce stalls */ - r = drmModeGetFB(drm_fd, fb_info->fb_id); - igt_assert(r); - - do_or_die(drmModeAddFB(drm_fd, o->fb_width, o->fb_height, o->depth, - o->bpp, fb_info->stride, - r->handle, &new_fb_id)); - - gem_close(drm_fd, r->handle); - drmFree(r); - do_or_die(drmModeRmFB(drm_fd, fb_info->fb_id)); - - o->fb_ids[o->current_fb_id] = new_fb_id; - o->fb_info[o->current_fb_id].fb_id = new_fb_id; -} - -static void set_y_tiling(struct test_output *o, int fb_idx) -{ - drmModeFBPtr r; - struct igt_fb *fb_info = &o->fb_info[fb_idx]; - - /* Call rmfb/getfb/addfb to ensure those don't introduce stalls */ - r = drmModeGetFB(drm_fd, fb_info->fb_id); - igt_assert(r); - /* Newer kernels don't allow such shenagians any more, so skip the test. */ - igt_require(__gem_set_tiling(drm_fd, r->handle, I915_TILING_Y, fb_info->stride) == 0); - gem_close(drm_fd, r->handle); - drmFree(r); -} - -static void stop_rings(bool stop) -{ - if (stop) - igt_set_stop_rings(STOP_RING_DEFAULTS); - else - igt_set_stop_rings(STOP_RING_NONE); -} - -static void eat_error_state(void) -{ - static const char dfs_entry_error[] = "i915_error_state"; - static const char data[] = ""; - int fd; - - fd = igt_debugfs_open(dfs_entry_error, O_WRONLY); - igt_assert(fd >= 0); - - igt_assert(write(fd, data, sizeof(data)) == sizeof(data)); - close(fd); - - /* and check whether stop_rings is not reset, i.e. the hang has indeed - * happened */ - igt_assert_f(igt_get_stop_rings() == STOP_RING_NONE, - "no gpu hang detected, stop_rings is still 0x%x\n", - igt_get_stop_rings()); - - close(fd); -} - -static void unhang_gpu(int fd, uint32_t handle) -{ - gem_sync(drm_fd, handle); - gem_close(drm_fd, handle); - eat_error_state(); - stop_rings(false); -} - -static uint32_t hang_gpu(int fd) -{ - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 gem_exec; - uint32_t b[2] = {MI_BATCH_BUFFER_END}; - - stop_rings(true); - - memset(&gem_exec, 0, sizeof(gem_exec)); - gem_exec.handle = gem_create(fd, 4096); - gem_write(fd, gem_exec.handle, 0, b, sizeof(b)); - - memset(&execbuf, 0, sizeof(execbuf)); - execbuf.buffers_ptr = (uintptr_t)&gem_exec; - execbuf.buffer_count = 1; - execbuf.batch_len = sizeof(b); - - if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)) { - igt_assert_f(errno == EIO, - "failed to exercise page flip hang recovery\n"); - - unhang_gpu(fd, gem_exec.handle); - gem_exec.handle = 0; - } - - return gem_exec.handle; -} - -static bool is_hung(int fd) -{ - if (drmIoctl(fd, DRM_IOCTL_I915_GEM_THROTTLE, 0) == 0) - return false; - - return errno == EIO; -} - -static int set_mode(struct test_output *o, uint32_t fb, int x, int y) -{ - int n; - - for (n = 0; n < o->count; n++) { - if (fb == 0) { - int ret = drmModeSetCrtc(drm_fd, o->_crtc[n], - 0, 0, 0, - 0, 0, 0); - if (ret) - return ret; - } else { - int ret = drmModeSetCrtc(drm_fd, o->_crtc[n], - fb, x, y, - &o->_connector[n], 1, &o->kmode[n]); - if (ret) - return ret; - } - } - - return 0; -} - -/* Return mask of completed events. */ -static unsigned int run_test_step(struct test_output *o) -{ - unsigned int new_fb_id; - /* for funny reasons page_flip returns -EBUSY on disabled crtcs ... */ - int expected_einval = o->flags & TEST_MODESET ? -EBUSY : -EINVAL; - unsigned int completed_events = 0; - bool do_flip; - bool do_vblank; - struct vblank_reply vbl_reply; - unsigned int target_seq; - uint32_t hang = 0; /* Suppress GCC warning */ - - target_seq = o->vblank_state.seq_step; - /* Absolute waits only works once we have a frame counter. */ - if (o->flags & TEST_VBLANK_ABSOLUTE && o->vblank_state.count > 0) - target_seq += o->vblank_state.last_seq; - - /* - * It's possible that we don't have a pending flip here, in case both - * wf-vblank and flip were scheduled and the wf-vblank event was - * delivered earlier. The same applies to vblank events w.r.t flip. - */ - do_flip = (o->flags & TEST_FLIP) && !(o->pending_events & EVENT_FLIP); - do_vblank = (o->flags & TEST_VBLANK) && - !(o->pending_events & EVENT_VBLANK); - - if (o->flags & TEST_DPMS_OFF_OTHERS) - dpms_off_other_outputs(o); - - if (!(o->flags & TEST_SINGLE_BUFFER)) - o->current_fb_id = !o->current_fb_id; - - if (o->flags & TEST_WITH_DUMMY_BCS) - emit_dummy_load__bcs(o, 1); - - if (o->flags & TEST_WITH_DUMMY_RCS) - emit_dummy_load__rcs(o, 1); - - if (o->flags & TEST_FB_RECREATE) - recreate_fb(o); - new_fb_id = o->fb_ids[o->current_fb_id]; - - if (o->flags & TEST_FB_BAD_TILING) - new_fb_id = o->fb_ids[2]; - - if ((o->flags & TEST_VBLANK_EXPIRED_SEQ) && - !(o->pending_events & EVENT_VBLANK) && o->flip_state.count > 0) { - struct vblank_reply reply; - unsigned int exp_seq; - unsigned long start; - - exp_seq = o->flip_state.current_seq; - start = gettime_us(); - do_or_die(__wait_for_vblank(TEST_VBLANK_ABSOLUTE | - TEST_VBLANK_BLOCK, o->pipe, exp_seq, - 0, &reply)); - igt_assert(gettime_us() - start < 500); - igt_assert(reply.sequence == exp_seq); - igt_assert(timercmp(&reply.ts, &o->flip_state.last_ts, ==)); - } - - if (o->flags & TEST_ENOENT) { - /* hope that fb 0xfffffff0 does not exist */ - igt_assert(do_page_flip(o, 0xfffffff0, false) == -ENOENT); - igt_assert(set_mode(o, 0xfffffff0, 0, 0) == -ENOENT); - } - - if (do_flip && (o->flags & TEST_EINVAL) && o->flip_state.count > 0) - igt_assert(do_page_flip(o, new_fb_id, true) == expected_einval); - - if (o->flags & TEST_FB_BAD_TILING) - new_fb_id = o->fb_ids[o->current_fb_id]; - - if (do_vblank && (o->flags & TEST_EINVAL) && o->vblank_state.count > 0) - igt_assert(do_wait_for_vblank(o, o->pipe, target_seq, &vbl_reply) - == -EINVAL); - - if (o->flags & TEST_VBLANK_RACE) { - spawn_vblank_wait_thread(o); - - if (o->flags & TEST_MODESET) - igt_assert_f(set_mode(o, 0 /* no fb */, 0, 0) == 0, - "failed to disable output: %s\n", - strerror(errno)); - } - - if (o->flags & TEST_DPMS_OFF) - set_dpms(o, DRM_MODE_DPMS_OFF); - - if (o->flags & TEST_MODESET) - igt_assert(set_mode(o, o->fb_ids[o->current_fb_id], 0, 0) == 0); - - if (o->flags & TEST_DPMS) - set_dpms(o, DRM_MODE_DPMS_ON); - - if (o->flags & TEST_VBLANK_RACE) { - struct vblank_reply reply; - unsigned long start, end; - - /* modeset/DPMS is done, vblank wait should work normally now */ - start = gettime_us(); - igt_assert(__wait_for_vblank(TEST_VBLANK_BLOCK, o->pipe, 2, 0, &reply) == 0); - end = gettime_us(); - /* - * we waited for two vblanks, so verify that - * we were blocked for ~1-2 frames. - */ - igt_assert_f(end - start > 0.9 * frame_time(o) && - end - start < 2.1 * frame_time(o), - "wait for two vblanks took %lu usec (frame time %f usec)\n", - end - start, frame_time(o)); - join_vblank_wait_thread(); - } - - igt_print_activity(); - - if (do_flip && (o->flags & TEST_HANG)) { - hang = hang_gpu(drm_fd); - igt_assert_f(hang, "failed to exercise page flip hang recovery\n"); - } - - /* try to make sure we can issue two flips during the same frame */ - if (do_flip && (o->flags & TEST_EBUSY)) { - struct vblank_reply reply; - igt_assert(__wait_for_vblank(TEST_VBLANK_BLOCK, o->pipe, 1, 0, &reply) == 0); - } - - if (do_flip) - do_or_die(do_page_flip(o, new_fb_id, !(o->flags & TEST_NOEVENT))); - - if (o->flags & TEST_FENCE_STRESS) - emit_fence_stress(o); - - if (do_vblank) { - do_or_die(do_wait_for_vblank(o, o->pipe, target_seq, - &vbl_reply)); - if (o->flags & TEST_VBLANK_BLOCK) { - event_handler(&o->vblank_state, vbl_reply.sequence, - vbl_reply.ts.tv_sec, - vbl_reply.ts.tv_usec); - completed_events = EVENT_VBLANK; - } - } - - if (do_flip && (o->flags & TEST_EBUSY)) - igt_assert(do_page_flip(o, new_fb_id, true) == -EBUSY); - - if (do_flip && (o->flags & TEST_RMFB)) - recreate_fb(o); - - /* pan before the flip completes */ - if (o->flags & TEST_PAN) { - int count = do_flip ? - o->flip_state.count : o->vblank_state.count; - int x_ofs = min(count * 10, o->fb_width - o->kmode[0].hdisplay); - - /* Make sure DSPSURF changes value */ - if (o->flags & TEST_HANG) - o->current_fb_id = !o->current_fb_id; - - /* Make sure DSPSURF changes value */ - if (o->flags & TEST_HANG) - o->current_fb_id = !o->current_fb_id; - - igt_assert_f(set_mode(o, o->fb_ids[o->current_fb_id], x_ofs, 0) == 0, - "failed to pan (%dx%d@%dHz)+%d: %s\n", - o->kmode[0].hdisplay, o->kmode[0].vdisplay, o->kmode[0].vrefresh, - x_ofs, strerror(errno)); - } - - if (o->flags & TEST_DPMS) - set_dpms(o, DRM_MODE_DPMS_OFF); - - if (o->flags & TEST_MODESET && !(o->flags & TEST_RMFB) && !(o->flags & TEST_VBLANK_RACE)) - igt_assert_f(set_mode(o, 0 /* no fb */, 0, 0) == 0, - "failed to disable output: %s\n", - strerror(errno)); - - if (o->flags & TEST_RPM) - igt_assert(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_SUSPENDED)); - - if (o->flags & TEST_SUSPEND) - igt_system_suspend_autoresume(); - - if (do_vblank && (o->flags & TEST_EINVAL) && o->vblank_state.count > 0) - igt_assert(do_wait_for_vblank(o, o->pipe, target_seq, &vbl_reply) - == -EINVAL); - - if (do_flip && (o->flags & TEST_EINVAL) && !(o->flags & TEST_FB_BAD_TILING)) - igt_assert(do_page_flip(o, new_fb_id, true) == expected_einval); - - if (hang) - unhang_gpu(drm_fd, hang); - - return completed_events; -} - -static void update_state(struct event_state *es) -{ - es->last_received_ts = es->current_received_ts; - es->last_ts = es->current_ts; - es->last_seq = es->current_seq; - es->count++; -} - -static void update_all_state(struct test_output *o, - unsigned int completed_events) -{ - if (completed_events & EVENT_FLIP) - update_state(&o->flip_state); - - if (completed_events & EVENT_VBLANK) - update_state(&o->vblank_state); -} - -static void connector_find_preferred_mode(uint32_t connector_id, int crtc_idx, - struct test_output *o) -{ - struct kmstest_connector_config config; - - if (!kmstest_get_connector_config(drm_fd, connector_id, 1 << crtc_idx, - &config)) { - o->mode_valid = 0; - return; - } - - o->pipe = config.pipe; - o->kconnector[0] = config.connector; - o->kencoder[0] = config.encoder; - o->_crtc[0] = config.crtc->crtc_id; - o->kmode[0] = config.default_mode; - o->mode_valid = 1; - - o->fb_width = o->kmode[0].hdisplay; - o->fb_height = o->kmode[0].vdisplay; - - drmModeFreeCrtc(config.crtc); -} - -static bool mode_compatible(const drmModeModeInfo *a, const drmModeModeInfo *b) -{ - int d_refresh; - - if (a->hdisplay != b->hdisplay) - return false; - - if (a->vdisplay != b->vdisplay) - return false; - - d_refresh = a->vrefresh - b->vrefresh; - if (d_refresh < -1 || d_refresh > 1) - return false; - - return true; -} - -static void connector_find_compatible_mode(int crtc_idx0, int crtc_idx1, - struct test_output *o) -{ - struct kmstest_connector_config config[2]; - drmModeModeInfo *mode[2]; - int n, m; - - if (!kmstest_get_connector_config(drm_fd, o->_connector[0], - 1 << crtc_idx0, &config[0])) - return; - - if (!kmstest_get_connector_config(drm_fd, o->_connector[1], - 1 << crtc_idx1, &config[1])) { - kmstest_free_connector_config(&config[0]); - return; - } - - mode[0] = &config[0].default_mode; - mode[1] = &config[1].default_mode; - if (!mode_compatible(mode[0], mode[1])) { - for (n = 0; n < config[0].connector->count_modes; n++) { - mode[0] = &config[0].connector->modes[n]; - for (m = 0; m < config[1].connector->count_modes; m++) { - mode[1] = &config[1].connector->modes[m]; - if (mode_compatible(mode[0], mode[1])) - goto found; - } - } - - /* hope for the best! */ - mode[1] = mode[0] = &config[0].default_mode; - } - -found: - o->pipe = config[0].pipe; - o->fb_width = mode[0]->hdisplay; - o->fb_height = mode[0]->vdisplay; - o->mode_valid = 1; - - o->kconnector[0] = config[0].connector; - o->kencoder[0] = config[0].encoder; - o->_crtc[0] = config[0].crtc->crtc_id; - o->kmode[0] = *mode[0]; - - o->kconnector[1] = config[1].connector; - o->kencoder[1] = config[1].encoder; - o->_crtc[1] = config[1].crtc->crtc_id; - o->kmode[1] = *mode[1]; - - drmModeFreeCrtc(config[0].crtc); - drmModeFreeCrtc(config[1].crtc); -} - -static void paint_flip_mode(struct igt_fb *fb, bool odd_frame) -{ - cairo_t *cr = igt_get_cairo_ctx(drm_fd, fb); - int width = fb->width; - int height = fb->height; - - igt_paint_test_pattern(cr, width, height); - - if (odd_frame) - cairo_rectangle(cr, width/4, height/2, width/4, height/8); - else - cairo_rectangle(cr, width/2, height/2, width/4, height/8); - - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_fill(cr); - - igt_assert(!cairo_status(cr)); - cairo_destroy(cr); -} - -static int -fb_is_bound(struct test_output *o, int fb) -{ - int n; - - for (n = 0; n < o->count; n++) { - struct drm_mode_crtc mode; - - mode.crtc_id = o->_crtc[n]; - if (drmIoctl(drm_fd, DRM_IOCTL_MODE_GETCRTC, &mode)) - return 0; - - if (!mode.mode_valid || mode.fb_id != fb) - return false; - } - - return true; -} - -static void check_final_state(struct test_output *o, struct event_state *es, - unsigned int elapsed) -{ - igt_assert_f(es->count > 0, - "no %s event received\n", es->name); - - /* Verify we drop no frames, but only if it's not a TV encoder, since - * those use some funny fake timings behind userspace's back. */ - if (o->flags & TEST_CHECK_TS && !analog_tv_connector(o)) { - int expected; - int count = es->count; - - count *= o->seq_step; - expected = elapsed * o->kmode[0].vrefresh / (1000 * 1000); - igt_assert_f(count >= expected * 99/100 && count <= expected * 101/100, - "dropped frames, expected %d, counted %d, encoder type %d\n", - expected, count, o->kencoder[0]->encoder_type); - } -} - -/* - * Wait until at least one pending event completes. Return mask of completed - * events. - */ -static unsigned int wait_for_events(struct test_output *o) -{ - drmEventContext evctx; - struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; - fd_set fds; - unsigned int event_mask; - int ret; - - event_mask = o->pending_events; - igt_assert(event_mask); - - memset(&evctx, 0, sizeof evctx); - evctx.version = DRM_EVENT_CONTEXT_VERSION; - evctx.vblank_handler = vblank_handler; - evctx.page_flip_handler = page_flip_handler; - - /* make timeout lax with the dummy load */ - if (o->flags & (TEST_WITH_DUMMY_BCS | TEST_WITH_DUMMY_RCS)) - timeout.tv_sec *= 60; - - FD_ZERO(&fds); - FD_SET(drm_fd, &fds); - do { - do { - ret = select(drm_fd + 1, &fds, NULL, NULL, &timeout); - } while (ret < 0 && errno == EINTR); - - igt_assert_f(ret >= 0, - "select error (errno %i)\n", errno); - igt_assert_f(ret > 0, - "select timed out or error (ret %d)\n", ret); - igt_assert_f(!FD_ISSET(0, &fds), - "no fds active, breaking\n"); - - do_or_die(drmHandleEvent(drm_fd, &evctx)); - } while (o->pending_events); - - event_mask ^= o->pending_events; - igt_assert(event_mask); - - return event_mask; -} - -/* Returned the elapsed time in us */ -static unsigned event_loop(struct test_output *o, unsigned duration_ms) -{ - unsigned long start, end; - uint32_t hang = 0; /* Suppress GCC warning */ - int count = 0; - - if (o->flags & TEST_HANG_ONCE) { - hang = hang_gpu(drm_fd); - igt_assert_f(hang, "failed to exercise page flip hang recovery\n"); - } - - start = gettime_us(); - - while (1) { - unsigned int completed_events; - - completed_events = run_test_step(o); - if (o->pending_events) - completed_events |= wait_for_events(o); - check_all_state(o, completed_events); - update_all_state(o, completed_events); - - if (count && (gettime_us() - start) / 1000 >= duration_ms) - break; - - count++; - } - - end = gettime_us(); - - if (hang) - unhang_gpu(drm_fd, hang); - - /* Flush any remaining events */ - if (o->pending_events) - wait_for_events(o); - - return end - start; -} - -static void free_test_output(struct test_output *o) -{ - int i; - - for (i = 0; i < o->count; i++) { - drmModeFreeEncoder(o->kencoder[i]); - drmModeFreeConnector(o->kconnector[i]); - } -} - -static void run_test_on_crtc_set(struct test_output *o, int *crtc_idxs, - int crtc_count, int duration_ms) -{ - char test_name[128]; - unsigned elapsed; - unsigned bo_size = 0; - unsigned int tiling; - int i; - - switch (crtc_count) { - case 1: - connector_find_preferred_mode(o->_connector[0], crtc_idxs[0], o); - snprintf(test_name, sizeof(test_name), - "%s on crtc %d, connector %d", - igt_subtest_name(), o->_crtc[0], o->_connector[0]); - break; - case 2: - connector_find_compatible_mode(crtc_idxs[0], crtc_idxs[1], o); - snprintf(test_name, sizeof(test_name), - "%s on crtc %d:%d, connector %d:%d", - igt_subtest_name(), o->_crtc[0], o->_crtc[1], - o->_connector[0], o->_connector[1]); - break; - default: - igt_assert(0); - } - if (!o->mode_valid) - return; - - igt_assert(o->count == crtc_count); - - last_connector = o->kconnector[0]; - - igt_info("Beginning %s\n", test_name); - - if (o->flags & TEST_PAN) - o->fb_width *= 2; - - tiling = I915_TILING_NONE; - if (o->flags & TEST_FENCE_STRESS) - tiling = I915_TILING_X; - - /* 256 MB is usually the maximum mappable aperture, - * (make it 4x times that to ensure failure) */ - if (o->flags & TEST_BO_TOOBIG) - bo_size = 4*256*1024*1024; - - o->fb_ids[0] = igt_create_fb(drm_fd, o->fb_width, o->fb_height, - igt_bpp_depth_to_drm_format(o->bpp, o->depth), - tiling, &o->fb_info[0]); - o->fb_ids[1] = igt_create_fb_with_bo_size(drm_fd, o->fb_width, o->fb_height, - igt_bpp_depth_to_drm_format(o->bpp, o->depth), - tiling, &o->fb_info[1], bo_size); - o->fb_ids[2] = igt_create_fb(drm_fd, o->fb_width, o->fb_height, - igt_bpp_depth_to_drm_format(o->bpp, o->depth), - I915_TILING_X, &o->fb_info[2]); - igt_assert(o->fb_ids[0]); - igt_assert(o->fb_ids[1]); - if (o->flags & TEST_FB_BAD_TILING) - igt_require(o->fb_ids[2]); - - paint_flip_mode(&o->fb_info[0], false); - if (!(o->flags & TEST_BO_TOOBIG)) - paint_flip_mode(&o->fb_info[1], true); - if (o->fb_ids[2]) - paint_flip_mode(&o->fb_info[2], true); - - if (o->flags & TEST_FB_BAD_TILING) - set_y_tiling(o, 2); - - for (i = 0; i < o->count; i++) - kmstest_dump_mode(&o->kmode[i]); - - if (set_mode(o, o->fb_ids[0], 0, 0)) { - /* We may fail to apply the mode if there are hidden - * constraints, such as bandwidth on the third pipe. - */ - igt_assert_f(crtc_count > 1 || crtc_idxs[0] < 2, - "set_mode may only fail on the 3rd pipe or in multiple crtc tests\n"); - goto out; - } - igt_assert(fb_is_bound(o, o->fb_ids[0])); - - /* quiescent the hw a bit so ensure we don't miss a single frame */ - if (o->flags & TEST_CHECK_TS) - sleep(1); - - if (o->flags & TEST_BO_TOOBIG) { - igt_assert(do_page_flip(o, o->fb_ids[1], true) == -E2BIG); - goto out; - } else - igt_assert(do_page_flip(o, o->fb_ids[1], true) == 0); - wait_for_events(o); - - o->current_fb_id = 1; - - if (o->flags & TEST_FLIP) - o->flip_state.seq_step = 1; - else - o->flip_state.seq_step = 0; - if (o->flags & TEST_VBLANK) - o->vblank_state.seq_step = 10; - else - o->vblank_state.seq_step = 0; - - /* We run the vblank and flip actions in parallel by default. */ - o->seq_step = max(o->vblank_state.seq_step, o->flip_state.seq_step); - - elapsed = event_loop(o, duration_ms); - - if (o->flags & TEST_FLIP && !(o->flags & TEST_NOEVENT)) - check_final_state(o, &o->flip_state, elapsed); - if (o->flags & TEST_VBLANK) - check_final_state(o, &o->vblank_state, elapsed); - - igt_info("\n%s: PASSED\n\n", test_name); - -out: - if (o->fb_ids[2]) - igt_remove_fb(drm_fd, &o->fb_info[2]); - igt_remove_fb(drm_fd, &o->fb_info[1]); - igt_remove_fb(drm_fd, &o->fb_info[0]); - - last_connector = NULL; - - free_test_output(o); -} - -static int run_test(int duration, int flags) -{ - struct test_output o; - int i, n, modes = 0; - - igt_require((flags & TEST_HANG) == 0 || !is_hung(drm_fd)); - - if (flags & TEST_RPM) - igt_require(igt_setup_runtime_pm()); - - resources = drmModeGetResources(drm_fd); - igt_assert(resources); - - /* Count output configurations to scale test runtime. */ - for (i = 0; i < resources->count_connectors; i++) { - for (n = 0; n < resources->count_crtcs; n++) { - memset(&o, 0, sizeof(o)); - o.count = 1; - o._connector[0] = resources->connectors[i]; - o.flags = flags; - o.flip_state.name = "flip"; - o.vblank_state.name = "vblank"; - o.bpp = 32; - o.depth = 24; - - connector_find_preferred_mode(o._connector[0], n, &o); - if (o.mode_valid) - modes++; - - free_test_output(&o); - } - } - - igt_require(modes); - duration = duration * 1000 / modes; - duration = max(500, duration); - - /* Find any connected displays */ - for (i = 0; i < resources->count_connectors; i++) { - for (n = 0; n < resources->count_crtcs; n++) { - int crtc_idx; - - memset(&o, 0, sizeof(o)); - o.count = 1; - o._connector[0] = resources->connectors[i]; - o.flags = flags; - o.flip_state.name = "flip"; - o.vblank_state.name = "vblank"; - o.bpp = 32; - o.depth = 24; - - crtc_idx = n; - run_test_on_crtc_set(&o, &crtc_idx, 1, duration); - } - } - - drmModeFreeResources(resources); - return 1; -} - -static int run_pair(int duration, int flags) -{ - struct test_output o; - int i, j, m, n, modes = 0; - - igt_require((flags & TEST_HANG) == 0 || !is_hung(drm_fd)); - - resources = drmModeGetResources(drm_fd); - igt_assert(resources); - - /* Find a pair of connected displays */ - for (i = 0; i < resources->count_connectors; i++) { - for (n = 0; n < resources->count_crtcs; n++) { - for (j = i + 1; j < resources->count_connectors; j++) { - for (m = n + 1; m < resources->count_crtcs; m++) { - memset(&o, 0, sizeof(o)); - o.count = 2; - o._connector[0] = resources->connectors[i]; - o._connector[1] = resources->connectors[j]; - o.flags = flags; - o.flip_state.name = "flip"; - o.vblank_state.name = "vblank"; - o.bpp = 32; - o.depth = 24; - - connector_find_compatible_mode(n, m, &o); - if (o.mode_valid) - modes++; - - free_test_output(&o); - } - } - } - } - - /* If we have fewer than 2 connected outputs then we won't have any - * configuration at all. So skip in that case. */ - igt_require_f(modes, "At least two displays required\n"); - duration = duration * 1000 / modes; - duration = max(duration, 500); - - /* Find a pair of connected displays */ - for (i = 0; i < resources->count_connectors; i++) { - for (n = 0; n < resources->count_crtcs; n++) { - for (j = i + 1; j < resources->count_connectors; j++) { - for (m = n + 1; m < resources->count_crtcs; m++) { - int crtc_idxs[2]; - - memset(&o, 0, sizeof(o)); - o.count = 2; - o._connector[0] = resources->connectors[i]; - o._connector[1] = resources->connectors[j]; - o.flags = flags; - o.flip_state.name = "flip"; - o.vblank_state.name = "vblank"; - o.bpp = 32; - o.depth = 24; - - crtc_idxs[0] = n; - crtc_idxs[1] = m; - - run_test_on_crtc_set(&o, crtc_idxs, 2, - duration); - } - } - } - } - - drmModeFreeResources(resources); - return 1; -} - -static void get_timestamp_format(void) -{ - uint64_t cap_mono; - int ret; - - ret = drmGetCap(drm_fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap_mono); - igt_assert(ret == 0 || errno == EINVAL); - monotonic_timestamp = ret == 0 && cap_mono == 1; - igt_info("Using %s timestamps\n", - monotonic_timestamp ? "monotonic" : "real"); -} - -static void kms_flip_exit_handler(int sig) -{ - igt_fixture { - if (last_connector) - kmstest_set_connector_dpms(drm_fd, last_connector, DRM_MODE_DPMS_ON); - } -} - -static void test_nonblocking_read(int in) -{ - char buffer[1024]; - int fd = dup(in); - int ret; - - ret = -1; - if (fd != -1) - ret = fcntl(fd, F_GETFL); - if (ret != -1) { - ret |= O_NONBLOCK; - ret = fcntl(fd, F_SETFL, ret); - } - igt_require(ret != -1); - - igt_set_timeout(5); - ret = read(fd, buffer, sizeof(buffer)); - igt_set_timeout(0); - igt_assert_eq(ret, -1); - igt_assert_eq(errno, EAGAIN); - - close(fd); -} - -int main(int argc, char **argv) -{ - struct { - int duration; - int flags; - const char *name; - } tests[] = { - { 30, TEST_VBLANK, "wf_vblank" }, - { 30, TEST_VBLANK | TEST_CHECK_TS, "wf_vblank-ts-check" }, - { 30, TEST_VBLANK | TEST_VBLANK_BLOCK | TEST_CHECK_TS, - "blocking-wf_vblank" }, - { 30, TEST_VBLANK | TEST_VBLANK_ABSOLUTE, - "absolute-wf_vblank" }, - { 30, TEST_VBLANK | TEST_VBLANK_BLOCK | TEST_VBLANK_ABSOLUTE, - "blocking-absolute-wf_vblank" }, - { 60, TEST_VBLANK | TEST_DPMS | TEST_EINVAL, "wf_vblank-vs-dpms" }, - { 60, TEST_VBLANK | TEST_DPMS | TEST_WITH_DUMMY_BCS, - "blt-wf_vblank-vs-dpms" }, - { 60, TEST_VBLANK | TEST_DPMS | TEST_WITH_DUMMY_RCS, - "rcs-wf_vblank-vs-dpms" }, - { 60, TEST_VBLANK | TEST_MODESET | TEST_EINVAL, "wf_vblank-vs-modeset" }, - { 60, TEST_VBLANK | TEST_MODESET | TEST_WITH_DUMMY_BCS, - "blt-wf_vblank-vs-modeset" }, - { 60, TEST_VBLANK | TEST_MODESET | TEST_WITH_DUMMY_RCS, - "rcs-wf_vblank-vs-modeset" }, - - { 30, TEST_FLIP , "plain-flip" }, - { 30, TEST_FLIP | TEST_EBUSY , "busy-flip" }, - { 30, TEST_FLIP | TEST_FENCE_STRESS , "flip-vs-fences" }, - { 30, TEST_FLIP | TEST_CHECK_TS, "plain-flip-ts-check" }, - { 30, TEST_FLIP | TEST_CHECK_TS | TEST_FB_RECREATE, - "plain-flip-fb-recreate" }, - { 30, TEST_FLIP | TEST_RMFB | TEST_MODESET , "flip-vs-rmfb" }, - { 60, TEST_FLIP | TEST_DPMS | TEST_EINVAL, "flip-vs-dpms" }, - { 60, TEST_FLIP | TEST_DPMS | TEST_WITH_DUMMY_BCS, "blt-flip-vs-dpms" }, - { 60, TEST_FLIP | TEST_DPMS | TEST_WITH_DUMMY_RCS, "render-flip-vs-dpms" }, - { 30, TEST_FLIP | TEST_PAN, "flip-vs-panning" }, - { 60, TEST_FLIP | TEST_PAN | TEST_WITH_DUMMY_BCS, "blt-flip-vs-panning" }, - { 60, TEST_FLIP | TEST_PAN | TEST_WITH_DUMMY_RCS, "render-flip-vs-panning" }, - { 60, TEST_FLIP | TEST_MODESET | TEST_EINVAL, "flip-vs-modeset" }, - { 60, TEST_FLIP | TEST_MODESET | TEST_WITH_DUMMY_BCS, "blt-flip-vs-modeset" }, - { 60, TEST_FLIP | TEST_MODESET | TEST_WITH_DUMMY_RCS, "render-flip-vs-modeset" }, - { 30, TEST_FLIP | TEST_VBLANK_EXPIRED_SEQ, - "flip-vs-expired-vblank" }, - - { 30, TEST_FLIP | TEST_VBLANK | TEST_VBLANK_ABSOLUTE | - TEST_CHECK_TS, "flip-vs-absolute-wf_vblank" }, - { 30, TEST_FLIP | TEST_VBLANK | TEST_CHECK_TS, - "flip-vs-wf_vblank" }, - { 30, TEST_FLIP | TEST_VBLANK | TEST_VBLANK_BLOCK | - TEST_CHECK_TS, "flip-vs-blocking-wf-vblank" }, - { 30, TEST_FLIP | TEST_MODESET | TEST_HANG | TEST_NOEVENT, "flip-vs-modeset-vs-hang" }, - { 30, TEST_FLIP | TEST_PAN | TEST_HANG, "flip-vs-panning-vs-hang" }, - { 30, TEST_VBLANK | TEST_HANG_ONCE, "vblank-vs-hang" }, - { 1, TEST_FLIP | TEST_EINVAL | TEST_FB_BAD_TILING, "flip-vs-bad-tiling" }, - - { 1, TEST_DPMS_OFF | TEST_MODESET | TEST_FLIP, - "flip-vs-dpms-off-vs-modeset" }, - { 1, TEST_DPMS_OFF | TEST_MODESET | TEST_FLIP | TEST_SINGLE_BUFFER, - "single-buffer-flip-vs-dpms-off-vs-modeset" }, - { 30, TEST_FLIP | TEST_NO_2X_OUTPUT | TEST_DPMS_OFF_OTHERS , "dpms-off-confusion" }, - { 0, TEST_ENOENT | TEST_NOEVENT, "nonexisting-fb" }, - { 10, TEST_DPMS_OFF | TEST_DPMS | TEST_VBLANK_RACE, "dpms-vs-vblank-race" }, - { 10, TEST_MODESET | TEST_VBLANK_RACE, "modeset-vs-vblank-race" }, - { 10, TEST_VBLANK | TEST_DPMS | TEST_RPM | TEST_TS_CONT, "vblank-vs-dpms-rpm" }, - { 10, TEST_VBLANK | TEST_MODESET | TEST_RPM | TEST_TS_CONT, "vblank-vs-modeset-rpm" }, - { 0, TEST_VBLANK | TEST_DPMS | TEST_SUSPEND | TEST_TS_CONT, "vblank-vs-dpms-suspend" }, - { 0, TEST_VBLANK | TEST_MODESET | TEST_SUSPEND | TEST_TS_CONT, "vblank-vs-modeset-suspend" }, - { 0, TEST_VBLANK | TEST_SUSPEND | TEST_TS_CONT, "vblank-vs-suspend" }, - { 0, TEST_BO_TOOBIG | TEST_NO_2X_OUTPUT, "bo-too-big" }, - }; - int i; - - igt_subtest_init(argc, argv); - igt_skip_on_simulation(); - - igt_fixture { - drm_fd = drm_open_any_master(); - - igt_enable_connectors(); - - kmstest_set_vt_graphics_mode(); - igt_install_exit_handler(kms_flip_exit_handler); - get_timestamp_format(); - - bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096); - devid = intel_get_drm_devid(drm_fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - } - - igt_subtest("nonblocking-read") - test_nonblocking_read(drm_fd); - - for (i = 0; i < sizeof(tests) / sizeof (tests[0]); i++) { - igt_subtest(tests[i].name) - run_test(tests[i].duration, tests[i].flags); - - if (tests[i].flags & TEST_NO_2X_OUTPUT) - continue; - - /* code doesn't disable all crtcs, so skip rpm tests */ - if (tests[i].flags & TEST_RPM) - continue; - - igt_subtest_f( "2x-%s", tests[i].name) - run_pair(tests[i].duration, tests[i].flags); - } - - igt_fork_signal_helper(); - for (i = 0; i < sizeof(tests) / sizeof (tests[0]); i++) { - /* relative blocking vblank waits that get constantly interrupt - * take forver. So don't do them. */ - if ((tests[i].flags & TEST_VBLANK_BLOCK) && - !(tests[i].flags & TEST_VBLANK_ABSOLUTE)) - continue; - - igt_subtest_f( "%s-interruptible", tests[i].name) - run_test(tests[i].duration, tests[i].flags); - - if (tests[i].flags & TEST_NO_2X_OUTPUT) - continue; - - /* code doesn't disable all crtcs, so skip rpm tests */ - if (tests[i].flags & TEST_RPM) - continue; - - igt_subtest_f( "2x-%s-interruptible", tests[i].name) - run_pair(tests[i].duration, tests[i].flags); - } - igt_stop_signal_helper(); - - /* - * Let drm_fd leak, since it's needed by the dpms restore - * exit_handler and igt_exit() won't return. - */ - - igt_exit(); -} diff --git a/tests/kms_flip_event_leak.c b/tests/kms_flip_event_leak.c deleted file mode 100644 index ea4ce4cf..00000000 --- a/tests/kms_flip_event_leak.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright © 2014 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. - * - */ - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "intel_chipset.h" -#include "intel_batchbuffer.h" -#include "ioctl_wrappers.h" - -typedef struct { - int drm_fd; - igt_display_t display; -} data_t; - -IGT_TEST_DESCRIPTION( - "This test tries to provoke the kernel into leaking a pending page flip " - "event when the fd is closed before the flip has completed. The test " - "itself won't fail even if the kernel leaks the event, but the resulting " - "dmesg WARN will indicate a failure."); - -static bool test(data_t *data, enum pipe pipe, igt_output_t *output) -{ - igt_plane_t *primary; - drmModeModeInfo *mode; - struct igt_fb fb[2]; - int fd, ret; - - /* select the pipe we want to use */ - igt_output_set_pipe(output, pipe); - igt_display_commit(&data->display); - - if (!output->valid) { - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(&data->display); - return false; - } - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - mode = igt_output_get_mode(output); - - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - true, /* tiled */ - 0.0, 0.0, 0.0, &fb[0]); - - igt_plane_set_fb(primary, &fb[0]); - igt_display_commit2(&data->display, COMMIT_LEGACY); - - fd = drm_open_any(); - - ret = drmDropMaster(data->drm_fd); - igt_assert(ret == 0); - - ret = drmSetMaster(fd); - igt_assert(ret == 0); - - igt_create_color_fb(fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - true, /* tiled */ - 0.0, 0.0, 0.0, &fb[1]); - ret = drmModePageFlip(fd, output->config.crtc->crtc_id, - fb[1].fb_id, DRM_MODE_PAGE_FLIP_EVENT, - data); - igt_assert(ret == 0); - - ret = close(fd); - igt_assert(ret == 0); - - ret = drmSetMaster(data->drm_fd); - igt_assert(ret == 0); - - igt_plane_set_fb(primary, NULL); - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(&data->display); - - igt_remove_fb(data->drm_fd, &fb[0]); - - return true; -} - -igt_simple_main -{ - data_t data = {}; - igt_output_t *output; - int valid_tests = 0; - enum pipe pipe; - - igt_skip_on_simulation(); - - data.drm_fd = drm_open_any_master(); - kmstest_set_vt_graphics_mode(); - - igt_display_init(&data.display, data.drm_fd); - - for_each_pipe(&data.display, pipe) { - for_each_connected_output(&data.display, output) { - if (test(&data, pipe, output)) - valid_tests++; - } - } - - igt_require_f(valid_tests, "no valid crtc/connector combinations found\n"); - - igt_display_fini(&data.display); -} diff --git a/tests/kms_flip_tiling.c b/tests/kms_flip_tiling.c deleted file mode 100644 index 9bc085b2..00000000 --- a/tests/kms_flip_tiling.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright © 2014 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: - * Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> - */ - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "ioctl_wrappers.h" - -IGT_TEST_DESCRIPTION("Test that a page flip from a tiled buffer to a linear" - " one works correctly."); - -typedef struct { - int drm_fd; - igt_display_t display; -} data_t; - -/* - * Test that a page flip from a tiled buffer to a linear one works - * correctly. First, it sets the crtc with the linear buffer and generate - * a reference crc for the pipe. Then, the crtc is set with the tiled one - * and page flip to the linear one issued. A new crc is generated and - * compared to the rerence one. - */ - -static void -fill_linear_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode) -{ - cairo_t *cr; - - cr = igt_get_cairo_ctx(data->drm_fd, fb); - igt_paint_test_pattern(cr, mode->hdisplay, mode->vdisplay); - cairo_destroy(cr); -} - -static void -test_flip_changes_tiling(data_t *data, igt_output_t *output) -{ - struct igt_fb linear, tiled; - drmModeModeInfo *mode; - igt_plane_t *primary; - igt_pipe_crc_t *pipe_crc; - igt_crc_t reference_crc, crc; - int fb_id, pipe, ret, width; - - pipe = output->config.pipe; - pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); - igt_output_set_pipe(output, pipe); - - mode = igt_output_get_mode(output); - primary = igt_output_get_plane(output, 0); - - /* Allocate a linear buffer. Since a page flip to a buffer with - * different stride doesn't work, choose width so that the stride of - * both buffers is the same. */ - width = 512; - while (width < mode->hdisplay) - width *= 2; - fb_id = igt_create_fb(data->drm_fd, width, mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_NONE, &linear); - - /* fill it with a pattern that will look wrong if tiling is wrong */ - fill_linear_fb(&linear, data, mode); - - /* set the crtc and generate a reference crc */ - igt_plane_set_fb(primary, &linear); - igt_display_commit(&data->display); - igt_pipe_crc_collect_crc(pipe_crc, &reference_crc); - - /* allocate a tiled buffer and set the crtc with it */ - igt_create_color_fb(data->drm_fd, width, mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_X, 0.0, 0.0, 0.0, - &tiled); - igt_plane_set_fb(primary, &tiled); - igt_display_commit(&data->display); - - /* flip to the linear buffer */ - ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id, - fb_id, 0, NULL); - igt_assert(ret == 0); - - igt_wait_for_vblank(data->drm_fd, pipe); - - /* get a crc and compare with the reference */ - igt_pipe_crc_collect_crc(pipe_crc, &crc); - igt_assert(igt_crc_equal(&reference_crc, &crc)); - - /* clean up */ - igt_plane_set_fb(primary, NULL); - igt_pipe_crc_free(pipe_crc); - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(&data->display); - - igt_remove_fb(data->drm_fd, &tiled); - igt_remove_fb(data->drm_fd, &linear); -} - -static data_t data; -igt_output_t *output; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - data.drm_fd = drm_open_any_master(); - - kmstest_set_vt_graphics_mode(); - - igt_require_pipe_crc(); - igt_display_init(&data.display, data.drm_fd); - } - - igt_subtest_f("flip-changes-tiling") { - for_each_connected_output(&data.display, output) - test_flip_changes_tiling(&data, output); - } - - igt_fixture { - igt_display_fini(&data.display); - } -} diff --git a/tests/kms_force_connector.c b/tests/kms_force_connector.c deleted file mode 100644 index 42aaa7f6..00000000 --- a/tests/kms_force_connector.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright © 2014 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. - * - */ - -#include "igt_core.h" -#include "igt_kms.h" -#include "drmtest.h" - -IGT_TEST_DESCRIPTION("Check the debugfs force connector/edid features work" - " correctly."); - -#define CHECK_MODE(m, h, w, r) igt_assert(m.hdisplay == h && m.vdisplay == w \ - && m.vrefresh == r) - -igt_main -{ - /* force the VGA output and test that it worked */ - int drm_fd = 0; - drmModeRes *res; - drmModeConnector *vga_connector = NULL, *temp; - igt_display_t display; - int start_n_modes; - - igt_fixture { - drm_fd = drm_open_any_master(); - res = drmModeGetResources(drm_fd); - - /* find the vga connector */ - for (int i = 0; i < res->count_connectors; i++) { - - vga_connector = drmModeGetConnector(drm_fd, res->connectors[i]); - - if (vga_connector->connector_type == DRM_MODE_CONNECTOR_VGA) - break; - - drmModeFreeConnector(vga_connector); - - vga_connector = NULL; - } - - igt_require(vga_connector); - } - - igt_subtest("force-connector-state") { - /* force the connector on and check the reported values */ - kmstest_force_connector(drm_fd, vga_connector, FORCE_CONNECTOR_ON); - temp = drmModeGetConnector(drm_fd, vga_connector->connector_id); - igt_assert(temp->connection == DRM_MODE_CONNECTED); - igt_assert(temp->count_modes > 0); - drmModeFreeConnector(temp); - - /* attempt to use the display */ - kmstest_set_vt_graphics_mode(); - igt_display_init(&display, drm_fd); - igt_display_commit(&display); - - - /* force the connector off */ - kmstest_force_connector(drm_fd, vga_connector, - FORCE_CONNECTOR_OFF); - temp = drmModeGetConnector(drm_fd, vga_connector->connector_id); - igt_assert(temp->connection == DRM_MODE_DISCONNECTED); - igt_assert(temp->count_modes == 0); - drmModeFreeConnector(temp); - - /* check that the previous state is restored */ - kmstest_force_connector(drm_fd, vga_connector, - FORCE_CONNECTOR_UNSPECIFIED); - temp = drmModeGetConnector(drm_fd, vga_connector->connector_id); - igt_assert(temp->connection == vga_connector->connection); - drmModeFreeConnector(temp); - } - - igt_subtest("force-edid") { - kmstest_force_connector(drm_fd, vga_connector, - FORCE_CONNECTOR_ON); - temp = drmModeGetConnector(drm_fd, vga_connector->connector_id); - start_n_modes = temp->count_modes; - drmModeFreeConnector(temp); - - /* test edid forcing */ - kmstest_force_edid(drm_fd, vga_connector, - igt_kms_get_base_edid(), EDID_LENGTH); - temp = drmModeGetConnector(drm_fd, - vga_connector->connector_id); - - CHECK_MODE(temp->modes[0], 1920, 1080, 60); - CHECK_MODE(temp->modes[1], 1280, 720, 60); - CHECK_MODE(temp->modes[2], 1024, 768, 60); - CHECK_MODE(temp->modes[3], 800, 600, 60); - CHECK_MODE(temp->modes[4], 640, 480, 60); - - drmModeFreeConnector(temp); - - /* remove edid */ - kmstest_force_edid(drm_fd, vga_connector, NULL, 0); - temp = drmModeGetConnector(drm_fd, vga_connector->connector_id); - /* the connector should now have the same number of modes that - * it started with */ - igt_assert(temp->count_modes == start_n_modes); - drmModeFreeConnector(temp); - - kmstest_force_connector(drm_fd, vga_connector, - FORCE_CONNECTOR_UNSPECIFIED); - } - - igt_fixture { - drmModeFreeConnector(vga_connector); - } - - igt_exit(); -} diff --git a/tests/kms_mmio_vs_cs_flip.c b/tests/kms_mmio_vs_cs_flip.c deleted file mode 100644 index 00557aa5..00000000 --- a/tests/kms_mmio_vs_cs_flip.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> -#include <time.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "intel_chipset.h" -#include "ioctl_wrappers.h" - -typedef struct { - int drm_fd; - igt_display_t display; - igt_pipe_crc_t *pipe_crc; - drm_intel_bufmgr *bufmgr; - drm_intel_bo *busy_bo; - uint32_t devid; - bool flip_done; -} data_t; - -static void exec_nop(data_t *data, uint32_t handle, unsigned int ring) -{ - struct intel_batchbuffer *batch; - drm_intel_bo *bo; - - batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(batch); - - bo = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle); - igt_assert(bo); - - /* add relocs to make sure the kernel will think we write to dst */ - BEGIN_BATCH(4, 1); - OUT_BATCH(MI_BATCH_BUFFER_END); - OUT_BATCH(MI_NOOP); - OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(MI_NOOP); - ADVANCE_BATCH(); - - intel_batchbuffer_flush_on_ring(batch, ring); - intel_batchbuffer_free(batch); - - drm_intel_bo_unreference(bo); -} - -static void exec_blt(data_t *data) -{ - struct intel_batchbuffer *batch; - int w, h, pitch, i; - - batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(batch); - - w = 8192; - h = data->busy_bo->size / (8192 * 4); - pitch = w * 4; - - for (i = 0; i < 40; i++) { - BLIT_COPY_BATCH_START(0); - OUT_BATCH((3 << 24) | /* 32 bits */ - (0xcc << 16) | /* copy ROP */ - pitch); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(h << 16 | w); - OUT_RELOC_FENCED(data->busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(0 << 16 | 0); - OUT_BATCH(pitch); - OUT_RELOC_FENCED(data->busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); - ADVANCE_BATCH(); - } - - intel_batchbuffer_flush(batch); - intel_batchbuffer_free(batch); -} - -static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *_data) -{ - data_t *data = _data; - - data->flip_done = true; -} - -static void wait_for_flip(data_t *data, uint32_t flip_handle) -{ - struct timeval timeout = { - .tv_sec = 3, - .tv_usec = 0, - }; - drmEventContext evctx = { - .version = DRM_EVENT_CONTEXT_VERSION, - .page_flip_handler = page_flip_handler, - }; - fd_set fds; - - FD_ZERO(&fds); - FD_SET(data->drm_fd, &fds); - - while (!data->flip_done) { - int ret = select(data->drm_fd + 1, &fds, NULL, NULL, &timeout); - - if (ret < 0 && errno == EINTR) - continue; - - igt_assert(ret >= 0); - - do_or_die(drmHandleEvent(data->drm_fd, &evctx)); - } - - /* - * The flip completion may have been signalled prematurely, so - * also submit another nop batch and wait for it to make sure - * the ring has really been drained. - */ - if (IS_GEN7(data->devid) || IS_GEN8(data->devid)) - exec_nop(data, flip_handle, I915_EXEC_BLT); - else - exec_nop(data, flip_handle, I915_EXEC_RENDER); - gem_sync(data->drm_fd, flip_handle); -} - -static void make_gpu_busy(data_t *data, uint32_t flip_handle) -{ - /* - * Make sure flip_handle has been used on the blt ring. - * This should make the flip use the same ring on gen7+. - */ - if (IS_GEN7(data->devid) || IS_GEN8(data->devid)) - exec_nop(data, flip_handle, I915_EXEC_BLT); - - /* - * Add a pile commands to the ring. The flip will be - * stuck behing these commands and hence gets delayed - * significantly. - */ - exec_blt(data); - - /* - * Make sure the render ring will block until the blt ring is clear. - * This is in case the flip will execute on the render ring and the - * blits were on the blt ring (this will be the case on gen6 at least). - * - * We can't add an explicit dependency between flip_handle and the - * blits since that would cause the driver to block until the blits - * have completed before it will perform a subsequent mmio flip, - * and so the test would fail to exercise the mmio vs. CS flip race. - */ - if (HAS_BLT_RING(data->devid)) - exec_nop(data, data->busy_bo->handle, I915_EXEC_RENDER); -} - -/* - * 1. set primary plane to full red - * 2. grab a reference crc - * 3. set primary plane to full blue - * 4. queue lots of GPU activity to delay the subsequent page flip - * 5. queue a page flip to the same blue fb - * 6. toggle a fullscreen sprite (green) on and back off again - * 7. set primary plane to red fb - * 8. wait for GPU to finish - * 9. compare current crc with reference crc - * - * We expect the primary plane to display full red at the end. - * If the sprite operations have interfered with the page flip, - * the driver may have mistakenly completed the flip before - * it was executed by the CS, and hence the subsequent mmio - * flips may have overtaken it. So once we've finished everything - * the CS flip may have been the last thing to occur, which means - * the primary plane may be full blue instead of the red it's - * supposed to be. - */ -static bool -test_plane(data_t *data, igt_output_t *output, enum pipe pipe, enum igt_plane plane) -{ - struct igt_fb red_fb, green_fb, blue_fb; - drmModeModeInfo *mode; - igt_plane_t *primary, *sprite; - igt_crc_t ref_crc, crc; - int ret; - - igt_output_set_pipe(output, pipe); - igt_display_commit(&data->display); - - if (!output->valid) { - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(&data->display); - return false; - } - - primary = igt_output_get_plane(output, 0); - sprite = igt_output_get_plane(output, plane); - - mode = igt_output_get_mode(output); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - 1.0, 0.0, 0.0, - &red_fb); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - 0.0, 1.0, 0.0, - &green_fb); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - 0.0, 0.0, 1.0, - &blue_fb); - - /* - * Make sure these buffers are suited for display use - * because most of the modeset operations must be fast - * later on. - */ - igt_plane_set_fb(primary, &blue_fb); - igt_display_commit(&data->display); - igt_plane_set_fb(sprite, &green_fb); - igt_display_commit(&data->display); - igt_plane_set_fb(sprite, NULL); - igt_display_commit(&data->display); - - if (data->pipe_crc) - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); - - /* set red fb and grab reference crc */ - igt_plane_set_fb(primary, &red_fb); - igt_display_commit(&data->display); - igt_pipe_crc_collect_crc(data->pipe_crc, &ref_crc); - - ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id, - blue_fb.fb_id, 0, 0, &output->id, 1, - mode); - igt_assert(ret == 0); - - make_gpu_busy(data, blue_fb.gem_handle); - - data->flip_done = false; - ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id, - blue_fb.fb_id, DRM_MODE_PAGE_FLIP_EVENT, data); - igt_assert(ret == 0); - - /* - * Toggle a fullscreen sprite on and back off. This will result - * in the primary plane getting disabled and re-enbled, and that - * leads to mmio flips. The driver may then mistake the flip done - * interrupts from the mmio flips as the flip done interrupts for - * the CS flip, and hence subsequent mmio flips won't wait for the - * CS flips like they should. - */ - ret = drmModeSetPlane(data->drm_fd, - sprite->drm_plane->plane_id, - output->config.crtc->crtc_id, - green_fb.fb_id, 0, - 0, 0, mode->hdisplay, mode->vdisplay, - 0, 0, mode->hdisplay << 16, mode->vdisplay << 16); - igt_assert(ret == 0); - ret = drmModeSetPlane(data->drm_fd, - sprite->drm_plane->plane_id, - output->config.crtc->crtc_id, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0); - igt_assert(ret == 0); - - /* - * Set primary plane to red fb. This should wait for the CS flip - * to complete. But if the kernel mistook the flip done interrupt - * from the mmio flip as the flip done from the CS flip, this will - * not wait for anything. And hence the the CS flip will actually - * occur after this mmio flip. - */ - ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id, - red_fb.fb_id, 0, 0, &output->id, 1, - mode); - igt_assert(ret == 0); - - /* Make sure the flip has been executed */ - wait_for_flip(data, blue_fb.gem_handle); - - /* Grab crc and compare with the extected result */ - igt_pipe_crc_collect_crc(data->pipe_crc, &crc); - - igt_plane_set_fb(primary, NULL); - igt_display_commit(&data->display); - - igt_remove_fb(data->drm_fd, &red_fb); - igt_remove_fb(data->drm_fd, &green_fb); - igt_remove_fb(data->drm_fd, &blue_fb); - - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = NULL; - - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(&data->display); - - igt_assert(igt_crc_equal(&ref_crc, &crc)); - - return true; -} - -/* - * 1. set primary plane to full red - * 2. grab a reference crc - * 3. set primary plane to full green - * 4. wait for vblank - * 5. pan primary plane a bit (to cause a mmio flip w/o vblank wait) - * 6. queue lots of GPU activity to delay the subsequent page flip - * 6. queue a page flip to a blue fb - * 7. set primary plane to red fb - * 8. wait for GPU to finish - * 9. compare current crc with reference crc - * - * We expect the primary plane to display full red at the end. - * If the previously schedule primary plane pan operation has interfered - * with the following page flip, the driver may have mistakenly completed - * the flip before it was executed by the CS, and hence the subsequent mmio - * flips may have overtaken it. So once we've finished everything - * the CS flip may have been the last thing to occur, which means - * the primary plane may be full blue instead of the red it's - * supposed to be. - */ -static bool -test_crtc(data_t *data, igt_output_t *output, enum pipe pipe) -{ - struct igt_fb red_fb, green_fb, blue_fb; - drmModeModeInfo *mode; - igt_plane_t *primary; - igt_crc_t ref_crc, crc; - int ret; - - igt_output_set_pipe(output, pipe); - igt_display_commit(&data->display); - - if (!output->valid) { - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(&data->display); - return false; - } - - primary = igt_output_get_plane(output, 0); - - mode = igt_output_get_mode(output); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - 1.0, 0.0, 0.0, - &red_fb); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - 0.0, 0.0, 1.0, - &blue_fb); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - 0.0, 1.0, 0.0, - &green_fb); - - /* - * Make sure these buffers are suited for display use - * because most of the modeset operations must be fast - * later on. - */ - igt_plane_set_fb(primary, &green_fb); - igt_display_commit(&data->display); - igt_plane_set_fb(primary, &blue_fb); - igt_display_commit(&data->display); - - if (data->pipe_crc) - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); - - /* set red fb and grab reference crc */ - igt_plane_set_fb(primary, &red_fb); - igt_display_commit(&data->display); - igt_pipe_crc_collect_crc(data->pipe_crc, &ref_crc); - - /* - * Further down we need to issue an mmio flip w/o the kernel - * waiting for vblank. The easiest way is to just pan within - * the same FB. So pan away a bit here, and later we undo this - * with another pan which will result in the desired mmio flip. - */ - ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id, - green_fb.fb_id, 0, 1, &output->id, 1, - mode); - igt_assert(ret == 0); - - /* - * Make it more likely that the CS flip has been submitted into the - * ring by the time the mmio flip from the drmModeSetCrtc() below - * completes. The driver will then mistake the flip done interrupt - * from the mmio flip as the flip done interrupt from the CS flip. - */ - igt_wait_for_vblank(data->drm_fd, pipe); - - /* now issue the mmio flip w/o vblank waits in the kernel, ie. pan a bit */ - ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id, - green_fb.fb_id, 0, 0, &output->id, 1, - mode); - igt_assert(ret == 0); - - make_gpu_busy(data, blue_fb.gem_handle); - - /* - * Submit the CS flip. The commands must be emitted into the ring - * before the mmio flip from the panning operation completes. - */ - data->flip_done = false; - ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id, - blue_fb.fb_id, DRM_MODE_PAGE_FLIP_EVENT, data); - igt_assert(ret == 0); - - /* - * Set primary plane to red fb. This should wait for the CS flip - * to complete. But if the kernel mistook the flip done interrupt - * from the mmio flip as the flip done from the CS flip, this will - * not wait for anything. And hence the the CS flip will actually - * occur after this mmio flip. - */ - ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id, - red_fb.fb_id, 0, 0, &output->id, 1, - mode); - igt_assert(ret == 0); - - /* Make sure the flip has been executed */ - wait_for_flip(data, blue_fb.gem_handle); - - /* Grab crc and compare with the extected result */ - igt_pipe_crc_collect_crc(data->pipe_crc, &crc); - - igt_plane_set_fb(primary, NULL); - igt_display_commit(&data->display); - - igt_remove_fb(data->drm_fd, &red_fb); - igt_remove_fb(data->drm_fd, &green_fb); - igt_remove_fb(data->drm_fd, &blue_fb); - - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = NULL; - - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(&data->display); - - igt_assert(igt_crc_equal(&ref_crc, &crc)); - - return true; -} - -static void -run_plane_test(data_t *data) -{ - igt_output_t *output; - enum igt_plane plane = 1; /* testing with one sprite is enough */ - int valid_tests = 0; - enum pipe pipe; - - for_each_connected_output(&data->display, output) { - for_each_pipe(&data->display, pipe) { - igt_require(data->display.pipes[pipe].n_planes > 2); - - if (test_plane(data, output, pipe, plane)) - valid_tests++; - } - } - - igt_require_f(valid_tests, "no valid crtc/connector combinations found\n"); -} - -static void -run_crtc_test(data_t *data) -{ - igt_output_t *output; - int valid_tests = 0; - enum pipe pipe; - - for_each_connected_output(&data->display, output) { - for_each_pipe(&data->display, pipe) { - if (test_crtc(data, output, pipe)) - valid_tests++; - } - } - - igt_require_f(valid_tests, "no valid crtc/connector combinations found\n"); -} - -static data_t data; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - data.drm_fd = drm_open_any_master(); - - kmstest_set_vt_graphics_mode(); - - data.devid = intel_get_drm_devid(data.drm_fd); - - igt_require_pipe_crc(); - igt_display_init(&data.display, data.drm_fd); - - data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096); - igt_assert(data.bufmgr); - drm_intel_bufmgr_gem_enable_reuse(data.bufmgr); - - data.busy_bo = drm_intel_bo_alloc(data.bufmgr, "bo", - 64*1024*1024, 4096); - gem_set_tiling(data.drm_fd, data.busy_bo->handle, 0, 4096); - } - - igt_subtest_f("setplane_vs_cs_flip") - run_plane_test(&data); - - igt_subtest_f("setcrtc_vs_cs_flip") - run_crtc_test(&data); - - igt_fixture { - drm_intel_bo_unreference(data.busy_bo); - drm_intel_bufmgr_destroy(data.bufmgr); - igt_display_fini(&data.display); - } -} diff --git a/tests/kms_pipe_crc_basic.c b/tests/kms_pipe_crc_basic.c deleted file mode 100644 index a658b39d..00000000 --- a/tests/kms_pipe_crc_basic.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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. - * - */ - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_gt.h" -#include "igt_kms.h" -#include "igt_aux.h" -#include "ioctl_wrappers.h" - -typedef struct { - int drm_fd; - igt_display_t display; - struct igt_fb fb; -} data_t; - -static struct { - double r, g, b; - igt_crc_t crc; -} colors[2] = { - { .r = 0.0, .g = 1.0, .b = 0.0 }, - { .r = 0.0, .g = 1.0, .b = 1.0 }, -}; - -static uint64_t submit_batch(int fd, unsigned ring_id) -{ - const uint32_t batch[] = { MI_NOOP, - MI_BATCH_BUFFER_END }; - struct drm_i915_gem_execbuffer2 execbuf; - struct drm_i915_gem_exec_object2 exec; - uint64_t presumed_offset; - - gem_require_ring(fd, ring_id); - - exec.handle = gem_create(fd, 4096); - gem_write(fd, exec.handle, 0, batch, sizeof(batch)); - exec.relocation_count = 0; - exec.relocs_ptr = 0; - exec.alignment = 0; - exec.offset = 0; - exec.flags = 0; - exec.rsvd1 = 0; - exec.rsvd2 = 0; - - execbuf.buffers_ptr = (uintptr_t)&exec; - execbuf.buffer_count = 1; - execbuf.batch_start_offset = 0; - execbuf.batch_len = sizeof(batch); - execbuf.cliprects_ptr = 0; - execbuf.num_cliprects = 0; - execbuf.DR1 = 0; - execbuf.DR4 = 0; - execbuf.flags = ring_id; - i915_execbuffer2_set_context_id(execbuf, 0); - execbuf.rsvd2 = 0; - - gem_execbuf(fd, &execbuf); - gem_sync(fd, exec.handle); - presumed_offset = exec.offset; - - igt_set_stop_rings(igt_to_stop_ring_flag(ring_id)); - - gem_execbuf(fd, &execbuf); - gem_sync(fd, exec.handle); - - igt_assert(igt_get_stop_rings() == STOP_RING_NONE); - igt_assert(presumed_offset == exec.offset); - - gem_close(fd, exec.handle); - - return exec.offset; -} - -static void test_bad_command(data_t *data, const char *cmd) -{ - FILE *ctl; - size_t written; - - ctl = igt_debugfs_fopen("i915_display_crc_ctl", "r+"); - written = fwrite(cmd, 1, strlen(cmd), ctl); - fflush(ctl); - igt_assert_eq(written, strlen(cmd)); - igt_assert(ferror(ctl)); - igt_assert_eq(errno, EINVAL); - - fclose(ctl); -} - -#define N_CRCS 3 - -#define TEST_SEQUENCE (1<<0) - -static int -test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output, - unsigned flags) -{ - igt_display_t *display = &data->display; - igt_plane_t *primary; - drmModeModeInfo *mode; - igt_pipe_crc_t *pipe_crc; - igt_crc_t *crcs = NULL; - int c, j; - - for (c = 0; c < ARRAY_SIZE(colors); c++) { - char *crc_str; - - igt_output_set_pipe(output, pipe); - - igt_debug("Clearing the fb with color (%.02lf,%.02lf,%.02lf)\n", - colors[c].r, colors[c].g, colors[c].b); - - mode = igt_output_get_mode(output); - igt_create_color_fb(data->drm_fd, - mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - colors[c].r, - colors[c].g, - colors[c].b, - &data->fb); - - primary = igt_output_get_plane(output, 0); - igt_plane_set_fb(primary, &data->fb); - - igt_display_commit(display); - - pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); - - igt_pipe_crc_start(pipe_crc); - - /* wait for N_CRCS vblanks and the corresponding N_CRCS CRCs */ - igt_pipe_crc_get_crcs(pipe_crc, N_CRCS, &crcs); - - igt_pipe_crc_stop(pipe_crc); - - /* - * save the CRC in colors so it can be compared to the CRC of - * other fbs - */ - colors[c].crc = crcs[0]; - - crc_str = igt_crc_to_string(&crcs[0]); - igt_debug("CRC for this fb: %s\n", crc_str); - free(crc_str); - - /* - * make sure the CRC of this fb is different from the ones of - * previous fbs - */ - for (j = 0; j < c; j++) - igt_assert(!igt_crc_equal(&colors[j].crc, - &colors[c].crc)); - - /* ensure the CRCs are not all 0s */ - for (j = 0; j < N_CRCS; j++) - igt_assert(!igt_crc_is_null(&crcs[j])); - - /* and ensure that they'are all equal, we haven't changed the fb */ - for (j = 0; j < (N_CRCS - 1); j++) - igt_assert(igt_crc_equal(&crcs[j], &crcs[j + 1])); - - if (flags & TEST_SEQUENCE) - for (j = 0; j < (N_CRCS - 1); j++) - igt_assert(crcs[j].frame + 1 == crcs[j + 1].frame); - - free(crcs); - igt_pipe_crc_free(pipe_crc); - igt_remove_fb(data->drm_fd, &data->fb); - igt_plane_set_fb(primary, NULL); - - igt_output_set_pipe(output, PIPE_ANY); - } - - return 1; -} - -static void test_read_crc(data_t *data, int pipe, unsigned flags) -{ - igt_display_t *display = &data->display; - int valid_connectors = 0; - igt_output_t *output; - - igt_skip_on(pipe >= data->display.n_pipes); - - for_each_connected_output(display, output) { - - igt_info("%s: Testing connector %s using pipe %s\n", - igt_subtest_name(), igt_output_name(output), - kmstest_pipe_name(pipe)); - - valid_connectors += test_read_crc_for_output(data, pipe, output, flags); - } - - igt_require_f(valid_connectors, "No connector found for pipe %i\n", pipe); -} - -data_t data = {0, }; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - data.drm_fd = drm_open_any_master(); - - igt_enable_connectors(); - - kmstest_set_vt_graphics_mode(); - - igt_require_pipe_crc(); - - igt_display_init(&data.display, data.drm_fd); - } - - igt_subtest("bad-pipe") - test_bad_command(&data, "pipe D none"); - - igt_subtest("bad-source") - test_bad_command(&data, "pipe A foo"); - - igt_subtest("bad-nb-words-1") - test_bad_command(&data, "pipe foo"); - - igt_subtest("bad-nb-words-3") - test_bad_command(&data, "pipe A none option"); - - for (int i = 0; i < 3; i++) { - igt_subtest_f("read-crc-pipe-%c", 'A'+i) - test_read_crc(&data, i, 0); - - igt_subtest_f("read-crc-pipe-%c-frame-sequence", 'A'+i) - test_read_crc(&data, i, TEST_SEQUENCE); - - igt_subtest_f("suspend-read-crc-pipe-%c", 'A'+i) { - igt_system_suspend_autoresume(); - - test_read_crc(&data, i, 0); - } - - igt_subtest_f("hang-read-crc-pipe-%c", 'A'+i) { - submit_batch(data.drm_fd, I915_EXEC_RENDER); - - test_read_crc(&data, i, 0); - } - } - - igt_fixture { - igt_display_fini(&data.display); - } -} diff --git a/tests/kms_plane.c b/tests/kms_plane.c deleted file mode 100644 index 8a08f203..00000000 --- a/tests/kms_plane.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright © 2014 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: - * Damien Lespiau <damien.lespiau@intel.com> - */ - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "igt_aux.h" - -typedef struct { - float red; - float green; - float blue; -} color_t; - -typedef struct { - int drm_fd; - igt_display_t display; - igt_pipe_crc_t *pipe_crc; -} data_t; - -static color_t red = { 1.0f, 0.0f, 0.0f }; -static color_t green = { 0.0f, 1.0f, 0.0f }; -static color_t blue = { 0.0f, 0.0f, 1.0f }; - -/* - * Common code across all tests, acting on data_t - */ -static void test_init(data_t *data, enum pipe pipe) -{ - data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); -} - -static void test_fini(data_t *data) -{ - igt_pipe_crc_free(data->pipe_crc); -} - -static void -test_grab_crc(data_t *data, igt_output_t *output, enum pipe pipe, - color_t *fb_color, igt_crc_t *crc /* out */) -{ - struct igt_fb fb; - drmModeModeInfo *mode; - igt_plane_t *primary; - char *crc_str; - - igt_output_set_pipe(output, pipe); - - primary = igt_output_get_plane(output, 0); - - mode = igt_output_get_mode(output); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - fb_color->red, fb_color->green, fb_color->blue, - &fb); - igt_plane_set_fb(primary, &fb); - - igt_display_commit(&data->display); - - igt_pipe_crc_collect_crc(data->pipe_crc, crc); - - igt_plane_set_fb(primary, NULL); - igt_display_commit(&data->display); - - igt_remove_fb(data->drm_fd, &fb); - - crc_str = igt_crc_to_string(crc); - igt_debug("CRC for a (%.02f,%.02f,%.02f) fb: %s\n", fb_color->red, - fb_color->green, fb_color->blue, crc_str); - free(crc_str); -} - -/* - * Plane position test. - * - We start by grabbing a reference CRC of a full green fb being scanned - * out on the primary plane - * - Then we scannout 2 planes: - * - the primary plane uses a green fb with a black rectangle - * - a plane, on top of the primary plane, with a green fb that is set-up - * to cover the black rectangle of the primary plane fb - * The resulting CRC should be identical to the reference CRC - */ - -typedef struct { - data_t *data; - igt_crc_t reference_crc; -} test_position_t; - -/* - * create a green fb with a black rectangle at (rect_x,rect_y) and of size - * (rect_w,rect_h) - */ -static void -create_fb_for_mode__position(data_t *data, drmModeModeInfo *mode, - double rect_x, double rect_y, - double rect_w, double rect_h, - struct igt_fb *fb /* out */) -{ - unsigned int fb_id; - cairo_t *cr; - - fb_id = igt_create_fb(data->drm_fd, - mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - fb); - igt_assert(fb_id); - - cr = igt_get_cairo_ctx(data->drm_fd, fb); - igt_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay, - 0.0, 1.0, 0.0); - igt_paint_color(cr, rect_x, rect_y, rect_w, rect_h, 0.0, 0.0, 0.0); - igt_assert(cairo_status(cr) == 0); - cairo_destroy(cr); -} - -enum { - TEST_POSITION_FULLY_COVERED = 1 << 0, -}; - -static void -test_plane_position_with_output(data_t *data, - enum pipe pipe, - enum igt_plane plane, - igt_output_t *output, - unsigned int flags) -{ - test_position_t test = { .data = data }; - igt_plane_t *primary, *sprite; - struct igt_fb primary_fb, sprite_fb; - drmModeModeInfo *mode; - igt_crc_t crc; - - igt_info("Testing connector %s using pipe %s plane %d\n", - igt_output_name(output), kmstest_pipe_name(pipe), plane); - - test_init(data, pipe); - - test_grab_crc(data, output, pipe, &green, &test.reference_crc); - - igt_output_set_pipe(output, pipe); - - mode = igt_output_get_mode(output); - primary = igt_output_get_plane(output, 0); - sprite = igt_output_get_plane(output, plane); - - create_fb_for_mode__position(data, mode, 100, 100, 64, 64, - &primary_fb); - igt_plane_set_fb(primary, &primary_fb); - - igt_create_color_fb(data->drm_fd, - 64, 64, /* width, height */ - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - 0.0, 1.0, 0.0, - &sprite_fb); - igt_plane_set_fb(sprite, &sprite_fb); - - if (flags & TEST_POSITION_FULLY_COVERED) - igt_plane_set_position(sprite, 100, 100); - else - igt_plane_set_position(sprite, 132, 132); - - igt_display_commit(&data->display); - - igt_pipe_crc_collect_crc(data->pipe_crc, &crc); - - if (flags & TEST_POSITION_FULLY_COVERED) - igt_assert(igt_crc_equal(&test.reference_crc, &crc)); - else - igt_assert(!igt_crc_equal(&test.reference_crc, &crc)); - - igt_plane_set_fb(primary, NULL); - igt_plane_set_fb(sprite, NULL); - - /* reset the constraint on the pipe */ - igt_output_set_pipe(output, PIPE_ANY); - - test_fini(data); -} - -static void -test_plane_position(data_t *data, enum pipe pipe, enum igt_plane plane, - unsigned int flags) -{ - igt_output_t *output; - - igt_skip_on(pipe >= data->display.n_pipes); - igt_skip_on(plane >= data->display.pipes[pipe].n_planes); - - for_each_connected_output(&data->display, output) - test_plane_position_with_output(data, pipe, plane, output, - flags); -} - -/* - * Plane panning test. - * - We start by grabbing reference CRCs of a full red and a full blue fb - * being scanned out on the primary plane - * - Then we create a big fb, sized (2 * hdisplay, 2 * vdisplay) and: - * - fill the top left quarter with red - * - fill the bottom right quarter with blue - * - The TEST_PANNING_TOP_LEFT test makes sure that with panning at (0, 0) - * we do get the same CRC than the full red fb. - * - The TEST_PANNING_BOTTOM_RIGHT test makes sure that with panning at - * (vdisplay, hdisplay) we do get the same CRC than the full blue fb. - */ -typedef struct { - data_t *data; - igt_crc_t red_crc, blue_crc; -} test_panning_t; - -static void -create_fb_for_mode__panning(data_t *data, drmModeModeInfo *mode, - struct igt_fb *fb /* out */) -{ - unsigned int fb_id; - cairo_t *cr; - - fb_id = igt_create_fb(data->drm_fd, - mode->hdisplay * 2, mode->vdisplay * 2, - DRM_FORMAT_XRGB8888, - I915_TILING_NONE, - fb); - igt_assert(fb_id); - - cr = igt_get_cairo_ctx(data->drm_fd, fb); - - igt_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay, - 1.0, 0.0, 0.0); - - igt_paint_color(cr, - mode->hdisplay, mode->vdisplay, - mode->hdisplay, mode->vdisplay, - 0.0, 0.0, 1.0); - - igt_assert(cairo_status(cr) == 0); - cairo_destroy(cr); -} - -enum { - TEST_PANNING_TOP_LEFT = 1 << 0, - TEST_PANNING_BOTTOM_RIGHT = 1 << 1, - TEST_SUSPEND_RESUME = 1 << 2, -}; - -static void -test_plane_panning_with_output(data_t *data, - enum pipe pipe, - enum igt_plane plane, - igt_output_t *output, - unsigned int flags) -{ - test_panning_t test = { .data = data }; - igt_plane_t *primary; - struct igt_fb primary_fb; - drmModeModeInfo *mode; - igt_crc_t crc; - - igt_info("Testing connector %s using pipe %s plane %d\n", - igt_output_name(output), kmstest_pipe_name(pipe), plane); - - test_init(data, pipe); - - test_grab_crc(data, output, pipe, &red, &test.red_crc); - test_grab_crc(data, output, pipe, &blue, &test.blue_crc); - - igt_output_set_pipe(output, pipe); - - mode = igt_output_get_mode(output); - primary = igt_output_get_plane(output, 0); - - create_fb_for_mode__panning(data, mode, &primary_fb); - igt_plane_set_fb(primary, &primary_fb); - - if (flags & TEST_PANNING_TOP_LEFT) - igt_plane_set_panning(primary, 0, 0); - else - igt_plane_set_panning(primary, mode->hdisplay, mode->vdisplay); - - igt_plane_set_position(primary, 0, 0); - - igt_display_commit(&data->display); - - if (flags & TEST_SUSPEND_RESUME) - igt_system_suspend_autoresume(); - - igt_pipe_crc_collect_crc(data->pipe_crc, &crc); - - igt_debug_wait_for_keypress("crc"); - - if (flags & TEST_PANNING_TOP_LEFT) - igt_assert(igt_crc_equal(&test.red_crc, &crc)); - else - igt_assert(igt_crc_equal(&test.blue_crc, &crc)); - - igt_plane_set_fb(primary, NULL); - - /* reset states to neutral values, assumed by other tests */ - igt_output_set_pipe(output, PIPE_ANY); - igt_plane_set_panning(primary, 0, 0); - - test_fini(data); -} - -static void -test_plane_panning(data_t *data, enum pipe pipe, enum igt_plane plane, - unsigned int flags) -{ - igt_output_t *output; - - igt_skip_on(pipe >= data->display.n_pipes); - igt_skip_on(plane >= data->display.pipes[pipe].n_planes); - - for_each_connected_output(&data->display, output) - test_plane_panning_with_output(data, pipe, plane, output, - flags); -} - -static void -run_tests_for_pipe_plane(data_t *data, enum pipe pipe, enum igt_plane plane) -{ - igt_subtest_f("plane-position-covered-pipe-%s-plane-%d", - kmstest_pipe_name(pipe), plane) - test_plane_position(data, pipe, plane, - TEST_POSITION_FULLY_COVERED); - - igt_subtest_f("plane-position-hole-pipe-%s-plane-%d", - kmstest_pipe_name(pipe), plane) - test_plane_position(data, pipe, plane, 0); - - igt_subtest_f("plane-panning-top-left-pipe-%s-plane-%d", - kmstest_pipe_name(pipe), plane) - test_plane_panning(data, pipe, plane, TEST_PANNING_TOP_LEFT); - - igt_subtest_f("plane-panning-bottom-right-pipe-%s-plane-%d", - kmstest_pipe_name(pipe), plane) - test_plane_panning(data, pipe, plane, - TEST_PANNING_BOTTOM_RIGHT); - - igt_subtest_f("plane-panning-bottom-right-suspend-pipe-%s-plane-%d", - kmstest_pipe_name(pipe), plane) - test_plane_panning(data, pipe, plane, - TEST_PANNING_BOTTOM_RIGHT | - TEST_SUSPEND_RESUME); -} - -static void -run_tests_for_pipe(data_t *data, enum pipe pipe) -{ - int plane; - - for (plane = 1; plane < IGT_MAX_PLANES; plane++) - run_tests_for_pipe_plane(data, pipe, plane); -} - -static data_t data; - -igt_main -{ - - igt_skip_on_simulation(); - - igt_fixture { - data.drm_fd = drm_open_any_master(); - - kmstest_set_vt_graphics_mode(); - - igt_require_pipe_crc(); - igt_display_init(&data.display, data.drm_fd); - } - - for (int pipe = 0; pipe < I915_MAX_PIPES; pipe++) - run_tests_for_pipe(&data, pipe); - - igt_fixture { - igt_display_fini(&data.display); - } -} diff --git a/tests/kms_psr_sink_crc.c b/tests/kms_psr_sink_crc.c deleted file mode 100644 index 92566405..00000000 --- a/tests/kms_psr_sink_crc.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * 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. - * - */ - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "igt_aux.h" - -bool running_with_psr_disabled; - -#define CRC_BLACK "000000000000" - -enum planes { - PRIMARY, - SPRITE, - CURSOR, -}; - -enum operations { - PAGE_FLIP, - MMAP_GTT, - MMAP_GTT_WAITING, - MMAP_CPU, - BLT, - RENDER, - PLANE_MOVE, - PLANE_ONOFF, -}; - -static const char *op_str(enum operations op) -{ - static const char * const name[] = { - [PAGE_FLIP] = "page_flip", - [MMAP_GTT] = "mmap_gtt", - [MMAP_GTT_WAITING] = "mmap_gtt_waiting", - [MMAP_CPU] = "mmap_cpu", - [BLT] = "blt", - [RENDER] = "render", - [PLANE_MOVE] = "plane_move", - [PLANE_ONOFF] = "plane_onoff", - }; - - return name[op]; -} - -typedef struct { - int drm_fd; - enum planes test_plane; - enum operations op; - uint32_t devid; - uint32_t crtc_id; - igt_display_t display; - drm_intel_bufmgr *bufmgr; - struct igt_fb fb_green, fb_white; - igt_plane_t *primary, *sprite, *cursor; -} data_t; - -static void create_cursor_fb(data_t *data) -{ - cairo_t *cr; - uint32_t fb_id; - - fb_id = igt_create_fb(data->drm_fd, 64, 64, - DRM_FORMAT_ARGB8888, I915_TILING_NONE, - &data->fb_white); - igt_assert(fb_id); - - cr = igt_get_cairo_ctx(data->drm_fd, &data->fb_white); - igt_paint_color_alpha(cr, 0, 0, 64, 64, 1.0, 1.0, 1.0, 1.0); - igt_assert(cairo_status(cr) == 0); -} - -static void display_init(data_t *data) -{ - igt_display_init(&data->display, data->drm_fd); -} - -static void display_fini(data_t *data) -{ - igt_display_fini(&data->display); -} - -static void fill_blt(data_t *data, uint32_t handle, unsigned char color) -{ - drm_intel_bo *dst = gem_handle_to_libdrm_bo(data->bufmgr, - data->drm_fd, - "", handle); - struct intel_batchbuffer *batch; - - batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(batch); - - COLOR_BLIT_COPY_BATCH_START(0); - OUT_BATCH((1 << 24) | (0xf0 << 16) | 0); - OUT_BATCH(0); - OUT_BATCH(1 << 16 | 4); - OUT_RELOC(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(color); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); - intel_batchbuffer_free(batch); - - gem_bo_busy(data->drm_fd, handle); -} - -static void scratch_buf_init(struct igt_buf *buf, drm_intel_bo *bo) -{ - buf->bo = bo; - buf->stride = 4096; - buf->tiling = I915_TILING_X; - buf->size = 4096; -} - -static void fill_render(data_t *data, uint32_t handle, unsigned char color) -{ - drm_intel_bo *src, *dst; - struct intel_batchbuffer *batch; - struct igt_buf src_buf, dst_buf; - const uint8_t buf[4] = { color, color, color, color }; - igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(data->devid); - - igt_skip_on(!rendercopy); - - dst = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle); - igt_assert(dst); - - src = drm_intel_bo_alloc(data->bufmgr, "", 4096, 4096); - igt_assert(src); - - gem_write(data->drm_fd, src->handle, 0, buf, 4); - - scratch_buf_init(&src_buf, src); - scratch_buf_init(&dst_buf, dst); - - batch = intel_batchbuffer_alloc(data->bufmgr, data->devid); - igt_assert(batch); - - rendercopy(batch, NULL, - &src_buf, 0, 0, 1, 1, - &dst_buf, 0, 0); - - intel_batchbuffer_free(batch); - - gem_bo_busy(data->drm_fd, handle); -} - -static bool psr_enabled(data_t *data) -{ - int ret; - FILE *file; - char str[4]; - - if (running_with_psr_disabled) - return true; - - file = igt_debugfs_fopen("i915_edp_psr_status", "r"); - igt_require(file); - - ret = fscanf(file, "Sink_Support: %s\n", str); - igt_assert(ret != 0); - ret = fscanf(file, "Source_OK: %s\n", str); - igt_assert(ret != 0); - ret = fscanf(file, "Enabled: %s\n", str); - igt_assert(ret != 0); - - fclose(file); - return strcmp(str, "yes") == 0; -} - -static bool psr_active(data_t *data) -{ - int ret; - FILE *file; - char str[4]; - - if (running_with_psr_disabled) - return true; - - file = igt_debugfs_fopen("i915_edp_psr_status", "r"); - igt_require(file); - - ret = fscanf(file, "Sink_Support: %s\n", str); - igt_assert(ret != 0); - ret = fscanf(file, "Source_OK: %s\n", str); - igt_assert(ret != 0); - ret = fscanf(file, "Enabled: %s\n", str); - igt_assert(ret != 0); - ret = fscanf(file, "Active: %s\n", str); - igt_assert(ret != 0); - ret = fscanf(file, "Busy frontbuffer bits: %s\n", str); - igt_assert(ret != 0); - ret = fscanf(file, "Re-enable work scheduled: %s\n", str); - igt_assert(ret != 0); - ret = fscanf(file, "HW Enabled & Active bit: %s\n", str); - igt_assert(ret != 0); - - fclose(file); - return strcmp(str, "yes") == 0; -} - -static bool wait_psr_entry(data_t *data, int timeout) -{ - while (timeout--) { - if (psr_active(data)) - return true; - sleep(1); - } - return false; -} - -static void get_sink_crc(data_t *data, char *crc) { - int ret; - FILE *file; - - file = igt_debugfs_fopen("i915_sink_crc_eDP1", "r"); - igt_require(file); - - ret = fscanf(file, "%s\n", crc); - igt_require(ret > 0); - - fclose(file); - - igt_debug("%s\n", crc); - igt_debug_wait_for_keypress("crc"); - - /* The important value was already taken. - * Now give a time for human eyes - */ - usleep(300000); - - /* Black screen is always invalid */ - igt_assert(strcmp(crc, CRC_BLACK) != 0); -} - -static bool is_green(char *crc) -{ - char color_mask[5] = "FFFF\0"; - char rs[5], gs[5], bs[5]; - unsigned int rh, gh, bh, mask; - int ret; - - sscanf(color_mask, "%4x", &mask); - - memcpy(rs, &crc[0], 4); - rs[4] = '\0'; - ret = sscanf(rs, "%4x", &rh); - igt_require(ret > 0); - - memcpy(gs, &crc[4], 4); - gs[4] = '\0'; - ret = sscanf(gs, "%4x", &gh); - igt_require(ret > 0); - - memcpy(bs, &crc[8], 4); - bs[4] = '\0'; - ret = sscanf(bs, "%4x", &bh); - igt_require(ret > 0); - - return ((rh & mask) == 0 && - (gh & mask) != 0 && - (bh & mask) == 0); -} - -static void test_crc(data_t *data) -{ - uint32_t handle = data->fb_white.gem_handle; - igt_plane_t *test_plane; - void *ptr; - char ref_crc[12]; - char crc[12]; - - igt_plane_set_fb(data->primary, &data->fb_green); - igt_display_commit(&data->display); - - /* Confirm that screen became Green */ - get_sink_crc(data, ref_crc); - igt_assert(is_green(ref_crc)); - - /* Confirm screen stays Green after PSR got active */ - igt_assert(wait_psr_entry(data, 10)); - get_sink_crc(data, ref_crc); - igt_assert(is_green(ref_crc)); - - /* Setting a secondary fb/plane */ - switch (data->test_plane) { - case PRIMARY: default: test_plane = data->primary; break; - case SPRITE: test_plane = data->sprite; break; - case CURSOR: test_plane = data->cursor; break; - } - igt_plane_set_fb(test_plane, &data->fb_white); - igt_display_commit(&data->display); - - /* Confirm it is not Green anymore */ - igt_assert(wait_psr_entry(data, 10)); - get_sink_crc(data, ref_crc); - igt_assert(!is_green(ref_crc)); - - switch (data->op) { - case PAGE_FLIP: - /* Only in use when testing primary plane */ - igt_assert(drmModePageFlip(data->drm_fd, data->crtc_id, - data->fb_green.fb_id, 0, NULL) == 0); - get_sink_crc(data, crc); - igt_assert(is_green(crc)); - break; - case MMAP_GTT: - ptr = gem_mmap__gtt(data->drm_fd, handle, 4096, PROT_WRITE); - gem_set_domain(data->drm_fd, handle, - I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - memset(ptr, 0, 4); - munmap(ptr, 4096); - break; - case MMAP_GTT_WAITING: - ptr = gem_mmap__gtt(data->drm_fd, handle, 4096, PROT_WRITE); - gem_set_domain(data->drm_fd, handle, - I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); - - /* Printing white on white so the screen shouldn't change */ - memset(ptr, 0xff, 4); - get_sink_crc(data, crc); - igt_assert(strcmp(ref_crc, crc) == 0); - - igt_info("Waiting 10s...\n"); - sleep(10); - - /* Now lets print black to change the screen */ - memset(ptr, 0, 4); - munmap(ptr, 4096); - break; - case MMAP_CPU: - ptr = gem_mmap__cpu(data->drm_fd, handle, 0, 4096, PROT_WRITE); - gem_set_domain(data->drm_fd, handle, - I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); - memset(ptr, 0, 4); - munmap(ptr, 4096); - gem_sw_finish(data->drm_fd, handle); - break; - case BLT: - fill_blt(data, handle, 0); - break; - case RENDER: - fill_render(data, handle, 0); - break; - case PLANE_MOVE: - /* Only in use when testing Sprite and Cursor */ - igt_plane_set_position(test_plane, 1, 1); - igt_display_commit(&data->display); - break; - case PLANE_ONOFF: - /* Only in use when testing Sprite and Cursor */ - igt_plane_set_fb(test_plane, NULL); - igt_display_commit(&data->display); - break; - } - get_sink_crc(data, crc); - igt_assert(strcmp(ref_crc, crc) != 0); -} - -static void test_cleanup(data_t *data) { - igt_plane_set_fb(data->primary, NULL); - if (data->test_plane == SPRITE) - igt_plane_set_fb(data->sprite, NULL); - if (data->test_plane == CURSOR) - igt_plane_set_fb(data->cursor, NULL); - - igt_display_commit(&data->display); - - igt_remove_fb(data->drm_fd, &data->fb_green); - igt_remove_fb(data->drm_fd, &data->fb_white); -} - -static void run_test(data_t *data) -{ - igt_display_t *display = &data->display; - igt_output_t *output; - drmModeModeInfo *mode; - uint32_t white_h, white_v; - - for_each_connected_output(display, output) { - drmModeConnectorPtr c = output->config.connector; - - if (c->connector_type != DRM_MODE_CONNECTOR_eDP || - c->connection != DRM_MODE_CONNECTED) - continue; - - igt_output_set_pipe(output, PIPE_ANY); - data->crtc_id = output->config.crtc->crtc_id; - - mode = igt_output_get_mode(output); - - igt_create_color_fb(data->drm_fd, - mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_X, - 0.0, 1.0, 0.0, - &data->fb_green); - - data->primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - igt_plane_set_fb(data->primary, NULL); - - white_h = mode->hdisplay; - white_v = mode->vdisplay; - - switch (data->test_plane) { - case SPRITE: - data->sprite = igt_output_get_plane(output, - IGT_PLANE_2); - igt_plane_set_fb(data->sprite, NULL); - /* To make it different for human eyes let's make - * sprite visible in only one quarter of the primary - */ - white_h = white_h/2; - white_v = white_v/2; - case PRIMARY: - igt_create_color_fb(data->drm_fd, - white_h, white_v, - DRM_FORMAT_XRGB8888, I915_TILING_X, - 1.0, 1.0, 1.0, - &data->fb_white); - break; - case CURSOR: - data->cursor = igt_output_get_plane(output, - IGT_PLANE_CURSOR); - igt_plane_set_fb(data->cursor, NULL); - create_cursor_fb(data); - igt_plane_set_position(data->cursor, 0, 0); - break; - } - - igt_display_commit(&data->display); - - test_crc(data); - - test_cleanup(data); - } -} - -static int opt_handler(int opt, int opt_index) -{ - switch (opt) { - case 'n': - running_with_psr_disabled = true; - break; - default: - igt_assert(0); - } - - return 0; -} - -int main(int argc, char *argv[]) -{ - const char *help_str = - " --no-psr\tRun test without PSR to check the CRC test logic."; - static struct option long_options[] = { - {"no-psr", 0, 0, 'n'}, - { 0, 0, 0, 0 } - }; - data_t data = {}; - enum operations op; - - igt_subtest_init_parse_opts(&argc, argv, "", long_options, - help_str, opt_handler); - igt_skip_on_simulation(); - - igt_fixture { - data.drm_fd = drm_open_any_master(); - kmstest_set_vt_graphics_mode(); - data.devid = intel_get_drm_devid(data.drm_fd); - - igt_skip_on(!psr_enabled(&data)); - - data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096); - igt_assert(data.bufmgr); - drm_intel_bufmgr_gem_enable_reuse(data.bufmgr); - - display_init(&data); - } - - for (op = PAGE_FLIP; op <= RENDER; op++) { - igt_subtest_f("primary_%s", op_str(op)) { - data.test_plane = PRIMARY; - data.op = op; - run_test(&data); - } - } - - for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) { - igt_subtest_f("sprite_%s", op_str(op)) { - data.test_plane = SPRITE; - data.op = op; - run_test(&data); - } - } - - for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) { - igt_subtest_f("cursor_%s", op_str(op)) { - data.test_plane = CURSOR; - data.op = op; - run_test(&data); - } - } - - igt_fixture { - drm_intel_bufmgr_destroy(data.bufmgr); - display_fini(&data); - } - - igt_exit(); -} diff --git a/tests/kms_pwrite_crc.c b/tests/kms_pwrite_crc.c deleted file mode 100644 index aa1d3a30..00000000 --- a/tests/kms_pwrite_crc.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright © 2014 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. - * - */ - -#include <errno.h> -#include <limits.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "intel_chipset.h" -#include "ioctl_wrappers.h" -#include "igt_aux.h" - -IGT_TEST_DESCRIPTION( - "Use the display CRC support to validate pwrite to an already uncached future scanout buffer."); - -typedef struct { - int drm_fd; - igt_display_t display; - struct igt_fb fb[2]; - igt_output_t *output; - igt_plane_t *primary; - enum pipe pipe; - igt_crc_t ref_crc; - igt_pipe_crc_t *pipe_crc; - uint32_t devid; -} data_t; - -static void test(data_t *data) -{ - igt_display_t *display = &data->display; - igt_output_t *output = data->output; - struct igt_fb *fb = &data->fb[1]; - drmModeModeInfo *mode; - cairo_t *cr; - uint32_t caching; - void *buf; - igt_crc_t crc; - - mode = igt_output_get_mode(output); - - /* create a non-white fb where we can pwrite later */ - igt_create_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_NONE, fb); - - cr = igt_get_cairo_ctx(data->drm_fd, fb); - igt_paint_test_pattern(cr, fb->width, fb->height); - cairo_destroy(cr); - - /* flip to it to make it UC/WC and fully flushed */ - igt_plane_set_fb(data->primary, fb); - igt_display_commit(display); - - /* sanity check to make sure crc changed */ - igt_pipe_crc_collect_crc(data->pipe_crc, &crc); - igt_assert(!igt_crc_equal(&crc, &data->ref_crc)); - - /* flip back the original white buffer */ - igt_plane_set_fb(data->primary, &data->fb[0]); - igt_display_commit(display); - - /* make sure caching mode has become UC/WT */ - caching = gem_get_caching(data->drm_fd, fb->gem_handle); - igt_assert(caching == I915_CACHING_NONE || caching == I915_CACHING_DISPLAY); - - /* use pwrite to make the other fb all white too */ - buf = malloc(fb->size); - igt_assert(buf != NULL); - memset(buf, 0xff, fb->size); - gem_write(data->drm_fd, fb->gem_handle, 0, buf, fb->size); - free(buf); - - /* and flip to it */ - igt_plane_set_fb(data->primary, fb); - igt_display_commit(display); - - /* check that the crc is as expected, which requires that caches got flushed */ - igt_pipe_crc_collect_crc(data->pipe_crc, &crc); - igt_assert(igt_crc_equal(&crc, &data->ref_crc)); -} - -static bool prepare_crtc(data_t *data) -{ - igt_display_t *display = &data->display; - igt_output_t *output = data->output; - drmModeModeInfo *mode; - - /* select the pipe we want to use */ - igt_output_set_pipe(output, data->pipe); - igt_display_commit(display); - - if (!output->valid) { - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(display); - return false; - } - - mode = igt_output_get_mode(output); - - /* create a white reference fb and flip to it */ - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_NONE, - 1.0, 1.0, 1.0, &data->fb[0]); - - data->primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - - igt_plane_set_fb(data->primary, &data->fb[0]); - igt_display_commit(display); - - if (data->pipe_crc) - igt_pipe_crc_free(data->pipe_crc); - - data->pipe_crc = igt_pipe_crc_new(data->pipe, - INTEL_PIPE_CRC_SOURCE_AUTO); - - /* get reference crc for the white fb */ - igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc); - - return true; -} - -static void cleanup_crtc(data_t *data) -{ - igt_display_t *display = &data->display; - igt_output_t *output = data->output; - - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = NULL; - - igt_plane_set_fb(data->primary, NULL); - - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit(display); - - igt_remove_fb(data->drm_fd, &data->fb[0]); - igt_remove_fb(data->drm_fd, &data->fb[1]); - -} - -static void run_test(data_t *data) -{ - igt_display_t *display = &data->display; - igt_output_t *output; - enum pipe pipe; - - for_each_connected_output(display, output) { - data->output = output; - for_each_pipe(display, pipe) { - data->pipe = pipe; - - if (!prepare_crtc(data)) - continue; - - test(data); - cleanup_crtc(data); - - /* once is enough */ - return; - } - } - - igt_skip("no valid crtc/connector combinations found\n"); -} - -static data_t data; - -igt_simple_main -{ - igt_skip_on_simulation(); - - igt_fixture { - data.drm_fd = drm_open_any_master(); - - data.devid = intel_get_drm_devid(data.drm_fd); - - kmstest_set_vt_graphics_mode(); - - igt_require_pipe_crc(); - - igt_display_init(&data.display, data.drm_fd); - } - - run_test(&data); - - igt_fixture { - igt_display_fini(&data.display); - } -} diff --git a/tests/kms_render.c b/tests/kms_render.c deleted file mode 100644 index a3487dd8..00000000 --- a/tests/kms_render.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * 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 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: - * Imre Deak <imre.deak@intel.com> - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <cairo.h> -#include <errno.h> -#include <stdint.h> -#include <unistd.h> -#include <sys/time.h> - -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "igt_kms.h" -#include "ioctl_wrappers.h" - -drmModeRes *resources; -int drm_fd; -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -uint32_t devid; - -enum test_flags { - TEST_DIRECT_RENDER = 0x01, - TEST_GPU_BLIT = 0x02, -}; - -static int paint_fb(struct igt_fb *fb, const char *test_name, - const char *mode_format_str, const char *cconf_str) -{ - cairo_t *cr; - - cr = igt_get_cairo_ctx(drm_fd, fb); - - igt_paint_color_gradient(cr, 0, 0, fb->width, fb->height, 1, 1, 1); - igt_paint_test_pattern(cr, fb->width, fb->height); - - cairo_move_to(cr, fb->width / 2, fb->height / 2); - cairo_set_font_size(cr, 36); - igt_cairo_printf_line(cr, align_hcenter, 10, "%s", test_name); - igt_cairo_printf_line(cr, align_hcenter, 10, "%s", mode_format_str); - igt_cairo_printf_line(cr, align_hcenter, 10, "%s", cconf_str); - - cairo_destroy(cr); - - return 0; -} - -static void gpu_blit(struct igt_fb *dst_fb, struct igt_fb *src_fb) -{ - drm_intel_bo *dst_bo; - drm_intel_bo *src_bo; - int bpp; - - igt_assert(dst_fb->drm_format == src_fb->drm_format); - igt_assert(src_fb->drm_format == DRM_FORMAT_RGB565 || - igt_drm_format_to_bpp(src_fb->drm_format) != 16); - bpp = igt_drm_format_to_bpp(src_fb->drm_format); - dst_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "destination", - dst_fb->gem_handle); - igt_assert(dst_bo); - src_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "source", - src_fb->gem_handle); - igt_assert(src_bo); - - intel_blt_copy(batch, - src_bo, 0, 0, src_fb->width * bpp / 8, - dst_bo, 0, 0, dst_fb->width * bpp / 8, - src_fb->width, src_fb->height, bpp); - intel_batchbuffer_flush(batch); - gem_quiescent_gpu(drm_fd); - - drm_intel_bo_unreference(src_bo); - drm_intel_bo_unreference(dst_bo); -} - -static int test_format(const char *test_name, - struct kmstest_connector_config *cconf, - drmModeModeInfo *mode, uint32_t format, - enum test_flags flags) -{ - int width; - int height; - struct igt_fb fb[2]; - char *mode_format_str; - char *cconf_str; - int ret; - - ret = asprintf(&mode_format_str, "%s @ %dHz / %s", - mode->name, mode->vrefresh, igt_format_str(format)); - igt_assert(ret > 0); - ret = asprintf(&cconf_str, "pipe %s, encoder %s, connector %s", - kmstest_pipe_name(cconf->pipe), - kmstest_encoder_type_str(cconf->encoder->encoder_type), - kmstest_connector_type_str(cconf->connector->connector_type)); - igt_assert(ret > 0); - - igt_info("Beginning test %s with %s on %s\n", - test_name, mode_format_str, cconf_str); - - width = mode->hdisplay; - height = mode->vdisplay; - - if (!igt_create_fb(drm_fd, width, height, format, I915_TILING_NONE, - &fb[0])) - goto err1; - - if (!igt_create_fb(drm_fd, width, height, format, I915_TILING_NONE, - &fb[1])) - goto err2; - - if (drmModeSetCrtc(drm_fd, cconf->crtc->crtc_id, fb[0].fb_id, - 0, 0, &cconf->connector->connector_id, 1, - mode)) - goto err2; - do_or_die(drmModePageFlip(drm_fd, cconf->crtc->crtc_id, fb[0].fb_id, - 0, NULL)); - sleep(2); - - if (flags & TEST_DIRECT_RENDER) { - paint_fb(&fb[0], test_name, mode_format_str, cconf_str); - } else if (flags & TEST_GPU_BLIT) { - paint_fb(&fb[1], test_name, mode_format_str, cconf_str); - gpu_blit(&fb[0], &fb[1]); - } - sleep(5); - - igt_info("Test %s with %s on %s: PASSED\n", - test_name, mode_format_str, cconf_str); - free(mode_format_str); - free(cconf_str); - - igt_remove_fb(drm_fd, &fb[1]); - igt_remove_fb(drm_fd, &fb[0]); - - return 0; - -err2: - igt_remove_fb(drm_fd, &fb[0]); -err1: - igt_info("Test %s with %s on %s: SKIPPED\n", - test_name, mode_format_str, cconf_str); - free(mode_format_str); - free(cconf_str); - - return -1; -} - -static void test_connector(const char *test_name, - struct kmstest_connector_config *cconf, - enum test_flags flags) -{ - const uint32_t *formats; - int format_count; - int i; - - igt_get_all_formats(&formats, &format_count); - for (i = 0; i < format_count; i++) { - if (intel_gen(intel_get_drm_devid(drm_fd)) < 4 - && formats[i] == DRM_FORMAT_XRGB2101010) { - igt_info("gen2/3 don't support 10bpc, skipping\n"); - continue; - } - - test_format(test_name, - cconf, &cconf->connector->modes[0], - formats[i], flags); - } -} - -static int run_test(const char *test_name, enum test_flags flags) -{ - int i; - - resources = drmModeGetResources(drm_fd); - igt_assert(resources); - - /* Find any connected displays */ - for (i = 0; i < resources->count_connectors; i++) { - uint32_t connector_id; - int j; - - connector_id = resources->connectors[i]; - for (j = 0; j < resources->count_crtcs; j++) { - struct kmstest_connector_config cconf; - - if (!kmstest_get_connector_config(drm_fd, connector_id, - 1 << j, &cconf)) - continue; - - test_connector(test_name, &cconf, flags); - - kmstest_free_connector_config(&cconf); - } - } - - drmModeFreeResources(resources); - - return 1; -} - -igt_main -{ - struct { - enum test_flags flags; - const char *name; - } tests[] = { - { TEST_DIRECT_RENDER, "direct-render" }, - { TEST_GPU_BLIT, "gpu-blit" }, - }; - int i; - - igt_skip_on_simulation(); - - igt_fixture { - drm_fd = drm_open_any_master(); - - bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096); - devid = intel_get_drm_devid(drm_fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - - kmstest_set_vt_graphics_mode(); - } - - for (i = 0; i < ARRAY_SIZE(tests); i++) { - igt_subtest(tests[i].name) - run_test(tests[i].name, tests[i].flags); - } - - igt_fixture - close(drm_fd); -} diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c deleted file mode 100644 index 7f09df31..00000000 --- a/tests/kms_rotation_crc.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright © 2013,2014 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. - * - */ - -#include <math.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" -#include "igt_core.h" - -typedef struct { - int gfx_fd; - igt_display_t display; - struct igt_fb fb; - struct igt_fb fb_cursor; - igt_crc_t ref_crc; - igt_pipe_crc_t *pipe_crc; -} data_t; - -static void -paint_squares(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode, - igt_rotation_t rotation, igt_plane_t *plane) -{ - cairo_t *cr; - int w, h; - - if (plane->is_cursor) { - w = 128; - h = 128; - cr = igt_get_cairo_ctx(data->gfx_fd, &data->fb_cursor); - - if (rotation == IGT_ROTATION_180) { - cairo_translate(cr, w, h); - cairo_rotate(cr, M_PI); - } - - igt_paint_color(cr, 0, 0, w / 2, h / 2, .75, 0.5, 0.5); - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.5, .75, 0.5); - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.5, 0.5, .75); - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, .75, .75, .75); - } else { - w = mode->hdisplay; - h = mode->vdisplay; - - cr = igt_get_cairo_ctx(data->gfx_fd, &data->fb); - - if (rotation == IGT_ROTATION_180) { - cairo_translate(cr, w, h); - cairo_rotate(cr, M_PI); - } - - /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ - igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); - } - cairo_destroy(cr); -} - -static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, - igt_plane_t *plane) -{ - drmModeModeInfo *mode; - igt_display_t *display = &data->display; - int fb_id, fb_cursor_id; - - igt_output_set_pipe(output, pipe); - - /* create the pipe_crc object for this pipe */ - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); - - mode = igt_output_get_mode(output); - - fb_id = igt_create_fb(data->gfx_fd, - mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - &data->fb); - igt_assert(fb_id); - - fb_cursor_id = igt_create_fb(data->gfx_fd, - 128, 128, - DRM_FORMAT_ARGB8888, - false, /* tiled */ - &data->fb_cursor); - igt_assert(fb_cursor_id); - - /* Step 1: create a reference CRC for a software-rotated fb */ - - /* - * XXX: We always set the primary plane to actually enable the pipe as - * there's no way (that works) to light up a pipe with only a sprite - * plane enabled at the moment. - */ - if (!plane->is_primary) { - igt_plane_t *primary; - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - paint_squares(data, &data->fb, mode, IGT_ROTATION_180, primary); - igt_plane_set_fb(primary, &data->fb); - } - - if (plane->is_cursor) { - paint_squares(data, &data->fb_cursor, mode, IGT_ROTATION_180, plane); - igt_plane_set_fb(plane, &data->fb_cursor); - } else { - paint_squares(data, &data->fb, mode, IGT_ROTATION_180, plane); - igt_plane_set_fb(plane, &data->fb); - } - igt_display_commit(display); - igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc); - - /* - * Step 2: prepare the plane with an non-rotated fb let the hw - * rotate it. - */ - if (plane->is_cursor) { - paint_squares(data, &data->fb_cursor, mode, IGT_ROTATION_0, plane); - igt_plane_set_fb(plane, &data->fb_cursor); - } else { - paint_squares(data, &data->fb, mode, IGT_ROTATION_0, plane); - igt_plane_set_fb(plane, &data->fb); - } -} - -static void cleanup_crtc(data_t *data, igt_output_t *output, igt_plane_t *plane) -{ - igt_display_t *display = &data->display; - - igt_pipe_crc_free(data->pipe_crc); - data->pipe_crc = NULL; - - igt_remove_fb(data->gfx_fd, &data->fb); - igt_remove_fb(data->gfx_fd, &data->fb_cursor); - - /* XXX: see the note in prepare_crtc() */ - if (!plane->is_primary) { - igt_plane_t *primary; - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - igt_plane_set_fb(primary, NULL); - } - - igt_plane_set_fb(plane, NULL); - igt_output_set_pipe(output, PIPE_ANY); - - igt_display_commit(display); -} - -static void test_plane_rotation(data_t *data, enum igt_plane plane_type) -{ - igt_display_t *display = &data->display; - igt_output_t *output; - enum pipe pipe; - int valid_tests = 0; - igt_crc_t crc_output, crc_unrotated; - enum igt_commit_style commit = COMMIT_LEGACY; - - if (plane_type == IGT_PLANE_PRIMARY || plane_type == IGT_PLANE_CURSOR) { - igt_require(data->display.has_universal_planes); - commit = COMMIT_UNIVERSAL; - } - - for_each_connected_output(display, output) { - for_each_pipe(display, pipe) { - igt_plane_t *plane; - - igt_output_set_pipe(output, pipe); - - plane = igt_output_get_plane(output, plane_type); - igt_require(igt_plane_supports_rotation(plane)); - - prepare_crtc(data, output, pipe, plane); - - igt_display_commit2(display, commit); - - /* collect unrotated CRC */ - igt_pipe_crc_collect_crc(data->pipe_crc, &crc_unrotated); - - igt_plane_set_rotation(plane, IGT_ROTATION_180); - igt_display_commit2(display, commit); - - igt_pipe_crc_collect_crc(data->pipe_crc, &crc_output); - igt_assert(igt_crc_equal(&data->ref_crc, &crc_output)); - - /* check the rotation state has been reset when the VT - * mode is restored */ - kmstest_restore_vt_mode(); - kmstest_set_vt_graphics_mode(); - prepare_crtc(data, output, pipe, plane); - igt_pipe_crc_collect_crc(data->pipe_crc, &crc_output); - igt_assert(igt_crc_equal(&crc_unrotated, &crc_output)); - - - valid_tests++; - cleanup_crtc(data, output, plane); - } - } - igt_require_f(valid_tests, "no valid crtc/connector combinations found\n"); -} - -igt_main -{ - data_t data = {}; - - igt_skip_on_simulation(); - - igt_fixture { - data.gfx_fd = drm_open_any_master(); - - kmstest_set_vt_graphics_mode(); - - igt_require_pipe_crc(); - - igt_display_init(&data.display, data.gfx_fd); - } - - igt_subtest_f("primary-rotation") - test_plane_rotation(&data, IGT_PLANE_PRIMARY); - - igt_subtest_f("sprite-rotation") - test_plane_rotation(&data, IGT_PLANE_2); - - igt_subtest_f("cursor-rotation") - test_plane_rotation(&data, IGT_PLANE_CURSOR); - - igt_fixture { - igt_display_fini(&data.display); - } -} diff --git a/tests/kms_setmode.c b/tests/kms_setmode.c deleted file mode 100644 index 8e6afbff..00000000 --- a/tests/kms_setmode.c +++ /dev/null @@ -1,739 +0,0 @@ -/* - * 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 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: - * Imre Deak <imre.deak@intel.com> - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <cairo.h> -#include <errno.h> -#include <stdint.h> -#include <unistd.h> -#include <string.h> -#include <sys/time.h> - -#include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "igt_kms.h" - -#define MAX_CONNECTORS 10 -#define MAX_CRTCS 3 - -/* max combinations with repetitions */ -#define MAX_COMBINATION_COUNT \ - (MAX_CONNECTORS * MAX_CONNECTORS * MAX_CONNECTORS) -#define MAX_COMBINATION_ELEMS MAX_CRTCS - -static int drm_fd; -static drmModeRes *drm_resources; -static int filter_test_id; -static bool dry_run; - -const drmModeModeInfo mode_640_480 = { - .name = "640x480", - .vrefresh = 60, - .clock = 25200, - - .hdisplay = 640, - .hsync_start = 656, - .hsync_end = 752, - .htotal = 800, - - .vdisplay = 480, - .vsync_start = 490, - .vsync_end = 492, - .vtotal = 525, - - .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, -}; - -enum test_flags { - TEST_INVALID = 0x01, - TEST_CLONE = 0x02, - TEST_SINGLE_CRTC_CLONE = 0x04, - TEST_EXCLUSIVE_CRTC_CLONE = 0x08, -}; - -struct test_config { - const char *name; - enum test_flags flags; - drmModeRes *resources; -}; - -struct connector_config { - drmModeConnector *connector; - int crtc_idx; - bool connected; - drmModeModeInfo default_mode; -}; - -struct crtc_config { - int crtc_idx; - int crtc_id; - int pipe_id; - int connector_count; - struct connector_config *cconfs; - struct igt_fb fb_info; - drmModeModeInfo mode; -}; - -static bool drm_mode_equal(drmModeModeInfo *m1, drmModeModeInfo *m2) -{ -#define COMP(x) do { if (m1->x != m2->x) return false; } while (0) - COMP(vrefresh); - COMP(clock); - COMP(hdisplay); - COMP(hsync_start); - COMP(hsync_end); - COMP(htotal); - COMP(vdisplay); - COMP(vsync_start); - COMP(vsync_end); - COMP(vtotal); - COMP(flags); - - return true; -} - -static bool connector_supports_mode(drmModeConnector *connector, - drmModeModeInfo *mode) -{ - int i; - - for (i = 0; i < connector->count_modes; i++) - if (drm_mode_equal(&connector->modes[i], mode)) - return true; - - return false; -} - -static bool crtc_supports_mode(struct crtc_config *crtc, drmModeModeInfo *mode) -{ - int i; - - for (i = 0; i < crtc->connector_count; i++) { - if (!connector_supports_mode(crtc->cconfs[i].connector, mode)) - return false; - } - - return true; -} - -static int paint_fb(struct igt_fb *fb, const char *test_name, - const char **crtc_str, int crtc_count, int current_crtc_idx) -{ - double x, y; - cairo_t *cr; - int i; - - cr = igt_get_cairo_ctx(drm_fd, fb); - - igt_paint_test_pattern(cr, fb->width, fb->height); - - cairo_move_to(cr, fb->width / 2, fb->height / 2); - cairo_set_font_size(cr, 24); - igt_cairo_printf_line(cr, align_hcenter, 40, "%s", test_name); - - cairo_get_current_point(cr, &x, &y); - cairo_move_to(cr, 60, y); - - for (i = 0; i < crtc_count; i++) { - if (i == current_crtc_idx) { - cairo_get_current_point(cr, &x, &y); - cairo_move_to(cr, x - 20, y); - igt_cairo_printf_line(cr, align_right, 20, "X"); - cairo_move_to(cr, x, y); - } - igt_cairo_printf_line(cr, align_left, 20, "%s", - crtc_str[i]); - } - - cairo_destroy(cr); - - return 0; -} - -static void create_fb_for_crtc(struct crtc_config *crtc, - struct igt_fb *fb_info) -{ - int bpp; - int depth; - int fb_id; - - bpp = 32; - depth = 24; - fb_id = igt_create_fb(drm_fd, crtc->mode.hdisplay, - crtc->mode.vdisplay, - igt_bpp_depth_to_drm_format(bpp, depth), - I915_TILING_NONE, fb_info); - igt_assert(fb_id > 0); -} - -static void get_mode_for_crtc(struct crtc_config *crtc, - drmModeModeInfo *mode_ret) -{ - drmModeModeInfo mode; - int i; - - /* - * First try to select a default mode that is supported by all - * connectors. - */ - for (i = 0; i < crtc->connector_count; i++) { - mode = crtc->cconfs[i].default_mode; - if (crtc_supports_mode(crtc, &mode)) - goto found; - } - - /* - * Then just fall back to find any that is supported by all - * connectors. - */ - for (i = 0; i < crtc->cconfs[0].connector->count_modes; i++) { - mode = crtc->cconfs[0].connector->modes[i]; - if (crtc_supports_mode(crtc, &mode)) - goto found; - } - - /* - * If none is found then just pick the default mode of the first - * connector and hope the other connectors can support it by scaling - * etc. - */ - mode = crtc->cconfs[0].default_mode; -found: - *mode_ret = mode; -} - -static int get_encoder_idx(drmModeRes *resources, drmModeEncoder *encoder) -{ - int i; - - for (i = 0; i < resources->count_encoders; i++) - if (resources->encoders[i] == encoder->encoder_id) - return i; - igt_assert(0); -} - -static void get_crtc_config_str(struct crtc_config *crtc, char *buf, - size_t buf_size) -{ - int pos; - int i; - - pos = snprintf(buf, buf_size, - "CRTC[%d] [Pipe %s] Mode: %s@%dHz Connectors: ", - crtc->crtc_id, kmstest_pipe_name(crtc->pipe_id), - crtc->mode.name, crtc->mode.vrefresh); - if (pos > buf_size) - return; - for (i = 0; i < crtc->connector_count; i++) { - drmModeConnector *connector = crtc->cconfs[i].connector; - - pos += snprintf(&buf[pos], buf_size - pos, - "%s%s-%d[%d]%s", i ? ", " : "", - kmstest_connector_type_str(connector->connector_type), - connector->connector_type_id, connector->connector_id, - crtc->cconfs[i].connected ? "" : " (NC)"); - if (pos > buf_size) - return; - } -} - -static void setup_crtcs(drmModeRes *resources, struct connector_config *cconf, - int connector_count, struct crtc_config *crtcs, - int *crtc_count_ret, bool *config_valid_ret) -{ - struct crtc_config *crtc; - int crtc_count; - bool config_valid; - int i; - int encoder_usage_count[resources->count_encoders]; - - i = 0; - crtc_count = 0; - crtc = crtcs; - config_valid = true; - - while (i < connector_count) { - drmModeCrtc *drm_crtc; - unsigned long encoder_mask; - int j; - - igt_assert(crtc_count < MAX_CRTCS); - - crtc->crtc_idx = cconf[i].crtc_idx; - drm_crtc = drmModeGetCrtc(drm_fd, - resources->crtcs[crtc->crtc_idx]); - crtc->crtc_id = drm_crtc->crtc_id; - drmModeFreeCrtc(drm_crtc); - crtc->pipe_id = kmstest_get_pipe_from_crtc_id(drm_fd, - crtc->crtc_id); - - crtc->connector_count = 1; - for (j = i + 1; j < connector_count; j++) - if (cconf[j].crtc_idx == crtc->crtc_idx) - crtc->connector_count++; - - crtc->cconfs = malloc(sizeof(*crtc->cconfs) * - crtc->connector_count); - igt_assert(crtc->cconfs); - - encoder_mask = 0; - for (j = 0; j < crtc->connector_count; j++) { - drmModeConnector *connector; - drmModeEncoder *encoder; - - crtc->cconfs[j] = cconf[i + j]; - connector = cconf[i + j].connector; - - /* Intel connectors have only a single encoder */ - igt_assert(connector->count_encoders == 1); - encoder = drmModeGetEncoder(drm_fd, - connector->encoders[0]); - igt_assert(encoder); - - config_valid &= !!(encoder->possible_crtcs & - (1 << crtc->crtc_idx)); - - encoder_mask |= 1 << get_encoder_idx(resources, - encoder); - config_valid &= !(encoder_mask & - ~encoder->possible_clones); - - drmModeFreeEncoder(encoder); - } - get_mode_for_crtc(crtc, &crtc->mode); - create_fb_for_crtc(crtc, &crtc->fb_info); - - i += crtc->connector_count; - crtc_count++; - crtc++; - } - - memset(encoder_usage_count, 0, sizeof(encoder_usage_count)); - for (i = 0; i < connector_count; i++) { - drmModeConnector *connector = cconf[i].connector; - drmModeEncoder *encoder; - - igt_assert(connector->count_encoders == 1); - encoder = drmModeGetEncoder(drm_fd, connector->encoders[0]); - encoder_usage_count[get_encoder_idx(resources, encoder)]++; - drmModeFreeEncoder(encoder); - } - for (i = 0; i < resources->count_encoders; i++) - if (encoder_usage_count[i] > 1) - config_valid = false; - - *crtc_count_ret = crtc_count; - *config_valid_ret = config_valid; -} - -static void cleanup_crtcs(struct crtc_config *crtcs, int crtc_count) -{ - int i; - - for (i = 0; i < crtc_count; i++) { - free(crtcs[i].cconfs); - } -} - -static uint32_t *get_connector_ids(struct crtc_config *crtc) -{ - uint32_t *ids; - int i; - - ids = malloc(sizeof(*ids) * crtc->connector_count); - igt_assert(ids); - for (i = 0; i < crtc->connector_count; i++) - ids[i] = crtc->cconfs[i].connector->connector_id; - - return ids; -} - -static void test_crtc_config(const struct test_config *tconf, - struct crtc_config *crtcs, int crtc_count) -{ - char str_buf[MAX_CRTCS][1024]; - const char *crtc_strs[MAX_CRTCS]; - struct crtc_config *crtc; - static int test_id; - bool config_failed = false; - bool connector_connected = false; - int ret = 0; - int i; - - test_id++; - - if (filter_test_id && filter_test_id != test_id) - return; - - igt_info(" Test id#%d CRTC count %d\n", test_id, crtc_count); - - for (i = 0; i < crtc_count; i++) { - get_crtc_config_str(&crtcs[i], str_buf[i], sizeof(str_buf[i])); - crtc_strs[i] = &str_buf[i][0]; - } - - if (dry_run) { - for (i = 0; i < crtc_count; i++) - igt_info(" %s\n", crtc_strs[i]); - return; - } - - for (i = 0; i < crtc_count; i++) { - uint32_t *ids; - int j; - - crtc = &crtcs[i]; - - igt_info(" %s\n", crtc_strs[i]); - - create_fb_for_crtc(crtc, &crtc->fb_info); - paint_fb(&crtc->fb_info, tconf->name, crtc_strs, crtc_count, i); - - ids = get_connector_ids(crtc); - ret = drmModeSetCrtc(drm_fd, crtc->crtc_id, - crtc->fb_info.fb_id, 0, 0, ids, - crtc->connector_count, &crtc->mode); - free(ids); - - if (ret < 0) { - igt_assert(errno == EINVAL); - config_failed = true; - } - - for (j = 0; j < crtc->connector_count; j++) - connector_connected |= crtc->cconfs[j].connected; - } - - igt_assert(config_failed == !!(tconf->flags & TEST_INVALID)); - - if (ret == 0 && connector_connected && !(tconf->flags & TEST_INVALID)) - sleep(5); - - for (i = 0; i < crtc_count; i++) { - if (crtcs[i].fb_info.fb_id) { - drmModeSetCrtc(drm_fd, crtcs[i].crtc_id, 0, 0, 0, NULL, - 0, NULL); - drmModeRmFB(drm_fd, crtcs[i].fb_info.fb_id); - crtcs[i].fb_info.fb_id = 0; - } - } - - return; -} - -static void test_one_combination(const struct test_config *tconf, - struct connector_config *cconfs, - int connector_count) -{ - struct crtc_config crtcs[MAX_CRTCS]; - int crtc_count; - bool config_valid; - - setup_crtcs(tconf->resources, cconfs, connector_count, crtcs, - &crtc_count, &config_valid); - - if (config_valid == !(tconf->flags & TEST_INVALID)) - test_crtc_config(tconf, crtcs, crtc_count); - - cleanup_crtcs(crtcs, crtc_count); -} - -static int assign_crtc_to_connectors(const struct test_config *tconf, - int *crtc_idxs, int connector_count, - struct connector_config *cconfs) -{ - unsigned long crtc_idx_mask; - int i; - - crtc_idx_mask = 0; - for (i = 0; i < connector_count; i++) { - int crtc_idx = crtc_idxs[i]; - - if ((tconf->flags & TEST_SINGLE_CRTC_CLONE) && - crtc_idx_mask & ~(1 << crtc_idx)) - return -1; - - if ((tconf->flags & TEST_EXCLUSIVE_CRTC_CLONE) && - crtc_idx_mask & (1 << crtc_idx)) - return -1; - - crtc_idx_mask |= 1 << crtc_idx; - - cconfs[i].crtc_idx = crtc_idx; - } - - return 0; -} - -static int get_one_connector(drmModeRes *resources, int connector_id, - struct connector_config *cconf) -{ - drmModeConnector *connector; - drmModeModeInfo mode; - - connector = drmModeGetConnector(drm_fd, connector_id); - igt_assert(connector); - cconf->connector = connector; - - cconf->connected = connector->connection == DRM_MODE_CONNECTED; - - /* - * For DP/eDP we need a connected sink, since mode setting depends - * on successful link training and retrieved DPCD parameters. - */ - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_DisplayPort: - case DRM_MODE_CONNECTOR_eDP: - if (!cconf->connected) { - drmModeFreeConnector(connector); - return -1; - } - } - - if (cconf->connected) { - if (!kmstest_get_connector_default_mode(drm_fd, connector, - &mode)) - mode = mode_640_480; - } else { - mode = mode_640_480; - } - - cconf->default_mode = mode; - - return 0; -} - -static int get_connectors(drmModeRes *resources, int *connector_idxs, - int connector_count, struct connector_config *cconfs) -{ - int i; - - for (i = 0; i < connector_count; i++) { - int connector_idx; - int connector_id; - - connector_idx = connector_idxs[i]; - igt_assert(connector_idx < resources->count_connectors); - connector_id = resources->connectors[connector_idx]; - - if (get_one_connector(resources, connector_id, &cconfs[i]) < 0) - goto err; - - } - - return 0; - -err: - while (i--) - drmModeFreeConnector(cconfs[i].connector); - - return -1; -} - -static void free_connectors(struct connector_config *cconfs, - int connector_count) -{ - int i; - - for (i = 0; i < connector_count; i++) - drmModeFreeConnector(cconfs[i].connector); -} - -struct combination { - int elems[MAX_COMBINATION_ELEMS]; -}; - -struct combination_set { - int count; - struct combination items[MAX_COMBINATION_COUNT]; -}; - -/* - * Get all possible selection of k elements from n elements with or without - * repetitions. - */ -static void iterate_combinations(int n, int k, bool allow_repetitions, - int depth, int base, struct combination *comb, - struct combination_set *set) -{ - int v; - - if (!k) { - igt_assert(set->count < ARRAY_SIZE(set->items)); - set->items[set->count++] = *comb; - return; - } - - for (v = base; v < n; v++) { - comb->elems[depth] = v; - iterate_combinations(n, k - 1, allow_repetitions, - depth + 1, allow_repetitions ? 0 : v + 1, - comb, set); - } - -} - -static void get_combinations(int n, int k, bool allow_repetitions, - struct combination_set *set) -{ - struct combination comb; - - igt_assert(k <= ARRAY_SIZE(set->items[0].elems)); - set->count = 0; - iterate_combinations(n, k, allow_repetitions, 0, 0, &comb, set); -} - -static void test_combinations(const struct test_config *tconf, - int connector_count) -{ - struct combination_set connector_combs; - struct combination_set crtc_combs; - struct connector_config *cconfs; - int i; - - get_combinations(tconf->resources->count_connectors, connector_count, - false, &connector_combs); - get_combinations(tconf->resources->count_crtcs, connector_count, - true, &crtc_combs); - - igt_info("Testing: %s %d connector combinations\n", tconf->name, - connector_count); - for (i = 0; i < connector_combs.count; i++) { - int *connector_idxs; - int ret; - int j; - - cconfs = malloc(sizeof(*cconfs) * connector_count); - igt_assert(cconfs); - - connector_idxs = &connector_combs.items[i].elems[0]; - ret = get_connectors(tconf->resources, connector_idxs, - connector_count, cconfs); - if (ret < 0) - goto free_cconfs; - - for (j = 0; j < crtc_combs.count; j++) { - int *crtc_idxs = &crtc_combs.items[j].elems[0]; - ret = assign_crtc_to_connectors(tconf, crtc_idxs, - connector_count, - cconfs); - if (ret < 0) - continue; - - test_one_combination(tconf, cconfs, connector_count); - } - - free_connectors(cconfs, connector_count); -free_cconfs: - free(cconfs); - } -} - -static void run_test(const struct test_config *tconf) -{ - int connector_num; - - connector_num = tconf->flags & TEST_CLONE ? 2 : 1; - for (; connector_num <= tconf->resources->count_crtcs; connector_num++) - test_combinations(tconf, connector_num); -} - -static int opt_handler(int opt, int opt_index) -{ - switch (opt) { - case 'd': - dry_run = true; - break; - case 't': - filter_test_id = atoi(optarg); - break; - default: - igt_assert(0); - } - - return 0; -} - -int main(int argc, char **argv) -{ - const struct { - enum test_flags flags; - const char *name; - } tests[] = { - { TEST_CLONE | TEST_SINGLE_CRTC_CLONE, - "clone-single-crtc" }, - { TEST_INVALID | TEST_CLONE | TEST_SINGLE_CRTC_CLONE, - "invalid-clone-single-crtc" }, - { TEST_INVALID | TEST_CLONE | TEST_EXCLUSIVE_CRTC_CLONE, - "invalid-clone-exclusive-crtc" }, - { TEST_CLONE | TEST_EXCLUSIVE_CRTC_CLONE, - "clone-exclusive-crtc" }, - }; - const char *help_str = - " -d\t\tDon't run any test, only print what would be done. (still needs DRM access)\n" - " -t <test id>\tRun only the test with this id."; - int i; - int ret; - - ret = igt_subtest_init_parse_opts(&argc, argv, "dt:", NULL, help_str, - opt_handler); - if (ret < 0) - return ret == -1 ? 0 : ret; - - igt_skip_on_simulation(); - - igt_assert_f(!(dry_run && filter_test_id), - "only one of -d and -t is accepted\n"); - - igt_fixture { - drm_fd = drm_open_any_master(); - if (!dry_run) - kmstest_set_vt_graphics_mode(); - - drm_resources = drmModeGetResources(drm_fd); - igt_assert(drm_resources); - } - - for (i = 0; i < ARRAY_SIZE(tests); i++) { - igt_subtest(tests[i].name) { - struct test_config tconf = { - .flags = tests[i].flags, - .name = tests[i].name, - .resources = drm_resources, - }; - run_test(&tconf); - } - } - - igt_fixture { - drmModeFreeResources(drm_resources); - - close(drm_fd); - } - - igt_exit(); -} diff --git a/tests/kms_sink_crc_basic.c b/tests/kms_sink_crc_basic.c deleted file mode 100644 index 41accf4a..00000000 --- a/tests/kms_sink_crc_basic.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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. - * - */ - -#include <errno.h> -#include <limits.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drm_fourcc.h" - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" - -#define CRC_BLACK "000000000000" - -enum color { - RED, - GREEN, -}; - -typedef struct { - int drm_fd; - igt_display_t display; - struct igt_fb fb_green, fb_red; - igt_plane_t *primary; -} data_t; - -static void get_crc(char *crc) { - int ret; - FILE *file; - - file = igt_debugfs_fopen("i915_sink_crc_eDP1", "r"); - igt_require(file); - - ret = fscanf(file, "%s\n", crc); - igt_require(ret > 0); - - fclose(file); - - /* Black screen is always invalid */ - igt_assert(strcmp(crc, CRC_BLACK) != 0); -} - -static void assert_color(char *crc, enum color color) -{ - char color_mask[5] = "FFFF\0"; - char rs[5], gs[5], bs[5]; - unsigned int rh, gh, bh, mask; - int ret; - - sscanf(color_mask, "%4x", &mask); - - memcpy(rs, &crc[0], 4); - rs[4] = '\0'; - ret = sscanf(rs, "%4x", &rh); - igt_require(ret > 0); - - memcpy(gs, &crc[4], 4); - gs[4] = '\0'; - ret = sscanf(gs, "%4x", &gh); - igt_require(ret > 0); - - memcpy(bs, &crc[8], 4); - bs[4] = '\0'; - ret = sscanf(bs, "%4x", &bh); - igt_require(ret > 0); - - switch (color) { - case RED: - igt_assert((rh & mask) != 0 && - (gh & mask) == 0 && - (bh & mask) == 0); - break; - case GREEN: - igt_assert((rh & mask) == 0 && - (gh & mask) != 0 && - (bh & mask) == 0); - break; - default: - igt_fail(-1); - } -} - -static void basic_sink_crc_check(data_t *data) -{ - char crc[13]; - - /* Go Green */ - igt_plane_set_fb(data->primary, &data->fb_green); - igt_display_commit(&data->display); - - /* It should be Green */ - get_crc(crc); - assert_color(crc, GREEN); - - /* Go Red */ - igt_plane_set_fb(data->primary, &data->fb_red); - igt_display_commit(&data->display); - - /* It should be Red */ - get_crc(crc); - assert_color(crc, RED); -} - -static void run_test(data_t *data) -{ - igt_display_t *display = &data->display; - igt_output_t *output; - drmModeModeInfo *mode; - - for_each_connected_output(display, output) { - drmModeConnectorPtr c = output->config.connector; - - if (c->connector_type != DRM_MODE_CONNECTOR_eDP || - c->connection != DRM_MODE_CONNECTED) - continue; - - igt_output_set_pipe(output, PIPE_ANY); - - mode = igt_output_get_mode(output); - - igt_create_color_fb(data->drm_fd, - mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_X, - 0.0, 1.0, 0.0, - &data->fb_green); - - igt_create_color_fb(data->drm_fd, - mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_X, - 1.0, 0.0, 0.0, - &data->fb_red); - - data->primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - - basic_sink_crc_check(data); - return; - } - - igt_skip("no eDP with CRC support found\n"); -} - -igt_simple_main -{ - data_t data = {}; - - igt_skip_on_simulation(); - - data.drm_fd = drm_open_any_master(); - - kmstest_set_vt_graphics_mode(); - igt_display_init(&data.display, data.drm_fd); - - run_test(&data); - - igt_display_fini(&data.display); -} diff --git a/tests/kms_sysfs_edid_timing b/tests/kms_sysfs_edid_timing deleted file mode 100755 index ec704f67..00000000 --- a/tests/kms_sysfs_edid_timing +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -# -# This check the time we take to read the content of all the possible connectors. -# Without the edid -ENXIO patch (http://permalink.gmane.org/gmane.comp.video.dri.devel/62083), -# we sometimes take a *really* long time. So let's just check for some reasonable timing here -# - -DRM_LIB_ALLOW_NO_MASTER=1 - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -TIME1=$(date +%s%N) -cat $(find /sys/devices/|grep drm | grep /status) > /dev/null -TIME2=$(date +%s%N) - -# time in ms -RES=$(((TIME2 - TIME1) / 1000000)) - -if [ $RES -gt 600 ]; then - echo "Talking to outputs took ${RES}ms, something is wrong" - exit 1 -fi - -exit 0 diff --git a/tests/kms_universal_plane.c b/tests/kms_universal_plane.c deleted file mode 100644 index 077a9487..00000000 --- a/tests/kms_universal_plane.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include "drmtest.h" -#include "igt_debugfs.h" -#include "igt_kms.h" - -typedef struct { - int drm_fd; - igt_display_t display; -} data_t; - -typedef struct { - data_t *data; - igt_pipe_crc_t *pipe_crc; - igt_crc_t crc_1, crc_2, crc_3, crc_4, crc_5, crc_6, crc_7, crc_8, - crc_9, crc_10; - struct igt_fb red_fb, blue_fb, black_fb, yellow_fb; - drmModeModeInfo *mode; -} functional_test_t; - -typedef struct { - data_t *data; - drmModeResPtr moderes; - struct igt_fb blue_fb, oversized_fb, undersized_fb; -} sanity_test_t; - -typedef struct { - data_t *data; - struct igt_fb red_fb, blue_fb; -} pageflip_test_t; - -static void -functional_test_init(functional_test_t *test, igt_output_t *output, enum pipe pipe) -{ - data_t *data = test->data; - drmModeModeInfo *mode; - - test->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); - - igt_output_set_pipe(output, pipe); - - mode = igt_output_get_mode(output); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 0.0, 0.0, 0.0, - &test->black_fb); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 0.0, 0.0, 1.0, - &test->blue_fb); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 1.0, 1.0, 0.0, - &test->yellow_fb); - igt_create_color_fb(data->drm_fd, 100, 100, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 1.0, 0.0, 0.0, - &test->red_fb); - - test->mode = mode; -} - -static void -functional_test_fini(functional_test_t *test, igt_output_t *output) -{ - igt_pipe_crc_free(test->pipe_crc); - - igt_remove_fb(test->data->drm_fd, &test->black_fb); - igt_remove_fb(test->data->drm_fd, &test->blue_fb); - igt_remove_fb(test->data->drm_fd, &test->red_fb); - igt_remove_fb(test->data->drm_fd, &test->yellow_fb); - - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit2(&test->data->display, COMMIT_LEGACY); -} - -/* - * Universal plane functional testing. - * - Black primary plane via traditional interfaces, red sprite, grab CRC:1. - * - Blue primary plane via traditional interfaces, red sprite, grab CRC:2. - * - Yellow primary via traditional interfaces - * - Blue primary plane, red sprite via universal planes, grab CRC:3 and compare - * with CRC:2 (should be the same) - * - Disable primary plane, grab CRC:4 (should be same as CRC:1) - * - Reenable primary, grab CRC:5 (should be same as CRC:2 and CRC:3) - * - Yellow primary, no sprite - * - Disable CRTC - * - Program red sprite (while CRTC off) - * - Program blue primary (while CRTC off) - * - Enable CRTC, grab CRC:6 (should be same as CRC:2) - */ -static void -functional_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output) -{ - functional_test_t test = { .data = data }; - igt_display_t *display = &data->display; - igt_plane_t *primary, *sprite; - int num_primary = 0, num_cursor = 0; - int i; - - igt_assert(data->display.has_universal_planes); - igt_skip_on(pipe >= display->n_pipes); - - igt_info("Testing connector %s using pipe %s\n", igt_output_name(output), - kmstest_pipe_name(pipe)); - - functional_test_init(&test, output, pipe); - - /* - * Make sure we have no more than one primary or cursor plane per crtc. - * If the kernel accidentally calls drm_plane_init() rather than - * drm_universal_plane_init(), the type enum can get interpreted as a - * boolean and show up in userspace as the wrong type. - */ - for (i = 0; i < display->pipes[pipe].n_planes; i++) - if (display->pipes[pipe].planes[i].is_primary) - num_primary++; - else if (display->pipes[pipe].planes[i].is_cursor) - num_cursor++; - - igt_assert(num_primary == 1); - igt_assert(num_cursor <= 1); - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - sprite = igt_output_get_plane(output, IGT_PLANE_2); - if (!sprite) { - functional_test_fini(&test, output); - igt_skip("No sprite plane available\n"); - } - - igt_plane_set_position(sprite, 100, 100); - - /* Step 1: Legacy API's, black primary, red sprite (CRC 1) */ - igt_plane_set_fb(primary, &test.black_fb); - igt_plane_set_fb(sprite, &test.red_fb); - igt_display_commit2(display, COMMIT_LEGACY); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_1); - - /* Step 2: Legacy API', blue primary, red sprite (CRC 2) */ - igt_plane_set_fb(primary, &test.blue_fb); - igt_plane_set_fb(sprite, &test.red_fb); - igt_display_commit2(display, COMMIT_LEGACY); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_2); - - /* Step 3: Legacy API's, yellow primary (CRC 3) */ - igt_plane_set_fb(primary, &test.yellow_fb); - igt_display_commit2(display, COMMIT_LEGACY); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_3); - - /* Step 4: Universal API's, blue primary, red sprite (CRC 4) */ - igt_plane_set_fb(primary, &test.blue_fb); - igt_plane_set_fb(sprite, &test.red_fb); - igt_display_commit2(display, COMMIT_UNIVERSAL); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_4); - - /* Step 5: Universal API's, disable primary plane (CRC 5) */ - igt_plane_set_fb(primary, NULL); - igt_display_commit2(display, COMMIT_UNIVERSAL); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_5); - - /* Step 6: Universal API's, re-enable primary with blue (CRC 6) */ - igt_plane_set_fb(primary, &test.blue_fb); - igt_display_commit2(display, COMMIT_UNIVERSAL); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_6); - - /* Step 7: Legacy API's, yellow primary, no sprite */ - igt_plane_set_fb(primary, &test.yellow_fb); - igt_plane_set_fb(sprite, NULL); - igt_display_commit2(display, COMMIT_LEGACY); - - /* Step 8: Disable CRTC */ - igt_plane_set_fb(primary, NULL); - igt_display_commit2(display, COMMIT_LEGACY); - - /* Step 9: Universal API's with crtc off: - * - red sprite - * - multiple primary fb's, ending in blue - */ - igt_plane_set_fb(sprite, &test.red_fb); - igt_display_commit2(display, COMMIT_UNIVERSAL); - igt_plane_set_fb(primary, &test.yellow_fb); - igt_display_commit2(display, COMMIT_UNIVERSAL); - igt_plane_set_fb(primary, &test.black_fb); - igt_display_commit2(display, COMMIT_UNIVERSAL); - igt_plane_set_fb(primary, &test.blue_fb); - igt_display_commit2(display, COMMIT_UNIVERSAL); - - /* Step 10: Enable crtc (fb = -1), take CRC (CRC 7) */ - igt_assert(drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id, -1, - 0, 0, &output->config.connector->connector_id, - 1, test.mode) == 0); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_7); - - /* Step 11: Disable primary plane */ - igt_plane_set_fb(primary, NULL); - igt_display_commit2(display, COMMIT_UNIVERSAL); - - /* Step 12: Legacy modeset to yellow FB (CRC 8) */ - igt_plane_set_fb(primary, &test.yellow_fb); - igt_display_commit2(display, COMMIT_LEGACY); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_8); - - /* Step 13: Legacy API', blue primary, red sprite */ - igt_plane_set_fb(primary, &test.blue_fb); - igt_plane_set_fb(sprite, &test.red_fb); - igt_display_commit2(display, COMMIT_LEGACY); - - /* Step 14: Universal API, set primary completely offscreen (CRC 9) */ - igt_assert(drmModeSetPlane(data->drm_fd, primary->drm_plane->plane_id, - output->config.crtc->crtc_id, - test.blue_fb.fb_id, 0, - 9000, 9000, - test.mode->hdisplay, - test.mode->vdisplay, - IGT_FIXED(0,0), IGT_FIXED(0,0), - IGT_FIXED(test.mode->hdisplay,0), - IGT_FIXED(test.mode->vdisplay,0)) == 0); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_9); - - /* - * Step 15: Explicitly disable primary after it's already been - * implicitly disabled (CRC 10). - */ - igt_plane_set_fb(primary, NULL); - igt_display_commit2(display, COMMIT_UNIVERSAL); - igt_pipe_crc_collect_crc(test.pipe_crc, &test.crc_10); - - /* Step 16: Legacy API's, blue primary, red sprite */ - igt_plane_set_fb(primary, &test.blue_fb); - igt_plane_set_fb(sprite, &test.red_fb); - igt_display_commit2(display, COMMIT_LEGACY); - - /* Blue bg + red sprite should be same under both types of API's */ - igt_assert(igt_crc_equal(&test.crc_2, &test.crc_4)); - - /* Disabling primary plane should be same as black primary */ - igt_assert(igt_crc_equal(&test.crc_1, &test.crc_5)); - - /* Re-enabling primary should return to blue properly */ - igt_assert(igt_crc_equal(&test.crc_2, &test.crc_6)); - - /* - * We should be able to setup plane FB's while CRTC is disabled and - * then have them pop up correctly when the CRTC is re-enabled. - */ - igt_assert(igt_crc_equal(&test.crc_2, &test.crc_7)); - - /* - * We should be able to modeset with the primary plane off - * successfully - */ - igt_assert(igt_crc_equal(&test.crc_3, &test.crc_8)); - - /* - * We should be able to move the primary plane completely offscreen - * and have it disable successfully. - */ - igt_assert(igt_crc_equal(&test.crc_5, &test.crc_9)); - - /* - * We should be able to explicitly disable an already - * implicitly-disabled primary plane - */ - igt_assert(igt_crc_equal(&test.crc_5, &test.crc_10)); - - igt_plane_set_fb(primary, NULL); - igt_plane_set_fb(sprite, NULL); - - functional_test_fini(&test, output); -} - -static void -sanity_test_init(sanity_test_t *test, igt_output_t *output, enum pipe pipe) -{ - data_t *data = test->data; - drmModeModeInfo *mode; - - igt_output_set_pipe(output, pipe); - - mode = igt_output_get_mode(output); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 0.0, 0.0, 1.0, - &test->blue_fb); - igt_create_color_fb(data->drm_fd, - mode->hdisplay + 100, mode->vdisplay + 100, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 0.0, 0.0, 1.0, - &test->oversized_fb); - igt_create_color_fb(data->drm_fd, - mode->hdisplay - 100, mode->vdisplay - 100, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 0.0, 0.0, 1.0, - &test->undersized_fb); - - test->moderes = drmModeGetResources(data->drm_fd); -} - -static void -sanity_test_fini(sanity_test_t *test, igt_output_t *output) -{ - drmModeFreeResources(test->moderes); - - igt_remove_fb(test->data->drm_fd, &test->oversized_fb); - igt_remove_fb(test->data->drm_fd, &test->undersized_fb); - igt_remove_fb(test->data->drm_fd, &test->blue_fb); - - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit2(&test->data->display, COMMIT_LEGACY); -} - -/* - * Universal plane sanity testing. - * - Primary doesn't cover CRTC - * - Primary plane tries to scale down - * - Primary plane tries to scale up - */ -static void -sanity_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output) -{ - sanity_test_t test = { .data = data }; - igt_plane_t *primary; - drmModeModeInfo *mode; - int i; - - igt_skip_on(pipe >= data->display.n_pipes); - - igt_output_set_pipe(output, pipe); - mode = igt_output_get_mode(output); - - sanity_test_init(&test, output, pipe); - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - - /* Use legacy API to set a mode with a blue FB */ - igt_plane_set_fb(primary, &test.blue_fb); - igt_display_commit2(&data->display, COMMIT_LEGACY); - - /* - * Try to use universal plane API to set primary plane that - * doesn't cover CRTC (should fail). - */ - igt_plane_set_fb(primary, &test.undersized_fb); - igt_assert(igt_display_try_commit2(&data->display, COMMIT_UNIVERSAL) == -EINVAL); - - /* Same as above, but different plane positioning. */ - igt_plane_set_position(primary, 100, 100); - igt_assert(igt_display_try_commit2(&data->display, COMMIT_UNIVERSAL) == -EINVAL); - - igt_plane_set_position(primary, 0, 0); - - /* Try to use universal plane API to scale down (should fail) */ - igt_assert(drmModeSetPlane(data->drm_fd, primary->drm_plane->plane_id, - output->config.crtc->crtc_id, - test.oversized_fb.fb_id, 0, - 0, 0, - mode->hdisplay + 100, - mode->vdisplay + 100, - IGT_FIXED(0,0), IGT_FIXED(0,0), - IGT_FIXED(mode->hdisplay,0), - IGT_FIXED(mode->vdisplay,0)) == -ERANGE); - - /* Try to use universal plane API to scale up (should fail) */ - igt_assert(drmModeSetPlane(data->drm_fd, primary->drm_plane->plane_id, - output->config.crtc->crtc_id, - test.oversized_fb.fb_id, 0, - 0, 0, - mode->hdisplay, - mode->vdisplay, - IGT_FIXED(0,0), IGT_FIXED(0,0), - IGT_FIXED(mode->hdisplay - 100,0), - IGT_FIXED(mode->vdisplay - 100,0)) == -ERANGE); - - /* Find other crtcs and try to program our primary plane on them */ - for (i = 0; i < test.moderes->count_crtcs; i++) - if (test.moderes->crtcs[i] != output->config.crtc->crtc_id) { - igt_assert(drmModeSetPlane(data->drm_fd, - primary->drm_plane->plane_id, - test.moderes->crtcs[i], - test.blue_fb.fb_id, 0, - 0, 0, - mode->hdisplay, - mode->vdisplay, - IGT_FIXED(0,0), IGT_FIXED(0,0), - IGT_FIXED(mode->hdisplay,0), - IGT_FIXED(mode->vdisplay,0)) == -EINVAL); - } - - igt_plane_set_fb(primary, NULL); - sanity_test_fini(&test, output); -} - -static void -pageflip_test_init(pageflip_test_t *test, igt_output_t *output, enum pipe pipe) -{ - data_t *data = test->data; - drmModeModeInfo *mode; - - igt_output_set_pipe(output, pipe); - - mode = igt_output_get_mode(output); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 1.0, 0.0, 0.0, - &test->red_fb); - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - false, /* tiled */ - 0.0, 0.0, 1.0, - &test->blue_fb); -} - -static void -pageflip_test_fini(pageflip_test_t *test, igt_output_t *output) -{ - igt_remove_fb(test->data->drm_fd, &test->red_fb); - igt_remove_fb(test->data->drm_fd, &test->blue_fb); - - igt_output_set_pipe(output, PIPE_ANY); - igt_display_commit2(&test->data->display, COMMIT_LEGACY); -} - -static void -pageflip_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output) -{ - pageflip_test_t test = { .data = data }; - igt_plane_t *primary; - struct timeval timeout = { .tv_sec = 0, .tv_usec = 500 }; - drmEventContext evctx = { .version = DRM_EVENT_CONTEXT_VERSION }; - - fd_set fds; - int ret = 0; - - igt_skip_on(pipe >= data->display.n_pipes); - - igt_output_set_pipe(output, pipe); - - pageflip_test_init(&test, output, pipe); - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - - /* Use legacy API to set a mode with a blue FB */ - igt_plane_set_fb(primary, &test.blue_fb); - igt_display_commit2(&data->display, COMMIT_LEGACY); - - /* Disable the primary plane */ - igt_plane_set_fb(primary, NULL); - igt_display_commit2(&data->display, COMMIT_UNIVERSAL); - - /* - * Issue a pageflip to red FB - * - * Note that crtc->primary->fb = NULL causes flip to return EBUSY for - * historical reasons... - */ - igt_assert(drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id, - test.red_fb.fb_id, 0, NULL) == -EBUSY); - - /* Turn primary plane back on */ - igt_plane_set_fb(primary, &test.blue_fb); - igt_display_commit2(&data->display, COMMIT_UNIVERSAL); - - /* - * Issue a pageflip to red, then immediately try to disable the primary - * plane, hopefully before the pageflip has a chance to complete. The - * plane disable operation should wind up blocking while the pageflip - * completes, which we don't have a good way to specifically test for, - * but at least we can make sure that nothing blows up. - */ - igt_assert(drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id, - test.red_fb.fb_id, DRM_MODE_PAGE_FLIP_EVENT, - &test) == 0); - igt_plane_set_fb(primary, NULL); - igt_display_commit2(&data->display, COMMIT_UNIVERSAL); - - /* Wait for pageflip completion, then consume event on fd */ - FD_ZERO(&fds); - FD_SET(data->drm_fd, &fds); - do { - ret = select(data->drm_fd + 1, &fds, NULL, NULL, &timeout); - } while (ret < 0 && errno == EINTR); - igt_assert(ret == 1); - igt_assert(drmHandleEvent(data->drm_fd, &evctx) == 0); - - igt_plane_set_fb(primary, NULL); - pageflip_test_fini(&test, output); -} - -static void -cursor_leak_test_fini(data_t *data, - igt_output_t *output, - struct igt_fb *bg, - struct igt_fb *curs) -{ - int i; - - igt_remove_fb(data->drm_fd, bg); - for (i = 0; i < 10; i++) - igt_remove_fb(data->drm_fd, &curs[i]); - - igt_output_set_pipe(output, PIPE_ANY); -} - -static int -i915_gem_fb_count(void) -{ - char buf[1024]; - FILE *fp; - int count = 0; - - fp = igt_debugfs_fopen("i915_gem_framebuffer", "r"); - igt_require(fp); - while (fgets(buf, sizeof(buf), fp) != NULL) - count++; - fclose(fp); - - return count; -} - -static void -cursor_leak_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output) -{ - igt_display_t *display = &data->display; - igt_plane_t *primary, *cursor; - drmModeModeInfo *mode; - struct igt_fb background_fb; - struct igt_fb cursor_fb[10]; - int i; - int r, g, b; - int count1, count2; - - igt_assert(data->display.has_universal_planes); - igt_skip_on(pipe >= display->n_pipes); - - igt_output_set_pipe(output, pipe); - mode = igt_output_get_mode(output); - - /* Count GEM framebuffers before creating our cursor FB's */ - count1 = i915_gem_fb_count(); - - /* Black background FB */ - igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, - false, - 0.0, 0.0, 0.0, - &background_fb); - - /* Random color cursors */ - for (i = 0; i < 10; i++) { - r = rand() % 0xFF; - g = rand() % 0xFF; - b = rand() % 0xFF; - igt_create_color_fb(data->drm_fd, 64, 64, - DRM_FORMAT_ARGB8888, - false, - (double)r / 0xFF, - (double)g / 0xFF, - (double)b / 0xFF, - &cursor_fb[i]); - } - - primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY); - cursor = igt_output_get_plane(output, IGT_PLANE_CURSOR); - if (!primary || !cursor) { - cursor_leak_test_fini(data, output, &background_fb, cursor_fb); - igt_skip("Primary and/or cursor are unavailable\n"); - } - - - igt_plane_set_fb(primary, &background_fb); - igt_display_commit2(display, COMMIT_LEGACY); - - igt_plane_set_position(cursor, 100, 100); - - /* - * Exercise both legacy and universal code paths. Note that legacy - * handling in the kernel redirects through universal codepaths - * internally, so that redirection is where we're most worried about - * leaking. - */ - for (i = 0; i < 10; i++) { - igt_plane_set_fb(cursor, &cursor_fb[i]); - igt_display_commit2(display, COMMIT_UNIVERSAL); - } - for (i = 0; i < 10; i++) { - igt_plane_set_fb(cursor, &cursor_fb[i]); - igt_display_commit2(display, COMMIT_LEGACY); - } - - /* Release our framebuffer handles before we take a second count */ - igt_plane_set_fb(primary, NULL); - igt_plane_set_fb(cursor, NULL); - igt_display_commit2(display, COMMIT_LEGACY); - cursor_leak_test_fini(data, output, &background_fb, cursor_fb); - - /* We should be back to the same framebuffer count as when we started */ - count2 = i915_gem_fb_count(); - - igt_assert_eq(count1, count2); -} - -static void -run_tests_for_pipe(data_t *data, enum pipe pipe) -{ - igt_output_t *output; - - igt_subtest_f("universal-plane-pipe-%s-functional", - kmstest_pipe_name(pipe)) - for_each_connected_output(&data->display, output) - functional_test_pipe(data, pipe, output); - - igt_subtest_f("universal-plane-pipe-%s-sanity", - kmstest_pipe_name(pipe)) - for_each_connected_output(&data->display, output) - sanity_test_pipe(data, pipe, output); - - igt_subtest_f("disable-primary-vs-flip-pipe-%s", - kmstest_pipe_name(pipe)) - for_each_connected_output(&data->display, output) - pageflip_test_pipe(data, pipe, output); - - igt_subtest_f("cursor-fb-leak-pipe-%s", - kmstest_pipe_name(pipe)) - for_each_connected_output(&data->display, output) - cursor_leak_test_pipe(data, pipe, output); -} - -static data_t data; - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - data.drm_fd = drm_open_any_master(); - - kmstest_set_vt_graphics_mode(); - - igt_require_pipe_crc(); - igt_display_init(&data.display, data.drm_fd); - - igt_require(data.display.has_universal_planes); - } - - for (int pipe = 0; pipe < I915_MAX_PIPES; pipe++) - run_tests_for_pipe(&data, pipe); - - igt_fixture { - igt_display_fini(&data.display); - } -} diff --git a/tests/pm_lpsp.c b/tests/pm_lpsp.c deleted file mode 100644 index 4c6b3d6f..00000000 --- a/tests/pm_lpsp.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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. - * - * Author: Paulo Zanoni <paulo.r.zanoni@intel.com> - * - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "drmtest.h" -#include "igt_kms.h" -#include "intel_io.h" -#include "intel_chipset.h" - -/* We know that if we don't enable audio runtime PM, snd_hda_intel will never - * release its power well refcount, and we'll never reach the LPSP sate. OTOH - * there's no guarantee that it will release the power well if we enable runtime - * PM, but at least we can try. We don't have any assertions since the user may - * not even have snd_hda_intel loaded, which is not a problem. */ -static void disable_audio_runtime_pm(void) -{ - int fd; - - fd = open("/sys/module/snd_hda_intel/parameters/power_save", O_WRONLY); - if (fd >= 0) { - write(fd, "1\n", 2); - close(fd); - } - fd = open("/sys/bus/pci/devices/0000:00:03.0/power/control", O_WRONLY); - if (fd >= 0) { - write(fd, "auto\n", 5); - close(fd); - } - /* Give some time for it to react. */ - sleep(1); -} - -static bool supports_lpsp(uint32_t devid) -{ - return IS_HASWELL(devid) || IS_BROADWELL(devid); -} - -static bool lpsp_is_enabled(int drm_fd) -{ - uint32_t val; - - val = INREG(HSW_PWR_WELL_CTL2); - return !(val & HSW_PWR_WELL_STATE_ENABLED); -} - -/* The LPSP mode is all about an enabled pipe, but we expect to also be in the - * low power mode when no pipes are enabled, so do this check anyway. */ -static void screens_disabled_subtest(int drm_fd, drmModeResPtr drm_res) -{ - kmstest_unset_all_crtcs(drm_fd, drm_res); - igt_assert(lpsp_is_enabled(drm_fd)); -} - -static uint32_t create_fb(int drm_fd, int width, int height) -{ - struct igt_fb fb; - cairo_t *cr; - uint32_t buffer_id; - - buffer_id = igt_create_fb(drm_fd, width, height, DRM_FORMAT_XRGB8888, - I915_TILING_NONE, &fb); - cr = igt_get_cairo_ctx(drm_fd, &fb); - igt_paint_test_pattern(cr, width, height); - cairo_destroy(cr); - - return buffer_id; -} - -static void edp_subtest(int drm_fd, drmModeResPtr drm_res, - drmModeConnectorPtr *drm_connectors, uint32_t devid, - bool use_panel_fitter) -{ - int i, rc; - uint32_t connector_id = 0, crtc_id = 0, buffer_id = 0; - drmModeModeInfoPtr mode = NULL; - drmModeModeInfo std_1024_mode = { - .clock = 65000, - .hdisplay = 1024, - .hsync_start = 1048, - .hsync_end = 1184, - .htotal = 1344, - .vtotal = 806, - .hskew = 0, - .vdisplay = 768, - .vsync_start = 771, - .vsync_end = 777, - .vtotal = 806, - .vscan = 0, - .vrefresh = 60, - .flags = 0xA, - .type = 0x40, - .name = "Custom 1024x768", - }; - - kmstest_unset_all_crtcs(drm_fd, drm_res); - - for (i = 0; i < drm_res->count_connectors; i++) { - drmModeConnectorPtr c = drm_connectors[i]; - - if (c->connector_type != DRM_MODE_CONNECTOR_eDP) - continue; - if (c->connection != DRM_MODE_CONNECTED) - continue; - - if (!use_panel_fitter && c->count_modes) { - connector_id = c->connector_id; - mode = &c->modes[0]; - break; - } - if (use_panel_fitter) { - connector_id = c->connector_id; - - /* This is one of the modes Xorg creates for panels, so - * it should work just fine. Notice that Gens that - * support LPSP are too new for panels with native - * 1024x768 resolution, so this should force the panel - * fitter. */ - igt_assert(c->count_modes && - c->modes[0].hdisplay > 1024); - igt_assert(c->count_modes && - c->modes[0].vdisplay > 768); - mode = &std_1024_mode; - break; - } - } - igt_require(connector_id); - - crtc_id = drm_res->crtcs[0]; - buffer_id = create_fb(drm_fd, mode->hdisplay, mode->vdisplay); - - igt_assert(crtc_id); - igt_assert(buffer_id); - igt_assert(connector_id); - igt_assert(mode); - - rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, 1, - mode); - igt_assert(rc == 0); - - if (use_panel_fitter) { - if (IS_HASWELL(devid)) - igt_assert(!lpsp_is_enabled(drm_fd)); - else - igt_assert(lpsp_is_enabled(drm_fd)); - } else { - igt_assert(lpsp_is_enabled(drm_fd)); - } -} - -static void non_edp_subtest(int drm_fd, drmModeResPtr drm_res, - drmModeConnectorPtr *drm_connectors) -{ - int i, rc; - uint32_t connector_id = 0, crtc_id = 0, buffer_id = 0; - drmModeModeInfoPtr mode = NULL; - - kmstest_unset_all_crtcs(drm_fd, drm_res); - - for (i = 0; i < drm_res->count_connectors; i++) { - drmModeConnectorPtr c = drm_connectors[i]; - - if (c->connector_type == DRM_MODE_CONNECTOR_eDP) - continue; - if (c->connection != DRM_MODE_CONNECTED) - continue; - - if (c->count_modes) { - connector_id = c->connector_id; - mode = &c->modes[0]; - break; - } - } - igt_require(connector_id); - - crtc_id = drm_res->crtcs[0]; - buffer_id = create_fb(drm_fd, mode->hdisplay, mode->vdisplay); - - igt_assert(crtc_id); - igt_assert(buffer_id); - igt_assert(connector_id); - igt_assert(mode); - - rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, 1, - mode); - igt_assert(rc == 0); - - igt_assert(!lpsp_is_enabled(drm_fd)); -} - -#define MAX_CONNECTORS 32 - -int drm_fd; -uint32_t devid; -drmModeResPtr drm_res; -drmModeConnectorPtr drm_connectors[MAX_CONNECTORS]; - -igt_main -{ - igt_fixture { - int i; - - drm_fd = drm_open_any_master(); - igt_require(drm_fd >= 0); - - devid = intel_get_drm_devid(drm_fd); - - drm_res = drmModeGetResources(drm_fd); - igt_assert(drm_res->count_connectors <= MAX_CONNECTORS); - - for (i = 0; i < drm_res->count_connectors; i++) - drm_connectors[i] = drmModeGetConnector(drm_fd, - drm_res->connectors[i]); - - disable_audio_runtime_pm(); - - igt_require(supports_lpsp(devid)); - - intel_register_access_init(intel_get_pci_device(), 0); - - kmstest_set_vt_graphics_mode(); - } - - igt_subtest("screens-disabled") - screens_disabled_subtest(drm_fd, drm_res); - igt_subtest("edp-native") - edp_subtest(drm_fd, drm_res, drm_connectors, devid, false); - igt_subtest("edp-panel-fitter") - edp_subtest(drm_fd, drm_res, drm_connectors, devid, true); - igt_subtest("non-edp") - non_edp_subtest(drm_fd, drm_res, drm_connectors); - - igt_fixture { - int i; - - intel_register_access_fini(); - for (i = 0; i < drm_res->count_connectors; i++) - drmModeFreeConnector(drm_connectors[i]); - drmModeFreeResources(drm_res); - close(drm_fd); - } -} diff --git a/tests/pm_rc6_residency.c b/tests/pm_rc6_residency.c deleted file mode 100644 index f6152da0..00000000 --- a/tests/pm_rc6_residency.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright © 2012 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: - * Ben Widawsky <ben@bwidawsk.net> - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include "drmtest.h" -#include "intel_chipset.h" - -#define SLEEP_DURATION 3000 // in milliseconds -#define RC6_FUDGE 900 // in milliseconds -#define CODE_TIME 50 // in microseconfs - -static unsigned int readit(const char *path) -{ - unsigned int ret; - int scanned; - - FILE *file; - file = fopen(path, "r"); - igt_assert(file); - scanned = fscanf(file, "%u", &ret); - igt_assert(scanned == 1); - - fclose(file); - - return ret; -} - -static void read_rc6_residency( int value[], const char *name_of_rc6_residency) -{ - unsigned int i; - const int device = drm_get_card(); - char *path ; - int ret; - FILE *file; - - /* For some reason my ivb isn't idle even after syncing up with the gpu. - * Let's add a sleept just to make it happy. */ - sleep(5); - - ret = asprintf(&path, "/sys/class/drm/card%d/power/rc6_enable", device); - igt_assert(ret != -1); - - file = fopen(path, "r"); - igt_require(file); - - /* claim success if no rc6 enabled. */ - if (readit(path) == 0) - igt_success(); - - for(i = 0; i < 2; i++) - { - sleep(SLEEP_DURATION / 1000); - ret = asprintf(&path, "/sys/class/drm/card%d/power/%s_residency_ms",device,name_of_rc6_residency); - igt_assert(ret != -1); - value[i] = readit(path); - } - free(path); -} - -static void residency_accuracy(int value[],const char *name_of_rc6_residency) -{ - unsigned int flag_counter,flag_support; - double counter_result = 0; - unsigned int diff; - unsigned int tmp_counter, tmp_support; - double counter; - flag_counter = 0; - flag_support = 0; - diff = (value[1] - value[0]); - - igt_assert_f(diff <= (SLEEP_DURATION + RC6_FUDGE),"Diff was too high. That is unpossible\n"); - igt_assert_f(diff >= (SLEEP_DURATION - RC6_FUDGE),"GPU was not in RC6 long enough. Check that " - "the GPU is as idle as possible(ie. no X, " - "running and running no other tests)\n"); - - counter = ((double)value[1] - (double)value[0]) /(double) (SLEEP_DURATION + CODE_TIME); - - if( counter > 0.9 ){ - counter_result = counter; - tmp_counter = 1; - } - else - tmp_counter = 0; - - if( value [1] == 0){ - tmp_support = 0; - igt_info("This machine/configuration doesn't support %s\n", name_of_rc6_residency); - } - else - tmp_support = 1; - - flag_counter = flag_counter + tmp_counter; - flag_counter = flag_counter << 1; - - flag_support = flag_support + tmp_support; - flag_support = flag_support << 1; - - igt_info("The residency counter: %f \n", counter_result); - igt_skip_on_f(flag_support == 0 , "This machine didn't entry %s state.\n", name_of_rc6_residency); - igt_assert_f((flag_counter != 0) && (counter_result <=1) , "Sysfs RC6 residency counter is inaccurate.\n"); - igt_info("This machine entry %s state.\n", name_of_rc6_residency); -} - -igt_main -{ - int fd; - int devid = 0; - int rc6[2], rc6p[2], rc6pp[2], media[2]; - - igt_skip_on_simulation(); - - /* Use drm_open_any to verify device existence */ - igt_fixture { - fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - close(fd); - - read_rc6_residency(rc6, "rc6"); - if (IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid)) - read_rc6_residency(media, "media_rc6"); - - if (IS_GEN6(devid) || IS_IVYBRIDGE(devid)) { - read_rc6_residency(rc6p, "rc6p"); - read_rc6_residency(rc6pp, "rc6pp"); - } - } - - igt_subtest("rc6-accuracy") - residency_accuracy(rc6, "rc6"); - igt_subtest("media-rc6-accuracy") - if (IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid)) - residency_accuracy(media, "media_rc6"); - igt_subtest("rc6p-accuracy") { - if (!IS_GEN6(devid) && !IS_IVYBRIDGE(devid)) - igt_skip("This platform doesn't support RC6p\n"); - residency_accuracy(rc6p, "rc6p"); - } - igt_subtest("rc6pp-accuracy") { - if (!IS_GEN6(devid) && !IS_IVYBRIDGE(devid)) - igt_skip("This platform doesn't support RC6pp\n"); - residency_accuracy(rc6pp, "rc6pp"); - } -} diff --git a/tests/pm_rpm.c b/tests/pm_rpm.c deleted file mode 100644 index db8f4277..00000000 --- a/tests/pm_rpm.c +++ /dev/null @@ -1,1953 +0,0 @@ -/* - * 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: - * Paulo Zanoni <paulo.r.zanoni@intel.com> - * - */ - -#include <stdio.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> - -#include <unistd.h> -#include <fcntl.h> -#include <dirent.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <linux/i2c.h> -#include <linux/i2c-dev.h> - -#include <drm.h> - -#include "drmtest.h" -#include "intel_batchbuffer.h" -#include "intel_io.h" -#include "intel_chipset.h" -#include "ioctl_wrappers.h" -#include "igt_aux.h" -#include "igt_kms.h" -#include "igt_gt.h" - -/* One day, this will be on your libdrm. */ -#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 - -#define MSR_PC8_RES 0x630 -#define MSR_PC9_RES 0x631 -#define MSR_PC10_RES 0x632 - -#define MAX_CONNECTORS 32 -#define MAX_ENCODERS 32 -#define MAX_CRTCS 16 - -#define POWER_DIR "/sys/devices/pci0000:00/0000:00:02.0/power" - -enum pc8_status { - PC8_ENABLED, - PC8_DISABLED -}; - -enum screen_type { - SCREEN_TYPE_LPSP, - SCREEN_TYPE_NON_LPSP, - SCREEN_TYPE_ANY, -}; - -enum plane_type { - PLANE_OVERLAY, - PLANE_PRIMARY, - PLANE_CURSOR, -}; - -/* Wait flags */ -#define DONT_WAIT 0 -#define WAIT_STATUS 1 -#define WAIT_PC8_RES 2 -#define WAIT_EXTRA 4 -#define USE_DPMS 8 - -int drm_fd, msr_fd, pm_status_fd, pc8_status_fd; -bool has_runtime_pm, has_pc8; -struct mode_set_data ms_data; - -/* Stuff used when creating FBs and mode setting. */ -struct mode_set_data { - drmModeResPtr res; - drmModeConnectorPtr connectors[MAX_CONNECTORS]; - drmModePropertyBlobPtr edids[MAX_CONNECTORS]; - - uint32_t devid; -}; - -/* Stuff we query at different times so we can compare. */ -struct compare_data { - drmModeResPtr res; - drmModeEncoderPtr encoders[MAX_ENCODERS]; - drmModeConnectorPtr connectors[MAX_CONNECTORS]; - drmModeCrtcPtr crtcs[MAX_CRTCS]; - drmModePropertyBlobPtr edids[MAX_CONNECTORS]; -}; - -struct modeset_params { - uint32_t crtc_id; - uint32_t connector_id; - struct igt_fb fb; - drmModeModeInfoPtr mode; -}; - -struct modeset_params lpsp_mode_params; -struct modeset_params non_lpsp_mode_params; -struct modeset_params *default_mode_params; - -/* If the read fails, then the machine doesn't support PC8+ residencies. */ -static bool supports_pc8_plus_residencies(void) -{ - int rc; - uint64_t val; - - rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC8_RES); - if (rc != sizeof(val)) - return false; - rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC9_RES); - if (rc != sizeof(val)) - return false; - rc = pread(msr_fd, &val, sizeof(uint64_t), MSR_PC10_RES); - if (rc != sizeof(val)) - return false; - - return true; -} - -static uint64_t get_residency(uint32_t type) -{ - int rc; - uint64_t ret; - - rc = pread(msr_fd, &ret, sizeof(uint64_t), type); - igt_assert(rc == sizeof(ret)); - - return ret; -} - -static bool pc8_plus_residency_changed(unsigned int timeout_sec) -{ - unsigned int i; - uint64_t res_pc8, res_pc9, res_pc10; - int to_sleep = 100 * 1000; - - res_pc8 = get_residency(MSR_PC8_RES); - res_pc9 = get_residency(MSR_PC9_RES); - res_pc10 = get_residency(MSR_PC10_RES); - - for (i = 0; i < timeout_sec * 1000 * 1000; i += to_sleep) { - if (res_pc8 != get_residency(MSR_PC8_RES) || - res_pc9 != get_residency(MSR_PC9_RES) || - res_pc10 != get_residency(MSR_PC10_RES)) { - return true; - } - usleep(to_sleep); - } - - return false; -} - -static enum pc8_status get_pc8_status(void) -{ - ssize_t n_read; - char buf[150]; /* The whole file has less than 100 chars. */ - - lseek(pc8_status_fd, 0, SEEK_SET); - n_read = read(pc8_status_fd, buf, ARRAY_SIZE(buf)); - igt_assert(n_read >= 0); - buf[n_read] = '\0'; - - if (strstr(buf, "\nEnabled: yes\n")) - return PC8_ENABLED; - else - return PC8_DISABLED; -} - -static bool wait_for_pc8_status(enum pc8_status status) -{ - int i; - int hundred_ms = 100 * 1000, ten_s = 10 * 1000 * 1000; - - for (i = 0; i < ten_s; i += hundred_ms) { - if (get_pc8_status() == status) - return true; - - usleep(hundred_ms); - } - - return false; -} - -static bool wait_for_suspended(void) -{ - if (has_pc8 && !has_runtime_pm) - return wait_for_pc8_status(PC8_ENABLED); - else - return igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_SUSPENDED); -} - -static bool wait_for_active(void) -{ - if (has_pc8 && !has_runtime_pm) - return wait_for_pc8_status(PC8_DISABLED); - else - return igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_ACTIVE); -} - -static void disable_all_screens_dpms(struct mode_set_data *data) -{ - int i; - - for (i = 0; i < data->res->count_connectors; i++) { - drmModeConnectorPtr c = data->connectors[i]; - - kmstest_set_connector_dpms(drm_fd, c, DRM_MODE_DPMS_OFF); - } -} - -static void disable_all_screens(struct mode_set_data *data) -{ - kmstest_unset_all_crtcs(drm_fd, data->res); -} - -#define disable_all_screens_and_wait(data) do { \ - disable_all_screens(data); \ - igt_assert(wait_for_suspended()); \ -} while (0) - -static void disable_or_dpms_all_screens(struct mode_set_data *data, bool dpms) -{ - if (dpms) - disable_all_screens_dpms(&ms_data); - else - disable_all_screens(&ms_data); -} - -#define disable_or_dpms_all_screens_and_wait(data, dpms) do { \ - disable_or_dpms_all_screens((data), (dpms)); \ - igt_assert(wait_for_suspended()); \ -} while (0) - -static bool init_modeset_params_for_type(struct mode_set_data *data, - struct modeset_params *params, - enum screen_type type) -{ - int i; - uint32_t connector_id = 0; - drmModeModeInfoPtr mode = NULL; - cairo_t *cr; - - for (i = 0; i < data->res->count_connectors; i++) { - drmModeConnectorPtr c = data->connectors[i]; - - if (type == SCREEN_TYPE_LPSP && - c->connector_type != DRM_MODE_CONNECTOR_eDP) - continue; - - if (type == SCREEN_TYPE_NON_LPSP && - c->connector_type == DRM_MODE_CONNECTOR_eDP) - continue; - - if (c->connection == DRM_MODE_CONNECTED && c->count_modes) { - connector_id = c->connector_id; - mode = &c->modes[0]; - break; - } - } - - if (!connector_id) - return false; - - igt_create_fb(drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_NONE, ¶ms->fb); - cr = igt_get_cairo_ctx(drm_fd, ¶ms->fb); - igt_paint_test_pattern(cr, mode->hdisplay, mode->vdisplay); - cairo_destroy(cr); - - params->crtc_id = data->res->crtcs[0]; - params->connector_id = connector_id; - params->mode = mode; - - return true; -} - -static void init_modeset_cached_params(struct mode_set_data *data) -{ - bool lpsp, non_lpsp; - - lpsp = init_modeset_params_for_type(data, &lpsp_mode_params, - SCREEN_TYPE_LPSP); - non_lpsp = init_modeset_params_for_type(data, &non_lpsp_mode_params, - SCREEN_TYPE_NON_LPSP); - - if (lpsp) - default_mode_params = &lpsp_mode_params; - else if (non_lpsp) - default_mode_params = &non_lpsp_mode_params; - else - default_mode_params = NULL; -} - -static bool set_mode_for_params(struct modeset_params *params) -{ - int rc; - - rc = drmModeSetCrtc(drm_fd, params->crtc_id, params->fb.fb_id, 0, 0, - ¶ms->connector_id, 1, params->mode); - return (rc == 0); -} - -#define set_mode_for_params_and_wait(params) do { \ - igt_assert(set_mode_for_params(params)); \ - igt_assert(wait_for_active()); \ -} while (0) - -static bool enable_one_screen_with_type(struct mode_set_data *data, - enum screen_type type) -{ - struct modeset_params *params = NULL; - - switch (type) { - case SCREEN_TYPE_ANY: - params = default_mode_params; - break; - case SCREEN_TYPE_LPSP: - params = &lpsp_mode_params; - break; - case SCREEN_TYPE_NON_LPSP: - params = &non_lpsp_mode_params; - break; - default: - igt_assert(0); - } - - if (!params) - return false; - - return set_mode_for_params(params); -} - -static void enable_one_screen(struct mode_set_data *data) -{ - /* SKIP if there are no connected screens. */ - igt_require(enable_one_screen_with_type(data, SCREEN_TYPE_ANY)); -} - -#define enable_one_screen_and_wait(data) do { \ - enable_one_screen(data); \ - igt_assert(wait_for_active()); \ -} while (0) - -static drmModePropertyBlobPtr get_connector_edid(drmModeConnectorPtr connector, - int index) -{ - bool found; - uint64_t prop_value; - drmModePropertyPtr prop; - drmModePropertyBlobPtr blob = NULL; - - found = kmstest_get_property(drm_fd, connector->connector_id, - DRM_MODE_OBJECT_CONNECTOR, "EDID", - NULL, &prop_value, &prop); - - if (found) { - igt_assert(prop->flags & DRM_MODE_PROP_BLOB); - igt_assert(prop->count_blobs == 0); - - blob = drmModeGetPropertyBlob(drm_fd, prop_value); - - drmModeFreeProperty(prop); - } - - return blob; -} - -static void init_mode_set_data(struct mode_set_data *data) -{ - int i; - - data->res = drmModeGetResources(drm_fd); - igt_assert(data->res); - igt_assert(data->res->count_connectors <= MAX_CONNECTORS); - - for (i = 0; i < data->res->count_connectors; i++) { - data->connectors[i] = drmModeGetConnector(drm_fd, - data->res->connectors[i]); - data->edids[i] = get_connector_edid(data->connectors[i], i); - } - - data->devid = intel_get_drm_devid(drm_fd); - - kmstest_set_vt_graphics_mode(); - - init_modeset_cached_params(&ms_data); -} - -static void fini_mode_set_data(struct mode_set_data *data) -{ - int i; - - for (i = 0; i < data->res->count_connectors; i++) { - drmModeFreeConnector(data->connectors[i]); - drmModeFreePropertyBlob(data->edids[i]); - } - drmModeFreeResources(data->res); -} - -static void get_drm_info(struct compare_data *data) -{ - int i; - - data->res = drmModeGetResources(drm_fd); - igt_assert(data->res); - - igt_assert(data->res->count_connectors <= MAX_CONNECTORS); - igt_assert(data->res->count_encoders <= MAX_ENCODERS); - igt_assert(data->res->count_crtcs <= MAX_CRTCS); - - for (i = 0; i < data->res->count_connectors; i++) { - data->connectors[i] = drmModeGetConnector(drm_fd, - data->res->connectors[i]); - data->edids[i] = get_connector_edid(data->connectors[i], i); - } - for (i = 0; i < data->res->count_encoders; i++) - data->encoders[i] = drmModeGetEncoder(drm_fd, - data->res->encoders[i]); - for (i = 0; i < data->res->count_crtcs; i++) - data->crtcs[i] = drmModeGetCrtc(drm_fd, data->res->crtcs[i]); -} - -static void free_drm_info(struct compare_data *data) -{ - int i; - - for (i = 0; i < data->res->count_connectors; i++) { - drmModeFreeConnector(data->connectors[i]); - drmModeFreePropertyBlob(data->edids[i]); - } - for (i = 0; i < data->res->count_encoders; i++) - drmModeFreeEncoder(data->encoders[i]); - for (i = 0; i < data->res->count_crtcs; i++) - drmModeFreeCrtc(data->crtcs[i]); - - drmModeFreeResources(data->res); -} - -#define COMPARE(d1, d2, data) igt_assert_eq(d1->data, d2->data) -#define COMPARE_ARRAY(d1, d2, size, data) do { \ - for (i = 0; i < size; i++) \ - igt_assert(d1->data[i] == d2->data[i]); \ -} while (0) - -static void assert_drm_resources_equal(struct compare_data *d1, - struct compare_data *d2) -{ - COMPARE(d1, d2, res->count_connectors); - COMPARE(d1, d2, res->count_encoders); - COMPARE(d1, d2, res->count_crtcs); - COMPARE(d1, d2, res->min_width); - COMPARE(d1, d2, res->max_width); - COMPARE(d1, d2, res->min_height); - COMPARE(d1, d2, res->max_height); -} - -static void assert_modes_equal(drmModeModeInfoPtr m1, drmModeModeInfoPtr m2) -{ - COMPARE(m1, m2, clock); - COMPARE(m1, m2, hdisplay); - COMPARE(m1, m2, hsync_start); - COMPARE(m1, m2, hsync_end); - COMPARE(m1, m2, htotal); - COMPARE(m1, m2, hskew); - COMPARE(m1, m2, vdisplay); - COMPARE(m1, m2, vsync_start); - COMPARE(m1, m2, vsync_end); - COMPARE(m1, m2, vtotal); - COMPARE(m1, m2, vscan); - COMPARE(m1, m2, vrefresh); - COMPARE(m1, m2, flags); - COMPARE(m1, m2, type); - igt_assert(strcmp(m1->name, m2->name) == 0); -} - -static void assert_drm_connectors_equal(drmModeConnectorPtr c1, - drmModeConnectorPtr c2) -{ - int i; - - COMPARE(c1, c2, connector_id); - COMPARE(c1, c2, connector_type); - COMPARE(c1, c2, connector_type_id); - COMPARE(c1, c2, mmWidth); - COMPARE(c1, c2, mmHeight); - COMPARE(c1, c2, count_modes); - COMPARE(c1, c2, count_props); - COMPARE(c1, c2, count_encoders); - COMPARE_ARRAY(c1, c2, c1->count_props, props); - COMPARE_ARRAY(c1, c2, c1->count_encoders, encoders); - - for (i = 0; i < c1->count_modes; i++) - assert_modes_equal(&c1->modes[0], &c2->modes[0]); -} - -static void assert_drm_encoders_equal(drmModeEncoderPtr e1, - drmModeEncoderPtr e2) -{ - COMPARE(e1, e2, encoder_id); - COMPARE(e1, e2, encoder_type); - COMPARE(e1, e2, possible_crtcs); - COMPARE(e1, e2, possible_clones); -} - -static void assert_drm_crtcs_equal(drmModeCrtcPtr c1, drmModeCrtcPtr c2) -{ - COMPARE(c1, c2, crtc_id); -} - -static void assert_drm_edids_equal(drmModePropertyBlobPtr e1, - drmModePropertyBlobPtr e2) -{ - if (!e1 && !e2) - return; - igt_assert(e1 && e2); - - COMPARE(e1, e2, id); - COMPARE(e1, e2, length); - - igt_assert(memcmp(e1->data, e2->data, e1->length) == 0); -} - -static void assert_drm_infos_equal(struct compare_data *d1, - struct compare_data *d2) -{ - int i; - - assert_drm_resources_equal(d1, d2); - - for (i = 0; i < d1->res->count_connectors; i++) { - assert_drm_connectors_equal(d1->connectors[i], - d2->connectors[i]); - assert_drm_edids_equal(d1->edids[i], d2->edids[i]); - } - - for (i = 0; i < d1->res->count_encoders; i++) - assert_drm_encoders_equal(d1->encoders[i], d2->encoders[i]); - - for (i = 0; i < d1->res->count_crtcs; i++) - assert_drm_crtcs_equal(d1->crtcs[i], d2->crtcs[i]); -} - -/* We could check the checksum too, but just the header is probably enough. */ -static bool edid_is_valid(const unsigned char *edid) -{ - char edid_header[] = { - 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, - }; - - return (memcmp(edid, edid_header, sizeof(edid_header)) == 0); -} - -static int count_drm_valid_edids(struct mode_set_data *data) -{ - int i, ret = 0; - - for (i = 0; i < data->res->count_connectors; i++) - if (data->edids[i] && edid_is_valid(data->edids[i]->data)) - ret++; - return ret; -} - -static bool i2c_edid_is_valid(int fd) -{ - int rc; - unsigned char edid[128] = {}; - struct i2c_msg msgs[] = { - { /* Start at 0. */ - .addr = 0x50, - .flags = 0, - .len = 1, - .buf = edid, - }, { /* Now read the EDID. */ - .addr = 0x50, - .flags = I2C_M_RD, - .len = 128, - .buf = edid, - } - }; - struct i2c_rdwr_ioctl_data msgset = { - .msgs = msgs, - .nmsgs = 2, - }; - - rc = ioctl(fd, I2C_RDWR, &msgset); - return (rc >= 0) ? edid_is_valid(edid) : false; -} - -static int count_i2c_valid_edids(void) -{ - int fd, ret = 0; - DIR *dir; - - struct dirent *dirent; - char full_name[32]; - - dir = opendir("/dev/"); - igt_assert(dir); - - while ((dirent = readdir(dir))) { - if (strncmp(dirent->d_name, "i2c-", 4) == 0) { - snprintf(full_name, 32, "/dev/%s", dirent->d_name); - fd = open(full_name, O_RDWR); - igt_assert(fd != -1); - if (i2c_edid_is_valid(fd)) - ret++; - close(fd); - } - } - - closedir(dir); - - return ret; -} - -static int count_vga_outputs(struct mode_set_data *data) -{ - int i, count = 0; - - for (i = 0; i < data->res->count_connectors; i++) - if (data->connectors[i]->connector_type == - DRM_MODE_CONNECTOR_VGA) - count++; - - return count; -} - -static void test_i2c(struct mode_set_data *data) -{ - int i2c_edids = count_i2c_valid_edids(); - int drm_edids = count_drm_valid_edids(data); - int vga_outputs = count_vga_outputs(data); - int diff; - - igt_debug("i2c edids:%d drm edids:%d vga outputs:%d\n", - i2c_edids, drm_edids, vga_outputs); - - /* We fail to detect some VGA monitors using our i2c method. If you look - * at the dmesg of these cases, you'll see the Kernel complaining about - * the EDID reading mostly FFs and then disabling bit-banging. Since we - * don't want to reimplement everything the Kernel does, let's just - * accept the fact that some VGA outputs won't be properly detected. */ - diff = drm_edids - i2c_edids; - igt_assert(diff <= vga_outputs && diff >= 0); -} - -static void setup_pc8(void) -{ - has_pc8 = false; - - /* Only Haswell supports the PC8 feature. */ - if (!IS_HASWELL(ms_data.devid) && !IS_BROADWELL(ms_data.devid)) - return; - - /* Make sure our Kernel supports MSR and the module is loaded. */ - igt_assert(system("modprobe -q msr > /dev/null 2>&1") != -1); - - msr_fd = open("/dev/cpu/0/msr", O_RDONLY); - igt_assert_f(msr_fd >= 0, - "Can't open /dev/cpu/0/msr.\n"); - - /* Non-ULT machines don't support PC8+. */ - if (!supports_pc8_plus_residencies()) - return; - - pc8_status_fd = igt_debugfs_open("i915_pc8_status", O_RDONLY); - igt_assert_f(pc8_status_fd >= 0, - "Can't open /sys/kernel/debug/dri/0/i915_pc8_status"); - - has_pc8 = true; -} - -/* If we want to actually reach PC8+ states, we need to properly configure all - * the devices on the system to allow this. This function will try to setup the - * things we know we need, but won't scream in case anything fails: we don't - * know which devices are present on your machine, so we can't really expect - * anything, just try to help with the more common problems. */ -static void setup_non_graphics_runtime_pm(void) -{ - int fd, i; - char *file_name; - - /* Disk runtime PM policies. */ - file_name = malloc(PATH_MAX); - for (i = 0; ; i++) { - - snprintf(file_name, PATH_MAX, - "/sys/class/scsi_host/host%d/link_power_management_policy", - i); - - fd = open(file_name, O_WRONLY); - if (fd < 0) - break; - - igt_assert(write(fd, "min_power\n", 10) == 10); - close(fd); - } - free(file_name); -} - -static void setup_environment(void) -{ - drm_fd = drm_open_any_master(); - - init_mode_set_data(&ms_data); - - setup_non_graphics_runtime_pm(); - - has_runtime_pm = igt_setup_runtime_pm(); - setup_pc8(); - - igt_info("Runtime PM support: %d\n", has_runtime_pm); - igt_info("PC8 residency support: %d\n", has_pc8); - - igt_require(has_runtime_pm); - -} - -static void teardown_environment(void) -{ - fini_mode_set_data(&ms_data); - drmClose(drm_fd); - close(msr_fd); - if (has_pc8) - close(pc8_status_fd); -} - -static void basic_subtest(void) -{ - disable_all_screens_and_wait(&ms_data); - - enable_one_screen_and_wait(&ms_data); -} - -static void pc8_residency_subtest(void) -{ - igt_require(has_pc8); - - /* Make sure PC8+ residencies move! */ - disable_all_screens(&ms_data); - igt_assert_f(pc8_plus_residency_changed(120), - "Machine is not reaching PC8+ states, please check its " - "configuration.\n"); - - /* Make sure PC8+ residencies stop! */ - enable_one_screen(&ms_data); - igt_assert_f(!pc8_plus_residency_changed(10), - "PC8+ residency didn't stop with screen enabled.\n"); -} - -static void modeset_subtest(enum screen_type type, int rounds, int wait_flags) -{ - int i; - - if (wait_flags & WAIT_PC8_RES) - igt_require(has_pc8); - - if (wait_flags & WAIT_EXTRA) - rounds /= 2; - - for (i = 0; i < rounds; i++) { - if (wait_flags & USE_DPMS) - disable_all_screens_dpms(&ms_data); - else - disable_all_screens(&ms_data); - - if (wait_flags & WAIT_STATUS) - igt_assert(wait_for_suspended()); - if (wait_flags & WAIT_PC8_RES) - igt_assert(pc8_plus_residency_changed(120)); - if (wait_flags & WAIT_EXTRA) - sleep(5); - - /* If we skip this line it's because the type of screen we want - * is not connected. */ - igt_require(enable_one_screen_with_type(&ms_data, type)); - if (wait_flags & WAIT_STATUS) - igt_assert(wait_for_active()); - if (wait_flags & WAIT_PC8_RES) - igt_assert(!pc8_plus_residency_changed(5)); - if (wait_flags & WAIT_EXTRA) - sleep(5); - } -} - -/* Test of the DRM resources reported by the IOCTLs are still the same. This - * ensures we still see the monitors with the same eyes. We get the EDIDs and - * compare them, which ensures we use DP AUX or GMBUS depending on what's - * connected. */ -static void drm_resources_equal_subtest(void) -{ - struct compare_data pre_suspend, during_suspend, post_suspend; - - enable_one_screen_and_wait(&ms_data); - get_drm_info(&pre_suspend); - igt_assert(wait_for_active()); - - disable_all_screens_and_wait(&ms_data); - get_drm_info(&during_suspend); - igt_assert(wait_for_suspended()); - - enable_one_screen_and_wait(&ms_data); - get_drm_info(&post_suspend); - igt_assert(wait_for_active()); - - assert_drm_infos_equal(&pre_suspend, &during_suspend); - assert_drm_infos_equal(&pre_suspend, &post_suspend); - - free_drm_info(&pre_suspend); - free_drm_info(&during_suspend); - free_drm_info(&post_suspend); -} - -static void i2c_subtest_check_environment(void) -{ - int i2c_dev_files = 0; - DIR *dev_dir; - struct dirent *dirent; - - /* Make sure the /dev/i2c-* files exist. */ - igt_assert(system("modprobe -q i2c-dev > /dev/null 2>&1") != -1); - - dev_dir = opendir("/dev"); - igt_assert(dev_dir); - while ((dirent = readdir(dev_dir))) { - if (strncmp(dirent->d_name, "i2c-", 4) == 0) - i2c_dev_files++; - } - closedir(dev_dir); - igt_require(i2c_dev_files); -} - -/* Try to use raw I2C, which also needs interrupts. */ -static void i2c_subtest(void) -{ - i2c_subtest_check_environment(); - - enable_one_screen_and_wait(&ms_data); - - disable_all_screens_and_wait(&ms_data); - test_i2c(&ms_data); - igt_assert(wait_for_suspended()); - - enable_one_screen(&ms_data); -} - -static void read_full_file(const char *name) -{ - int rc, fd; - char buf[128]; - - igt_assert_f(wait_for_suspended(), "File: %s\n", name); - - fd = open(name, O_RDONLY); - if (fd < 0) - return; - - do { - rc = read(fd, buf, ARRAY_SIZE(buf)); - } while (rc == ARRAY_SIZE(buf)); - - rc = close(fd); - igt_assert(rc == 0); - - igt_assert_f(wait_for_suspended(), "File: %s\n", name); -} - -static void read_files_from_dir(const char *name, int level) -{ - DIR *dir; - struct dirent *dirent; - char *full_name; - int rc; - - dir = opendir(name); - igt_assert(dir); - - full_name = malloc(PATH_MAX); - - igt_assert(level < 128); - - while ((dirent = readdir(dir))) { - struct stat stat_buf; - - if (strcmp(dirent->d_name, ".") == 0) - continue; - if (strcmp(dirent->d_name, "..") == 0) - continue; - - snprintf(full_name, PATH_MAX, "%s/%s", name, dirent->d_name); - - rc = lstat(full_name, &stat_buf); - igt_assert(rc == 0); - - if (S_ISDIR(stat_buf.st_mode)) - read_files_from_dir(full_name, level + 1); - - if (S_ISREG(stat_buf.st_mode)) - read_full_file(full_name); - } - - free(full_name); - closedir(dir); -} - -/* This test will probably pass, with a small chance of hanging the machine in - * case of bugs. Many of the bugs exercised by this patch just result in dmesg - * errors, so a "pass" here should be confirmed by a check on dmesg. */ -static void debugfs_read_subtest(void) -{ - const char *path = "/sys/kernel/debug/dri/0"; - DIR *dir; - - dir = opendir(path); - igt_require_f(dir, "Can't open the debugfs directory\n"); - closedir(dir); - - disable_all_screens_and_wait(&ms_data); - - read_files_from_dir(path, 0); -} - -/* Read the comment on debugfs_read_subtest(). */ -static void sysfs_read_subtest(void) -{ - const char *path = "/sys/devices/pci0000:00/0000:00:02.0"; - DIR *dir; - - dir = opendir(path); - igt_require_f(dir, "Can't open the sysfs directory\n"); - closedir(dir); - - disable_all_screens_and_wait(&ms_data); - - read_files_from_dir(path, 0); -} - -/* Make sure we don't suspend when we have the i915_forcewake_user file open. */ -static void debugfs_forcewake_user_subtest(void) -{ - int fd, rc; - - igt_require(intel_gen(ms_data.devid) >= 6); - - disable_all_screens_and_wait(&ms_data); - - fd = igt_open_forcewake_handle(); - igt_require(fd >= 0); - - if (has_runtime_pm) { - igt_assert(wait_for_active()); - sleep(10); - igt_assert(wait_for_active()); - } else { - igt_assert(wait_for_suspended()); - } - - rc = close(fd); - igt_assert(rc == 0); - - igt_assert(wait_for_suspended()); -} - -static void gem_mmap_subtest(bool gtt_mmap) -{ - int i; - uint32_t handle; - int buf_size = 8192; - uint8_t *gem_buf; - - /* Create, map and set data while the device is active. */ - enable_one_screen_and_wait(&ms_data); - - handle = gem_create(drm_fd, buf_size); - - if (gtt_mmap) - gem_buf = gem_mmap__gtt(drm_fd, handle, buf_size, - PROT_READ | PROT_WRITE); - else - gem_buf = gem_mmap__cpu(drm_fd, handle, 0, buf_size, 0); - - - for (i = 0; i < buf_size; i++) - gem_buf[i] = i & 0xFF; - - for (i = 0; i < buf_size; i++) - igt_assert(gem_buf[i] == (i & 0xFF)); - - /* Now suspend, read and modify. */ - disable_all_screens_and_wait(&ms_data); - - for (i = 0; i < buf_size; i++) - igt_assert(gem_buf[i] == (i & 0xFF)); - igt_assert(wait_for_suspended()); - - for (i = 0; i < buf_size; i++) - gem_buf[i] = (~i & 0xFF); - igt_assert(wait_for_suspended()); - - /* Now resume and see if it's still there. */ - enable_one_screen_and_wait(&ms_data); - for (i = 0; i < buf_size; i++) - igt_assert(gem_buf[i] == (~i & 0xFF)); - - igt_assert(munmap(gem_buf, buf_size) == 0); - - /* Now the opposite: suspend, and try to create the mmap while - * suspended. */ - disable_all_screens_and_wait(&ms_data); - - if (gtt_mmap) - gem_buf = gem_mmap__gtt(drm_fd, handle, buf_size, - PROT_READ | PROT_WRITE); - else - gem_buf = gem_mmap__cpu(drm_fd, handle, 0, buf_size, 0); - - igt_assert(wait_for_suspended()); - - for (i = 0; i < buf_size; i++) - gem_buf[i] = i & 0xFF; - - for (i = 0; i < buf_size; i++) - igt_assert(gem_buf[i] == (i & 0xFF)); - - igt_assert(wait_for_suspended()); - - /* Resume and check if it's still there. */ - enable_one_screen_and_wait(&ms_data); - for (i = 0; i < buf_size; i++) - igt_assert(gem_buf[i] == (i & 0xFF)); - - igt_assert(munmap(gem_buf, buf_size) == 0); - gem_close(drm_fd, handle); -} - -static void gem_pread_subtest(void) -{ - int i; - uint32_t handle; - int buf_size = 8192; - uint8_t *cpu_buf, *read_buf; - - cpu_buf = malloc(buf_size); - read_buf = malloc(buf_size); - igt_assert(cpu_buf); - igt_assert(read_buf); - memset(cpu_buf, 0, buf_size); - memset(read_buf, 0, buf_size); - - /* Create and set data while the device is active. */ - enable_one_screen_and_wait(&ms_data); - - handle = gem_create(drm_fd, buf_size); - - for (i = 0; i < buf_size; i++) - cpu_buf[i] = i & 0xFF; - - gem_write(drm_fd, handle, 0, cpu_buf, buf_size); - - gem_read(drm_fd, handle, 0, read_buf, buf_size); - - for (i = 0; i < buf_size; i++) - igt_assert(cpu_buf[i] == read_buf[i]); - - /* Now suspend, read and modify. */ - disable_all_screens_and_wait(&ms_data); - - memset(read_buf, 0, buf_size); - gem_read(drm_fd, handle, 0, read_buf, buf_size); - - for (i = 0; i < buf_size; i++) - igt_assert(cpu_buf[i] == read_buf[i]); - igt_assert(wait_for_suspended()); - - for (i = 0; i < buf_size; i++) - cpu_buf[i] = (~i & 0xFF); - gem_write(drm_fd, handle, 0, cpu_buf, buf_size); - igt_assert(wait_for_suspended()); - - /* Now resume and see if it's still there. */ - enable_one_screen_and_wait(&ms_data); - - memset(read_buf, 0, buf_size); - gem_read(drm_fd, handle, 0, read_buf, buf_size); - - for (i = 0; i < buf_size; i++) - igt_assert(cpu_buf[i] == read_buf[i]); - - gem_close(drm_fd, handle); - - free(cpu_buf); - free(read_buf); -} - -/* Paints a square of color $color, size $width x $height, at position $x x $y - * of $dst_handle, which contains pitch $pitch. */ -static void submit_blt_cmd(uint32_t dst_handle, uint16_t x, uint16_t y, - uint16_t width, uint16_t height, uint32_t pitch, - uint32_t color, uint32_t *presumed_dst_offset) -{ - int i, reloc_pos; - uint32_t batch_handle; - int batch_size = 8 * sizeof(uint32_t); - uint32_t batch_buf[batch_size]; - struct drm_i915_gem_execbuffer2 execbuf = {}; - struct drm_i915_gem_exec_object2 objs[2] = {{}, {}}; - struct drm_i915_gem_relocation_entry relocs[1] = {{}}; - struct drm_i915_gem_wait gem_wait; - - i = 0; - - if (intel_gen(ms_data.devid) >= 8) - batch_buf[i++] = XY_COLOR_BLT_CMD_NOLEN | - XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB | 0x5; - else - batch_buf[i++] = XY_COLOR_BLT_CMD_NOLEN | - XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB | 0x4; - batch_buf[i++] = (3 << 24) | (0xF0 << 16) | (pitch); - batch_buf[i++] = (y << 16) | x; - batch_buf[i++] = ((y + height) << 16) | (x + width); - reloc_pos = i; - batch_buf[i++] = *presumed_dst_offset; - if (intel_gen(ms_data.devid) >= 8) - batch_buf[i++] = 0; - batch_buf[i++] = color; - - batch_buf[i++] = MI_BATCH_BUFFER_END; - if (intel_gen(ms_data.devid) < 8) - batch_buf[i++] = MI_NOOP; - - igt_assert(i * sizeof(uint32_t) == batch_size); - - batch_handle = gem_create(drm_fd, batch_size); - gem_write(drm_fd, batch_handle, 0, batch_buf, batch_size); - - relocs[0].target_handle = dst_handle; - relocs[0].delta = 0; - relocs[0].offset = reloc_pos * sizeof(uint32_t); - relocs[0].presumed_offset = *presumed_dst_offset; - relocs[0].read_domains = 0; - relocs[0].write_domain = I915_GEM_DOMAIN_RENDER; - - objs[0].handle = dst_handle; - objs[0].alignment = 64; - - objs[1].handle = batch_handle; - objs[1].relocation_count = 1; - objs[1].relocs_ptr = (uintptr_t)relocs; - - execbuf.buffers_ptr = (uintptr_t)objs; - execbuf.buffer_count = 2; - execbuf.batch_len = batch_size; - execbuf.flags = I915_EXEC_BLT; - i915_execbuffer2_set_context_id(execbuf, 0); - - do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - - *presumed_dst_offset = relocs[0].presumed_offset; - - gem_wait.flags = 0; - gem_wait.timeout_ns = 10000000000LL; /* 10s */ - - gem_wait.bo_handle = batch_handle; - do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_WAIT, &gem_wait); - - gem_wait.bo_handle = dst_handle; - do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_WAIT, &gem_wait); - - gem_close(drm_fd, batch_handle); -} - -/* Make sure we can submit a batch buffer and verify its result. */ -static void gem_execbuf_subtest(void) -{ - int x, y; - uint32_t handle; - int bpp = 4; - int pitch = 128 * bpp; - int dst_size = 128 * 128 * bpp; /* 128x128 square */ - uint32_t *cpu_buf; - uint32_t presumed_offset = 0; - int sq_x = 5, sq_y = 10, sq_w = 15, sq_h = 20; - uint32_t color; - - /* Create and set data while the device is active. */ - enable_one_screen_and_wait(&ms_data); - - handle = gem_create(drm_fd, dst_size); - - cpu_buf = malloc(dst_size); - igt_assert(cpu_buf); - memset(cpu_buf, 0, dst_size); - gem_write(drm_fd, handle, 0, cpu_buf, dst_size); - - /* Now suspend and try it. */ - disable_all_screens_and_wait(&ms_data); - - color = 0x12345678; - submit_blt_cmd(handle, sq_x, sq_y, sq_w, sq_h, pitch, color, - &presumed_offset); - igt_assert(wait_for_suspended()); - - gem_read(drm_fd, handle, 0, cpu_buf, dst_size); - igt_assert(wait_for_suspended()); - for (y = 0; y < 128; y++) { - for (x = 0; x < 128; x++) { - uint32_t px = cpu_buf[y * 128 + x]; - - if (y >= sq_y && y < (sq_y + sq_h) && - x >= sq_x && x < (sq_x + sq_w)) - igt_assert(px == color); - else - igt_assert(px == 0); - } - } - - /* Now resume and check for it again. */ - enable_one_screen_and_wait(&ms_data); - - memset(cpu_buf, 0, dst_size); - gem_read(drm_fd, handle, 0, cpu_buf, dst_size); - for (y = 0; y < 128; y++) { - for (x = 0; x < 128; x++) { - uint32_t px = cpu_buf[y * 128 + x]; - - if (y >= sq_y && y < (sq_y + sq_h) && - x >= sq_x && x < (sq_x + sq_w)) - igt_assert(px == color); - else - igt_assert(px == 0); - } - } - - /* Now we'll do the opposite: do the blt while active, then read while - * suspended. We use the same spot, but a different color. As a bonus, - * we're testing the presumed_offset from the previous command. */ - color = 0x87654321; - submit_blt_cmd(handle, sq_x, sq_y, sq_w, sq_h, pitch, color, - &presumed_offset); - - disable_all_screens_and_wait(&ms_data); - - memset(cpu_buf, 0, dst_size); - gem_read(drm_fd, handle, 0, cpu_buf, dst_size); - for (y = 0; y < 128; y++) { - for (x = 0; x < 128; x++) { - uint32_t px = cpu_buf[y * 128 + x]; - - if (y >= sq_y && y < (sq_y + sq_h) && - x >= sq_x && x < (sq_x + sq_w)) - igt_assert(px == color); - else - igt_assert(px == 0); - } - } - - gem_close(drm_fd, handle); - - free(cpu_buf); -} - -/* Assuming execbuf already works, let's see what happens when we force many - * suspend/resume cycles with commands. */ -static void gem_execbuf_stress_subtest(int rounds, int wait_flags) -{ - int i; - int batch_size = 4 * sizeof(uint32_t); - uint32_t batch_buf[batch_size]; - uint32_t handle; - struct drm_i915_gem_execbuffer2 execbuf = {}; - struct drm_i915_gem_exec_object2 objs[1] = {{}}; - - if (wait_flags & WAIT_PC8_RES) - igt_require(has_pc8); - - i = 0; - batch_buf[i++] = MI_NOOP; - batch_buf[i++] = MI_NOOP; - batch_buf[i++] = MI_BATCH_BUFFER_END; - batch_buf[i++] = MI_NOOP; - igt_assert(i * sizeof(uint32_t) == batch_size); - - disable_all_screens_and_wait(&ms_data); - - handle = gem_create(drm_fd, batch_size); - gem_write(drm_fd, handle, 0, batch_buf, batch_size); - - objs[0].handle = handle; - - execbuf.buffers_ptr = (uintptr_t)objs; - execbuf.buffer_count = 1; - execbuf.batch_len = batch_size; - execbuf.flags = I915_EXEC_RENDER; - i915_execbuffer2_set_context_id(execbuf, 0); - - for (i = 0; i < rounds; i++) { - do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - - if (wait_flags & WAIT_STATUS) - igt_assert(wait_for_suspended()); - if (wait_flags & WAIT_PC8_RES) - igt_assert(pc8_plus_residency_changed(120)); - if (wait_flags & WAIT_EXTRA) - sleep(5); - } - - gem_close(drm_fd, handle); -} - -/* When this test was written, it triggered WARNs and DRM_ERRORs on dmesg. */ -static void gem_idle_subtest(void) -{ - disable_all_screens_and_wait(&ms_data); - - sleep(5); - - gem_quiescent_gpu(drm_fd); -} - -static void gem_evict_pwrite_subtest(void) -{ - static drm_intel_bufmgr *bufmgr; - uint32_t buf; - int i; - - bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096); - igt_assert(bufmgr); - igt_init_aperture_trashers(bufmgr); - - igt_trash_aperture(); - - disable_or_dpms_all_screens_and_wait(&ms_data, true); - igt_assert(wait_for_suspended()); - - buf = 0; - for (i = 0; i < num_trash_bos; i++) - gem_write(drm_fd, trash_bos[i]->handle, 0, &buf, sizeof(buf)); - - igt_cleanup_aperture_trashers(); - drm_intel_bufmgr_destroy(bufmgr); -} - -/* This also triggered WARNs on dmesg at some point. */ -static void reg_read_ioctl_subtest(void) -{ - struct drm_i915_reg_read rr = { - .offset = 0x2358, /* render ring timestamp */ - }; - - disable_all_screens_and_wait(&ms_data); - - do_ioctl(drm_fd, DRM_IOCTL_I915_REG_READ, &rr); - - igt_assert(wait_for_suspended()); -} - -static bool device_in_pci_d3(void) -{ - struct pci_device *pci_dev; - int rc; - uint16_t val; - - pci_dev = intel_get_pci_device(); - - rc = pci_device_cfg_read_u16(pci_dev, &val, 0xd4); - igt_assert(rc == 0); - - return (val & 0x3) == 0x3; -} - -static void pci_d3_state_subtest(void) -{ - igt_require(has_runtime_pm); - - disable_all_screens_and_wait(&ms_data); - - igt_assert(device_in_pci_d3()); - - enable_one_screen_and_wait(&ms_data); - - igt_assert(!device_in_pci_d3()); -} - -static void stay_subtest(void) -{ - disable_all_screens_and_wait(&ms_data); - - while (1) - sleep(600); -} - -static void system_suspend_subtest(void) -{ - disable_all_screens_and_wait(&ms_data); - igt_system_suspend_autoresume(); - igt_assert(wait_for_suspended()); -} - -static void system_suspend_execbuf_subtest(void) -{ - int i; - int batch_size = 4 * sizeof(uint32_t); - uint32_t batch_buf[batch_size]; - uint32_t handle; - struct drm_i915_gem_execbuffer2 execbuf = {}; - struct drm_i915_gem_exec_object2 objs[1] = {{}}; - - i = 0; - batch_buf[i++] = MI_NOOP; - batch_buf[i++] = MI_NOOP; - batch_buf[i++] = MI_BATCH_BUFFER_END; - batch_buf[i++] = MI_NOOP; - igt_assert(i * sizeof(uint32_t) == batch_size); - - handle = gem_create(drm_fd, batch_size); - gem_write(drm_fd, handle, 0, batch_buf, batch_size); - - objs[0].handle = handle; - - execbuf.buffers_ptr = (uintptr_t)objs; - execbuf.buffer_count = 1; - execbuf.batch_len = batch_size; - execbuf.flags = I915_EXEC_RENDER; - i915_execbuffer2_set_context_id(execbuf, 0); - - disable_all_screens_and_wait(&ms_data); - igt_system_suspend_autoresume(); - igt_assert(wait_for_suspended()); - - for (i = 0; i < 20; i++) { - do_ioctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); - igt_assert(wait_for_suspended()); - } - - gem_close(drm_fd, handle); -} - -static void system_suspend_modeset_subtest(void) -{ - disable_all_screens_and_wait(&ms_data); - igt_system_suspend_autoresume(); - igt_assert(wait_for_suspended()); - - enable_one_screen_and_wait(&ms_data); - disable_all_screens_and_wait(&ms_data); -} - -/* Enable a screen, activate DPMS, then do a modeset. At some point our driver - * produced WARNs on this case. */ -static void dpms_mode_unset_subtest(enum screen_type type) -{ - disable_all_screens_and_wait(&ms_data); - - igt_require(enable_one_screen_with_type(&ms_data, type)); - igt_assert(wait_for_active()); - - disable_all_screens_dpms(&ms_data); - igt_assert(wait_for_suspended()); - - disable_all_screens_and_wait(&ms_data); -} - -static void fill_igt_fb(struct igt_fb *fb, uint32_t color) -{ - int i; - uint32_t *ptr; - - ptr = gem_mmap__gtt(drm_fd, fb->gem_handle, fb->size, PROT_WRITE); - for (i = 0; i < fb->size/sizeof(uint32_t); i++) - ptr[i] = color; - igt_assert(munmap(ptr, fb->size) == 0); -} - -/* At some point, this test triggered WARNs in the Kernel. */ -static void cursor_subtest(bool dpms) -{ - int rc; - struct igt_fb cursor_fb1, cursor_fb2, cursor_fb3; - uint32_t crtc_id; - - disable_all_screens_and_wait(&ms_data); - - igt_require(default_mode_params); - crtc_id = default_mode_params->crtc_id; - - igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_ARGB8888, I915_TILING_NONE, - &cursor_fb1); - igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_ARGB8888, I915_TILING_NONE, - &cursor_fb2); - igt_create_fb(drm_fd, 64, 64, DRM_FORMAT_ARGB8888, I915_TILING_X, - &cursor_fb3); - - fill_igt_fb(&cursor_fb1, 0xFF00FFFF); - fill_igt_fb(&cursor_fb2, 0xFF00FF00); - fill_igt_fb(&cursor_fb3, 0xFFFF0000); - - set_mode_for_params_and_wait(default_mode_params); - - rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb1.gem_handle, - cursor_fb1.width, cursor_fb1.height); - igt_assert(rc == 0); - rc = drmModeMoveCursor(drm_fd, crtc_id, 0, 0); - igt_assert(rc == 0); - igt_assert(wait_for_active()); - - disable_or_dpms_all_screens_and_wait(&ms_data, dpms); - - /* First, just move the cursor. */ - rc = drmModeMoveCursor(drm_fd, crtc_id, 1, 1); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - /* Then unset it, and set a new one. */ - rc = drmModeSetCursor(drm_fd, crtc_id, 0, 0, 0); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb2.gem_handle, - cursor_fb1.width, cursor_fb2.height); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - /* Move the new cursor. */ - rc = drmModeMoveCursor(drm_fd, crtc_id, 2, 2); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - /* Now set a new one without unsetting the previous one. */ - rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb1.gem_handle, - cursor_fb1.width, cursor_fb1.height); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - /* Cursor 3 was created with tiling and painted with a GTT mmap, so - * hopefully it has some fences around it. */ - rc = drmModeRmFB(drm_fd, cursor_fb3.fb_id); - igt_assert(rc == 0); - gem_set_tiling(drm_fd, cursor_fb3.gem_handle, false, cursor_fb3.stride); - igt_assert(wait_for_suspended()); - - rc = drmModeSetCursor(drm_fd, crtc_id, cursor_fb3.gem_handle, - cursor_fb3.width, cursor_fb3.height); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - /* Make sure nothing remains for the other tests. */ - rc = drmModeSetCursor(drm_fd, crtc_id, 0, 0, 0); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); -} - -static enum plane_type get_plane_type(uint32_t plane_id) -{ - int i; - bool found; - uint64_t prop_value; - drmModePropertyPtr prop; - const char *enum_name = NULL; - enum plane_type type; - - found = kmstest_get_property(drm_fd, plane_id, DRM_MODE_OBJECT_PLANE, - "type", NULL, &prop_value, &prop); - igt_assert(found); - - igt_assert(prop->flags & DRM_MODE_PROP_ENUM); - igt_assert(prop_value < prop->count_enums); - - for (i = 0; i < prop->count_enums; i++) { - if (prop->enums[i].value == prop_value) { - enum_name = prop->enums[i].name; - break; - } - } - igt_assert(enum_name); - - if (strcmp(enum_name, "Overlay") == 0) - type = PLANE_OVERLAY; - else if (strcmp(enum_name, "Primary") == 0) - type = PLANE_PRIMARY; - else if (strcmp(enum_name, "Cursor") == 0) - type = PLANE_CURSOR; - else - igt_assert(0); - - drmModeFreeProperty(prop); - - return type; -} - -static void test_one_plane(bool dpms, uint32_t plane_id, - enum plane_type plane_type) -{ - int rc; - uint32_t plane_format, plane_w, plane_h; - uint32_t crtc_id; - struct igt_fb plane_fb1, plane_fb2; - int32_t crtc_x = 0, crtc_y = 0; - unsigned int tiling; - - disable_all_screens_and_wait(&ms_data); - - igt_require(default_mode_params); - crtc_id = default_mode_params->crtc_id; - - switch (plane_type) { - case PLANE_OVERLAY: - plane_format = DRM_FORMAT_XRGB8888; - plane_w = 64; - plane_h = 64; - tiling = I915_TILING_X; - break; - case PLANE_PRIMARY: - plane_format = DRM_FORMAT_XRGB8888; - plane_w = default_mode_params->mode->hdisplay; - plane_h = default_mode_params->mode->vdisplay; - tiling = I915_TILING_X; - break; - case PLANE_CURSOR: - plane_format = DRM_FORMAT_ARGB8888; - plane_w = 64; - plane_h = 64; - tiling = I915_TILING_NONE; - break; - default: - igt_assert(0); - break; - } - - igt_create_fb(drm_fd, plane_w, plane_h, plane_format, tiling, - &plane_fb1); - igt_create_fb(drm_fd, plane_w, plane_h, plane_format, tiling, - &plane_fb2); - fill_igt_fb(&plane_fb1, 0xFF00FFFF); - fill_igt_fb(&plane_fb2, 0xFF00FF00); - - set_mode_for_params_and_wait(default_mode_params); - - rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0, - 0, 0, plane_fb1.width, plane_fb1.height, - 0 << 16, 0 << 16, plane_fb1.width << 16, - plane_fb1.height << 16); - igt_assert(rc == 0); - - disable_or_dpms_all_screens_and_wait(&ms_data, dpms); - - /* Just move the plane around. */ - if (plane_type != PLANE_PRIMARY) { - crtc_x++; - crtc_y++; - } - rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0, - crtc_x, crtc_y, plane_fb1.width, plane_fb1.height, - 0 << 16, 0 << 16, plane_fb1.width << 16, - plane_fb1.height << 16); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - /* Unset, then change the plane. */ - rc = drmModeSetPlane(drm_fd, plane_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb2.fb_id, 0, - crtc_x, crtc_y, plane_fb2.width, plane_fb2.height, - 0 << 16, 0 << 16, plane_fb2.width << 16, - plane_fb2.height << 16); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - /* Now change the plane without unsetting first. */ - rc = drmModeSetPlane(drm_fd, plane_id, crtc_id, plane_fb1.fb_id, 0, - crtc_x, crtc_y, plane_fb1.width, plane_fb1.height, - 0 << 16, 0 << 16, plane_fb1.width << 16, - plane_fb1.height << 16); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); - - /* Make sure nothing remains for the other tests. */ - rc = drmModeSetPlane(drm_fd, plane_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - igt_assert(rc == 0); - igt_assert(wait_for_suspended()); -} - -/* This one also triggered WARNs on our driver at some point in time. */ -static void planes_subtest(bool universal, bool dpms) -{ - int i, rc, planes_tested = 0; - drmModePlaneResPtr planes; - - if (universal) { - rc = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, - 1); - igt_require(rc == 0); - } - - planes = drmModeGetPlaneResources(drm_fd); - for (i = 0; i < planes->count_planes; i++) { - drmModePlanePtr plane; - - plane = drmModeGetPlane(drm_fd, planes->planes[i]); - igt_assert(plane); - - /* We just pick the first CRTC on the list, so we can test for - * 0x1 as the index. */ - if (plane->possible_crtcs & 0x1) { - enum plane_type type; - - type = universal ? get_plane_type(plane->plane_id) : - PLANE_OVERLAY; - test_one_plane(dpms, plane->plane_id, type); - planes_tested++; - } - drmModeFreePlane(plane); - } - drmModeFreePlaneResources(planes); - - if (universal) { - rc = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0); - igt_assert(rc == 0); - - igt_assert(planes_tested >= 3); - } else { - igt_assert(planes_tested >= 1); - } -} - -static void fences_subtest(bool dpms) -{ - int i; - uint32_t *buf_ptr; - uint32_t tiling = false, swizzle; - struct modeset_params params; - - disable_all_screens_and_wait(&ms_data); - - igt_require(default_mode_params); - params.crtc_id = default_mode_params->crtc_id; - params.connector_id = default_mode_params->connector_id; - params.mode = default_mode_params->mode; - igt_create_fb(drm_fd, params.mode->hdisplay, params.mode->vdisplay, - DRM_FORMAT_XRGB8888, I915_TILING_X, ¶ms.fb); - - /* Even though we passed "true" as the tiling argument, double-check - * that the fb is really tiled. */ - gem_get_tiling(drm_fd, params.fb.gem_handle, &tiling, &swizzle); - igt_assert(tiling); - - buf_ptr = gem_mmap__gtt(drm_fd, params.fb.gem_handle, - params.fb.size, PROT_WRITE | PROT_READ); - for (i = 0; i < params.fb.size/sizeof(uint32_t); i++) - buf_ptr[i] = i; - - set_mode_for_params_and_wait(¶ms); - - disable_or_dpms_all_screens_and_wait(&ms_data, dpms); - - for (i = 0; i < params.fb.size/sizeof(uint32_t); i++) - igt_assert_eq(buf_ptr[i], i); - igt_assert(wait_for_suspended()); - - if (dpms) { - drmModeConnectorPtr c = NULL; - - for (i = 0; i < ms_data.res->count_connectors; i++) - if (ms_data.connectors[i]->connector_id == - params.connector_id) - c = ms_data.connectors[i]; - igt_assert(c); - - kmstest_set_connector_dpms(drm_fd, c, DRM_MODE_DPMS_ON); - } else { - set_mode_for_params(¶ms); - } - igt_assert(wait_for_active()); - - for (i = 0; i < params.fb.size/sizeof(uint32_t); i++) - igt_assert_eq(buf_ptr[i], i); - - igt_assert(munmap(buf_ptr, params.fb.size) == 0); -} - -int rounds = 40; -bool stay = false; - -static int opt_handler(int opt, int opt_index) -{ - switch (opt) { - case 'q': - rounds = 10; - break; - case 's': - stay = true; - break; - default: - igt_assert(0); - } - - return 0; -} - -int main(int argc, char *argv[]) -{ - const char *help_str = - " --quick\t\tMake the stress-tests not stressful, for quick regression testing.\n" - " --stay\t\tDisable all screen and try to go into runtime pm. Useful for debugging."; - static struct option long_options[] = { - {"quick", 0, 0, 'q'}, - {"stay", 0, 0, 's'}, - { 0, 0, 0, 0 } - }; - - igt_subtest_init_parse_opts(&argc, argv, "", long_options, - help_str, opt_handler); - - /* Skip instead of failing in case the machine is not prepared to reach - * PC8+. We don't want bug reports from cases where the machine is just - * not properly configured. */ - igt_fixture - setup_environment(); - - if (stay) - igt_subtest("stay") - stay_subtest(); - - /* Essential things */ - igt_subtest("rte") - basic_subtest(); - igt_subtest("drm-resources-equal") - drm_resources_equal_subtest(); - igt_subtest("pci-d3-state") - pci_d3_state_subtest(); - - /* Basic modeset */ - igt_subtest("modeset-lpsp") - modeset_subtest(SCREEN_TYPE_LPSP, 1, WAIT_STATUS); - igt_subtest("modeset-non-lpsp") - modeset_subtest(SCREEN_TYPE_NON_LPSP, 1, WAIT_STATUS); - igt_subtest("dpms-lpsp") - modeset_subtest(SCREEN_TYPE_LPSP, 1, WAIT_STATUS | USE_DPMS); - igt_subtest("dpms-non-lpsp") - modeset_subtest(SCREEN_TYPE_NON_LPSP, 1, WAIT_STATUS | USE_DPMS); - - /* GEM */ - igt_subtest("gem-mmap-cpu") - gem_mmap_subtest(false); - igt_subtest("gem-mmap-gtt") - gem_mmap_subtest(true); - igt_subtest("gem-pread") - gem_pread_subtest(); - igt_subtest("gem-execbuf") - gem_execbuf_subtest(); - igt_subtest("gem-idle") - gem_idle_subtest(); - igt_subtest("gem-evict-pwrite") - gem_evict_pwrite_subtest(); - - /* Planes and cursors */ - igt_subtest("cursor") - cursor_subtest(false); - igt_subtest("cursor-dpms") - cursor_subtest(true); - igt_subtest("legacy-planes") - planes_subtest(false, false); - igt_subtest("legacy-planes-dpms") - planes_subtest(false, true); - igt_subtest("universal-planes") - planes_subtest(true, false); - igt_subtest("universal-planes-dpms") - planes_subtest(true, true); - - /* Misc */ - igt_subtest("reg-read-ioctl") - reg_read_ioctl_subtest(); - igt_subtest("i2c") - i2c_subtest(); - igt_subtest("pc8-residency") - pc8_residency_subtest(); - igt_subtest("debugfs-read") - debugfs_read_subtest(); - igt_subtest("debugfs-forcewake-user") - debugfs_forcewake_user_subtest(); - igt_subtest("sysfs-read") - sysfs_read_subtest(); - igt_subtest("dpms-mode-unset-lpsp") - dpms_mode_unset_subtest(SCREEN_TYPE_LPSP); - igt_subtest("dpms-mode-unset-non-lpsp") - dpms_mode_unset_subtest(SCREEN_TYPE_NON_LPSP); - igt_subtest("fences") - fences_subtest(false); - igt_subtest("fences-dpms") - fences_subtest(true); - - /* Modeset stress */ - igt_subtest("modeset-lpsp-stress") - modeset_subtest(SCREEN_TYPE_LPSP, rounds, WAIT_STATUS); - igt_subtest("modeset-non-lpsp-stress") - modeset_subtest(SCREEN_TYPE_NON_LPSP, rounds, WAIT_STATUS); - igt_subtest("modeset-lpsp-stress-no-wait") - modeset_subtest(SCREEN_TYPE_LPSP, rounds, DONT_WAIT); - igt_subtest("modeset-non-lpsp-stress-no-wait") - modeset_subtest(SCREEN_TYPE_NON_LPSP, rounds, DONT_WAIT); - igt_subtest("modeset-pc8-residency-stress") - modeset_subtest(SCREEN_TYPE_ANY, rounds, WAIT_PC8_RES); - igt_subtest("modeset-stress-extra-wait") - modeset_subtest(SCREEN_TYPE_ANY, rounds, - WAIT_STATUS | WAIT_EXTRA); - - /* System suspend */ - igt_subtest("system-suspend") - system_suspend_subtest(); - igt_subtest("system-suspend-execbuf") - system_suspend_execbuf_subtest(); - igt_subtest("system-suspend-modeset") - system_suspend_modeset_subtest(); - - /* GEM stress */ - igt_subtest("gem-execbuf-stress") - gem_execbuf_stress_subtest(rounds, WAIT_STATUS); - igt_subtest("gem-execbuf-stress-pc8") - gem_execbuf_stress_subtest(rounds, WAIT_PC8_RES); - igt_subtest("gem-execbuf-stress-extra-wait") - gem_execbuf_stress_subtest(rounds, WAIT_STATUS | WAIT_EXTRA); - - igt_fixture - teardown_environment(); - - igt_exit(); -} diff --git a/tests/pm_rps.c b/tests/pm_rps.c deleted file mode 100644 index d6897881..00000000 --- a/tests/pm_rps.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright © 2012 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: - * Ben Widawsky <ben@bwidawsk.net> - * Jeff McGee <jeff.mcgee@intel.com> - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#include <time.h> -#include <sys/wait.h> - -#include "drmtest.h" -#include "intel_io.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "igt_gt.h" -#include "ioctl_wrappers.h" - -static int drm_fd; - -static const char sysfs_base_path[] = "/sys/class/drm/card%d/gt_%s_freq_mhz"; -enum { - CUR, - MIN, - MAX, - RP0, - RP1, - RPn, - NUMFREQ -}; - -static int origfreqs[NUMFREQ]; - -struct junk { - const char *name; - const char *mode; - FILE *filp; -} stuff[] = { - { "cur", "r", NULL }, { "min", "rb+", NULL }, { "max", "rb+", NULL }, { "RP0", "r", NULL }, { "RP1", "r", NULL }, { "RPn", "r", NULL }, { NULL, NULL, NULL } -}; - -static int readval(FILE *filp) -{ - int val; - int scanned; - - rewind(filp); - scanned = fscanf(filp, "%d", &val); - igt_assert(scanned == 1); - - return val; -} - -static void read_freqs(int *freqs) -{ - int i; - - for (i = 0; i < NUMFREQ; i++) - freqs[i] = readval(stuff[i].filp); -} - -static void nsleep(unsigned long ns) -{ - struct timespec ts; - int ret; - - ts.tv_sec = 0; - ts.tv_nsec = ns; - do { - struct timespec rem; - - ret = nanosleep(&ts, &rem); - igt_assert(ret == 0 || errno == EINTR); - ts = rem; - } while (ret && errno == EINTR); -} - -static void wait_freq_settle(void) -{ - int timeout = 10; - - while (1) { - int freqs[NUMFREQ]; - - read_freqs(freqs); - if (freqs[CUR] >= freqs[MIN] && freqs[CUR] <= freqs[MAX]) - break; - nsleep(1000000); - if (!timeout--) - break; - } -} - -static int do_writeval(FILE *filp, int val, int lerrno, bool readback_check) -{ - int ret, orig; - - orig = readval(filp); - rewind(filp); - ret = fprintf(filp, "%d", val); - - if (lerrno) { - /* Expecting specific error */ - igt_assert(ret == EOF && errno == lerrno); - if (readback_check) - igt_assert_eq(readval(filp), orig); - } else { - /* Expecting no error */ - igt_assert_neq(ret, 0); - wait_freq_settle(); - if (readback_check) - igt_assert_eq(readval(filp), val); - } - - return ret; -} -#define writeval(filp, val) do_writeval(filp, val, 0, true) -#define writeval_inval(filp, val) do_writeval(filp, val, EINVAL, true) -#define writeval_nocheck(filp, val) do_writeval(filp, val, 0, false) - -static void checkit(const int *freqs) -{ - igt_assert_lte(freqs[MIN], freqs[MAX]); - igt_assert_lte(freqs[CUR], freqs[MAX]); - igt_assert_lte(freqs[MIN], freqs[CUR]); - igt_assert_lte(freqs[RPn], freqs[MIN]); - igt_assert_lte(freqs[MAX], freqs[RP0]); - igt_assert_lte(freqs[RP1], freqs[RP0]); - igt_assert_lte(freqs[RPn], freqs[RP1]); - igt_assert_neq(freqs[RP0], 0); - igt_assert_neq(freqs[RP1], 0); -} - -static void matchit(const int *freqs1, const int *freqs2) -{ - igt_assert_eq(freqs1[CUR], freqs2[CUR]); - igt_assert_eq(freqs1[MIN], freqs2[MIN]); - igt_assert_eq(freqs1[MAX], freqs2[MAX]); - igt_assert_eq(freqs1[RP0], freqs2[RP0]); - igt_assert_eq(freqs1[RP1], freqs2[RP1]); - igt_assert_eq(freqs1[RPn], freqs2[RPn]); -} - -static void dump(const int *freqs) -{ - int i; - - igt_debug("gt freq (MHz):"); - for (i = 0; i < NUMFREQ; i++) - igt_debug(" %s=%d", stuff[i].name, freqs[i]); - - igt_debug("\n"); -} - -enum load { - LOW, - HIGH -}; - -static struct load_helper { - int devid; - int has_ppgtt; - drm_intel_bufmgr *bufmgr; - struct intel_batchbuffer *batch; - drm_intel_bo *target_buffer; - enum load load; - bool exit; - struct igt_helper_process igt_proc; - drm_intel_bo *src, *dst; -} lh; - -static void load_helper_signal_handler(int sig) -{ - if (sig == SIGUSR2) - lh.load = lh.load == LOW ? HIGH : LOW; - else - lh.exit = true; -} - -static void emit_store_dword_imm(uint32_t val) -{ - int cmd; - struct intel_batchbuffer *batch = lh.batch; - - cmd = MI_STORE_DWORD_IMM; - if (!lh.has_ppgtt) - cmd |= MI_MEM_VIRTUAL; - - BEGIN_BATCH(4, 0); /* just ignore the reloc we emit and count dwords */ - OUT_BATCH(cmd); - if (batch->gen >= 8) { - OUT_RELOC(lh.target_buffer, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - } else { - OUT_BATCH(0); /* reserved */ - OUT_RELOC(lh.target_buffer, I915_GEM_DOMAIN_INSTRUCTION, - I915_GEM_DOMAIN_INSTRUCTION, 0); - } - OUT_BATCH(val); - ADVANCE_BATCH(); -} - -#define LOAD_HELPER_PAUSE_USEC 500 -#define LOAD_HELPER_BO_SIZE (16*1024*1024) -static void load_helper_set_load(enum load load) -{ - igt_assert(lh.igt_proc.running); - - if (lh.load == load) - return; - - lh.load = load; - kill(lh.igt_proc.pid, SIGUSR2); -} - -static void load_helper_run(enum load load) -{ - /* - * FIXME fork helpers won't get cleaned up when started from within a - * subtest, so handle the case where it sticks around a bit too long. - */ - if (lh.igt_proc.running) { - load_helper_set_load(load); - return; - } - - lh.load = load; - - igt_fork_helper(&lh.igt_proc) { - uint32_t val = 0; - - signal(SIGUSR1, load_helper_signal_handler); - signal(SIGUSR2, load_helper_signal_handler); - - while (!lh.exit) { - if (lh.load == HIGH) - intel_copy_bo(lh.batch, lh.dst, lh.src, - LOAD_HELPER_BO_SIZE); - - emit_store_dword_imm(val); - intel_batchbuffer_flush_on_ring(lh.batch, 0); - val++; - - /* Lower the load by pausing after every submitted - * write. */ - if (lh.load == LOW) - usleep(LOAD_HELPER_PAUSE_USEC); - } - - /* Map buffer to stall for write completion */ - drm_intel_bo_map(lh.target_buffer, 0); - drm_intel_bo_unmap(lh.target_buffer); - - igt_debug("load helper sent %u dword writes\n", val); - } -} - -static void load_helper_stop(void) -{ - kill(lh.igt_proc.pid, SIGUSR1); - igt_assert(igt_wait_helper(&lh.igt_proc) == 0); -} - -static void load_helper_init(void) -{ - lh.devid = intel_get_drm_devid(drm_fd); - lh.has_ppgtt = gem_uses_aliasing_ppgtt(drm_fd); - - /* MI_STORE_DATA can only use GTT address on gen4+/g33 and needs - * snoopable mem on pre-gen6. Hence load-helper only works on gen6+, but - * that's also all we care about for the rps testcase*/ - igt_assert(intel_gen(lh.devid) >= 6); - lh.bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096); - igt_assert(lh.bufmgr); - - drm_intel_bufmgr_gem_enable_reuse(lh.bufmgr); - - lh.batch = intel_batchbuffer_alloc(lh.bufmgr, lh.devid); - igt_assert(lh.batch); - - lh.target_buffer = drm_intel_bo_alloc(lh.bufmgr, "target bo", - 4096, 4096); - igt_assert(lh.target_buffer); - - lh.dst = drm_intel_bo_alloc(lh.bufmgr, "dst bo", - LOAD_HELPER_BO_SIZE, 4096); - igt_assert(lh.dst); - lh.src = drm_intel_bo_alloc(lh.bufmgr, "src bo", - LOAD_HELPER_BO_SIZE, 4096); - igt_assert(lh.src); -} - -static void load_helper_deinit(void) -{ - if (lh.igt_proc.running) - load_helper_stop(); - - if (lh.target_buffer) - drm_intel_bo_unreference(lh.target_buffer); - if (lh.src) - drm_intel_bo_unreference(lh.src); - if (lh.dst) - drm_intel_bo_unreference(lh.dst); - - if (lh.batch) - intel_batchbuffer_free(lh.batch); - - if (lh.bufmgr) - drm_intel_bufmgr_destroy(lh.bufmgr); -} - -static void do_load_gpu(void) -{ - load_helper_run(LOW); - nsleep(10000000); - load_helper_stop(); -} - -/* Return a frequency rounded by HW to the nearest supported value */ -static int get_hw_rounded_freq(int target) -{ - int freqs[NUMFREQ]; - int old_freq; - int idx; - int ret; - - read_freqs(freqs); - - if (freqs[MIN] > target) - idx = MIN; - else - idx = MAX; - - old_freq = freqs[idx]; - writeval_nocheck(stuff[idx].filp, target); - read_freqs(freqs); - ret = freqs[idx]; - writeval_nocheck(stuff[idx].filp, old_freq); - - return ret; -} - -static void min_max_config(void (*check)(void), bool load_gpu) -{ - int fmid = (origfreqs[RPn] + origfreqs[RP0]) / 2; - - /* - * hw (and so kernel) rounds to the nearest value supported by - * the given platform. - */ - fmid = get_hw_rounded_freq(fmid); - - igt_debug("\nCheck original min and max...\n"); - if (load_gpu) - do_load_gpu(); - check(); - - igt_debug("\nSet min=RPn and max=RP0...\n"); - writeval(stuff[MIN].filp, origfreqs[RPn]); - writeval(stuff[MAX].filp, origfreqs[RP0]); - if (load_gpu) - do_load_gpu(); - check(); - - igt_debug("\nIncrease min to midpoint...\n"); - writeval(stuff[MIN].filp, fmid); - check(); - - igt_debug("\nIncrease min to RP0...\n"); - writeval(stuff[MIN].filp, origfreqs[RP0]); - check(); - - igt_debug("\nIncrease min above RP0 (invalid)...\n"); - writeval_inval(stuff[MIN].filp, origfreqs[RP0] + 1000); - check(); - - igt_debug("\nDecrease max to RPn (invalid)...\n"); - writeval_inval(stuff[MAX].filp, origfreqs[RPn]); - check(); - - igt_debug("\nDecrease min to midpoint...\n"); - writeval(stuff[MIN].filp, fmid); - if (load_gpu) - do_load_gpu(); - check(); - - igt_debug("\nDecrease min to RPn...\n"); - writeval(stuff[MIN].filp, origfreqs[RPn]); - if (load_gpu) - do_load_gpu(); - check(); - - igt_debug("\nDecrease min below RPn (invalid)...\n"); - writeval_inval(stuff[MIN].filp, 0); - check(); - - igt_debug("\nDecrease max to midpoint...\n"); - writeval(stuff[MAX].filp, fmid); - check(); - - igt_debug("\nDecrease max to RPn...\n"); - writeval(stuff[MAX].filp, origfreqs[RPn]); - check(); - - igt_debug("\nDecrease max below RPn (invalid)...\n"); - writeval_inval(stuff[MAX].filp, 0); - check(); - - igt_debug("\nIncrease min to RP0 (invalid)...\n"); - writeval_inval(stuff[MIN].filp, origfreqs[RP0]); - check(); - - igt_debug("\nIncrease max to midpoint...\n"); - writeval(stuff[MAX].filp, fmid); - check(); - - igt_debug("\nIncrease max to RP0...\n"); - writeval(stuff[MAX].filp, origfreqs[RP0]); - check(); - - igt_debug("\nIncrease max above RP0 (invalid)...\n"); - writeval_inval(stuff[MAX].filp, origfreqs[RP0] + 1000); - check(); - - writeval(stuff[MIN].filp, origfreqs[MIN]); - writeval(stuff[MAX].filp, origfreqs[MAX]); -} - -static void basic_check(void) -{ - int freqs[NUMFREQ]; - - read_freqs(freqs); - dump(freqs); - checkit(freqs); -} - -#define IDLE_WAIT_TIMESTEP_MSEC 100 -#define IDLE_WAIT_TIMEOUT_MSEC 10000 -static void idle_check(void) -{ - int freqs[NUMFREQ]; - int wait = 0; - - /* Monitor frequencies until cur settles down to min, which should - * happen within the allotted time */ - do { - read_freqs(freqs); - dump(freqs); - checkit(freqs); - if (freqs[CUR] == freqs[MIN]) - break; - usleep(1000 * IDLE_WAIT_TIMESTEP_MSEC); - wait += IDLE_WAIT_TIMESTEP_MSEC; - } while (wait < IDLE_WAIT_TIMEOUT_MSEC); - - igt_assert_eq(freqs[CUR], freqs[MIN]); - igt_debug("Required %d msec to reach cur=min\n", wait); -} - -#define LOADED_WAIT_TIMESTEP_MSEC 100 -#define LOADED_WAIT_TIMEOUT_MSEC 3000 -static void loaded_check(void) -{ - int freqs[NUMFREQ]; - int wait = 0; - - /* Monitor frequencies until cur increases to max, which should - * happen within the allotted time */ - do { - read_freqs(freqs); - dump(freqs); - checkit(freqs); - if (freqs[CUR] == freqs[MAX]) - break; - usleep(1000 * LOADED_WAIT_TIMESTEP_MSEC); - wait += LOADED_WAIT_TIMESTEP_MSEC; - } while (wait < LOADED_WAIT_TIMEOUT_MSEC); - - igt_assert_eq(freqs[CUR], freqs[MAX]); - igt_debug("Required %d msec to reach cur=max\n", wait); -} - -#define STABILIZE_WAIT_TIMESTEP_MSEC 100 -#define STABILIZE_WAIT_TIMEOUT_MSEC 10000 -static void stabilize_check(int *freqs) -{ - int wait = 0; - - do { - read_freqs(freqs); - dump(freqs); - usleep(1000 * STABILIZE_WAIT_TIMESTEP_MSEC); - wait += STABILIZE_WAIT_TIMESTEP_MSEC; - } while (wait < STABILIZE_WAIT_TIMEOUT_MSEC); - - igt_debug("Waited %d msec to stabilize cur\n", wait); -} - -static void reset(void) -{ - int pre_freqs[NUMFREQ]; - int post_freqs[NUMFREQ]; - - /* - * quiescent_gpu upsets the gpu and makes it get pegged to max somehow. - * Don't ask. - */ - sleep(10); - - igt_debug("Apply low load...\n"); - load_helper_run(LOW); - stabilize_check(pre_freqs); - - igt_debug("Stop rings...\n"); - igt_set_stop_rings(STOP_RING_DEFAULTS); - while (igt_get_stop_rings()) - usleep(1000 * 100); - igt_debug("Ring stop cleared\n"); - - igt_debug("Apply high load...\n"); - load_helper_set_load(HIGH); - loaded_check(); - - igt_debug("Apply low load...\n"); - load_helper_set_load(LOW); - stabilize_check(post_freqs); - matchit(pre_freqs, post_freqs); - - igt_debug("Apply high load...\n"); - load_helper_set_load(HIGH); - loaded_check(); - - igt_debug("Removing load...\n"); - load_helper_stop(); - idle_check(); -} - -static void blocking(void) -{ - int pre_freqs[NUMFREQ]; - int post_freqs[NUMFREQ]; - - int fd = drm_open_any(); - igt_assert(fd >= 0); - - /* - * quiescent_gpu upsets the gpu and makes it get pegged to max somehow. - * Don't ask. - */ - sleep(10); - - igt_debug("Apply low load...\n"); - load_helper_run(LOW); - stabilize_check(pre_freqs); - load_helper_stop(); - - sleep(5); - - igt_debug("Kick gpu hard ...\n"); - /* This relies on the blocking waits in quiescent_gpu and the kernel - * boost logic to ramp the gpu to full load. */ - gem_quiescent_gpu(fd); - gem_quiescent_gpu(fd); - - igt_debug("Apply low load again...\n"); - load_helper_run(LOW); - stabilize_check(post_freqs); - load_helper_stop(); - matchit(pre_freqs, post_freqs); - - igt_debug("Removing load...\n"); - idle_check(); -} - -static void pm_rps_exit_handler(int sig) -{ - if (origfreqs[MIN] > readval(stuff[MAX].filp)) { - writeval(stuff[MAX].filp, origfreqs[MAX]); - writeval(stuff[MIN].filp, origfreqs[MIN]); - } else { - writeval(stuff[MIN].filp, origfreqs[MIN]); - writeval(stuff[MAX].filp, origfreqs[MAX]); - } - - load_helper_deinit(); - close(drm_fd); -} - -igt_main -{ - igt_skip_on_simulation(); - - igt_fixture { - const int device = drm_get_card(); - struct junk *junk = stuff; - int ret; - - /* Use drm_open_any to verify device existence */ - drm_fd = drm_open_any(); - - do { - int val = -1; - char *path; - ret = asprintf(&path, sysfs_base_path, device, junk->name); - igt_assert(ret != -1); - junk->filp = fopen(path, junk->mode); - igt_require(junk->filp); - setbuf(junk->filp, NULL); - - val = readval(junk->filp); - igt_assert(val >= 0); - junk++; - } while(junk->name != NULL); - - read_freqs(origfreqs); - - igt_install_exit_handler(pm_rps_exit_handler); - - load_helper_init(); - } - - igt_subtest("basic-api") - min_max_config(basic_check, false); - - igt_subtest("min-max-config-idle") - min_max_config(idle_check, true); - - igt_subtest("min-max-config-loaded") { - load_helper_run(HIGH); - min_max_config(loaded_check, false); - load_helper_stop(); - } - - igt_subtest("reset") - reset(); - - igt_subtest("blocking") - blocking(); -} diff --git a/tests/prime_nv_api.c b/tests/prime_nv_api.c deleted file mode 100644 index 99d5cf29..00000000 --- a/tests/prime_nv_api.c +++ /dev/null @@ -1,413 +0,0 @@ -/* wierd use of API tests */ - -/* test1- export buffer from intel, import same fd twice into nouveau, - check handles match - test2 - export buffer from intel, import fd once, close fd, try import again - fail if it succeeds - test3 - export buffer from intel, import twice on nouveau, check handle is the same - test4 - export handle twice from intel, import into nouveau twice, check handle is the same -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> - -#include "intel_bufmgr.h" -#include "nouveau.h" -#include "intel_io.h" -#include "intel_batchbuffer.h" -#include "drmtest.h" -#include "intel_chipset.h" - -#define BO_SIZE (256*1024) - -int intel_fd = -1, intel_fd2 = -1, nouveau_fd = -1, nouveau_fd2 = -1; -drm_intel_bufmgr *bufmgr; -drm_intel_bufmgr *bufmgr2; -struct nouveau_device *ndev, *ndev2; -struct nouveau_client *nclient, *nclient2; -uint32_t devid; -struct intel_batchbuffer *intel_batch; - -static void find_and_open_devices(void) -{ - int i; - char path[80]; - struct stat buf; - FILE *fl; - char vendor_id[8]; - int venid; - for (i = 0; i < 9; i++) { - char *ret; - - sprintf(path, "/sys/class/drm/card%d/device/vendor", i); - if (stat(path, &buf)) - break; - - fl = fopen(path, "r"); - if (!fl) - break; - - ret = fgets(vendor_id, 8, fl); - igt_assert(ret); - fclose(fl); - - venid = strtoul(vendor_id, NULL, 16); - sprintf(path, "/dev/dri/card%d", i); - if (venid == 0x8086) { - intel_fd = open(path, O_RDWR); - igt_assert(intel_fd); - intel_fd2 = open(path, O_RDWR); - igt_assert(intel_fd2); - } else if (venid == 0x10de) { - nouveau_fd = open(path, O_RDWR); - igt_assert(nouveau_fd); - nouveau_fd2 = open(path, O_RDWR); - igt_assert(nouveau_fd2); - } - } -} - -static void test_i915_nv_import_twice(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo = NULL, *nvbo2 = NULL; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - igt_assert(drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd) == 0); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - igt_assert(nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2) == 0); - close(prime_fd); - - nouveau_bo_ref(NULL, &nvbo2); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -static void test_i915_nv_import_twice_check_flink_name(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo = NULL, *nvbo2 = NULL; - uint32_t flink_name1, flink_name2; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - igt_assert(drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd) == 0); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - igt_assert(nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2) == 0); - close(prime_fd); - - igt_assert(nouveau_bo_name_get(nvbo, &flink_name1) == 0); - igt_assert(nouveau_bo_name_get(nvbo2, &flink_name2) == 0); - - igt_assert(flink_name1 == flink_name2); - - nouveau_bo_ref(NULL, &nvbo2); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -static void test_i915_nv_reimport_twice_check_flink_name(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo = NULL, *nvbo2 = NULL; - uint32_t flink_name1, flink_name2; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - igt_assert(drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd) == 0); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - - /* create a new dma-buf */ - close(prime_fd); - igt_assert(drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd) == 0); - - igt_assert(nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2) == 0); - close(prime_fd); - - igt_assert(nouveau_bo_name_get(nvbo, &flink_name1) == 0); - igt_assert(nouveau_bo_name_get(nvbo2, &flink_name2) == 0); - - igt_assert(flink_name1 == flink_name2); - - nouveau_bo_ref(NULL, &nvbo2); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -static void test_nv_i915_import_twice_check_flink_name(void) -{ - drm_intel_bo *intel_bo = NULL, *intel_bo2 = NULL; - int prime_fd; - struct nouveau_bo *nvbo = NULL; - uint32_t flink_name1, flink_name2; - - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, BO_SIZE, NULL, &nvbo) == 0); - - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - - intel_bo = drm_intel_bo_gem_create_from_prime(bufmgr, prime_fd, BO_SIZE); - igt_assert(intel_bo); - - intel_bo2 = drm_intel_bo_gem_create_from_prime(bufmgr2, prime_fd, BO_SIZE); - igt_assert(intel_bo2); - close(prime_fd); - - igt_assert(drm_intel_bo_flink(intel_bo, &flink_name1) == 0); - igt_assert(drm_intel_bo_flink(intel_bo2, &flink_name2) == 0); - - igt_assert(flink_name1 == flink_name2); - - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(intel_bo); - drm_intel_bo_unreference(intel_bo2); -} - -static void test_nv_i915_reimport_twice_check_flink_name(void) -{ - drm_intel_bo *intel_bo = NULL, *intel_bo2 = NULL; - int prime_fd; - struct nouveau_bo *nvbo = NULL; - uint32_t flink_name1, flink_name2; - - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, BO_SIZE, NULL, &nvbo) == 0); - - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - - intel_bo = drm_intel_bo_gem_create_from_prime(bufmgr, prime_fd, BO_SIZE); - igt_assert(intel_bo); - close(prime_fd); - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - - intel_bo2 = drm_intel_bo_gem_create_from_prime(bufmgr2, prime_fd, BO_SIZE); - igt_assert(intel_bo2); - close(prime_fd); - - igt_assert(drm_intel_bo_flink(intel_bo, &flink_name1) == 0); - igt_assert(drm_intel_bo_flink(intel_bo2, &flink_name2) == 0); - - igt_assert(flink_name1 == flink_name2); - - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(intel_bo); - drm_intel_bo_unreference(intel_bo2); -} - -static void test_i915_nv_import_vs_close(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo = NULL, *nvbo2 = NULL; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - igt_assert(test_intel_bo); - - igt_assert(drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd) == 0); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - close(prime_fd); - igt_assert(nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2) < 0); - - nouveau_bo_ref(NULL, &nvbo2); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* import handle twice on one driver */ -static void test_i915_nv_double_import(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo = NULL, *nvbo2 = NULL; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - igt_assert(test_intel_bo); - - igt_assert(drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd) == 0); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo2) == 0); - close(prime_fd); - - igt_assert(nvbo->handle == nvbo2->handle); - - nouveau_bo_ref(NULL, &nvbo2); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* export handle twice from one driver - import twice - see if we get same object */ -static void test_i915_nv_double_export(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd, prime_fd2; - struct nouveau_bo *nvbo = NULL, *nvbo2 = NULL; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - igt_assert(test_intel_bo); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd2); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - close(prime_fd); - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd2, &nvbo2) == 0); - close(prime_fd2); - - igt_assert(nvbo->handle == nvbo2->handle); - - nouveau_bo_ref(NULL, &nvbo2); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* export handle from intel driver - reimport to intel driver - see if you get same object */ -static void test_i915_self_import(void) -{ - drm_intel_bo *test_intel_bo, *test_intel_bo2; - int prime_fd; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - test_intel_bo2 = drm_intel_bo_gem_create_from_prime(bufmgr, prime_fd, BO_SIZE); - close(prime_fd); - igt_assert(test_intel_bo2); - - igt_assert(test_intel_bo->handle == test_intel_bo2->handle); - - drm_intel_bo_unreference(test_intel_bo); -} - -/* nouveau export reimport test */ -static void test_nv_self_import(void) -{ - int prime_fd; - struct nouveau_bo *nvbo, *nvbo2; - - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, BO_SIZE, NULL, &nvbo) == 0); - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo2) == 0); - close(prime_fd); - - igt_assert(nvbo->handle == nvbo2->handle); - nouveau_bo_ref(NULL, &nvbo); - nouveau_bo_ref(NULL, &nvbo2); -} - -/* export handle from intel driver - reimport to another intel driver bufmgr - see if you get same object */ -static void test_i915_self_import_to_different_fd(void) -{ - drm_intel_bo *test_intel_bo, *test_intel_bo2; - int prime_fd; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - test_intel_bo2 = drm_intel_bo_gem_create_from_prime(bufmgr2, prime_fd, BO_SIZE); - close(prime_fd); - igt_assert(test_intel_bo2); - - drm_intel_bo_unreference(test_intel_bo2); - drm_intel_bo_unreference(test_intel_bo); -} - -/* nouveau export reimport to other driver test */ -static void test_nv_self_import_to_different_fd(void) -{ - int prime_fd; - struct nouveau_bo *nvbo, *nvbo2; - - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, BO_SIZE, NULL, &nvbo) == 0); - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - - igt_assert(nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2) == 0); - close(prime_fd); - - /* not sure what to test for, just make sure we don't explode */ - nouveau_bo_ref(NULL, &nvbo); - nouveau_bo_ref(NULL, &nvbo2); -} - -igt_main -{ - igt_fixture { - find_and_open_devices(); - - igt_require(nouveau_fd != -1); - igt_require(nouveau_fd2 != -1); - igt_require(intel_fd != -1); - igt_require(intel_fd2 != -1); - - /* set up intel bufmgr */ - bufmgr = drm_intel_bufmgr_gem_init(intel_fd, 4096); - igt_assert(bufmgr); - /* Do not enable reuse, we share (almost) all buffers. */ - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - bufmgr2 = drm_intel_bufmgr_gem_init(intel_fd2, 4096); - igt_assert(bufmgr2); - drm_intel_bufmgr_gem_enable_reuse(bufmgr2); - - /* set up nouveau bufmgr */ - igt_assert(nouveau_device_wrap(nouveau_fd, 0, &ndev) >= 0); - igt_assert(nouveau_client_new(ndev, &nclient) >= 0); - - /* set up nouveau bufmgr */ - igt_assert(nouveau_device_wrap(nouveau_fd2, 0, &ndev2) >= 0); - - igt_assert(nouveau_client_new(ndev2, &nclient2) >= 0);; - - /* set up an intel batch buffer */ - devid = intel_get_drm_devid(intel_fd); - intel_batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(intel_batch); - } - -#define xtest(name) \ - igt_subtest(#name) \ - test_##name(); - - xtest(i915_nv_import_twice); - xtest(i915_nv_import_twice_check_flink_name); - xtest(i915_nv_reimport_twice_check_flink_name); - xtest(nv_i915_import_twice_check_flink_name); - xtest(nv_i915_reimport_twice_check_flink_name); - xtest(i915_nv_import_vs_close); - xtest(i915_nv_double_import); - xtest(i915_nv_double_export); - xtest(i915_self_import); - xtest(nv_self_import); - xtest(i915_self_import_to_different_fd); - xtest(nv_self_import_to_different_fd); - - igt_fixture { - intel_batchbuffer_free(intel_batch); - - nouveau_device_del(&ndev); - drm_intel_bufmgr_destroy(bufmgr); - - close(intel_fd); - close(nouveau_fd); - } -} diff --git a/tests/prime_nv_pcopy.c b/tests/prime_nv_pcopy.c deleted file mode 100644 index 218f4ba0..00000000 --- a/tests/prime_nv_pcopy.c +++ /dev/null @@ -1,908 +0,0 @@ -/* basic set of prime tests between intel and nouveau */ - -/* test list - - 1. share buffer from intel -> nouveau. - 2. share buffer from nouveau -> intel - 3. share intel->nouveau, map on both, write intel, read nouveau - 4. share intel->nouveau, blit intel fill, readback on nouveau - test 1 + map buffer, read/write, map other size. - do some hw actions on the buffer - some illegal operations - - close prime fd try and map - - TODO add some nouveau rendering tests -*/ - - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <errno.h> - -#include "ioctl_wrappers.h" -#include "intel_bufmgr.h" -#include "nouveau.h" -#include "intel_io.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "drmtest.h" - -static int intel_fd = -1, nouveau_fd = -1; -static drm_intel_bufmgr *bufmgr; -static struct nouveau_device *ndev; -static struct nouveau_client *nclient; -static uint32_t devid; -static struct intel_batchbuffer *batch; -static struct nouveau_object *nchannel, *pcopy; -static struct nouveau_bufctx *nbufctx; -static struct nouveau_pushbuf *npush; - -static struct nouveau_bo *query_bo; -static uint32_t query_counter; -static volatile uint32_t *query; -static uint32_t memtype_intel, tile_intel_y, tile_intel_x; - -#define SUBC_COPY(x) 6, (x) -#define NV01_SUBCHAN_OBJECT 0 - -#define NV01_SUBC(subc, mthd) SUBC_##subc((NV01_SUBCHAN_##mthd)) - -typedef struct { - uint32_t w, h; - uint32_t pitch, lines; -} rect; - -static void nv_bo_alloc(struct nouveau_bo **bo, rect *r, - uint32_t w, uint32_t h, uint32_t tile_mode, - int handle, uint32_t dom) -{ - uint32_t size; - uint32_t dx = 1, dy = 1, memtype = 0; - - *bo = NULL; - if (tile_mode) { - uint32_t tile_y; - uint32_t tile_x; - - /* Y major tiling */ - if ((tile_mode & 0xf) == 0xe) - /* but the internal layout is different */ - tile_x = 7; - else - tile_x = 6 + (tile_mode & 0xf); - if (ndev->chipset < 0xc0) { - memtype = 0x70; - tile_y = 2; - } else { - memtype = 0xfe; - tile_y = 3; - } - if ((tile_mode & 0xf) == 0xe) - memtype = memtype_intel; - tile_y += ((tile_mode & 0xf0)>>4); - - dx = 1 << tile_x; - dy = 1 << tile_y; - igt_debug("Tiling requirements: x y %u %u\n", dx, dy); - } - - r->w = w; - r->h = h; - - r->pitch = w = (w + dx-1) & ~(dx-1); - r->lines = h = (h + dy-1) & ~(dy-1); - size = w*h; - - if (handle < 0) { - union nouveau_bo_config cfg; - cfg.nv50.memtype = memtype; - cfg.nv50.tile_mode = tile_mode; - if (dom == NOUVEAU_BO_GART) - dom |= NOUVEAU_BO_MAP; - igt_assert(nouveau_bo_new(ndev, dom, 4096, size, &cfg, bo) == 0); - igt_assert(nouveau_bo_map(*bo, NOUVEAU_BO_RDWR, nclient) == 0); - - igt_debug("new flags %08x memtype %08x tile %08x\n", - (*bo)->flags, (*bo)->config.nv50.memtype, - (*bo)->config.nv50.tile_mode); - if (tile_mode == tile_intel_y || tile_mode == tile_intel_x) { - igt_debug("tile mode was: %02x, now: %02x\n", - (*bo)->config.nv50.tile_mode, tile_mode); - /* Doesn't like intel tiling much.. */ - (*bo)->config.nv50.tile_mode = tile_mode; - } - } else { - igt_assert(nouveau_bo_prime_handle_ref(ndev, handle, bo) == 0); - close(handle); - igt_assert_f((*bo)->size >= size, - "expected bo size to be at least %u," - "but received %"PRIu64"\n", size, (*bo)->size); - igt_debug("prime flags %08x memtype %08x tile %08x\n", - (*bo)->flags, (*bo)->config.nv50.memtype, - (*bo)->config.nv50.tile_mode); - (*bo)->config.nv50.memtype = memtype; - (*bo)->config.nv50.tile_mode = tile_mode; - } - igt_debug("size: %"PRIu64"\n", (*bo)->size); -} - -static inline void -PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data) -{ - *push->cur++ = data; -} - -static inline void -BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, int size) -{ - PUSH_DATA (push, 0x00000000 | (size << 18) | (subc << 13) | mthd); -} - -static inline void -BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, int size) -{ - PUSH_DATA (push, 0x40000000 | (size << 18) | (subc << 13) | mthd); -} - -static inline void -BEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, int size) -{ - PUSH_DATA (push, 0x20000000 | (size << 16) | (subc << 13) | (mthd / 4)); -} - -static inline void -BEGIN_NVXX(struct nouveau_pushbuf *push, int subc, int mthd, int size) -{ - if (ndev->chipset < 0xc0) - BEGIN_NV04(push, subc, mthd, size); - else - BEGIN_NVC0(push, subc, mthd, size); -} - -static void -noop_intel(drm_intel_bo *bo) -{ - BEGIN_BATCH(3, 1); - OUT_BATCH(MI_NOOP); - OUT_BATCH(MI_BATCH_BUFFER_END); - OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER, - I915_GEM_DOMAIN_RENDER, 0); - ADVANCE_BATCH(); - - intel_batchbuffer_flush(batch); -} - -static void find_and_open_devices(void) -{ - int i; - char path[80], *unused; - struct stat buf; - FILE *fl; - char vendor_id[8] = {}; - int venid; - for (i = 0; i < 9; i++) { - sprintf(path, "/sys/class/drm/card%d/device/vendor", i); - if (stat(path, &buf)) - break; - - fl = fopen(path, "r"); - if (!fl) - break; - - unused = fgets(vendor_id, sizeof(vendor_id)-1, fl); - (void)unused; - fclose(fl); - - venid = strtoul(vendor_id, NULL, 16); - sprintf(path, "/dev/dri/card%d", i); - if (venid == 0x8086) { - intel_fd = open(path, O_RDWR); - igt_assert(intel_fd); - } else if (venid == 0x10de) { - nouveau_fd = open(path, O_RDWR); - igt_assert(nouveau_fd); - } - } -} - -static void init_nouveau(void) -{ - struct nv04_fifo nv04_data = { .vram = 0xbeef0201, - .gart = 0xbeef0202 }; - struct nvc0_fifo nvc0_data = { }; - struct nouveau_fifo *fifo; - int size; - uint32_t class; - void *data; - - igt_assert(nouveau_device_wrap(nouveau_fd, 0, &ndev) == 0); - - igt_assert(nouveau_client_new(ndev, &nclient) == 0); - - igt_skip_on_f(ndev->chipset < 0xa3 || ndev->chipset == 0xaa || ndev->chipset == 0xac, - "Your card doesn't support PCOPY\n"); - - // TODO: Get a kepler and add support for it - igt_skip_on_f(ndev->chipset >= 0xe0, - "Unsure how kepler works!\n"); - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 4096, 4096, NULL, &query_bo) == 0); - igt_assert(nouveau_bo_map(query_bo, NOUVEAU_BO_RDWR, nclient) == 0); - query = query_bo->map; - *query = query_counter; - - if (ndev->chipset < 0xc0) { - class = 0x85b5; - data = &nv04_data; - size = sizeof(nv04_data); - } else { - class = ndev->chipset < 0xe0 ? 0x490b5 : 0xa0b5; - data = &nvc0_data; - size = sizeof(nvc0_data); - } - - igt_assert(nouveau_object_new(&ndev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS, - data, size, &nchannel) == 0); - - fifo = nchannel->data; - - igt_assert(nouveau_pushbuf_new(nclient, nchannel, 4, 32 * 1024, - true, &npush) == 0); - - igt_assert(nouveau_bufctx_new(nclient, 1, &nbufctx) == 0); - - npush->user_priv = nbufctx; - - /* Hope this is enough init for PCOPY */ - igt_assert(nouveau_object_new(nchannel, class, class & 0xffff, NULL, 0, &pcopy) == 0); - igt_assert(nouveau_pushbuf_space(npush, 512, 0, 0) == 0); - - if (ndev->chipset < 0xc0) { - struct nv04_fifo *nv04_fifo = (struct nv04_fifo*)fifo; - tile_intel_y = 0x3e; - tile_intel_x = 0x13; - - BEGIN_NV04(npush, NV01_SUBC(COPY, OBJECT), 1); - PUSH_DATA(npush, pcopy->handle); - BEGIN_NV04(npush, SUBC_COPY(0x0180), 3); - PUSH_DATA(npush, nv04_fifo->vram); - PUSH_DATA(npush, nv04_fifo->vram); - PUSH_DATA(npush, nv04_fifo->vram); - } else { - tile_intel_y = 0x2e; - tile_intel_x = 0x03; - BEGIN_NVC0(npush, NV01_SUBC(COPY, OBJECT), 1); - PUSH_DATA(npush, pcopy->handle); - } - nouveau_pushbuf_kick(npush, npush->channel); -} - -static void fill16(void *ptr, uint32_t val) -{ - uint32_t *p = ptr; - val = (val) | (val << 8) | (val << 16) | (val << 24); - p[0] = p[1] = p[2] = p[3] = val; -} - -#define TILE_SIZE 4096 - -static void swtile_y(uint8_t *out, const uint8_t *in, int w, int h) -{ - uint32_t x, y, dx, dy; - uint8_t *endptr = out + w * h; - igt_assert(!(w % 128)); - igt_assert(!(h % 32)); - - for (y = 0; y < h; y += 32) { - for (x = 0; x < w; x += 128, out += TILE_SIZE) { - for (dx = 0; dx < 8; ++dx) { - for (dy = 0; dy < 32; ++dy) { - uint32_t out_ofs = (dx * 32 + dy) * 16; - uint32_t in_ofs = (y + dy) * w + (x + 16 * dx); - igt_assert(out_ofs < TILE_SIZE); - igt_assert(in_ofs < w*h); - - // To do the Y tiling quirk: - // out_ofs = out_ofs ^ (((out_ofs >> 9) & 1) << 6); - memcpy(&out[out_ofs], &in[in_ofs], 16); - } - } - } - } - igt_assert(out == endptr); -} - -static void swtile_x(uint8_t *out, const uint8_t *in, int w, int h) -{ - uint32_t x, y, dy; - uint8_t *endptr = out + w * h; - igt_assert(!(w % 512)); - igt_assert(!(h % 8)); - - for (y = 0; y < h; y += 8) { - for (x = 0; x < w; x += 512, out += TILE_SIZE) { - for (dy = 0; dy < 8; ++dy) { - uint32_t out_ofs = 512 * dy; - uint32_t in_ofs = (y + dy) * w + x; - igt_assert(out_ofs < TILE_SIZE); - igt_assert(in_ofs < w*h); - memcpy(&out[out_ofs], &in[in_ofs], 512); - } - } - } - igt_assert(out == endptr); -} - -static void perform_copy(struct nouveau_bo *nvbo, const rect *dst, - uint32_t dst_x, uint32_t dst_y, - struct nouveau_bo *nvbi, const rect *src, - uint32_t src_x, uint32_t src_y, - uint32_t w, uint32_t h) -{ - struct nouveau_pushbuf_refn refs[] = { - { nvbi, (nvbi->flags & NOUVEAU_BO_APER) | NOUVEAU_BO_RD }, - { nvbo, (nvbo->flags & NOUVEAU_BO_APER) | NOUVEAU_BO_WR }, - { query_bo, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR } - }; - uint32_t cpp = 1, exec = 0x00003000; /* QUERY|QUERY_SHORT|FORMAT */ - uint32_t src_off = 0, dst_off = 0; - struct nouveau_pushbuf *push = npush; - int ret; - - if (nvbi->config.nv50.tile_mode == tile_intel_y) - igt_debug("src is y-tiled\n"); - if (nvbo->config.nv50.tile_mode == tile_intel_y) - igt_debug("dst is y-tiled\n"); - - igt_assert(nouveau_pushbuf_space(push, 64, 0, 0) == 0); - igt_assert(nouveau_pushbuf_refn(push, refs, 3) == 0); - - if (!nvbi->config.nv50.tile_mode) { - src_off = src_y * src->pitch + src_x; - exec |= 0x00000010; - } - - if (!nvbo->config.nv50.tile_mode) { - dst_off = dst_y * dst->pitch + dst_x; - exec |= 0x00000100; - } - - BEGIN_NVXX(push, SUBC_COPY(0x0200), 7); - PUSH_DATA (push, nvbi->config.nv50.tile_mode); - PUSH_DATA (push, src->pitch / cpp); - PUSH_DATA (push, src->h); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, src_x / cpp); - PUSH_DATA (push, src_y); - - BEGIN_NVXX(push, SUBC_COPY(0x0220), 7); - PUSH_DATA (push, nvbo->config.nv50.tile_mode); - PUSH_DATA (push, dst->pitch / cpp); - PUSH_DATA (push, dst->h); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, dst_x / cpp); - PUSH_DATA (push, dst_y); - - BEGIN_NVXX(push, SUBC_COPY(0x030c), 9); - PUSH_DATA (push, (nvbi->offset + src_off) >> 32); - PUSH_DATA (push, (nvbi->offset + src_off)); - PUSH_DATA (push, (nvbo->offset + dst_off) >> 32); - PUSH_DATA (push, (nvbo->offset + dst_off)); - PUSH_DATA (push, src->pitch); - PUSH_DATA (push, dst->pitch); - PUSH_DATA (push, w / cpp); - PUSH_DATA (push, h); - PUSH_DATA (push, 0x03333120); - - BEGIN_NVXX(push, SUBC_COPY(0x0338), 3); - PUSH_DATA (push, (query_bo->offset) >> 32); - PUSH_DATA (push, (query_bo->offset)); - PUSH_DATA (push, ++query_counter); - - BEGIN_NVXX(push, SUBC_COPY(0x0300), 1); - PUSH_DATA (push, exec); - - ret = nouveau_pushbuf_kick(push, push->channel); - while (!ret && *query < query_counter) { usleep(1000); } - - igt_assert(ret == 0); -} - -static void check1_macro(uint32_t *p, uint32_t w, uint32_t h) -{ - uint32_t i, val, j; - - for (i = 0; i < 256; ++i, p += 4) { - val = (i) | (i << 8) | (i << 16) | (i << 24); - igt_assert_f(p[0] == val && p[1] == val && p[2] == val && p[3] == val, - "Retile check failed in first tile!\n" - "%08x %08x %08x %08x instead of %08x\n", - p[0], p[1], p[2], p[3], val); - } - - val = 0x3e3e3e3e; - for (i = 0; i < 256 * (w-1); ++i, p += 4) { - igt_assert_f(p[0] == val && p[1] == val && p[2] == val && p[3] == val, - "Retile check failed in second tile!\n" - "%08x %08x %08x %08x instead of %08x\n", - p[0], p[1], p[2], p[3], val); - } - - for (j = 1; j < h; ++j) { - val = 0x7e7e7e7e; - for (i = 0; i < 256; ++i, p += 4) { - igt_assert_f(p[0] == val && p[1] == val && p[2] == val && p[3] == val, - "Retile check failed in third tile!\n" - "%08x %08x %08x %08x instead of %08x\n", - p[0], p[1], p[2], p[3], val); - } - - val = 0xcececece; - for (i = 0; i < 256 * (w-1); ++i, p += 4) { - igt_assert_f(p[0] == val && p[1] == val && p[2] == val && p[3] == val, - "Retile check failed in fourth tile!\n" - "%08x %08x %08x %08x instead of %08x\n", - p[0], p[1], p[2], p[3], val); - } - } -} - -/* test 1, see if we can copy from linear to intel Y format safely */ -static void test1_macro(void) -{ - int prime_fd = -1; - struct nouveau_bo *nvbo = NULL, *nvbi = NULL; - rect dst, src; - uint8_t *ptr; - uint32_t w = 2 * 128, h = 2 * 32, x, y; - - nv_bo_alloc(&nvbi, &src, w, h, 0, -1, NOUVEAU_BO_GART); - nv_bo_alloc(&nvbo, &dst, w, h, tile_intel_y, -1, NOUVEAU_BO_GART); - - nouveau_bo_set_prime(nvbo, &prime_fd); - - /* Set up something for our tile that should map into the first - * y-major tile, assuming my understanding of documentation is - * correct - */ - - /* First tile should be read out in groups of 16 bytes that - * are all set to a linear increasing value.. - */ - ptr = nvbi->map; - for (x = 0; x < 128; x += 16) - for (y = 0; y < 32; ++y) - fill16(&ptr[y * w + x], x * 2 + y); - - /* second tile */ - for (x = 128; x < w; x += 16) - for (y = 0; y < 32; ++y) - fill16(&ptr[y * w + x], 0x3e); - - /* third tile */ - for (x = 0; x < 128; x += 16) - for (y = 32; y < h; ++y) - fill16(&ptr[y * w + x], 0x7e); - - /* last tile */ - for (x = 128; x < w; x += 16) - for (y = 32; y < h; ++y) - fill16(&ptr[y * w + x], 0xce); - memset(nvbo->map, 0xfc, w * h); - - if (pcopy) - perform_copy(nvbo, &dst, 0, 0, nvbi, &src, 0, 0, w, h); - else - swtile_y(nvbo->map, nvbi->map, w, h); - check1_macro(nvbo->map, w/128, h/32); - - nouveau_bo_ref(NULL, &nvbo); - nouveau_bo_ref(NULL, &nvbi); - close(prime_fd); -} - -static void dump_line(uint8_t *map) -{ - uint32_t dx, dy; - igt_debug("Dumping sub-tile:\n"); - for (dy = 0; dy < 32; ++dy) { - for (dx = 0; dx < 15; ++dx, ++map) { - igt_debug("%02x ", *map); - } - igt_debug("%02x\n", *(map++)); - } -} - -static void check1_micro(void *map, uint32_t pitch, uint32_t lines, - uint32_t dst_x, uint32_t dst_y, uint32_t w, uint32_t h) -{ - uint32_t x, y; - - /* check only the relevant subrectangle [0..w) [0...h) */ - uint8_t *m = map; - for (y = 0; y < h; ++y, m += pitch) { - for (x = 0; x < w; ++x) { - uint8_t expected = ((y & 3) << 6) | (x & 0x3f); - - if (expected != m[x]) - dump_line(m); - - igt_assert_f(expected == m[x], - "failed check at x=%u y=%u, expected %02x got %02x\n", - x, y, expected, m[x]); - } - } -} - -/* test 1, but check micro format, should be unaffected by bit9 swizzling */ -static void test1_micro(void) -{ - struct nouveau_bo *bo_intel = NULL, *bo_nvidia = NULL, *bo_linear = NULL; - rect intel, nvidia, linear; - uint32_t tiling = I915_TILING_Y; - - uint32_t src_x = 0, src_y = 0; - uint32_t dst_x = 0, dst_y = 0; - uint32_t x, y, w = 256, h = 64; - - drm_intel_bo *test_intel_bo; - int prime_fd; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", w * h, 4096); - igt_assert(test_intel_bo); - drm_intel_bo_set_tiling(test_intel_bo, &tiling, w); - igt_assert(tiling == I915_TILING_Y); - igt_assert(drm_intel_gem_bo_map_gtt(test_intel_bo) == 0); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - igt_assert(prime_fd >= 0); - noop_intel(test_intel_bo); - - nv_bo_alloc(&bo_intel, &intel, w, h, tile_intel_y, prime_fd, 0); - nv_bo_alloc(&bo_nvidia, &nvidia, w, h, 0x10, -1, NOUVEAU_BO_VRAM); - nv_bo_alloc(&bo_linear, &linear, w, h, 0, -1, NOUVEAU_BO_GART); - - for (y = 0; y < linear.h; ++y) { - uint8_t *map = bo_linear->map; - map += y * linear.pitch; - for (x = 0; x < linear.pitch; ++x) { - uint8_t pos = x & 0x3f; - /* low 4 bits: micro tile pos */ - /* 2 bits: x pos in tile (wraps) */ - /* 2 bits: y pos in tile (wraps) */ - pos |= (y & 3) << 6; - map[x] = pos; - } - } - - perform_copy(bo_nvidia, &nvidia, 0, 0, bo_linear, &linear, 0, 0, nvidia.pitch, nvidia.h); - - /* Perform the actual sub rectangle copy */ - if (pcopy) - perform_copy(bo_intel, &intel, dst_x, dst_y, bo_nvidia, &nvidia, src_x, src_y, w, h); - else - swtile_y(test_intel_bo->virtual, bo_linear->map, w, h); - - noop_intel(test_intel_bo); - check1_micro(test_intel_bo->virtual, intel.pitch, intel.h, dst_x, dst_y, w, h); - - nouveau_bo_ref(NULL, &bo_linear); - nouveau_bo_ref(NULL, &bo_nvidia); - nouveau_bo_ref(NULL, &bo_intel); - drm_intel_bo_unreference(test_intel_bo); -} - -/* test 2, see if we can copy from linear to intel X format safely - * Seems nvidia lacks a method to do it, so just keep this test - * as a reference for potential future tests. Software tiling is - * used for now - */ -static void test2(void) -{ - struct nouveau_bo *nvbo = NULL, *nvbi = NULL; - rect dst, src; - uint8_t *ptr; - uint32_t w = 1024, h = 16, x, y; - - nv_bo_alloc(&nvbi, &src, w, h, 0, -1, NOUVEAU_BO_GART); - nv_bo_alloc(&nvbo, &dst, w, h, tile_intel_x, -1, NOUVEAU_BO_GART); - - /* Set up something for our tile that should map into the first - * y-major tile, assuming my understanding of documentation is - * correct - */ - - /* First tile should be read out in groups of 16 bytes that - * are all set to a linear increasing value.. - */ - ptr = nvbi->map; - for (y = 0; y < 8; ++y) - for (x = 0; x < 512; x += 16) - fill16(&ptr[y * w + x], (y * 512 + x)/16); - - for (y = 0; y < 8; ++y) - for (x = 512; x < w; x += 16) - fill16(&ptr[y * w + x], 0x3e); - - for (y = 8; y < h; ++y) - for (x = 0; x < 512; x += 16) - fill16(&ptr[y * w + x], 0x7e); - - for (y = 8; y < h; ++y) - for (x = 512; x < w; x += 16) - fill16(&ptr[y * w + x], 0xce); - memset(nvbo->map, 0xfc, w * h); - - /* do this in software, there is no X major tiling in PCOPY (yet?) */ - if (0 && pcopy) - perform_copy(nvbo, &dst, 0, 0, nvbi, &src, 0, 0, w, h); - else - swtile_x(nvbo->map, nvbi->map, w, h); - check1_macro(nvbo->map, w/512, h/8); - - nouveau_bo_ref(NULL, &nvbo); - nouveau_bo_ref(NULL, &nvbi); -} - -static void check3(const uint32_t *p, uint32_t pitch, uint32_t lines, - uint32_t sub_x, uint32_t sub_y, - uint32_t sub_w, uint32_t sub_h) -{ - uint32_t x, y; - - sub_w += sub_x; - sub_h += sub_y; - - igt_assert_f(p[pitch * lines / 4 - 1] != 0x03030303, - "copy failed: Not all lines have been copied back!\n"); - - for (y = 0; y < lines; ++y) { - for (x = 0; x < pitch; x += 4, ++p) { - uint32_t expected; - if ((x < sub_x || x >= sub_w) || - (y < sub_y || y >= sub_h)) - expected = 0x80808080; - else - expected = 0x04040404; - igt_assert_f(*p == expected, - "%u,%u should be %08x, but is %08x\n", - x, y, expected, *p); - } - } -} - -/* copy from nvidia bo to intel bo and copy to a linear bo to check if tiling went succesful */ -static void test3_base(int tile_src, int tile_dst) -{ - struct nouveau_bo *bo_intel = NULL, *bo_nvidia = NULL, *bo_linear = NULL; - rect intel, nvidia, linear; - uint32_t cpp = 4; - - uint32_t src_x = 1 * cpp, src_y = 1; - uint32_t dst_x = 2 * cpp, dst_y = 26; - uint32_t w = 298 * cpp, h = 298; - - drm_intel_bo *test_intel_bo; - int prime_fd; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", 2048 * cpp * 768, 4096); - igt_assert(test_intel_bo); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - igt_assert(prime_fd >= 0); - - nv_bo_alloc(&bo_intel, &intel, 2048 * cpp, 768, tile_dst, prime_fd, 0); - nv_bo_alloc(&bo_nvidia, &nvidia, 300 * cpp, 300, tile_src, -1, NOUVEAU_BO_VRAM); - nv_bo_alloc(&bo_linear, &linear, 2048 * cpp, 768, 0, -1, NOUVEAU_BO_GART); - - noop_intel(test_intel_bo); - memset(bo_linear->map, 0x80, bo_linear->size); - perform_copy(bo_intel, &intel, 0, 0, bo_linear, &linear, 0, 0, linear.pitch, linear.h); - noop_intel(test_intel_bo); - - memset(bo_linear->map, 0x04, bo_linear->size); - perform_copy(bo_nvidia, &nvidia, 0, 0, bo_linear, &linear, 0, 0, nvidia.pitch, nvidia.h); - - /* Perform the actual sub rectangle copy */ - noop_intel(test_intel_bo); - perform_copy(bo_intel, &intel, dst_x, dst_y, bo_nvidia, &nvidia, src_x, src_y, w, h); - noop_intel(test_intel_bo); - - memset(bo_linear->map, 0x3, bo_linear->size); - noop_intel(test_intel_bo); - perform_copy(bo_linear, &linear, 0, 0, bo_intel, &intel, 0, 0, intel.pitch, intel.h); - noop_intel(test_intel_bo); - - check3(bo_linear->map, linear.pitch, linear.h, dst_x, dst_y, w, h); - - nouveau_bo_ref(NULL, &bo_linear); - nouveau_bo_ref(NULL, &bo_nvidia); - nouveau_bo_ref(NULL, &bo_intel); - drm_intel_bo_unreference(test_intel_bo); -} - -static void test3_1(void) -{ - /* nvidia tiling to intel */ - test3_base(0x40, tile_intel_y); -} - -static void test3_2(void) -{ - /* intel tiling to nvidia */ - test3_base(tile_intel_y, 0x40); -} - -static void test3_3(void) -{ - /* intel tiling to linear */ - test3_base(tile_intel_y, 0); -} - -static void test3_4(void) -{ - /* linear tiling to intel */ - test3_base(0, tile_intel_y); -} - -static void test3_5(void) -{ - /* linear to linear */ - test3_base(0, 0); -} - -/* Acquire when == SEQUENCE */ -#define SEMA_ACQUIRE_EQUAL 1 - -/* Release, and write a 16 byte query structure to sema: - * { (uint32)seq, (uint32)0, (uint64)timestamp } */ -#define SEMA_WRITE_LONG 2 - -/* Acquire when >= SEQUENCE */ -#define SEMA_ACQUIRE_GEQUAL 4 - -/* Test only new style semaphores, old ones are AWFUL */ -static void test_semaphore(void) -{ - drm_intel_bo *test_intel_bo = NULL; - struct nouveau_bo *sema_bo = NULL; - int prime_fd; - uint32_t *sema; - struct nouveau_pushbuf *push = npush; - - igt_skip_on(ndev->chipset < 0x84); - - /* Should probably be kept in sysmem */ - test_intel_bo = drm_intel_bo_alloc(bufmgr, "semaphore bo", 4096, 4096); - igt_assert(test_intel_bo); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - igt_assert(prime_fd >= 0); - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &sema_bo) == 0); - close(prime_fd); - - igt_assert(drm_intel_gem_bo_map_gtt(test_intel_bo) == 0); - sema = test_intel_bo->virtual; - sema++; - *sema = 0; - - igt_assert(nouveau_pushbuf_space(push, 64, 0, 0) == 0); - igt_assert(nouveau_pushbuf_refn(push, &(struct nouveau_pushbuf_refn) - { sema_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR }, 1) == 0); - - if (ndev->chipset < 0xc0) { - struct nv04_fifo *nv04_fifo = nchannel->data; - /* kernel binds it's own dma object here and overwrites old one, - * so just rebind vram every time we submit - */ - BEGIN_NV04(npush, SUBC_COPY(0x0060), 1); - PUSH_DATA(npush, nv04_fifo->vram); - } - BEGIN_NVXX(push, SUBC_COPY(0x0010), 4); - PUSH_DATA(push, sema_bo->offset >> 32); - PUSH_DATA(push, sema_bo->offset + 4); - PUSH_DATA(push, 2); // SEQUENCE - PUSH_DATA(push, SEMA_WRITE_LONG); // TRIGGER - - BEGIN_NVXX(push, SUBC_COPY(0x0018), 2); - PUSH_DATA(push, 3); - PUSH_DATA(push, SEMA_ACQUIRE_EQUAL); - BEGIN_NVXX(push, SUBC_COPY(0x0018), 2); - PUSH_DATA(push, 4); - PUSH_DATA(push, SEMA_WRITE_LONG); - - BEGIN_NVXX(push, SUBC_COPY(0x0018), 2); - PUSH_DATA(push, 5); - PUSH_DATA(push, SEMA_ACQUIRE_GEQUAL); - BEGIN_NVXX(push, SUBC_COPY(0x0018), 2); - PUSH_DATA(push, 6); - PUSH_DATA(push, SEMA_WRITE_LONG); - - BEGIN_NVXX(push, SUBC_COPY(0x0018), 2); - PUSH_DATA(push, 7); - PUSH_DATA(push, SEMA_ACQUIRE_GEQUAL); - BEGIN_NVXX(push, SUBC_COPY(0x0018), 2); - PUSH_DATA(push, 9); - PUSH_DATA(push, SEMA_WRITE_LONG); - nouveau_pushbuf_kick(push, push->channel); - - usleep(1000); - igt_assert(*sema == 2); - - *sema = 3; - usleep(1000); - igt_assert(*sema == 4); - - *sema = 5; - usleep(1000); - igt_assert(*sema == 6); - - *sema = 8; - usleep(1000); - igt_assert(*sema == 9); - - nouveau_bo_ref(NULL, &sema_bo); - drm_intel_bo_unreference(test_intel_bo); -} - -igt_main -{ - igt_fixture { - find_and_open_devices(); - - igt_require(nouveau_fd != -1); - igt_require(intel_fd != -1); - - /* set up intel bufmgr */ - bufmgr = drm_intel_bufmgr_gem_init(intel_fd, 4096); - igt_assert(bufmgr); - /* Do not enable reuse, we share (almost) all buffers. */ - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - /* set up nouveau bufmgr */ - init_nouveau(); - - /* set up an intel batch buffer */ - devid = intel_get_drm_devid(intel_fd); - batch = intel_batchbuffer_alloc(bufmgr, devid); - igt_assert(batch); - } - -#define xtest(x, args...) \ - igt_subtest( #x ) \ - (x)(args); - - xtest(test1_macro); - xtest(test1_micro); - //xtest(test1_swizzle); - xtest(test2); - xtest(test3_1); - xtest(test3_2); - xtest(test3_3); - xtest(test3_4); - xtest(test3_5); - xtest(test_semaphore); - - igt_fixture { - nouveau_bo_ref(NULL, &query_bo); - nouveau_object_del(&pcopy); - nouveau_bufctx_del(&nbufctx); - nouveau_pushbuf_del(&npush); - nouveau_object_del(&nchannel); - - intel_batchbuffer_free(batch); - - nouveau_client_del(&nclient); - nouveau_device_del(&ndev); - drm_intel_bufmgr_destroy(bufmgr); - - close(intel_fd); - close(nouveau_fd); - } -} diff --git a/tests/prime_nv_test.c b/tests/prime_nv_test.c deleted file mode 100644 index dc9287ca..00000000 --- a/tests/prime_nv_test.c +++ /dev/null @@ -1,403 +0,0 @@ -/* basic set of prime tests between intel and nouveau */ - -/* test list - - 1. share buffer from intel -> nouveau. - 2. share buffer from nouveau -> intel - 3. share intel->nouveau, map on both, write intel, read nouveau - 4. share intel->nouveau, blit intel fill, readback on nouveau - test 1 + map buffer, read/write, map other size. - do some hw actions on the buffer - some illegal operations - - close prime fd try and map - - TODO add some nouveau rendering tests -*/ - - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/ioctl.h> - -#include "ioctl_wrappers.h" -#include "intel_bufmgr.h" -#include "nouveau.h" -#include "intel_io.h" -#include "intel_batchbuffer.h" -#include "intel_chipset.h" -#include "drmtest.h" - -int intel_fd = -1, nouveau_fd = -1; -drm_intel_bufmgr *bufmgr; -struct nouveau_device *ndev; -struct nouveau_client *nclient; -uint32_t devid; -struct intel_batchbuffer *intel_batch; - -#define BO_SIZE (256*1024) - -static int find_and_open_devices(void) -{ - int i; - char path[80]; - struct stat buf; - FILE *fl; - char vendor_id[8]; - int venid; - for (i = 0; i < 9; i++) { - char *ret; - - sprintf(path, "/sys/class/drm/card%d/device/vendor", i); - if (stat(path, &buf)) - break; - - fl = fopen(path, "r"); - if (!fl) - break; - - ret = fgets(vendor_id, 8, fl); - igt_assert(ret); - fclose(fl); - - venid = strtoul(vendor_id, NULL, 16); - sprintf(path, "/dev/dri/card%d", i); - if (venid == 0x8086) { - intel_fd = open(path, O_RDWR); - if (!intel_fd) - return -1; - } else if (venid == 0x10de) { - nouveau_fd = open(path, O_RDWR); - if (!nouveau_fd) - return -1; - } - } - return 0; -} - -/* - * prime test 1 - - * allocate buffer on intel, - * set prime on buffer, - * retrive buffer from nouveau, - * close prime_fd, - * unref buffers - */ -static void test_i915_nv_sharing(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - igt_assert(test_intel_bo); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - close(prime_fd); - - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* - * prime test 2 - - * allocate buffer on nouveau - * set prime on buffer, - * retrive buffer from intel - * close prime_fd, - * unref buffers - */ -static void test_nv_i915_sharing(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo; - - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, BO_SIZE, NULL, &nvbo) == 0); - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - - test_intel_bo = drm_intel_bo_gem_create_from_prime(bufmgr, prime_fd, BO_SIZE); - close(prime_fd); - igt_assert(test_intel_bo); - - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* - * allocate intel, give to nouveau, map on nouveau - * write 0xdeadbeef, non-gtt map on intel, read - */ -static void test_nv_write_i915_cpu_mmap_read(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo = NULL; - uint32_t *ptr; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - close(prime_fd); - - igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0); - ptr = nvbo->map; - *ptr = 0xdeadbeef; - - drm_intel_bo_map(test_intel_bo, 1); - ptr = test_intel_bo->virtual; - igt_assert(ptr); - - igt_assert(*ptr == 0xdeadbeef); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* - * allocate intel, give to nouveau, map on nouveau - * write 0xdeadbeef, gtt map on intel, read - */ -static void test_nv_write_i915_gtt_mmap_read(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo = NULL; - uint32_t *ptr; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - close(prime_fd); - igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0); - ptr = nvbo->map; - *ptr = 0xdeadbeef; - - drm_intel_gem_bo_map_gtt(test_intel_bo); - ptr = test_intel_bo->virtual; - igt_assert(ptr); - - igt_assert(*ptr == 0xdeadbeef); - - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* test drm_intel_bo_map doesn't work properly, - this tries to map the backing shmem fd, which doesn't exist - for these objects */ -static void test_i915_import_cpu_mmap(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo; - uint32_t *ptr; - - igt_skip("cpu mmap support for imported dma-bufs not yet implemented\n"); - - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, BO_SIZE, NULL, &nvbo) == 0); - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - test_intel_bo = drm_intel_bo_gem_create_from_prime(bufmgr, prime_fd, BO_SIZE); - close(prime_fd); - igt_assert(test_intel_bo); - - igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0); - - ptr = nvbo->map; - *ptr = 0xdeadbeef; - - igt_assert(drm_intel_bo_map(test_intel_bo, 0) == 0); - igt_assert(test_intel_bo->virtual); - ptr = test_intel_bo->virtual; - - igt_assert(*ptr == 0xdeadbeef); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* test drm_intel_bo_map_gtt works properly, - this tries to map the backing shmem fd, which doesn't exist - for these objects */ -static void test_i915_import_gtt_mmap(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo; - uint32_t *ptr; - - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, BO_SIZE, NULL, &nvbo) == 0); - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - - test_intel_bo = drm_intel_bo_gem_create_from_prime(bufmgr, prime_fd, BO_SIZE); - close(prime_fd); - igt_assert(test_intel_bo); - - igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0); - - ptr = nvbo->map; - *ptr = 0xdeadbeef; - *(ptr + 1) = 0xa55a55; - - igt_assert(drm_intel_gem_bo_map_gtt(test_intel_bo) == 0); - igt_assert(test_intel_bo->virtual); - ptr = test_intel_bo->virtual; - - igt_assert(*ptr == 0xdeadbeef); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* test 7 - import from nouveau into intel, test pread/pwrite fail */ -static void test_i915_import_pread_pwrite(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - struct nouveau_bo *nvbo; - uint32_t *ptr; - uint32_t buf[64]; - - igt_assert(nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, BO_SIZE, NULL, &nvbo) == 0); - igt_assert(nouveau_bo_set_prime(nvbo, &prime_fd) == 0); - - test_intel_bo = drm_intel_bo_gem_create_from_prime(bufmgr, prime_fd, BO_SIZE); - close(prime_fd); - igt_assert(test_intel_bo); - - igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0); - - ptr = nvbo->map; - *ptr = 0xdeadbeef; - - gem_read(intel_fd, test_intel_bo->handle, 0, buf, 256); - igt_assert(buf[0] == 0xdeadbeef); - buf[0] = 0xabcdef55; - - gem_write(intel_fd, test_intel_bo->handle, 0, buf, 4); - - igt_assert(*ptr == 0xabcdef55); - - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -static void -set_bo(drm_intel_bo *bo, uint32_t val, int width, int height) -{ - int size = width * height; - uint32_t *vaddr; - - drm_intel_gem_bo_start_gtt_access(bo, true); - vaddr = bo->virtual; - while (size--) - *vaddr++ = val; -} - -static drm_intel_bo * -create_bo(drm_intel_bufmgr *ibufmgr, uint32_t val, int width, int height) -{ - drm_intel_bo *bo; - - bo = drm_intel_bo_alloc(ibufmgr, "bo", 4*width*height, 0); - igt_assert(bo); - - /* gtt map doesn't have a write parameter, so just keep the mapping - * around (to avoid the set_domain with the gtt write domain set) and - * manually tell the kernel when we start access the gtt. */ - drm_intel_gem_bo_map_gtt(bo); - - set_bo(bo, val, width, height); - - return bo; -} - -/* use intel hw to fill the BO with a blit from another BO, - then readback from the nouveau bo, check value is correct */ -static void test_i915_blt_fill_nv_read(void) -{ - drm_intel_bo *test_intel_bo, *src_bo; - int prime_fd; - struct nouveau_bo *nvbo = NULL; - uint32_t *ptr; - - src_bo = create_bo(bufmgr, 0xaa55aa55, 256, 1); - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0); - close(prime_fd); - - intel_copy_bo(intel_batch, test_intel_bo, src_bo, BO_SIZE); - - igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0); - - drm_intel_bo_map(test_intel_bo, 0); - - ptr = nvbo->map; - igt_assert(*ptr == 0xaa55aa55); - nouveau_bo_ref(NULL, &nvbo); - drm_intel_bo_unreference(test_intel_bo); -} - -/* test 8 use nouveau to do blit */ - -/* test 9 nouveau copy engine?? */ - -igt_main -{ - igt_fixture { - igt_assert(find_and_open_devices() == 0); - - igt_require(nouveau_fd != -1); - igt_require(intel_fd != -1); - - /* set up intel bufmgr */ - bufmgr = drm_intel_bufmgr_gem_init(intel_fd, 4096); - igt_assert(bufmgr); - /* Do not enable reuse, we share (almost) all buffers. */ - //drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - /* set up nouveau bufmgr */ - igt_assert(nouveau_device_wrap(nouveau_fd, 0, &ndev) == 0); - igt_assert(nouveau_client_new(ndev, &nclient) == 0); - - /* set up an intel batch buffer */ - devid = intel_get_drm_devid(intel_fd); - intel_batch = intel_batchbuffer_alloc(bufmgr, devid); - } - -#define xtest(name) \ - igt_subtest(#name) \ - test_##name(); - - xtest(i915_nv_sharing); - xtest(nv_i915_sharing); - xtest(nv_write_i915_cpu_mmap_read); - xtest(nv_write_i915_gtt_mmap_read); - xtest(i915_import_cpu_mmap); - xtest(i915_import_gtt_mmap); - xtest(i915_import_pread_pwrite); - xtest(i915_blt_fill_nv_read); - - igt_fixture { - intel_batchbuffer_free(intel_batch); - - nouveau_device_del(&ndev); - drm_intel_bufmgr_destroy(bufmgr); - - close(intel_fd); - close(nouveau_fd); - } -} diff --git a/tests/prime_self_import.c b/tests/prime_self_import.c deleted file mode 100644 index ded92cfc..00000000 --- a/tests/prime_self_import.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright © 2012-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: - * Daniel Vetter <daniel.vetter@ffwll.ch> - * - */ - -/* - * Testcase: Check whether prime import/export works on the same device - * - * ... but with different fds, i.e. the wayland usecase. - */ - -#define _GNU_SOURCE -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <inttypes.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <pthread.h> - -#include "drm.h" -#include "ioctl_wrappers.h" -#include "drmtest.h" -#include "igt_debugfs.h" - -IGT_TEST_DESCRIPTION("Check whether prime import/export works on the same" - " device."); - -#define BO_SIZE (16*1024) - -static char counter; -volatile int pls_die = 0; - -static void -check_bo(int fd1, uint32_t handle1, int fd2, uint32_t handle2) -{ - char *ptr1, *ptr2; - int i; - - ptr1 = gem_mmap(fd1, handle1, BO_SIZE, PROT_READ | PROT_WRITE); - ptr2 = gem_mmap(fd2, handle2, BO_SIZE, PROT_READ | PROT_WRITE); - - igt_assert(ptr1); - - /* check whether it's still our old object first. */ - for (i = 0; i < BO_SIZE; i++) { - igt_assert(ptr1[i] == counter); - igt_assert(ptr2[i] == counter); - } - - counter++; - - memset(ptr1, counter, BO_SIZE); - igt_assert(memcmp(ptr1, ptr2, BO_SIZE) == 0); - - munmap(ptr1, BO_SIZE); - munmap(ptr2, BO_SIZE); -} - -static void test_with_fd_dup(void) -{ - int fd1, fd2; - uint32_t handle, handle_import; - int dma_buf_fd1, dma_buf_fd2; - - counter = 0; - - fd1 = drm_open_any(); - fd2 = drm_open_any(); - - handle = gem_create(fd1, BO_SIZE); - - dma_buf_fd1 = prime_handle_to_fd(fd1, handle); - gem_close(fd1, handle); - - dma_buf_fd2 = dup(dma_buf_fd1); - close(dma_buf_fd1); - handle_import = prime_fd_to_handle(fd2, dma_buf_fd2); - check_bo(fd2, handle_import, fd2, handle_import); - - close(dma_buf_fd2); - check_bo(fd2, handle_import, fd2, handle_import); - - close(fd1); - close(fd2); -} - -static void test_with_two_bos(void) -{ - int fd1, fd2; - uint32_t handle1, handle2, handle_import; - int dma_buf_fd; - - counter = 0; - - fd1 = drm_open_any(); - fd2 = drm_open_any(); - - handle1 = gem_create(fd1, BO_SIZE); - handle2 = gem_create(fd1, BO_SIZE); - - dma_buf_fd = prime_handle_to_fd(fd1, handle1); - handle_import = prime_fd_to_handle(fd2, dma_buf_fd); - - close(dma_buf_fd); - gem_close(fd1, handle1); - - dma_buf_fd = prime_handle_to_fd(fd1, handle2); - handle_import = prime_fd_to_handle(fd2, dma_buf_fd); - check_bo(fd1, handle2, fd2, handle_import); - - gem_close(fd1, handle2); - close(dma_buf_fd); - - check_bo(fd2, handle_import, fd2, handle_import); - - close(fd1); - close(fd2); -} - -static void test_with_one_bo_two_files(void) -{ - int fd1, fd2; - uint32_t handle_import, handle_open, handle_orig, flink_name; - int dma_buf_fd1, dma_buf_fd2; - - fd1 = drm_open_any(); - fd2 = drm_open_any(); - - handle_orig = gem_create(fd1, BO_SIZE); - dma_buf_fd1 = prime_handle_to_fd(fd1, handle_orig); - - flink_name = gem_flink(fd1, handle_orig); - handle_open = gem_open(fd2, flink_name); - - dma_buf_fd2 = prime_handle_to_fd(fd2, handle_open); - handle_import = prime_fd_to_handle(fd2, dma_buf_fd2); - - /* dma-buf selfimporting an flink bo should give the same handle */ - igt_assert(handle_import == handle_open); - - close(fd1); - close(fd2); - close(dma_buf_fd1); - close(dma_buf_fd2); -} - -static void test_with_one_bo(void) -{ - int fd1, fd2; - uint32_t handle, handle_import1, handle_import2, handle_selfimport; - int dma_buf_fd; - - fd1 = drm_open_any(); - fd2 = drm_open_any(); - - handle = gem_create(fd1, BO_SIZE); - - dma_buf_fd = prime_handle_to_fd(fd1, handle); - handle_import1 = prime_fd_to_handle(fd2, dma_buf_fd); - - check_bo(fd1, handle, fd2, handle_import1); - - /* reimport should give us the same handle so that userspace can check - * whether it has that bo already somewhere. */ - handle_import2 = prime_fd_to_handle(fd2, dma_buf_fd); - igt_assert(handle_import1 == handle_import2); - - /* Same for re-importing on the exporting fd. */ - handle_selfimport = prime_fd_to_handle(fd1, dma_buf_fd); - igt_assert(handle == handle_selfimport); - - /* close dma_buf, check whether nothing disappears. */ - close(dma_buf_fd); - check_bo(fd1, handle, fd2, handle_import1); - - gem_close(fd1, handle); - check_bo(fd2, handle_import1, fd2, handle_import1); - - /* re-import into old exporter */ - dma_buf_fd = prime_handle_to_fd(fd2, handle_import1); - /* but drop all references to the obj in between */ - gem_close(fd2, handle_import1); - handle = prime_fd_to_handle(fd1, dma_buf_fd); - handle_import1 = prime_fd_to_handle(fd2, dma_buf_fd); - check_bo(fd1, handle, fd2, handle_import1); - - /* Completely rip out exporting fd. */ - close(fd1); - check_bo(fd2, handle_import1, fd2, handle_import1); -} - -static int get_object_count(void) -{ - FILE *file; - int ret, scanned; - - igt_drop_caches_set(DROP_RETIRE); - - file = igt_debugfs_fopen("i915_gem_objects", "r"); - - scanned = fscanf(file, "%i objects", &ret); - igt_assert(scanned == 1); - - return ret; -} - -static void *thread_fn_reimport_vs_close(void *p) -{ - struct drm_gem_close close_bo; - int *fds = p; - int fd = fds[0]; - int dma_buf_fd = fds[1]; - uint32_t handle; - - while (!pls_die) { - handle = prime_fd_to_handle(fd, dma_buf_fd); - - close_bo.handle = handle; - ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo); - } - - return (void *)0; -} - -static void test_reimport_close_race(void) -{ - pthread_t *threads; - int r, i, num_threads; - int fds[2]; - int obj_count; - void *status; - uint32_t handle; - int fake; - - /* Allocate exit handler fds in here so that we dont screw - * up the counts */ - fake = drm_open_any(); - - obj_count = get_object_count(); - - num_threads = sysconf(_SC_NPROCESSORS_ONLN); - - threads = calloc(num_threads, sizeof(pthread_t)); - - fds[0] = drm_open_any(); - - handle = gem_create(fds[0], BO_SIZE); - - fds[1] = prime_handle_to_fd(fds[0], handle); - - for (i = 0; i < num_threads; i++) { - r = pthread_create(&threads[i], NULL, - thread_fn_reimport_vs_close, - (void *)(uintptr_t)fds); - igt_assert(r == 0); - } - - sleep(5); - - pls_die = 1; - - for (i = 0; i < num_threads; i++) { - pthread_join(threads[i], &status); - igt_assert(status == 0); - } - - close(fds[0]); - close(fds[1]); - - obj_count = get_object_count() - obj_count; - - igt_info("leaked %i objects\n", obj_count); - - close(fake); - - igt_assert_eq(obj_count, 0); -} - -static void *thread_fn_export_vs_close(void *p) -{ - struct drm_prime_handle prime_h2f; - struct drm_gem_close close_bo; - int fd = (uintptr_t)p; - uint32_t handle; - - while (!pls_die) { - /* We want to race gem close against prime export on handle one.*/ - handle = gem_create(fd, 4096); - if (handle != 1) - gem_close(fd, handle); - - /* raw ioctl since we expect this to fail */ - - /* WTF: for gem_flink_race I've unconditionally used handle == 1 - * here, but with prime it seems to help a _lot_ to use - * something more random. */ - prime_h2f.handle = 1; - prime_h2f.flags = DRM_CLOEXEC; - prime_h2f.fd = -1; - - ioctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime_h2f); - - close_bo.handle = 1; - ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo); - - close(prime_h2f.fd); - } - - return (void *)0; -} - -static void test_export_close_race(void) -{ - pthread_t *threads; - int r, i, num_threads; - int fd; - int obj_count; - void *status; - int fake; - - num_threads = sysconf(_SC_NPROCESSORS_ONLN); - - threads = calloc(num_threads, sizeof(pthread_t)); - - /* Allocate exit handler fds in here so that we dont screw - * up the counts */ - fake = drm_open_any(); - - obj_count = get_object_count(); - - fd = drm_open_any(); - - for (i = 0; i < num_threads; i++) { - r = pthread_create(&threads[i], NULL, - thread_fn_export_vs_close, - (void *)(uintptr_t)fd); - igt_assert(r == 0); - } - - sleep(5); - - pls_die = 1; - - for (i = 0; i < num_threads; i++) { - pthread_join(threads[i], &status); - igt_assert(status == 0); - } - - close(fd); - - obj_count = get_object_count() - obj_count; - - igt_info("leaked %i objects\n", obj_count); - - close(fake); - - igt_assert_eq(obj_count, 0); -} - -static void test_llseek_size(void) -{ - int fd, i; - uint32_t handle; - int dma_buf_fd; - - counter = 0; - - fd = drm_open_any(); - - - for (i = 0; i < 10; i++) { - int bufsz = 4096 << i; - - handle = gem_create(fd, bufsz); - dma_buf_fd = prime_handle_to_fd(fd, handle); - - gem_close(fd, handle); - - igt_assert(prime_get_size(dma_buf_fd) == bufsz); - - close(dma_buf_fd); - } - - close(fd); -} - -static void test_llseek_bad(void) -{ - int fd; - uint32_t handle; - int dma_buf_fd; - - counter = 0; - - fd = drm_open_any(); - - - handle = gem_create(fd, BO_SIZE); - dma_buf_fd = prime_handle_to_fd(fd, handle); - - gem_close(fd, handle); - - igt_require(lseek(dma_buf_fd, 0, SEEK_END) >= 0); - - igt_assert(lseek(dma_buf_fd, -1, SEEK_END) == -1 && errno == EINVAL); - igt_assert(lseek(dma_buf_fd, 1, SEEK_SET) == -1 && errno == EINVAL); - igt_assert(lseek(dma_buf_fd, BO_SIZE, SEEK_SET) == -1 && errno == EINVAL); - igt_assert(lseek(dma_buf_fd, BO_SIZE + 1, SEEK_SET) == -1 && errno == EINVAL); - igt_assert(lseek(dma_buf_fd, BO_SIZE - 1, SEEK_SET) == -1 && errno == EINVAL); - - close(dma_buf_fd); - - close(fd); -} - -igt_main -{ - struct { - const char *name; - void (*fn)(void); - } tests[] = { - { "with_one_bo", test_with_one_bo }, - { "with_one_bo_two_files", test_with_one_bo_two_files }, - { "with_two_bos", test_with_two_bos }, - { "with_fd_dup", test_with_fd_dup }, - { "export-vs-gem_close-race", test_export_close_race }, - { "reimport-vs-gem_close-race", test_reimport_close_race }, - { "llseek-size", test_llseek_size }, - { "llseek-bad", test_llseek_bad }, - }; - int i; - - for (i = 0; i < ARRAY_SIZE(tests); i++) { - igt_subtest(tests[i].name) - tests[i].fn(); - } -} diff --git a/tests/prime_udl.c b/tests/prime_udl.c deleted file mode 100644 index 62b381a3..00000000 --- a/tests/prime_udl.c +++ /dev/null @@ -1,180 +0,0 @@ -/* basic set of prime tests between intel and nouveau */ - -/* test list - - 1. share buffer from intel -> nouveau. - 2. share buffer from nouveau -> intel - 3. share intel->nouveau, map on both, write intel, read nouveau - 4. share intel->nouveau, blit intel fill, readback on nouveau - test 1 + map buffer, read/write, map other size. - do some hw actions on the buffer - some illegal operations - - close prime fd try and map - - TODO add some nouveau rendering tests -*/ - - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <errno.h> - -#include "xf86drm.h" -#include <xf86drmMode.h> - -#include "ioctl_wrappers.h" -#include "intel_bufmgr.h" -#include "intel_io.h" -#include "intel_batchbuffer.h" -#include "drmtest.h" -#include "intel_chipset.h" - -int intel_fd = -1, udl_fd = -1; -drm_intel_bufmgr *bufmgr; -uint32_t devid; -struct intel_batchbuffer *intel_batch; - -#define BO_SIZE (640*480*2) - -static int find_and_open_devices(void) -{ - int i; - char path[80]; - struct stat buf; - FILE *fl; - char vendor_id[8]; - int venid; - for (i = 0; i < 9; i++) { - sprintf(path, "/sys/class/drm/card%d/device/vendor", i); - if (stat(path, &buf)) { - /* look for usb dev */ - sprintf(path, "/sys/class/drm/card%d/device/idVendor", i); - if (stat(path, &buf)) - break; - } - - fl = fopen(path, "r"); - if (!fl) - break; - - fgets(vendor_id, 8, fl); - fclose(fl); - - venid = strtoul(vendor_id, NULL, 16); - sprintf(path, "/dev/dri/card%d", i); - if (venid == 0x8086) { - intel_fd = open(path, O_RDWR); - if (!intel_fd) - return -1; - } else if (venid == 0x17e9) { - udl_fd = open(path, O_RDWR); - if (!udl_fd) - return -1; - } - } - return 0; -} - -static int dumb_bo_destroy(int fd, uint32_t handle) -{ - - struct drm_mode_destroy_dumb arg; - int ret; - memset(&arg, 0, sizeof(arg)); - arg.handle = handle; - ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); - if (ret) - return -errno; - return 0; - -} - -/* - * simple share and import - */ -static int test1(void) -{ - drm_intel_bo *test_intel_bo; - int prime_fd; - int ret; - uint32_t udl_handle; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - ret = drmPrimeFDToHandle(udl_fd, prime_fd, &udl_handle); - - dumb_bo_destroy(udl_fd, udl_handle); - drm_intel_bo_unreference(test_intel_bo); - return ret; -} - -static int test2(void) -{ - drm_intel_bo *test_intel_bo; - uint32_t fb_id; - drmModeClip clip; - int prime_fd; - uint32_t udl_handle; - int ret; - - test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096); - - drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd); - - ret = drmPrimeFDToHandle(udl_fd, prime_fd, &udl_handle); - if (ret) - goto out; - - ret = drmModeAddFB(udl_fd, 640, 480, 16, 16, 640, udl_handle, &fb_id); - if (ret) - goto out; - - clip.x1 = 0; - clip.y1 = 0; - clip.x2 = 10; - clip.y2 = 10; - ret = drmModeDirtyFB(udl_fd, fb_id, &clip, 1); - if (ret) { - return ret; - } -out: - dumb_bo_destroy(udl_fd, udl_handle); - drm_intel_bo_unreference(test_intel_bo); - return ret; -} - -igt_simple_main -{ - igt_skip_on_simulation(); - - igt_assert(find_and_open_devices() >= 0); - - igt_skip_on(udl_fd == -1); - igt_skip_on(intel_fd == -1); - - /* set up intel bufmgr */ - bufmgr = drm_intel_bufmgr_gem_init(intel_fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - - /* set up an intel batch buffer */ - devid = intel_get_drm_devid(intel_fd); - intel_batch = intel_batchbuffer_alloc(bufmgr, devid); - - /* create an object on the i915 */ - igt_assert(test1() == 0); - - igt_assert(test2() == 0); - - intel_batchbuffer_free(intel_batch); - - drm_intel_bufmgr_destroy(bufmgr); - - close(intel_fd); - close(udl_fd); -} diff --git a/tests/sysfs_l3_parity b/tests/sysfs_l3_parity deleted file mode 100755 index 9bd17246..00000000 --- a/tests/sysfs_l3_parity +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -if ! find /sys/class/drm/card*/ | grep l3_parity > /dev/null ; then - echo "no l3_parity interface, skipping test" - exit 77 -fi - -$SOURCE_DIR/../tools/intel_l3_parity -r 0 -b 0 -s 0 -e - -#Check that we can remap a row -$SOURCE_DIR/../tools/intel_l3_parity -r 0 -b 0 -s 0 -d -disabled=`$SOURCE_DIR/../tools/intel_l3_parity -l | grep -c 'Row 0, Bank 0, Subbank 0 is disabled'` -if [ "$disabled" != "1" ] ; then - echo "Fail" - exit 1 -fi - -$SOURCE_DIR/../tools/intel_l3_parity -r 0 -b 0 -s 0 -e - -#Check that we can clear remaps -if [ `$SOURCE_DIR/../tools/intel_l3_parity -l | wc -l` != 1 ] ; then - echo "Fail 2" - exit 1 -fi diff --git a/tests/test_rte_check b/tests/test_rte_check deleted file mode 100755 index eb12416a..00000000 --- a/tests/test_rte_check +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )" -. $SOURCE_DIR/drm_lib.sh - -exit 0 |