summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.gitignore78
-rw-r--r--tests/1080p-left.pngbin0 -> 5231820 bytes
-rw-r--r--tests/1080p-right.pngbin0 -> 5281220 bytes
-rw-r--r--tests/Makefile.am165
-rw-r--r--tests/Makefile.in3361
-rw-r--r--tests/Makefile.sources237
-rwxr-xr-xtests/ZZ_check_dmesg11
-rwxr-xr-xtests/ZZ_hangman42
-rw-r--r--tests/core_get_client_auth.c100
-rw-r--r--tests/core_getclient.c (renamed from tests/getclient.c)10
-rw-r--r--tests/core_getstats.c (renamed from tests/getstats.c)10
-rw-r--r--tests/core_getversion.c (renamed from tests/getversion.c)11
-rw-r--r--tests/ddi_compute_wrpll.c634
-rwxr-xr-xtests/ddx_intel_after_fbdev73
-rwxr-xr-xtests/debugfs_emon_crash2
-rwxr-xr-xtests/debugfs_wedged4
-rwxr-xr-xtests/drm_lib.sh33
-rw-r--r--tests/drm_vma_limiter.c24
-rw-r--r--tests/drm_vma_limiter_cached.c31
-rw-r--r--tests/drm_vma_limiter_cpu.c20
-rw-r--r--tests/drm_vma_limiter_gtt.c20
-rwxr-xr-xtests/drv_debugfs_reader (renamed from tests/debugfs_reader)2
-rw-r--r--tests/drv_hangman.c428
-rwxr-xr-xtests/drv_missed_irq_hang70
-rwxr-xr-xtests/drv_module_reload (renamed from tests/module_reload)13
-rw-r--r--tests/drv_suspend.c189
-rw-r--r--tests/eviction_common.c251
-rw-r--r--tests/flip_test.c317
-rw-r--r--tests/gem_alive.c35
-rw-r--r--tests/gem_bad_address.c6
-rw-r--r--tests/gem_bad_batch.c6
-rw-r--r--tests/gem_bad_blit.c14
-rw-r--r--tests/gem_bad_length.c24
-rw-r--r--tests/gem_bad_reloc.c137
-rw-r--r--tests/gem_basic.c33
-rw-r--r--tests/gem_caching.c289
-rw-r--r--tests/gem_close_race.c280
-rw-r--r--tests/gem_concurrent_blit.c398
-rw-r--r--tests/gem_cpu_concurrent_blit.c142
-rw-r--r--tests/gem_cpu_reloc.c247
-rw-r--r--tests/gem_cs_prefetch.c52
-rw-r--r--tests/gem_cs_tlb.c179
-rw-r--r--tests/gem_ctx_bad_destroy.c55
-rw-r--r--tests/gem_ctx_bad_exec.c66
-rw-r--r--tests/gem_ctx_basic.c66
-rw-r--r--tests/gem_ctx_create.c24
-rw-r--r--tests/gem_ctx_exec.c145
-rw-r--r--tests/gem_double_irq_loop.c48
-rw-r--r--tests/gem_dummy_reloc_loop.c225
-rw-r--r--tests/gem_evict_alignment.c228
-rw-r--r--tests/gem_evict_everything.c242
-rw-r--r--tests/gem_exec_bad_domains.c183
-rw-r--r--tests/gem_exec_big.c123
-rw-r--r--tests/gem_exec_blt.c105
-rw-r--r--tests/gem_exec_faulting_reloc.c114
-rw-r--r--tests/gem_exec_lut_handle.c204
-rw-r--r--tests/gem_exec_nop.c63
-rw-r--r--tests/gem_exec_params.c217
-rw-r--r--tests/gem_exec_parse.c397
-rw-r--r--tests/gem_fd_exhaustion.c94
-rw-r--r--tests/gem_fence_thrash.c166
-rw-r--r--tests/gem_fenced_exec_thrash.c149
-rw-r--r--tests/gem_flink.c99
-rw-r--r--tests/gem_flink_race.c216
-rw-r--r--tests/gem_gtt_concurrent_blit.c145
-rw-r--r--tests/gem_gtt_cpu_tlb.c17
-rw-r--r--tests/gem_gtt_hog.c192
-rw-r--r--tests/gem_gtt_speed.c105
-rw-r--r--tests/gem_hang.c14
-rw-r--r--tests/gem_hangcheck_forcewake.c29
-rw-r--r--tests/gem_largeobject.c30
-rw-r--r--tests/gem_linear_blits.c135
-rw-r--r--tests/gem_lut_handle.c238
-rw-r--r--tests/gem_madvise.c155
-rw-r--r--tests/gem_media_fill.c142
-rw-r--r--tests/gem_mmap.c79
-rw-r--r--tests/gem_mmap_gtt.c93
-rw-r--r--tests/gem_mmap_offset_exhaustion.c16
-rw-r--r--tests/gem_multi_bsd_sync_loop.c164
-rw-r--r--tests/gem_non_secure_batch.c113
-rw-r--r--tests/gem_partial_pwrite_pread.c189
-rw-r--r--tests/gem_persistent_relocs.c365
-rw-r--r--tests/gem_pin.c250
-rw-r--r--tests/gem_pipe_control_store_loop.c121
-rw-r--r--tests/gem_pread.c153
-rw-r--r--tests/gem_pread_after_blit.c172
-rw-r--r--tests/gem_pwrite.c91
-rw-r--r--tests/gem_pwrite_pread.c413
-rw-r--r--tests/gem_readwrite.c151
-rw-r--r--tests/gem_reg_read.c63
-rw-r--r--tests/gem_reloc_overflow.c381
-rw-r--r--tests/gem_reloc_vs_gpu.c278
-rw-r--r--tests/gem_render_copy.c193
-rw-r--r--tests/gem_render_copy_redux.c247
-rw-r--r--tests/gem_render_linear_blits.c205
-rw-r--r--tests/gem_render_tiled_blits.c216
-rw-r--r--tests/gem_reset_stats.c1163
-rw-r--r--tests/gem_ring_sync_copy.c368
-rw-r--r--tests/gem_ring_sync_loop.c44
-rw-r--r--tests/gem_ringfill.c100
-rw-r--r--tests/gem_seqno_wrap.c645
-rw-r--r--tests/gem_set_tiling_vs_blt.c119
-rw-r--r--tests/gem_set_tiling_vs_gtt.c37
-rw-r--r--tests/gem_set_tiling_vs_pwrite.c22
-rw-r--r--tests/gem_storedw_batches_loop.c157
-rw-r--r--tests/gem_storedw_loop_blt.c96
-rw-r--r--tests/gem_storedw_loop_bsd.c103
-rw-r--r--tests/gem_storedw_loop_render.c91
-rw-r--r--tests/gem_storedw_loop_vebox.c130
-rw-r--r--tests/gem_stress.c175
-rw-r--r--tests/gem_threaded_access_tiled.c122
-rw-r--r--tests/gem_tiled_blits.c149
-rw-r--r--tests/gem_tiled_fence_blits.c45
-rw-r--r--tests/gem_tiled_partial_pwrite_pread.c188
-rw-r--r--tests/gem_tiled_pread.c36
-rw-r--r--tests/gem_tiled_pread_pwrite.c33
-rw-r--r--tests/gem_tiled_swapping.c156
-rw-r--r--tests/gem_tiling_max_stride.c139
-rw-r--r--tests/gem_unfence_active_buffers.c41
-rw-r--r--tests/gem_unref_active_buffers.c31
-rw-r--r--tests/gem_userptr_blits.c1249
-rw-r--r--tests/gem_vmap_blits.c355
-rw-r--r--tests/gem_wait_render_timeout.c111
-rw-r--r--tests/gem_write_read_ring_switch.c197
-rw-r--r--tests/gen3_mixed_blits.c66
-rw-r--r--tests/gen3_render_linear_blits.c39
-rw-r--r--tests/gen3_render_mixed_blits.c58
-rw-r--r--tests/gen3_render_tiledx_blits.c44
-rw-r--r--tests/gen3_render_tiledy_blits.c58
-rw-r--r--tests/gen7_forcewake_mt.c206
-rw-r--r--tests/igt_fork_helper.c37
-rw-r--r--tests/igt_list_only.c42
-rw-r--r--tests/igt_no_exit.c39
-rw-r--r--tests/igt_no_exit_list_only.c40
-rw-r--r--tests/igt_no_subtest.c38
-rw-r--r--tests/igt_simulation.c156
-rw-r--r--tests/kms_addfb.c229
-rw-r--r--tests/kms_cursor_crc.c470
-rw-r--r--tests/kms_fbc_crc.c531
-rw-r--r--tests/kms_fence_pin_leak.c239
-rw-r--r--tests/kms_flip.c1651
-rw-r--r--tests/kms_flip_tiling.c145
-rw-r--r--tests/kms_mmio_vs_cs_flip.c580
-rw-r--r--tests/kms_pipe_crc_basic.c231
-rw-r--r--tests/kms_plane.c242
-rw-r--r--tests/kms_render.c249
-rw-r--r--tests/kms_setmode.c742
-rw-r--r--tests/kms_sink_crc_basic.c191
-rwxr-xr-xtests/kms_sysfs_edid_timing (renamed from tests/sysfs_edid_timing)7
-rw-r--r--tests/pm_lpsp.c280
-rw-r--r--tests/pm_psr.c86
-rw-r--r--tests/pm_rc6_residency.c169
-rw-r--r--tests/pm_rpm.c1497
-rw-r--r--tests/pm_rps.c595
-rw-r--r--tests/prime_nv_api.c423
-rw-r--r--tests/prime_nv_pcopy.c831
-rw-r--r--tests/prime_nv_test.c375
-rw-r--r--tests/prime_self_import.c362
-rw-r--r--tests/prime_udl.c180
-rwxr-xr-xtests/sysfs_l3_parity12
-rw-r--r--tests/sysfs_rc6_residency.c119
-rw-r--r--tests/template.c80
-rwxr-xr-xtests/test_rte_check8
-rw-r--r--tests/testdisplay.c671
-rwxr-xr-xtests/tools_test18
165 files changed, 29567 insertions, 4933 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
deleted file mode 100644
index 1a6795bc..00000000
--- a/tests/.gitignore
+++ /dev/null
@@ -1,78 +0,0 @@
-flip_test
-drm_vma_limiter
-drm_vma_limiter_cached
-drm_vma_limiter_cpu
-drm_vma_limiter_gtt
-gem_bad_address
-gem_bad_batch
-gem_bad_blit
-gem_bad_length
-gem_basic
-gem_cs_prefetch
-gem_cpu_concurrent_blit
-gem_ctx_bad_destroy
-gem_ctx_bad_exec
-gem_ctx_basic
-gem_ctx_create
-gem_ctx_exec
-gem_double_irq_loop
-gem_dummy_reloc_loop
-gem_exec_bad_domains
-gem_exec_blt
-gem_exec_faulting_reloc
-gem_exec_nop
-gem_fenced_exec_thrash
-gem_fence_thrash
-gem_flink
-gem_gtt_speed
-gem_gtt_concurrent_blit
-gem_gtt_cpu_tlb
-gem_hang
-gem_hangcheck_forcewake
-gem_largeobject
-gem_linear_blits
-gem_mmap
-gem_mmap_gtt
-gem_mmap_offset_exhaustion
-gem_partial_pwrite_pread
-gem_pipe_control_store_loop
-gem_pread_after_blit
-gem_pwrite
-gem_readwrite
-gem_reloc_vs_gpu
-gem_reg_read
-gem_ringfill
-gem_ring_sync_loop
-gem_set_tiling_vs_blt
-gem_set_tiling_vs_gtt
-gem_set_tiling_vs_pwrite
-gem_storedw_batches_loop
-gem_storedw_loop_blt
-gem_storedw_loop_bsd
-gem_storedw_loop_render
-gem_stress
-gem_tiled_blits
-gem_tiled_fence_blits
-gem_tiled_partial_pwrite_pread
-gem_tiled_pread
-gem_tiled_pread_pwrite
-gem_tiled_swapping
-gem_unfence_active_buffers
-gem_unref_active_buffers
-gem_vmap_blits
-gem_wait_render_timeout
-gen3_mixed_blits
-gen3_render_linear_blits
-gen3_render_mixed_blits
-gen3_render_tiledx_blits
-gen3_render_tiledy_blits
-getclient
-getstats
-getversion
-prime_nv_api
-prime_nv_pcopy
-prime_nv_test
-prime_self_import
-testdisplay
-sysfs_rc6_residency
-# Please keep sorted alphabetically
diff --git a/tests/1080p-left.png b/tests/1080p-left.png
new file mode 100644
index 00000000..b08f0715
--- /dev/null
+++ b/tests/1080p-left.png
Binary files differ
diff --git a/tests/1080p-right.png b/tests/1080p-right.png
new file mode 100644
index 00000000..ea4cd8aa
--- /dev/null
+++ b/tests/1080p-right.png
Binary files differ
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e29a383a..71ecdf20 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,144 +1,69 @@
-noinst_PROGRAMS = \
- gem_stress \
- $(TESTS_progs) \
- $(HANG) \
- $(NULL)
+include Makefile.sources
if HAVE_NOUVEAU
-NOUVEAU_TESTS = \
- prime_nv_api \
- prime_nv_pcopy \
- prime_nv_test
+ TESTS_progs_M += $(NOUVEAU_TESTS_M)
endif
-TESTS_progs = \
- getversion \
- getclient \
- getstats \
- gem_basic \
- gem_cpu_concurrent_blit \
- gem_gtt_concurrent_blit \
- gem_exec_nop \
- gem_exec_blt \
- gem_exec_bad_domains \
- gem_exec_faulting_reloc \
- gem_flink \
- gem_readwrite \
- gem_ringfill \
- gem_mmap \
- gem_mmap_gtt \
- gem_mmap_offset_exhaustion \
- gem_pwrite \
- gem_pread_after_blit \
- gem_set_tiling_vs_blt \
- gem_set_tiling_vs_gtt \
- gem_set_tiling_vs_pwrite \
- gem_tiled_pread \
- gem_tiled_pread_pwrite \
- gem_tiled_partial_pwrite_pread \
- gem_tiled_swapping \
- gem_partial_pwrite_pread \
- gem_linear_blits \
- gem_vmap_blits \
- gem_tiled_blits \
- gem_tiled_fence_blits \
- gem_largeobject \
- gem_bad_length \
- gem_fence_thrash \
- gem_fenced_exec_thrash \
- gem_gtt_speed \
- gem_gtt_cpu_tlb \
- gem_cs_prefetch \
- gen3_render_linear_blits \
- gen3_render_tiledx_blits \
- gen3_render_tiledy_blits \
- gen3_render_mixed_blits \
- gen3_mixed_blits \
- gem_storedw_loop_render \
- gem_storedw_loop_blt \
- gem_storedw_loop_bsd \
- gem_storedw_batches_loop \
- gem_dummy_reloc_loop \
- gem_double_irq_loop \
- gem_ring_sync_loop \
- gem_pipe_control_store_loop \
- gem_unfence_active_buffers \
- gem_unref_active_buffers \
- gem_reloc_vs_gpu \
- drm_vma_limiter \
- drm_vma_limiter_cpu \
- drm_vma_limiter_gtt \
- drm_vma_limiter_cached \
- sysfs_rc6_residency \
- flip_test \
- gem_wait_render_timeout \
- gem_ctx_create \
- gem_ctx_bad_destroy \
- gem_ctx_exec \
- gem_ctx_bad_exec \
- gem_ctx_basic \
- gem_reg_read \
- $(NOUVEAU_TESTS) \
- prime_self_import \
- $(NULL)
+if BUILD_TESTS
+all-local: single-tests.txt multi-tests.txt
-# IMPORTANT: The ZZ_ tests need to be run last!
-# ... and make can't deal with inlined comments ...
-TESTS_scripts = \
- debugfs_reader \
- debugfs_emon_crash \
- sysfs_l3_parity \
- sysfs_edid_timing \
- module_reload \
- ZZ_check_dmesg \
- ZZ_hangman \
- $(NULL)
+list-single-tests:
+ @echo TESTLIST
+ @echo ${single_kernel_tests}
+ @echo END TESTLIST
-kernel_tests = \
- $(TESTS_progs) \
- $(TESTS_scripts) \
- $(NULL)
+list-multi-tests:
+ @echo TESTLIST
+ @echo ${multi_kernel_tests}
+ @echo END TESTLIST
-TESTS = \
- $(NULL)
+single-tests.txt: Makefile.sources
+ @echo TESTLIST > $@
+ @echo ${single_kernel_tests} >> $@
+ @echo END TESTLIST >> $@
-test:
- whoami | grep root || ( echo ERROR: not running as root; exit 1 )
- ./check_drm_clients
- make TESTS="${kernel_tests}" check
+multi-tests.txt: Makefile.sources
+ @echo TESTLIST > $@
+ @echo ${multi_kernel_tests} >> $@
+ @echo END TESTLIST >> $@
-HANG = \
- gem_bad_batch \
- gem_hang \
- gem_bad_blit \
- gem_bad_address \
- $(NULL)
+EXTRA_PROGRAMS = $(TESTS_progs) $(TESTS_progs_M) $(HANG) $(TESTS_testsuite)
+EXTRA_DIST = $(TESTS_scripts) $(TESTS_scripts_M) $(scripts) $(IMAGES) $(common_files)
-EXTRA_PROGRAMS = $(TESTS_progs) $(HANG)
-EXTRA_DIST = $(TESTS_scripts) drm_lib.sh check_drm_clients debugfs_wedged
-CLEANFILES = $(EXTRA_PROGRAMS)
+CLEANFILES = $(EXTRA_PROGRAMS) single-tests.txt multi-tests.txt
AM_CFLAGS = $(DRM_CFLAGS) $(CWARNFLAGS) \
-I$(srcdir)/.. \
- -I$(srcdir)/../lib
-LDADD = ../lib/libintel_tools.la $(PCIACCESS_LIBS) $(DRM_LIBS)
-
-testdisplay_SOURCES = \
- testdisplay.c \
- testdisplay.h \
- testdisplay_hotplug.c \
+ -I$(srcdir)/../lib \
+ -include "$(srcdir)/../lib/check-ndebug.h" \
+ -include "$(top_builddir)/version.h" \
+ -DIGT_DATADIR=\""$(abs_srcdir)"\" \
$(NULL)
-TESTS_progs += testdisplay
+LDADD = ../lib/libintel_tools.la $(PCIACCESS_LIBS) $(DRM_LIBS)
+
LDADD += $(CAIRO_LIBS) $(LIBUDEV_LIBS) $(GLIB_LIBS)
AM_CFLAGS += $(CAIRO_CFLAGS) $(LIBUDEV_CFLAGS) $(GLIB_CFLAGS)
+gem_close_race_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+gem_close_race_LDADD = $(LDADD) -lpthread
+gem_ctx_basic_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+gem_ctx_basic_LDADD = $(LDADD) -lpthread
gem_fence_thrash_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
gem_fence_thrash_LDADD = $(LDADD) -lpthread
+gem_flink_race_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+gem_flink_race_LDADD = $(LDADD) -lpthread
+gem_threaded_access_tiled_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+gem_threaded_access_tiled_LDADD = $(LDADD) -lpthread
+gem_tiled_swapping_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+gem_tiled_swapping_LDADD = $(LDADD) -lpthread
+prime_self_import_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+prime_self_import_LDADD = $(LDADD) -lpthread
+gen7_forcewake_mt_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+gen7_forcewake_mt_LDADD = $(LDADD) -lpthread
gem_wait_render_timeout_LDADD = $(LDADD) -lrt
-
-gem_ctx_basic_LDADD = $(LDADD) -lpthread
+kms_flip_LDADD = $(LDADD) -lrt -lpthread
prime_nv_test_CFLAGS = $(AM_CFLAGS) $(DRM_NOUVEAU_CFLAGS)
prime_nv_test_LDADD = $(LDADD) $(DRM_NOUVEAU_LIBS)
@@ -146,3 +71,5 @@ prime_nv_api_CFLAGS = $(AM_CFLAGS) $(DRM_NOUVEAU_CFLAGS)
prime_nv_api_LDADD = $(LDADD) $(DRM_NOUVEAU_LIBS)
prime_nv_pcopy_CFLAGS = $(AM_CFLAGS) $(DRM_NOUVEAU_CFLAGS)
prime_nv_pcopy_LDADD = $(LDADD) $(DRM_NOUVEAU_LIBS)
+endif
+
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 00000000..5af503a8
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,3361 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+DIST_COMMON = $(srcdir)/Makefile.sources $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+noinst_PROGRAMS = gem_alive$(EXEEXT) gem_stress$(EXEEXT) \
+ ddi_compute_wrpll$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_4) \
+ $(am__EXEEXT_5) $(am__EXEEXT_6)
+TESTS = $(am__EXEEXT_6)
+XFAIL_TESTS = igt_no_exit$(EXEEXT) igt_no_exit_list_only$(EXEEXT) \
+ igt_no_subtest$(EXEEXT)
+@HAVE_NOUVEAU_TRUE@am__append_1 = $(NOUVEAU_TESTS_M)
+@BUILD_TESTS_TRUE@EXTRA_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_4) \
+@BUILD_TESTS_TRUE@ $(am__EXEEXT_5) $(am__EXEEXT_6)
+subdir = tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pkg_swig.m4 \
+ $(top_srcdir)/m4/ax_python_devel.m4 \
+ $(top_srcdir)/m4/ax_swig_python.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = core_getclient$(EXEEXT) core_getstats$(EXEEXT) \
+ core_getversion$(EXEEXT) drm_vma_limiter$(EXEEXT) \
+ drm_vma_limiter_cached$(EXEEXT) drm_vma_limiter_cpu$(EXEEXT) \
+ drm_vma_limiter_gtt$(EXEEXT) gem_bad_length$(EXEEXT) \
+ gem_cpu_reloc$(EXEEXT) gem_cs_prefetch$(EXEEXT) \
+ gem_ctx_bad_destroy$(EXEEXT) gem_ctx_basic$(EXEEXT) \
+ gem_ctx_create$(EXEEXT) gem_double_irq_loop$(EXEEXT) \
+ gem_exec_big$(EXEEXT) gem_exec_blt$(EXEEXT) \
+ gem_exec_lut_handle$(EXEEXT) gem_fd_exhaustion$(EXEEXT) \
+ gem_gtt_cpu_tlb$(EXEEXT) gem_gtt_hog$(EXEEXT) \
+ gem_gtt_speed$(EXEEXT) gem_hangcheck_forcewake$(EXEEXT) \
+ gem_largeobject$(EXEEXT) gem_lut_handle$(EXEEXT) \
+ gem_mmap_offset_exhaustion$(EXEEXT) gem_media_fill$(EXEEXT) \
+ gem_pin$(EXEEXT) gem_reg_read$(EXEEXT) \
+ gem_render_copy$(EXEEXT) gem_render_copy_redux$(EXEEXT) \
+ gem_render_linear_blits$(EXEEXT) \
+ gem_render_tiled_blits$(EXEEXT) gem_ring_sync_copy$(EXEEXT) \
+ gem_ring_sync_loop$(EXEEXT) gem_multi_bsd_sync_loop$(EXEEXT) \
+ gem_seqno_wrap$(EXEEXT) gem_set_tiling_vs_gtt$(EXEEXT) \
+ gem_set_tiling_vs_pwrite$(EXEEXT) \
+ gem_storedw_loop_blt$(EXEEXT) gem_storedw_loop_bsd$(EXEEXT) \
+ gem_storedw_loop_render$(EXEEXT) \
+ gem_storedw_loop_vebox$(EXEEXT) \
+ gem_threaded_access_tiled$(EXEEXT) \
+ gem_tiled_fence_blits$(EXEEXT) gem_tiled_pread$(EXEEXT) \
+ gem_tiled_pread_pwrite$(EXEEXT) gem_tiled_swapping$(EXEEXT) \
+ gem_tiling_max_stride$(EXEEXT) \
+ gem_unfence_active_buffers$(EXEEXT) \
+ gem_unref_active_buffers$(EXEEXT) gem_userptr_blits$(EXEEXT) \
+ gem_wait_render_timeout$(EXEEXT) gen3_mixed_blits$(EXEEXT) \
+ gen3_render_linear_blits$(EXEEXT) \
+ gen3_render_mixed_blits$(EXEEXT) \
+ gen3_render_tiledx_blits$(EXEEXT) \
+ gen3_render_tiledy_blits$(EXEEXT) gen7_forcewake_mt$(EXEEXT) \
+ kms_sink_crc_basic$(EXEEXT) kms_fence_pin_leak$(EXEEXT) \
+ pm_psr$(EXEEXT) pm_rc6_residency$(EXEEXT) prime_udl$(EXEEXT) \
+ testdisplay$(EXEEXT)
+am__EXEEXT_2 = prime_nv_api$(EXEEXT) prime_nv_pcopy$(EXEEXT) \
+ prime_nv_test$(EXEEXT)
+@HAVE_NOUVEAU_TRUE@am__EXEEXT_3 = $(am__EXEEXT_2)
+am__EXEEXT_4 = core_get_client_auth$(EXEEXT) drv_suspend$(EXEEXT) \
+ drv_hangman$(EXEEXT) gem_bad_reloc$(EXEEXT) gem_basic$(EXEEXT) \
+ gem_caching$(EXEEXT) gem_close_race$(EXEEXT) \
+ gem_concurrent_blit$(EXEEXT) gem_cs_tlb$(EXEEXT) \
+ gem_ctx_bad_exec$(EXEEXT) gem_ctx_exec$(EXEEXT) \
+ gem_dummy_reloc_loop$(EXEEXT) gem_evict_alignment$(EXEEXT) \
+ gem_evict_everything$(EXEEXT) gem_exec_bad_domains$(EXEEXT) \
+ gem_exec_faulting_reloc$(EXEEXT) gem_exec_nop$(EXEEXT) \
+ gem_exec_params$(EXEEXT) gem_exec_parse$(EXEEXT) \
+ gem_fenced_exec_thrash$(EXEEXT) gem_fence_thrash$(EXEEXT) \
+ gem_flink$(EXEEXT) gem_flink_race$(EXEEXT) \
+ gem_linear_blits$(EXEEXT) gem_madvise$(EXEEXT) \
+ gem_mmap$(EXEEXT) gem_mmap_gtt$(EXEEXT) \
+ gem_partial_pwrite_pread$(EXEEXT) \
+ gem_persistent_relocs$(EXEEXT) \
+ gem_pipe_control_store_loop$(EXEEXT) gem_pread$(EXEEXT) \
+ gem_pread_after_blit$(EXEEXT) gem_pwrite$(EXEEXT) \
+ gem_pwrite_pread$(EXEEXT) gem_readwrite$(EXEEXT) \
+ gem_reloc_overflow$(EXEEXT) gem_reloc_vs_gpu$(EXEEXT) \
+ gem_reset_stats$(EXEEXT) gem_ringfill$(EXEEXT) \
+ gem_set_tiling_vs_blt$(EXEEXT) \
+ gem_storedw_batches_loop$(EXEEXT) gem_tiled_blits$(EXEEXT) \
+ gem_tiled_partial_pwrite_pread$(EXEEXT) \
+ gem_write_read_ring_switch$(EXEEXT) kms_addfb$(EXEEXT) \
+ kms_cursor_crc$(EXEEXT) kms_fbc_crc$(EXEEXT) kms_flip$(EXEEXT) \
+ kms_flip_tiling$(EXEEXT) kms_mmio_vs_cs_flip$(EXEEXT) \
+ kms_pipe_crc_basic$(EXEEXT) kms_plane$(EXEEXT) \
+ kms_render$(EXEEXT) kms_setmode$(EXEEXT) pm_lpsp$(EXEEXT) \
+ pm_rpm$(EXEEXT) pm_rps$(EXEEXT) prime_self_import$(EXEEXT) \
+ template$(EXEEXT) $(am__EXEEXT_3)
+am__EXEEXT_5 = gem_bad_batch$(EXEEXT) gem_hang$(EXEEXT) \
+ gem_bad_blit$(EXEEXT) gem_bad_address$(EXEEXT) \
+ gem_non_secure_batch$(EXEEXT)
+am__EXEEXT_6 = igt_no_exit$(EXEEXT) igt_no_exit_list_only$(EXEEXT) \
+ igt_fork_helper$(EXEEXT) igt_list_only$(EXEEXT) \
+ igt_no_subtest$(EXEEXT) igt_simulation$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+core_get_client_auth_SOURCES = core_get_client_auth.c
+core_get_client_auth_OBJECTS = core_get_client_auth.$(OBJEXT)
+core_get_client_auth_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+@BUILD_TESTS_TRUE@core_get_client_auth_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+core_getclient_SOURCES = core_getclient.c
+core_getclient_OBJECTS = core_getclient.$(OBJEXT)
+core_getclient_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@core_getclient_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+core_getstats_SOURCES = core_getstats.c
+core_getstats_OBJECTS = core_getstats.$(OBJEXT)
+core_getstats_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@core_getstats_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+core_getversion_SOURCES = core_getversion.c
+core_getversion_OBJECTS = core_getversion.$(OBJEXT)
+core_getversion_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@core_getversion_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+ddi_compute_wrpll_SOURCES = ddi_compute_wrpll.c
+ddi_compute_wrpll_OBJECTS = ddi_compute_wrpll.$(OBJEXT)
+ddi_compute_wrpll_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@ddi_compute_wrpll_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+drm_vma_limiter_SOURCES = drm_vma_limiter.c
+drm_vma_limiter_OBJECTS = drm_vma_limiter.$(OBJEXT)
+drm_vma_limiter_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@drm_vma_limiter_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+drm_vma_limiter_cached_SOURCES = drm_vma_limiter_cached.c
+drm_vma_limiter_cached_OBJECTS = drm_vma_limiter_cached.$(OBJEXT)
+drm_vma_limiter_cached_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@drm_vma_limiter_cached_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+drm_vma_limiter_cpu_SOURCES = drm_vma_limiter_cpu.c
+drm_vma_limiter_cpu_OBJECTS = drm_vma_limiter_cpu.$(OBJEXT)
+drm_vma_limiter_cpu_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@drm_vma_limiter_cpu_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+drm_vma_limiter_gtt_SOURCES = drm_vma_limiter_gtt.c
+drm_vma_limiter_gtt_OBJECTS = drm_vma_limiter_gtt.$(OBJEXT)
+drm_vma_limiter_gtt_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@drm_vma_limiter_gtt_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+drv_hangman_SOURCES = drv_hangman.c
+drv_hangman_OBJECTS = drv_hangman.$(OBJEXT)
+drv_hangman_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@drv_hangman_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+drv_suspend_SOURCES = drv_suspend.c
+drv_suspend_OBJECTS = drv_suspend.$(OBJEXT)
+drv_suspend_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@drv_suspend_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_alive_SOURCES = gem_alive.c
+gem_alive_OBJECTS = gem_alive.$(OBJEXT)
+gem_alive_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_alive_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_bad_address_SOURCES = gem_bad_address.c
+gem_bad_address_OBJECTS = gem_bad_address.$(OBJEXT)
+gem_bad_address_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_bad_address_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_bad_batch_SOURCES = gem_bad_batch.c
+gem_bad_batch_OBJECTS = gem_bad_batch.$(OBJEXT)
+gem_bad_batch_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_bad_batch_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_bad_blit_SOURCES = gem_bad_blit.c
+gem_bad_blit_OBJECTS = gem_bad_blit.$(OBJEXT)
+gem_bad_blit_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_bad_blit_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_bad_length_SOURCES = gem_bad_length.c
+gem_bad_length_OBJECTS = gem_bad_length.$(OBJEXT)
+gem_bad_length_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_bad_length_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_bad_reloc_SOURCES = gem_bad_reloc.c
+gem_bad_reloc_OBJECTS = gem_bad_reloc.$(OBJEXT)
+gem_bad_reloc_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_bad_reloc_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_basic_SOURCES = gem_basic.c
+gem_basic_OBJECTS = gem_basic.$(OBJEXT)
+gem_basic_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_basic_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_caching_SOURCES = gem_caching.c
+gem_caching_OBJECTS = gem_caching.$(OBJEXT)
+gem_caching_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_caching_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_close_race_SOURCES = gem_close_race.c
+gem_close_race_OBJECTS = gem_close_race-gem_close_race.$(OBJEXT)
+@BUILD_TESTS_TRUE@am__DEPENDENCIES_2 = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+@BUILD_TESTS_TRUE@gem_close_race_DEPENDENCIES = $(am__DEPENDENCIES_2)
+gem_close_race_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(gem_close_race_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
+ $@
+gem_concurrent_blit_SOURCES = gem_concurrent_blit.c
+gem_concurrent_blit_OBJECTS = gem_concurrent_blit.$(OBJEXT)
+gem_concurrent_blit_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_concurrent_blit_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_cpu_reloc_SOURCES = gem_cpu_reloc.c
+gem_cpu_reloc_OBJECTS = gem_cpu_reloc.$(OBJEXT)
+gem_cpu_reloc_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_cpu_reloc_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_cs_prefetch_SOURCES = gem_cs_prefetch.c
+gem_cs_prefetch_OBJECTS = gem_cs_prefetch.$(OBJEXT)
+gem_cs_prefetch_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_cs_prefetch_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_cs_tlb_SOURCES = gem_cs_tlb.c
+gem_cs_tlb_OBJECTS = gem_cs_tlb.$(OBJEXT)
+gem_cs_tlb_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_cs_tlb_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_ctx_bad_destroy_SOURCES = gem_ctx_bad_destroy.c
+gem_ctx_bad_destroy_OBJECTS = gem_ctx_bad_destroy.$(OBJEXT)
+gem_ctx_bad_destroy_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_ctx_bad_destroy_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_ctx_bad_exec_SOURCES = gem_ctx_bad_exec.c
+gem_ctx_bad_exec_OBJECTS = gem_ctx_bad_exec.$(OBJEXT)
+gem_ctx_bad_exec_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_ctx_bad_exec_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_ctx_basic_SOURCES = gem_ctx_basic.c
+gem_ctx_basic_OBJECTS = gem_ctx_basic-gem_ctx_basic.$(OBJEXT)
+@BUILD_TESTS_TRUE@gem_ctx_basic_DEPENDENCIES = $(am__DEPENDENCIES_2)
+gem_ctx_basic_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(gem_ctx_basic_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+gem_ctx_create_SOURCES = gem_ctx_create.c
+gem_ctx_create_OBJECTS = gem_ctx_create.$(OBJEXT)
+gem_ctx_create_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_ctx_create_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_ctx_exec_SOURCES = gem_ctx_exec.c
+gem_ctx_exec_OBJECTS = gem_ctx_exec.$(OBJEXT)
+gem_ctx_exec_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_ctx_exec_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_double_irq_loop_SOURCES = gem_double_irq_loop.c
+gem_double_irq_loop_OBJECTS = gem_double_irq_loop.$(OBJEXT)
+gem_double_irq_loop_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_double_irq_loop_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_dummy_reloc_loop_SOURCES = gem_dummy_reloc_loop.c
+gem_dummy_reloc_loop_OBJECTS = gem_dummy_reloc_loop.$(OBJEXT)
+gem_dummy_reloc_loop_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_dummy_reloc_loop_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_evict_alignment_SOURCES = gem_evict_alignment.c
+gem_evict_alignment_OBJECTS = gem_evict_alignment.$(OBJEXT)
+gem_evict_alignment_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_evict_alignment_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_evict_everything_SOURCES = gem_evict_everything.c
+gem_evict_everything_OBJECTS = gem_evict_everything.$(OBJEXT)
+gem_evict_everything_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_evict_everything_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_exec_bad_domains_SOURCES = gem_exec_bad_domains.c
+gem_exec_bad_domains_OBJECTS = gem_exec_bad_domains.$(OBJEXT)
+gem_exec_bad_domains_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_exec_bad_domains_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_exec_big_SOURCES = gem_exec_big.c
+gem_exec_big_OBJECTS = gem_exec_big.$(OBJEXT)
+gem_exec_big_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_exec_big_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_exec_blt_SOURCES = gem_exec_blt.c
+gem_exec_blt_OBJECTS = gem_exec_blt.$(OBJEXT)
+gem_exec_blt_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_exec_blt_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_exec_faulting_reloc_SOURCES = gem_exec_faulting_reloc.c
+gem_exec_faulting_reloc_OBJECTS = gem_exec_faulting_reloc.$(OBJEXT)
+gem_exec_faulting_reloc_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_exec_faulting_reloc_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_exec_lut_handle_SOURCES = gem_exec_lut_handle.c
+gem_exec_lut_handle_OBJECTS = gem_exec_lut_handle.$(OBJEXT)
+gem_exec_lut_handle_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_exec_lut_handle_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_exec_nop_SOURCES = gem_exec_nop.c
+gem_exec_nop_OBJECTS = gem_exec_nop.$(OBJEXT)
+gem_exec_nop_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_exec_nop_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_exec_params_SOURCES = gem_exec_params.c
+gem_exec_params_OBJECTS = gem_exec_params.$(OBJEXT)
+gem_exec_params_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_exec_params_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_exec_parse_SOURCES = gem_exec_parse.c
+gem_exec_parse_OBJECTS = gem_exec_parse.$(OBJEXT)
+gem_exec_parse_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_exec_parse_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_fd_exhaustion_SOURCES = gem_fd_exhaustion.c
+gem_fd_exhaustion_OBJECTS = gem_fd_exhaustion.$(OBJEXT)
+gem_fd_exhaustion_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_fd_exhaustion_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_fence_thrash_SOURCES = gem_fence_thrash.c
+gem_fence_thrash_OBJECTS = \
+ gem_fence_thrash-gem_fence_thrash.$(OBJEXT)
+@BUILD_TESTS_TRUE@gem_fence_thrash_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_2)
+gem_fence_thrash_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(gem_fence_thrash_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+gem_fenced_exec_thrash_SOURCES = gem_fenced_exec_thrash.c
+gem_fenced_exec_thrash_OBJECTS = gem_fenced_exec_thrash.$(OBJEXT)
+gem_fenced_exec_thrash_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_fenced_exec_thrash_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_flink_SOURCES = gem_flink.c
+gem_flink_OBJECTS = gem_flink.$(OBJEXT)
+gem_flink_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_flink_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_flink_race_SOURCES = gem_flink_race.c
+gem_flink_race_OBJECTS = gem_flink_race-gem_flink_race.$(OBJEXT)
+@BUILD_TESTS_TRUE@gem_flink_race_DEPENDENCIES = $(am__DEPENDENCIES_2)
+gem_flink_race_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(gem_flink_race_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
+ $@
+gem_gtt_cpu_tlb_SOURCES = gem_gtt_cpu_tlb.c
+gem_gtt_cpu_tlb_OBJECTS = gem_gtt_cpu_tlb.$(OBJEXT)
+gem_gtt_cpu_tlb_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_gtt_cpu_tlb_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_gtt_hog_SOURCES = gem_gtt_hog.c
+gem_gtt_hog_OBJECTS = gem_gtt_hog.$(OBJEXT)
+gem_gtt_hog_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_gtt_hog_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_gtt_speed_SOURCES = gem_gtt_speed.c
+gem_gtt_speed_OBJECTS = gem_gtt_speed.$(OBJEXT)
+gem_gtt_speed_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_gtt_speed_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_hang_SOURCES = gem_hang.c
+gem_hang_OBJECTS = gem_hang.$(OBJEXT)
+gem_hang_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_hang_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_hangcheck_forcewake_SOURCES = gem_hangcheck_forcewake.c
+gem_hangcheck_forcewake_OBJECTS = gem_hangcheck_forcewake.$(OBJEXT)
+gem_hangcheck_forcewake_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_hangcheck_forcewake_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_largeobject_SOURCES = gem_largeobject.c
+gem_largeobject_OBJECTS = gem_largeobject.$(OBJEXT)
+gem_largeobject_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_largeobject_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_linear_blits_SOURCES = gem_linear_blits.c
+gem_linear_blits_OBJECTS = gem_linear_blits.$(OBJEXT)
+gem_linear_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_linear_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_lut_handle_SOURCES = gem_lut_handle.c
+gem_lut_handle_OBJECTS = gem_lut_handle.$(OBJEXT)
+gem_lut_handle_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_lut_handle_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_madvise_SOURCES = gem_madvise.c
+gem_madvise_OBJECTS = gem_madvise.$(OBJEXT)
+gem_madvise_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_madvise_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_media_fill_SOURCES = gem_media_fill.c
+gem_media_fill_OBJECTS = gem_media_fill.$(OBJEXT)
+gem_media_fill_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_media_fill_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_mmap_SOURCES = gem_mmap.c
+gem_mmap_OBJECTS = gem_mmap.$(OBJEXT)
+gem_mmap_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_mmap_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_mmap_gtt_SOURCES = gem_mmap_gtt.c
+gem_mmap_gtt_OBJECTS = gem_mmap_gtt.$(OBJEXT)
+gem_mmap_gtt_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_mmap_gtt_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_mmap_offset_exhaustion_SOURCES = gem_mmap_offset_exhaustion.c
+gem_mmap_offset_exhaustion_OBJECTS = \
+ gem_mmap_offset_exhaustion.$(OBJEXT)
+gem_mmap_offset_exhaustion_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_mmap_offset_exhaustion_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_multi_bsd_sync_loop_SOURCES = gem_multi_bsd_sync_loop.c
+gem_multi_bsd_sync_loop_OBJECTS = gem_multi_bsd_sync_loop.$(OBJEXT)
+gem_multi_bsd_sync_loop_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_multi_bsd_sync_loop_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_non_secure_batch_SOURCES = gem_non_secure_batch.c
+gem_non_secure_batch_OBJECTS = gem_non_secure_batch.$(OBJEXT)
+gem_non_secure_batch_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_non_secure_batch_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_partial_pwrite_pread_SOURCES = gem_partial_pwrite_pread.c
+gem_partial_pwrite_pread_OBJECTS = gem_partial_pwrite_pread.$(OBJEXT)
+gem_partial_pwrite_pread_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_partial_pwrite_pread_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_persistent_relocs_SOURCES = gem_persistent_relocs.c
+gem_persistent_relocs_OBJECTS = gem_persistent_relocs.$(OBJEXT)
+gem_persistent_relocs_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_persistent_relocs_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_pin_SOURCES = gem_pin.c
+gem_pin_OBJECTS = gem_pin.$(OBJEXT)
+gem_pin_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_pin_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_pipe_control_store_loop_SOURCES = gem_pipe_control_store_loop.c
+gem_pipe_control_store_loop_OBJECTS = \
+ gem_pipe_control_store_loop.$(OBJEXT)
+gem_pipe_control_store_loop_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_pipe_control_store_loop_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_pread_SOURCES = gem_pread.c
+gem_pread_OBJECTS = gem_pread.$(OBJEXT)
+gem_pread_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_pread_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_pread_after_blit_SOURCES = gem_pread_after_blit.c
+gem_pread_after_blit_OBJECTS = gem_pread_after_blit.$(OBJEXT)
+gem_pread_after_blit_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_pread_after_blit_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_pwrite_SOURCES = gem_pwrite.c
+gem_pwrite_OBJECTS = gem_pwrite.$(OBJEXT)
+gem_pwrite_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_pwrite_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_pwrite_pread_SOURCES = gem_pwrite_pread.c
+gem_pwrite_pread_OBJECTS = gem_pwrite_pread.$(OBJEXT)
+gem_pwrite_pread_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_pwrite_pread_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_readwrite_SOURCES = gem_readwrite.c
+gem_readwrite_OBJECTS = gem_readwrite.$(OBJEXT)
+gem_readwrite_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_readwrite_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_reg_read_SOURCES = gem_reg_read.c
+gem_reg_read_OBJECTS = gem_reg_read.$(OBJEXT)
+gem_reg_read_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_reg_read_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_reloc_overflow_SOURCES = gem_reloc_overflow.c
+gem_reloc_overflow_OBJECTS = gem_reloc_overflow.$(OBJEXT)
+gem_reloc_overflow_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_reloc_overflow_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_reloc_vs_gpu_SOURCES = gem_reloc_vs_gpu.c
+gem_reloc_vs_gpu_OBJECTS = gem_reloc_vs_gpu.$(OBJEXT)
+gem_reloc_vs_gpu_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_reloc_vs_gpu_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_render_copy_SOURCES = gem_render_copy.c
+gem_render_copy_OBJECTS = gem_render_copy.$(OBJEXT)
+gem_render_copy_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_render_copy_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_render_copy_redux_SOURCES = gem_render_copy_redux.c
+gem_render_copy_redux_OBJECTS = gem_render_copy_redux.$(OBJEXT)
+gem_render_copy_redux_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_render_copy_redux_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_render_linear_blits_SOURCES = gem_render_linear_blits.c
+gem_render_linear_blits_OBJECTS = gem_render_linear_blits.$(OBJEXT)
+gem_render_linear_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_render_linear_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_render_tiled_blits_SOURCES = gem_render_tiled_blits.c
+gem_render_tiled_blits_OBJECTS = gem_render_tiled_blits.$(OBJEXT)
+gem_render_tiled_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_render_tiled_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_reset_stats_SOURCES = gem_reset_stats.c
+gem_reset_stats_OBJECTS = gem_reset_stats.$(OBJEXT)
+gem_reset_stats_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_reset_stats_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_ring_sync_copy_SOURCES = gem_ring_sync_copy.c
+gem_ring_sync_copy_OBJECTS = gem_ring_sync_copy.$(OBJEXT)
+gem_ring_sync_copy_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_ring_sync_copy_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_ring_sync_loop_SOURCES = gem_ring_sync_loop.c
+gem_ring_sync_loop_OBJECTS = gem_ring_sync_loop.$(OBJEXT)
+gem_ring_sync_loop_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_ring_sync_loop_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_ringfill_SOURCES = gem_ringfill.c
+gem_ringfill_OBJECTS = gem_ringfill.$(OBJEXT)
+gem_ringfill_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_ringfill_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_seqno_wrap_SOURCES = gem_seqno_wrap.c
+gem_seqno_wrap_OBJECTS = gem_seqno_wrap.$(OBJEXT)
+gem_seqno_wrap_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_seqno_wrap_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_set_tiling_vs_blt_SOURCES = gem_set_tiling_vs_blt.c
+gem_set_tiling_vs_blt_OBJECTS = gem_set_tiling_vs_blt.$(OBJEXT)
+gem_set_tiling_vs_blt_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_set_tiling_vs_blt_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_set_tiling_vs_gtt_SOURCES = gem_set_tiling_vs_gtt.c
+gem_set_tiling_vs_gtt_OBJECTS = gem_set_tiling_vs_gtt.$(OBJEXT)
+gem_set_tiling_vs_gtt_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_set_tiling_vs_gtt_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_set_tiling_vs_pwrite_SOURCES = gem_set_tiling_vs_pwrite.c
+gem_set_tiling_vs_pwrite_OBJECTS = gem_set_tiling_vs_pwrite.$(OBJEXT)
+gem_set_tiling_vs_pwrite_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_set_tiling_vs_pwrite_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_storedw_batches_loop_SOURCES = gem_storedw_batches_loop.c
+gem_storedw_batches_loop_OBJECTS = gem_storedw_batches_loop.$(OBJEXT)
+gem_storedw_batches_loop_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_storedw_batches_loop_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_storedw_loop_blt_SOURCES = gem_storedw_loop_blt.c
+gem_storedw_loop_blt_OBJECTS = gem_storedw_loop_blt.$(OBJEXT)
+gem_storedw_loop_blt_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_storedw_loop_blt_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_storedw_loop_bsd_SOURCES = gem_storedw_loop_bsd.c
+gem_storedw_loop_bsd_OBJECTS = gem_storedw_loop_bsd.$(OBJEXT)
+gem_storedw_loop_bsd_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_storedw_loop_bsd_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_storedw_loop_render_SOURCES = gem_storedw_loop_render.c
+gem_storedw_loop_render_OBJECTS = gem_storedw_loop_render.$(OBJEXT)
+gem_storedw_loop_render_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_storedw_loop_render_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_storedw_loop_vebox_SOURCES = gem_storedw_loop_vebox.c
+gem_storedw_loop_vebox_OBJECTS = gem_storedw_loop_vebox.$(OBJEXT)
+gem_storedw_loop_vebox_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_storedw_loop_vebox_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_stress_SOURCES = gem_stress.c
+gem_stress_OBJECTS = gem_stress.$(OBJEXT)
+gem_stress_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_stress_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_threaded_access_tiled_SOURCES = gem_threaded_access_tiled.c
+gem_threaded_access_tiled_OBJECTS = \
+ gem_threaded_access_tiled-gem_threaded_access_tiled.$(OBJEXT)
+@BUILD_TESTS_TRUE@gem_threaded_access_tiled_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_2)
+gem_threaded_access_tiled_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(gem_threaded_access_tiled_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+gem_tiled_blits_SOURCES = gem_tiled_blits.c
+gem_tiled_blits_OBJECTS = gem_tiled_blits.$(OBJEXT)
+gem_tiled_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_tiled_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_tiled_fence_blits_SOURCES = gem_tiled_fence_blits.c
+gem_tiled_fence_blits_OBJECTS = gem_tiled_fence_blits.$(OBJEXT)
+gem_tiled_fence_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_tiled_fence_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_tiled_partial_pwrite_pread_SOURCES = \
+ gem_tiled_partial_pwrite_pread.c
+gem_tiled_partial_pwrite_pread_OBJECTS = \
+ gem_tiled_partial_pwrite_pread.$(OBJEXT)
+gem_tiled_partial_pwrite_pread_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_tiled_partial_pwrite_pread_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_tiled_pread_SOURCES = gem_tiled_pread.c
+gem_tiled_pread_OBJECTS = gem_tiled_pread.$(OBJEXT)
+gem_tiled_pread_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_tiled_pread_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_tiled_pread_pwrite_SOURCES = gem_tiled_pread_pwrite.c
+gem_tiled_pread_pwrite_OBJECTS = gem_tiled_pread_pwrite.$(OBJEXT)
+gem_tiled_pread_pwrite_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_tiled_pread_pwrite_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_tiled_swapping_SOURCES = gem_tiled_swapping.c
+gem_tiled_swapping_OBJECTS = \
+ gem_tiled_swapping-gem_tiled_swapping.$(OBJEXT)
+@BUILD_TESTS_TRUE@gem_tiled_swapping_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_2)
+gem_tiled_swapping_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(gem_tiled_swapping_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+gem_tiling_max_stride_SOURCES = gem_tiling_max_stride.c
+gem_tiling_max_stride_OBJECTS = gem_tiling_max_stride.$(OBJEXT)
+gem_tiling_max_stride_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_tiling_max_stride_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_unfence_active_buffers_SOURCES = gem_unfence_active_buffers.c
+gem_unfence_active_buffers_OBJECTS = \
+ gem_unfence_active_buffers.$(OBJEXT)
+gem_unfence_active_buffers_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_unfence_active_buffers_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_unref_active_buffers_SOURCES = gem_unref_active_buffers.c
+gem_unref_active_buffers_OBJECTS = gem_unref_active_buffers.$(OBJEXT)
+gem_unref_active_buffers_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_unref_active_buffers_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_userptr_blits_SOURCES = gem_userptr_blits.c
+gem_userptr_blits_OBJECTS = gem_userptr_blits.$(OBJEXT)
+gem_userptr_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_userptr_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gem_wait_render_timeout_SOURCES = gem_wait_render_timeout.c
+gem_wait_render_timeout_OBJECTS = gem_wait_render_timeout.$(OBJEXT)
+@BUILD_TESTS_TRUE@gem_wait_render_timeout_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_2)
+gem_write_read_ring_switch_SOURCES = gem_write_read_ring_switch.c
+gem_write_read_ring_switch_OBJECTS = \
+ gem_write_read_ring_switch.$(OBJEXT)
+gem_write_read_ring_switch_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gem_write_read_ring_switch_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gen3_mixed_blits_SOURCES = gen3_mixed_blits.c
+gen3_mixed_blits_OBJECTS = gen3_mixed_blits.$(OBJEXT)
+gen3_mixed_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gen3_mixed_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gen3_render_linear_blits_SOURCES = gen3_render_linear_blits.c
+gen3_render_linear_blits_OBJECTS = gen3_render_linear_blits.$(OBJEXT)
+gen3_render_linear_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gen3_render_linear_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gen3_render_mixed_blits_SOURCES = gen3_render_mixed_blits.c
+gen3_render_mixed_blits_OBJECTS = gen3_render_mixed_blits.$(OBJEXT)
+gen3_render_mixed_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gen3_render_mixed_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gen3_render_tiledx_blits_SOURCES = gen3_render_tiledx_blits.c
+gen3_render_tiledx_blits_OBJECTS = gen3_render_tiledx_blits.$(OBJEXT)
+gen3_render_tiledx_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gen3_render_tiledx_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gen3_render_tiledy_blits_SOURCES = gen3_render_tiledy_blits.c
+gen3_render_tiledy_blits_OBJECTS = gen3_render_tiledy_blits.$(OBJEXT)
+gen3_render_tiledy_blits_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@gen3_render_tiledy_blits_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+gen7_forcewake_mt_SOURCES = gen7_forcewake_mt.c
+gen7_forcewake_mt_OBJECTS = \
+ gen7_forcewake_mt-gen7_forcewake_mt.$(OBJEXT)
+@BUILD_TESTS_TRUE@gen7_forcewake_mt_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_2)
+gen7_forcewake_mt_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(gen7_forcewake_mt_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+igt_fork_helper_SOURCES = igt_fork_helper.c
+igt_fork_helper_OBJECTS = igt_fork_helper.$(OBJEXT)
+igt_fork_helper_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@igt_fork_helper_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+igt_list_only_SOURCES = igt_list_only.c
+igt_list_only_OBJECTS = igt_list_only.$(OBJEXT)
+igt_list_only_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@igt_list_only_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+igt_no_exit_SOURCES = igt_no_exit.c
+igt_no_exit_OBJECTS = igt_no_exit.$(OBJEXT)
+igt_no_exit_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@igt_no_exit_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+igt_no_exit_list_only_SOURCES = igt_no_exit_list_only.c
+igt_no_exit_list_only_OBJECTS = igt_no_exit_list_only.$(OBJEXT)
+igt_no_exit_list_only_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@igt_no_exit_list_only_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+igt_no_subtest_SOURCES = igt_no_subtest.c
+igt_no_subtest_OBJECTS = igt_no_subtest.$(OBJEXT)
+igt_no_subtest_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@igt_no_subtest_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+igt_simulation_SOURCES = igt_simulation.c
+igt_simulation_OBJECTS = igt_simulation.$(OBJEXT)
+igt_simulation_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@igt_simulation_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_addfb_SOURCES = kms_addfb.c
+kms_addfb_OBJECTS = kms_addfb.$(OBJEXT)
+kms_addfb_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_addfb_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_cursor_crc_SOURCES = kms_cursor_crc.c
+kms_cursor_crc_OBJECTS = kms_cursor_crc.$(OBJEXT)
+kms_cursor_crc_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_cursor_crc_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_fbc_crc_SOURCES = kms_fbc_crc.c
+kms_fbc_crc_OBJECTS = kms_fbc_crc.$(OBJEXT)
+kms_fbc_crc_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_fbc_crc_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_fence_pin_leak_SOURCES = kms_fence_pin_leak.c
+kms_fence_pin_leak_OBJECTS = kms_fence_pin_leak.$(OBJEXT)
+kms_fence_pin_leak_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_fence_pin_leak_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_flip_SOURCES = kms_flip.c
+kms_flip_OBJECTS = kms_flip.$(OBJEXT)
+@BUILD_TESTS_TRUE@kms_flip_DEPENDENCIES = $(am__DEPENDENCIES_2)
+kms_flip_tiling_SOURCES = kms_flip_tiling.c
+kms_flip_tiling_OBJECTS = kms_flip_tiling.$(OBJEXT)
+kms_flip_tiling_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_flip_tiling_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_mmio_vs_cs_flip_SOURCES = kms_mmio_vs_cs_flip.c
+kms_mmio_vs_cs_flip_OBJECTS = kms_mmio_vs_cs_flip.$(OBJEXT)
+kms_mmio_vs_cs_flip_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_mmio_vs_cs_flip_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_pipe_crc_basic_SOURCES = kms_pipe_crc_basic.c
+kms_pipe_crc_basic_OBJECTS = kms_pipe_crc_basic.$(OBJEXT)
+kms_pipe_crc_basic_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_pipe_crc_basic_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_plane_SOURCES = kms_plane.c
+kms_plane_OBJECTS = kms_plane.$(OBJEXT)
+kms_plane_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_plane_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_render_SOURCES = kms_render.c
+kms_render_OBJECTS = kms_render.$(OBJEXT)
+kms_render_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_render_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_setmode_SOURCES = kms_setmode.c
+kms_setmode_OBJECTS = kms_setmode.$(OBJEXT)
+kms_setmode_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_setmode_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+kms_sink_crc_basic_SOURCES = kms_sink_crc_basic.c
+kms_sink_crc_basic_OBJECTS = kms_sink_crc_basic.$(OBJEXT)
+kms_sink_crc_basic_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@kms_sink_crc_basic_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+pm_lpsp_SOURCES = pm_lpsp.c
+pm_lpsp_OBJECTS = pm_lpsp.$(OBJEXT)
+pm_lpsp_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@pm_lpsp_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+pm_psr_SOURCES = pm_psr.c
+pm_psr_OBJECTS = pm_psr.$(OBJEXT)
+pm_psr_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@pm_psr_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+pm_rc6_residency_SOURCES = pm_rc6_residency.c
+pm_rc6_residency_OBJECTS = pm_rc6_residency.$(OBJEXT)
+pm_rc6_residency_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@pm_rc6_residency_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+pm_rpm_SOURCES = pm_rpm.c
+pm_rpm_OBJECTS = pm_rpm.$(OBJEXT)
+pm_rpm_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@pm_rpm_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+pm_rps_SOURCES = pm_rps.c
+pm_rps_OBJECTS = pm_rps.$(OBJEXT)
+pm_rps_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@pm_rps_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+prime_nv_api_SOURCES = prime_nv_api.c
+prime_nv_api_OBJECTS = prime_nv_api-prime_nv_api.$(OBJEXT)
+@BUILD_TESTS_TRUE@prime_nv_api_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+prime_nv_api_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(prime_nv_api_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+prime_nv_pcopy_SOURCES = prime_nv_pcopy.c
+prime_nv_pcopy_OBJECTS = prime_nv_pcopy-prime_nv_pcopy.$(OBJEXT)
+@BUILD_TESTS_TRUE@prime_nv_pcopy_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+prime_nv_pcopy_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(prime_nv_pcopy_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
+ $@
+prime_nv_test_SOURCES = prime_nv_test.c
+prime_nv_test_OBJECTS = prime_nv_test-prime_nv_test.$(OBJEXT)
+@BUILD_TESTS_TRUE@prime_nv_test_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+prime_nv_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(prime_nv_test_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+prime_self_import_SOURCES = prime_self_import.c
+prime_self_import_OBJECTS = \
+ prime_self_import-prime_self_import.$(OBJEXT)
+@BUILD_TESTS_TRUE@prime_self_import_DEPENDENCIES = \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_2)
+prime_self_import_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(prime_self_import_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+prime_udl_SOURCES = prime_udl.c
+prime_udl_OBJECTS = prime_udl.$(OBJEXT)
+prime_udl_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@prime_udl_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+template_SOURCES = template.c
+template_OBJECTS = template.$(OBJEXT)
+template_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@template_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+am_testdisplay_OBJECTS = testdisplay.$(OBJEXT) \
+ testdisplay_hotplug.$(OBJEXT)
+testdisplay_OBJECTS = $(am_testdisplay_OBJECTS)
+testdisplay_LDADD = $(LDADD)
+@BUILD_TESTS_TRUE@testdisplay_DEPENDENCIES = ../lib/libintel_tools.la \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = core_get_client_auth.c core_getclient.c core_getstats.c \
+ core_getversion.c ddi_compute_wrpll.c drm_vma_limiter.c \
+ drm_vma_limiter_cached.c drm_vma_limiter_cpu.c \
+ drm_vma_limiter_gtt.c drv_hangman.c drv_suspend.c gem_alive.c \
+ gem_bad_address.c gem_bad_batch.c gem_bad_blit.c \
+ gem_bad_length.c gem_bad_reloc.c gem_basic.c gem_caching.c \
+ gem_close_race.c gem_concurrent_blit.c gem_cpu_reloc.c \
+ gem_cs_prefetch.c gem_cs_tlb.c gem_ctx_bad_destroy.c \
+ gem_ctx_bad_exec.c gem_ctx_basic.c gem_ctx_create.c \
+ gem_ctx_exec.c gem_double_irq_loop.c gem_dummy_reloc_loop.c \
+ gem_evict_alignment.c gem_evict_everything.c \
+ gem_exec_bad_domains.c gem_exec_big.c gem_exec_blt.c \
+ gem_exec_faulting_reloc.c gem_exec_lut_handle.c gem_exec_nop.c \
+ gem_exec_params.c gem_exec_parse.c gem_fd_exhaustion.c \
+ gem_fence_thrash.c gem_fenced_exec_thrash.c gem_flink.c \
+ gem_flink_race.c gem_gtt_cpu_tlb.c gem_gtt_hog.c \
+ gem_gtt_speed.c gem_hang.c gem_hangcheck_forcewake.c \
+ gem_largeobject.c gem_linear_blits.c gem_lut_handle.c \
+ gem_madvise.c gem_media_fill.c gem_mmap.c gem_mmap_gtt.c \
+ gem_mmap_offset_exhaustion.c gem_multi_bsd_sync_loop.c \
+ gem_non_secure_batch.c gem_partial_pwrite_pread.c \
+ gem_persistent_relocs.c gem_pin.c \
+ gem_pipe_control_store_loop.c gem_pread.c \
+ gem_pread_after_blit.c gem_pwrite.c gem_pwrite_pread.c \
+ gem_readwrite.c gem_reg_read.c gem_reloc_overflow.c \
+ gem_reloc_vs_gpu.c gem_render_copy.c gem_render_copy_redux.c \
+ gem_render_linear_blits.c gem_render_tiled_blits.c \
+ gem_reset_stats.c gem_ring_sync_copy.c gem_ring_sync_loop.c \
+ gem_ringfill.c gem_seqno_wrap.c gem_set_tiling_vs_blt.c \
+ gem_set_tiling_vs_gtt.c gem_set_tiling_vs_pwrite.c \
+ gem_storedw_batches_loop.c gem_storedw_loop_blt.c \
+ gem_storedw_loop_bsd.c gem_storedw_loop_render.c \
+ gem_storedw_loop_vebox.c gem_stress.c \
+ gem_threaded_access_tiled.c gem_tiled_blits.c \
+ gem_tiled_fence_blits.c gem_tiled_partial_pwrite_pread.c \
+ gem_tiled_pread.c gem_tiled_pread_pwrite.c \
+ gem_tiled_swapping.c gem_tiling_max_stride.c \
+ gem_unfence_active_buffers.c gem_unref_active_buffers.c \
+ gem_userptr_blits.c gem_wait_render_timeout.c \
+ gem_write_read_ring_switch.c gen3_mixed_blits.c \
+ gen3_render_linear_blits.c gen3_render_mixed_blits.c \
+ gen3_render_tiledx_blits.c gen3_render_tiledy_blits.c \
+ gen7_forcewake_mt.c igt_fork_helper.c igt_list_only.c \
+ igt_no_exit.c igt_no_exit_list_only.c igt_no_subtest.c \
+ igt_simulation.c kms_addfb.c kms_cursor_crc.c kms_fbc_crc.c \
+ kms_fence_pin_leak.c kms_flip.c kms_flip_tiling.c \
+ kms_mmio_vs_cs_flip.c kms_pipe_crc_basic.c kms_plane.c \
+ kms_render.c kms_setmode.c kms_sink_crc_basic.c pm_lpsp.c \
+ pm_psr.c pm_rc6_residency.c pm_rpm.c pm_rps.c prime_nv_api.c \
+ prime_nv_pcopy.c prime_nv_test.c prime_self_import.c \
+ prime_udl.c template.c $(testdisplay_SOURCES)
+DIST_SOURCES = core_get_client_auth.c core_getclient.c core_getstats.c \
+ core_getversion.c ddi_compute_wrpll.c drm_vma_limiter.c \
+ drm_vma_limiter_cached.c drm_vma_limiter_cpu.c \
+ drm_vma_limiter_gtt.c drv_hangman.c drv_suspend.c gem_alive.c \
+ gem_bad_address.c gem_bad_batch.c gem_bad_blit.c \
+ gem_bad_length.c gem_bad_reloc.c gem_basic.c gem_caching.c \
+ gem_close_race.c gem_concurrent_blit.c gem_cpu_reloc.c \
+ gem_cs_prefetch.c gem_cs_tlb.c gem_ctx_bad_destroy.c \
+ gem_ctx_bad_exec.c gem_ctx_basic.c gem_ctx_create.c \
+ gem_ctx_exec.c gem_double_irq_loop.c gem_dummy_reloc_loop.c \
+ gem_evict_alignment.c gem_evict_everything.c \
+ gem_exec_bad_domains.c gem_exec_big.c gem_exec_blt.c \
+ gem_exec_faulting_reloc.c gem_exec_lut_handle.c gem_exec_nop.c \
+ gem_exec_params.c gem_exec_parse.c gem_fd_exhaustion.c \
+ gem_fence_thrash.c gem_fenced_exec_thrash.c gem_flink.c \
+ gem_flink_race.c gem_gtt_cpu_tlb.c gem_gtt_hog.c \
+ gem_gtt_speed.c gem_hang.c gem_hangcheck_forcewake.c \
+ gem_largeobject.c gem_linear_blits.c gem_lut_handle.c \
+ gem_madvise.c gem_media_fill.c gem_mmap.c gem_mmap_gtt.c \
+ gem_mmap_offset_exhaustion.c gem_multi_bsd_sync_loop.c \
+ gem_non_secure_batch.c gem_partial_pwrite_pread.c \
+ gem_persistent_relocs.c gem_pin.c \
+ gem_pipe_control_store_loop.c gem_pread.c \
+ gem_pread_after_blit.c gem_pwrite.c gem_pwrite_pread.c \
+ gem_readwrite.c gem_reg_read.c gem_reloc_overflow.c \
+ gem_reloc_vs_gpu.c gem_render_copy.c gem_render_copy_redux.c \
+ gem_render_linear_blits.c gem_render_tiled_blits.c \
+ gem_reset_stats.c gem_ring_sync_copy.c gem_ring_sync_loop.c \
+ gem_ringfill.c gem_seqno_wrap.c gem_set_tiling_vs_blt.c \
+ gem_set_tiling_vs_gtt.c gem_set_tiling_vs_pwrite.c \
+ gem_storedw_batches_loop.c gem_storedw_loop_blt.c \
+ gem_storedw_loop_bsd.c gem_storedw_loop_render.c \
+ gem_storedw_loop_vebox.c gem_stress.c \
+ gem_threaded_access_tiled.c gem_tiled_blits.c \
+ gem_tiled_fence_blits.c gem_tiled_partial_pwrite_pread.c \
+ gem_tiled_pread.c gem_tiled_pread_pwrite.c \
+ gem_tiled_swapping.c gem_tiling_max_stride.c \
+ gem_unfence_active_buffers.c gem_unref_active_buffers.c \
+ gem_userptr_blits.c gem_wait_render_timeout.c \
+ gem_write_read_ring_switch.c gen3_mixed_blits.c \
+ gen3_render_linear_blits.c gen3_render_mixed_blits.c \
+ gen3_render_tiledx_blits.c gen3_render_tiledy_blits.c \
+ gen7_forcewake_mt.c igt_fork_helper.c igt_list_only.c \
+ igt_no_exit.c igt_no_exit_list_only.c igt_no_subtest.c \
+ igt_simulation.c kms_addfb.c kms_cursor_crc.c kms_fbc_crc.c \
+ kms_fence_pin_leak.c kms_flip.c kms_flip_tiling.c \
+ kms_mmio_vs_cs_flip.c kms_pipe_crc_basic.c kms_plane.c \
+ kms_render.c kms_setmode.c kms_sink_crc_basic.c pm_lpsp.c \
+ pm_psr.c pm_rc6_residency.c pm_rpm.c pm_rps.c prime_nv_api.c \
+ prime_nv_pcopy.c prime_nv_test.c prime_self_import.c \
+ prime_udl.c template.c $(testdisplay_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
+ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APP_MAN_DIR = @APP_MAN_DIR@
+APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
+AR = @AR@
+ASSEMBLER_WARN_CFLAGS = @ASSEMBLER_WARN_CFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AX_SWIG_PYTHON_CPPFLAGS = @AX_SWIG_PYTHON_CPPFLAGS@
+AX_SWIG_PYTHON_OPT = @AX_SWIG_PYTHON_OPT@
+BASE_CFLAGS = @BASE_CFLAGS@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
+DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
+DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
+DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
+DRM_CFLAGS = @DRM_CFLAGS@
+DRM_LIBS = @DRM_LIBS@
+DRM_NOUVEAU_CFLAGS = @DRM_NOUVEAU_CFLAGS@
+DRM_NOUVEAU_LIBS = @DRM_NOUVEAU_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILE_MAN_DIR = @FILE_MAN_DIR@
+FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_LIBS = @GLIB_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_CMD = @INSTALL_CMD@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUDEV_CFLAGS = @LIBUDEV_CFLAGS@
+LIBUDEV_LIBS = @LIBUDEV_LIBS@
+LIB_MAN_DIR = @LIB_MAN_DIR@
+LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MAN_SUBSTS = @MAN_SUBSTS@
+MISC_MAN_DIR = @MISC_MAN_DIR@
+MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJCOPY = @OBJCOPY@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+OVERLAY_XLIB_CFLAGS = @OVERLAY_XLIB_CFLAGS@
+OVERLAY_XLIB_LIBS = @OVERLAY_XLIB_LIBS@
+OVERLAY_XVLIB_CFLAGS = @OVERLAY_XVLIB_CFLAGS@
+OVERLAY_XVLIB_LIBS = @OVERLAY_XVLIB_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@
+PCIACCESS_LIBS = @PCIACCESS_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRICT_CFLAGS = @STRICT_CFLAGS@
+STRIP = @STRIP@
+SWIG = @SWIG@
+SWIG_LIB = @SWIG_LIB@
+THREAD_CFLAGS = @THREAD_CFLAGS@
+VERSION = @VERSION@
+XORG_MAN_PAGE = @XORG_MAN_PAGE@
+XRANDR_CFLAGS = @XRANDR_CFLAGS@
+XRANDR_LIBS = @XRANDR_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NOUVEAU_TESTS_M = \
+ prime_nv_api \
+ prime_nv_pcopy \
+ prime_nv_test \
+ $(NULL)
+
+TESTS_progs_M = core_get_client_auth drv_suspend drv_hangman \
+ gem_bad_reloc gem_basic gem_caching gem_close_race \
+ gem_concurrent_blit gem_cs_tlb gem_ctx_bad_exec gem_ctx_exec \
+ gem_dummy_reloc_loop gem_evict_alignment gem_evict_everything \
+ gem_exec_bad_domains gem_exec_faulting_reloc gem_exec_nop \
+ gem_exec_params gem_exec_parse gem_fenced_exec_thrash \
+ gem_fence_thrash gem_flink gem_flink_race gem_linear_blits \
+ gem_madvise gem_mmap gem_mmap_gtt gem_partial_pwrite_pread \
+ gem_persistent_relocs gem_pipe_control_store_loop gem_pread \
+ gem_pread_after_blit gem_pwrite gem_pwrite_pread gem_readwrite \
+ gem_reloc_overflow gem_reloc_vs_gpu gem_reset_stats \
+ gem_ringfill gem_set_tiling_vs_blt gem_storedw_batches_loop \
+ gem_tiled_blits gem_tiled_partial_pwrite_pread \
+ gem_write_read_ring_switch kms_addfb kms_cursor_crc \
+ kms_fbc_crc kms_flip kms_flip_tiling kms_mmio_vs_cs_flip \
+ kms_pipe_crc_basic kms_plane kms_render kms_setmode pm_lpsp \
+ pm_rpm pm_rps prime_self_import template $(NULL) \
+ $(am__append_1)
+TESTS_progs = core_getclient core_getstats core_getversion \
+ drm_vma_limiter drm_vma_limiter_cached drm_vma_limiter_cpu \
+ drm_vma_limiter_gtt gem_bad_length gem_cpu_reloc \
+ gem_cs_prefetch gem_ctx_bad_destroy gem_ctx_basic \
+ gem_ctx_create gem_double_irq_loop gem_exec_big gem_exec_blt \
+ gem_exec_lut_handle gem_fd_exhaustion gem_gtt_cpu_tlb \
+ gem_gtt_hog gem_gtt_speed gem_hangcheck_forcewake \
+ gem_largeobject gem_lut_handle gem_mmap_offset_exhaustion \
+ gem_media_fill gem_pin gem_reg_read gem_render_copy \
+ gem_render_copy_redux gem_render_linear_blits \
+ gem_render_tiled_blits gem_ring_sync_copy gem_ring_sync_loop \
+ gem_multi_bsd_sync_loop gem_seqno_wrap gem_set_tiling_vs_gtt \
+ gem_set_tiling_vs_pwrite gem_storedw_loop_blt \
+ gem_storedw_loop_bsd gem_storedw_loop_render \
+ gem_storedw_loop_vebox gem_threaded_access_tiled \
+ gem_tiled_fence_blits gem_tiled_pread gem_tiled_pread_pwrite \
+ gem_tiled_swapping gem_tiling_max_stride \
+ gem_unfence_active_buffers gem_unref_active_buffers \
+ gem_userptr_blits gem_wait_render_timeout gen3_mixed_blits \
+ gen3_render_linear_blits gen3_render_mixed_blits \
+ gen3_render_tiledx_blits gen3_render_tiledy_blits \
+ gen7_forcewake_mt kms_sink_crc_basic kms_fence_pin_leak pm_psr \
+ pm_rc6_residency prime_udl $(NULL) testdisplay
+
+# IMPORTANT: The ZZ_ tests need to be run last!
+# ... and make can't deal with inlined comments ...
+TESTS_scripts_M = \
+ $(NULL)
+
+TESTS_scripts = \
+ debugfs_emon_crash \
+ drv_debugfs_reader \
+ drv_missed_irq_hang \
+ drv_module_reload \
+ kms_sysfs_edid_timing \
+ sysfs_l3_parity \
+ test_rte_check \
+ tools_test \
+ $(NULL)
+
+
+# This target contains testcases which support automagic subtest enumeration
+# from the piglit testrunner with --list-subtests and running individual
+# subtests with --run-subtest <testname>
+#
+# Your testcase should probably use an igt_main and igt_fixture and should have
+# a pile of igt_subtest blocks.
+multi_kernel_tests = \
+ $(TESTS_progs_M) \
+ $(TESTS_scripts_M) \
+ $(NULL)
+
+
+# This target is for simple testcase which don't expose any subtest.
+#
+# Your testcase should probably use igt_simple_main, but none of the other magic
+# blocks like igt_fixture or igt_subtest.
+single_kernel_tests = \
+ $(TESTS_progs) \
+ $(TESTS_scripts) \
+ $(NULL)
+
+kernel_tests = \
+ $(single_kernel_tests) \
+ $(multi_kernel_tests) \
+ $(NULL)
+
+TESTS_testsuite = \
+ igt_no_exit \
+ igt_no_exit_list_only \
+ igt_fork_helper \
+ igt_list_only \
+ igt_no_subtest \
+ igt_simulation \
+ $(NULL)
+
+
+# IMPORTANT: These tests here are all disabled because the result in sometime
+# unrecoverable gpu hangs. Don't put real testcases here.
+HANG = \
+ gem_bad_batch \
+ gem_hang \
+ gem_bad_blit \
+ gem_bad_address \
+ gem_non_secure_batch \
+ $(NULL)
+
+scripts = \
+ check_drm_clients \
+ ddx_intel_after_fbdev \
+ debugfs_wedged \
+ drm_lib.sh \
+ $(NULL)
+
+IMAGES = pass.png 1080p-left.png 1080p-right.png
+testdisplay_SOURCES = \
+ testdisplay.c \
+ testdisplay.h \
+ testdisplay_hotplug.c \
+ $(NULL)
+
+common_files = \
+ eviction_common.c \
+ $(NULL)
+
+@BUILD_TESTS_TRUE@EXTRA_DIST = $(TESTS_scripts) $(TESTS_scripts_M) $(scripts) $(IMAGES) $(common_files)
+@BUILD_TESTS_TRUE@CLEANFILES = $(EXTRA_PROGRAMS) single-tests.txt multi-tests.txt
+@BUILD_TESTS_TRUE@AM_CFLAGS = $(DRM_CFLAGS) $(CWARNFLAGS) \
+@BUILD_TESTS_TRUE@ -I$(srcdir)/.. -I$(srcdir)/../lib -include \
+@BUILD_TESTS_TRUE@ "$(srcdir)/../lib/check-ndebug.h" -include \
+@BUILD_TESTS_TRUE@ "$(top_builddir)/version.h" \
+@BUILD_TESTS_TRUE@ -DIGT_DATADIR=\""$(abs_srcdir)"\" $(NULL) \
+@BUILD_TESTS_TRUE@ $(CAIRO_CFLAGS) $(LIBUDEV_CFLAGS) \
+@BUILD_TESTS_TRUE@ $(GLIB_CFLAGS)
+@BUILD_TESTS_TRUE@LDADD = ../lib/libintel_tools.la $(PCIACCESS_LIBS) \
+@BUILD_TESTS_TRUE@ $(DRM_LIBS) $(CAIRO_LIBS) $(LIBUDEV_LIBS) \
+@BUILD_TESTS_TRUE@ $(GLIB_LIBS)
+@BUILD_TESTS_TRUE@gem_close_race_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+@BUILD_TESTS_TRUE@gem_close_race_LDADD = $(LDADD) -lpthread
+@BUILD_TESTS_TRUE@gem_ctx_basic_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+@BUILD_TESTS_TRUE@gem_ctx_basic_LDADD = $(LDADD) -lpthread
+@BUILD_TESTS_TRUE@gem_fence_thrash_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+@BUILD_TESTS_TRUE@gem_fence_thrash_LDADD = $(LDADD) -lpthread
+@BUILD_TESTS_TRUE@gem_flink_race_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+@BUILD_TESTS_TRUE@gem_flink_race_LDADD = $(LDADD) -lpthread
+@BUILD_TESTS_TRUE@gem_threaded_access_tiled_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+@BUILD_TESTS_TRUE@gem_threaded_access_tiled_LDADD = $(LDADD) -lpthread
+@BUILD_TESTS_TRUE@gem_tiled_swapping_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+@BUILD_TESTS_TRUE@gem_tiled_swapping_LDADD = $(LDADD) -lpthread
+@BUILD_TESTS_TRUE@prime_self_import_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+@BUILD_TESTS_TRUE@prime_self_import_LDADD = $(LDADD) -lpthread
+@BUILD_TESTS_TRUE@gen7_forcewake_mt_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
+@BUILD_TESTS_TRUE@gen7_forcewake_mt_LDADD = $(LDADD) -lpthread
+@BUILD_TESTS_TRUE@gem_wait_render_timeout_LDADD = $(LDADD) -lrt
+@BUILD_TESTS_TRUE@kms_flip_LDADD = $(LDADD) -lrt -lpthread
+@BUILD_TESTS_TRUE@prime_nv_test_CFLAGS = $(AM_CFLAGS) $(DRM_NOUVEAU_CFLAGS)
+@BUILD_TESTS_TRUE@prime_nv_test_LDADD = $(LDADD) $(DRM_NOUVEAU_LIBS)
+@BUILD_TESTS_TRUE@prime_nv_api_CFLAGS = $(AM_CFLAGS) $(DRM_NOUVEAU_CFLAGS)
+@BUILD_TESTS_TRUE@prime_nv_api_LDADD = $(LDADD) $(DRM_NOUVEAU_LIBS)
+@BUILD_TESTS_TRUE@prime_nv_pcopy_CFLAGS = $(AM_CFLAGS) $(DRM_NOUVEAU_CFLAGS)
+@BUILD_TESTS_TRUE@prime_nv_pcopy_LDADD = $(LDADD) $(DRM_NOUVEAU_LIBS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/Makefile.sources $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+$(srcdir)/Makefile.sources:
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+core_get_client_auth$(EXEEXT): $(core_get_client_auth_OBJECTS) $(core_get_client_auth_DEPENDENCIES) $(EXTRA_core_get_client_auth_DEPENDENCIES)
+ @rm -f core_get_client_auth$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(core_get_client_auth_OBJECTS) $(core_get_client_auth_LDADD) $(LIBS)
+
+core_getclient$(EXEEXT): $(core_getclient_OBJECTS) $(core_getclient_DEPENDENCIES) $(EXTRA_core_getclient_DEPENDENCIES)
+ @rm -f core_getclient$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(core_getclient_OBJECTS) $(core_getclient_LDADD) $(LIBS)
+
+core_getstats$(EXEEXT): $(core_getstats_OBJECTS) $(core_getstats_DEPENDENCIES) $(EXTRA_core_getstats_DEPENDENCIES)
+ @rm -f core_getstats$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(core_getstats_OBJECTS) $(core_getstats_LDADD) $(LIBS)
+
+core_getversion$(EXEEXT): $(core_getversion_OBJECTS) $(core_getversion_DEPENDENCIES) $(EXTRA_core_getversion_DEPENDENCIES)
+ @rm -f core_getversion$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(core_getversion_OBJECTS) $(core_getversion_LDADD) $(LIBS)
+
+ddi_compute_wrpll$(EXEEXT): $(ddi_compute_wrpll_OBJECTS) $(ddi_compute_wrpll_DEPENDENCIES) $(EXTRA_ddi_compute_wrpll_DEPENDENCIES)
+ @rm -f ddi_compute_wrpll$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(ddi_compute_wrpll_OBJECTS) $(ddi_compute_wrpll_LDADD) $(LIBS)
+
+drm_vma_limiter$(EXEEXT): $(drm_vma_limiter_OBJECTS) $(drm_vma_limiter_DEPENDENCIES) $(EXTRA_drm_vma_limiter_DEPENDENCIES)
+ @rm -f drm_vma_limiter$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(drm_vma_limiter_OBJECTS) $(drm_vma_limiter_LDADD) $(LIBS)
+
+drm_vma_limiter_cached$(EXEEXT): $(drm_vma_limiter_cached_OBJECTS) $(drm_vma_limiter_cached_DEPENDENCIES) $(EXTRA_drm_vma_limiter_cached_DEPENDENCIES)
+ @rm -f drm_vma_limiter_cached$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(drm_vma_limiter_cached_OBJECTS) $(drm_vma_limiter_cached_LDADD) $(LIBS)
+
+drm_vma_limiter_cpu$(EXEEXT): $(drm_vma_limiter_cpu_OBJECTS) $(drm_vma_limiter_cpu_DEPENDENCIES) $(EXTRA_drm_vma_limiter_cpu_DEPENDENCIES)
+ @rm -f drm_vma_limiter_cpu$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(drm_vma_limiter_cpu_OBJECTS) $(drm_vma_limiter_cpu_LDADD) $(LIBS)
+
+drm_vma_limiter_gtt$(EXEEXT): $(drm_vma_limiter_gtt_OBJECTS) $(drm_vma_limiter_gtt_DEPENDENCIES) $(EXTRA_drm_vma_limiter_gtt_DEPENDENCIES)
+ @rm -f drm_vma_limiter_gtt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(drm_vma_limiter_gtt_OBJECTS) $(drm_vma_limiter_gtt_LDADD) $(LIBS)
+
+drv_hangman$(EXEEXT): $(drv_hangman_OBJECTS) $(drv_hangman_DEPENDENCIES) $(EXTRA_drv_hangman_DEPENDENCIES)
+ @rm -f drv_hangman$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(drv_hangman_OBJECTS) $(drv_hangman_LDADD) $(LIBS)
+
+drv_suspend$(EXEEXT): $(drv_suspend_OBJECTS) $(drv_suspend_DEPENDENCIES) $(EXTRA_drv_suspend_DEPENDENCIES)
+ @rm -f drv_suspend$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(drv_suspend_OBJECTS) $(drv_suspend_LDADD) $(LIBS)
+
+gem_alive$(EXEEXT): $(gem_alive_OBJECTS) $(gem_alive_DEPENDENCIES) $(EXTRA_gem_alive_DEPENDENCIES)
+ @rm -f gem_alive$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_alive_OBJECTS) $(gem_alive_LDADD) $(LIBS)
+
+gem_bad_address$(EXEEXT): $(gem_bad_address_OBJECTS) $(gem_bad_address_DEPENDENCIES) $(EXTRA_gem_bad_address_DEPENDENCIES)
+ @rm -f gem_bad_address$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_bad_address_OBJECTS) $(gem_bad_address_LDADD) $(LIBS)
+
+gem_bad_batch$(EXEEXT): $(gem_bad_batch_OBJECTS) $(gem_bad_batch_DEPENDENCIES) $(EXTRA_gem_bad_batch_DEPENDENCIES)
+ @rm -f gem_bad_batch$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_bad_batch_OBJECTS) $(gem_bad_batch_LDADD) $(LIBS)
+
+gem_bad_blit$(EXEEXT): $(gem_bad_blit_OBJECTS) $(gem_bad_blit_DEPENDENCIES) $(EXTRA_gem_bad_blit_DEPENDENCIES)
+ @rm -f gem_bad_blit$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_bad_blit_OBJECTS) $(gem_bad_blit_LDADD) $(LIBS)
+
+gem_bad_length$(EXEEXT): $(gem_bad_length_OBJECTS) $(gem_bad_length_DEPENDENCIES) $(EXTRA_gem_bad_length_DEPENDENCIES)
+ @rm -f gem_bad_length$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_bad_length_OBJECTS) $(gem_bad_length_LDADD) $(LIBS)
+
+gem_bad_reloc$(EXEEXT): $(gem_bad_reloc_OBJECTS) $(gem_bad_reloc_DEPENDENCIES) $(EXTRA_gem_bad_reloc_DEPENDENCIES)
+ @rm -f gem_bad_reloc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_bad_reloc_OBJECTS) $(gem_bad_reloc_LDADD) $(LIBS)
+
+gem_basic$(EXEEXT): $(gem_basic_OBJECTS) $(gem_basic_DEPENDENCIES) $(EXTRA_gem_basic_DEPENDENCIES)
+ @rm -f gem_basic$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_basic_OBJECTS) $(gem_basic_LDADD) $(LIBS)
+
+gem_caching$(EXEEXT): $(gem_caching_OBJECTS) $(gem_caching_DEPENDENCIES) $(EXTRA_gem_caching_DEPENDENCIES)
+ @rm -f gem_caching$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_caching_OBJECTS) $(gem_caching_LDADD) $(LIBS)
+
+gem_close_race$(EXEEXT): $(gem_close_race_OBJECTS) $(gem_close_race_DEPENDENCIES) $(EXTRA_gem_close_race_DEPENDENCIES)
+ @rm -f gem_close_race$(EXEEXT)
+ $(AM_V_CCLD)$(gem_close_race_LINK) $(gem_close_race_OBJECTS) $(gem_close_race_LDADD) $(LIBS)
+
+gem_concurrent_blit$(EXEEXT): $(gem_concurrent_blit_OBJECTS) $(gem_concurrent_blit_DEPENDENCIES) $(EXTRA_gem_concurrent_blit_DEPENDENCIES)
+ @rm -f gem_concurrent_blit$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_concurrent_blit_OBJECTS) $(gem_concurrent_blit_LDADD) $(LIBS)
+
+gem_cpu_reloc$(EXEEXT): $(gem_cpu_reloc_OBJECTS) $(gem_cpu_reloc_DEPENDENCIES) $(EXTRA_gem_cpu_reloc_DEPENDENCIES)
+ @rm -f gem_cpu_reloc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_cpu_reloc_OBJECTS) $(gem_cpu_reloc_LDADD) $(LIBS)
+
+gem_cs_prefetch$(EXEEXT): $(gem_cs_prefetch_OBJECTS) $(gem_cs_prefetch_DEPENDENCIES) $(EXTRA_gem_cs_prefetch_DEPENDENCIES)
+ @rm -f gem_cs_prefetch$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_cs_prefetch_OBJECTS) $(gem_cs_prefetch_LDADD) $(LIBS)
+
+gem_cs_tlb$(EXEEXT): $(gem_cs_tlb_OBJECTS) $(gem_cs_tlb_DEPENDENCIES) $(EXTRA_gem_cs_tlb_DEPENDENCIES)
+ @rm -f gem_cs_tlb$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_cs_tlb_OBJECTS) $(gem_cs_tlb_LDADD) $(LIBS)
+
+gem_ctx_bad_destroy$(EXEEXT): $(gem_ctx_bad_destroy_OBJECTS) $(gem_ctx_bad_destroy_DEPENDENCIES) $(EXTRA_gem_ctx_bad_destroy_DEPENDENCIES)
+ @rm -f gem_ctx_bad_destroy$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_ctx_bad_destroy_OBJECTS) $(gem_ctx_bad_destroy_LDADD) $(LIBS)
+
+gem_ctx_bad_exec$(EXEEXT): $(gem_ctx_bad_exec_OBJECTS) $(gem_ctx_bad_exec_DEPENDENCIES) $(EXTRA_gem_ctx_bad_exec_DEPENDENCIES)
+ @rm -f gem_ctx_bad_exec$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_ctx_bad_exec_OBJECTS) $(gem_ctx_bad_exec_LDADD) $(LIBS)
+
+gem_ctx_basic$(EXEEXT): $(gem_ctx_basic_OBJECTS) $(gem_ctx_basic_DEPENDENCIES) $(EXTRA_gem_ctx_basic_DEPENDENCIES)
+ @rm -f gem_ctx_basic$(EXEEXT)
+ $(AM_V_CCLD)$(gem_ctx_basic_LINK) $(gem_ctx_basic_OBJECTS) $(gem_ctx_basic_LDADD) $(LIBS)
+
+gem_ctx_create$(EXEEXT): $(gem_ctx_create_OBJECTS) $(gem_ctx_create_DEPENDENCIES) $(EXTRA_gem_ctx_create_DEPENDENCIES)
+ @rm -f gem_ctx_create$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_ctx_create_OBJECTS) $(gem_ctx_create_LDADD) $(LIBS)
+
+gem_ctx_exec$(EXEEXT): $(gem_ctx_exec_OBJECTS) $(gem_ctx_exec_DEPENDENCIES) $(EXTRA_gem_ctx_exec_DEPENDENCIES)
+ @rm -f gem_ctx_exec$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_ctx_exec_OBJECTS) $(gem_ctx_exec_LDADD) $(LIBS)
+
+gem_double_irq_loop$(EXEEXT): $(gem_double_irq_loop_OBJECTS) $(gem_double_irq_loop_DEPENDENCIES) $(EXTRA_gem_double_irq_loop_DEPENDENCIES)
+ @rm -f gem_double_irq_loop$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_double_irq_loop_OBJECTS) $(gem_double_irq_loop_LDADD) $(LIBS)
+
+gem_dummy_reloc_loop$(EXEEXT): $(gem_dummy_reloc_loop_OBJECTS) $(gem_dummy_reloc_loop_DEPENDENCIES) $(EXTRA_gem_dummy_reloc_loop_DEPENDENCIES)
+ @rm -f gem_dummy_reloc_loop$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_dummy_reloc_loop_OBJECTS) $(gem_dummy_reloc_loop_LDADD) $(LIBS)
+
+gem_evict_alignment$(EXEEXT): $(gem_evict_alignment_OBJECTS) $(gem_evict_alignment_DEPENDENCIES) $(EXTRA_gem_evict_alignment_DEPENDENCIES)
+ @rm -f gem_evict_alignment$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_evict_alignment_OBJECTS) $(gem_evict_alignment_LDADD) $(LIBS)
+
+gem_evict_everything$(EXEEXT): $(gem_evict_everything_OBJECTS) $(gem_evict_everything_DEPENDENCIES) $(EXTRA_gem_evict_everything_DEPENDENCIES)
+ @rm -f gem_evict_everything$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_evict_everything_OBJECTS) $(gem_evict_everything_LDADD) $(LIBS)
+
+gem_exec_bad_domains$(EXEEXT): $(gem_exec_bad_domains_OBJECTS) $(gem_exec_bad_domains_DEPENDENCIES) $(EXTRA_gem_exec_bad_domains_DEPENDENCIES)
+ @rm -f gem_exec_bad_domains$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_exec_bad_domains_OBJECTS) $(gem_exec_bad_domains_LDADD) $(LIBS)
+
+gem_exec_big$(EXEEXT): $(gem_exec_big_OBJECTS) $(gem_exec_big_DEPENDENCIES) $(EXTRA_gem_exec_big_DEPENDENCIES)
+ @rm -f gem_exec_big$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_exec_big_OBJECTS) $(gem_exec_big_LDADD) $(LIBS)
+
+gem_exec_blt$(EXEEXT): $(gem_exec_blt_OBJECTS) $(gem_exec_blt_DEPENDENCIES) $(EXTRA_gem_exec_blt_DEPENDENCIES)
+ @rm -f gem_exec_blt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_exec_blt_OBJECTS) $(gem_exec_blt_LDADD) $(LIBS)
+
+gem_exec_faulting_reloc$(EXEEXT): $(gem_exec_faulting_reloc_OBJECTS) $(gem_exec_faulting_reloc_DEPENDENCIES) $(EXTRA_gem_exec_faulting_reloc_DEPENDENCIES)
+ @rm -f gem_exec_faulting_reloc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_exec_faulting_reloc_OBJECTS) $(gem_exec_faulting_reloc_LDADD) $(LIBS)
+
+gem_exec_lut_handle$(EXEEXT): $(gem_exec_lut_handle_OBJECTS) $(gem_exec_lut_handle_DEPENDENCIES) $(EXTRA_gem_exec_lut_handle_DEPENDENCIES)
+ @rm -f gem_exec_lut_handle$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_exec_lut_handle_OBJECTS) $(gem_exec_lut_handle_LDADD) $(LIBS)
+
+gem_exec_nop$(EXEEXT): $(gem_exec_nop_OBJECTS) $(gem_exec_nop_DEPENDENCIES) $(EXTRA_gem_exec_nop_DEPENDENCIES)
+ @rm -f gem_exec_nop$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_exec_nop_OBJECTS) $(gem_exec_nop_LDADD) $(LIBS)
+
+gem_exec_params$(EXEEXT): $(gem_exec_params_OBJECTS) $(gem_exec_params_DEPENDENCIES) $(EXTRA_gem_exec_params_DEPENDENCIES)
+ @rm -f gem_exec_params$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_exec_params_OBJECTS) $(gem_exec_params_LDADD) $(LIBS)
+
+gem_exec_parse$(EXEEXT): $(gem_exec_parse_OBJECTS) $(gem_exec_parse_DEPENDENCIES) $(EXTRA_gem_exec_parse_DEPENDENCIES)
+ @rm -f gem_exec_parse$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_exec_parse_OBJECTS) $(gem_exec_parse_LDADD) $(LIBS)
+
+gem_fd_exhaustion$(EXEEXT): $(gem_fd_exhaustion_OBJECTS) $(gem_fd_exhaustion_DEPENDENCIES) $(EXTRA_gem_fd_exhaustion_DEPENDENCIES)
+ @rm -f gem_fd_exhaustion$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_fd_exhaustion_OBJECTS) $(gem_fd_exhaustion_LDADD) $(LIBS)
+
+gem_fence_thrash$(EXEEXT): $(gem_fence_thrash_OBJECTS) $(gem_fence_thrash_DEPENDENCIES) $(EXTRA_gem_fence_thrash_DEPENDENCIES)
+ @rm -f gem_fence_thrash$(EXEEXT)
+ $(AM_V_CCLD)$(gem_fence_thrash_LINK) $(gem_fence_thrash_OBJECTS) $(gem_fence_thrash_LDADD) $(LIBS)
+
+gem_fenced_exec_thrash$(EXEEXT): $(gem_fenced_exec_thrash_OBJECTS) $(gem_fenced_exec_thrash_DEPENDENCIES) $(EXTRA_gem_fenced_exec_thrash_DEPENDENCIES)
+ @rm -f gem_fenced_exec_thrash$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_fenced_exec_thrash_OBJECTS) $(gem_fenced_exec_thrash_LDADD) $(LIBS)
+
+gem_flink$(EXEEXT): $(gem_flink_OBJECTS) $(gem_flink_DEPENDENCIES) $(EXTRA_gem_flink_DEPENDENCIES)
+ @rm -f gem_flink$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_flink_OBJECTS) $(gem_flink_LDADD) $(LIBS)
+
+gem_flink_race$(EXEEXT): $(gem_flink_race_OBJECTS) $(gem_flink_race_DEPENDENCIES) $(EXTRA_gem_flink_race_DEPENDENCIES)
+ @rm -f gem_flink_race$(EXEEXT)
+ $(AM_V_CCLD)$(gem_flink_race_LINK) $(gem_flink_race_OBJECTS) $(gem_flink_race_LDADD) $(LIBS)
+
+gem_gtt_cpu_tlb$(EXEEXT): $(gem_gtt_cpu_tlb_OBJECTS) $(gem_gtt_cpu_tlb_DEPENDENCIES) $(EXTRA_gem_gtt_cpu_tlb_DEPENDENCIES)
+ @rm -f gem_gtt_cpu_tlb$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_gtt_cpu_tlb_OBJECTS) $(gem_gtt_cpu_tlb_LDADD) $(LIBS)
+
+gem_gtt_hog$(EXEEXT): $(gem_gtt_hog_OBJECTS) $(gem_gtt_hog_DEPENDENCIES) $(EXTRA_gem_gtt_hog_DEPENDENCIES)
+ @rm -f gem_gtt_hog$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_gtt_hog_OBJECTS) $(gem_gtt_hog_LDADD) $(LIBS)
+
+gem_gtt_speed$(EXEEXT): $(gem_gtt_speed_OBJECTS) $(gem_gtt_speed_DEPENDENCIES) $(EXTRA_gem_gtt_speed_DEPENDENCIES)
+ @rm -f gem_gtt_speed$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_gtt_speed_OBJECTS) $(gem_gtt_speed_LDADD) $(LIBS)
+
+gem_hang$(EXEEXT): $(gem_hang_OBJECTS) $(gem_hang_DEPENDENCIES) $(EXTRA_gem_hang_DEPENDENCIES)
+ @rm -f gem_hang$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_hang_OBJECTS) $(gem_hang_LDADD) $(LIBS)
+
+gem_hangcheck_forcewake$(EXEEXT): $(gem_hangcheck_forcewake_OBJECTS) $(gem_hangcheck_forcewake_DEPENDENCIES) $(EXTRA_gem_hangcheck_forcewake_DEPENDENCIES)
+ @rm -f gem_hangcheck_forcewake$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_hangcheck_forcewake_OBJECTS) $(gem_hangcheck_forcewake_LDADD) $(LIBS)
+
+gem_largeobject$(EXEEXT): $(gem_largeobject_OBJECTS) $(gem_largeobject_DEPENDENCIES) $(EXTRA_gem_largeobject_DEPENDENCIES)
+ @rm -f gem_largeobject$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_largeobject_OBJECTS) $(gem_largeobject_LDADD) $(LIBS)
+
+gem_linear_blits$(EXEEXT): $(gem_linear_blits_OBJECTS) $(gem_linear_blits_DEPENDENCIES) $(EXTRA_gem_linear_blits_DEPENDENCIES)
+ @rm -f gem_linear_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_linear_blits_OBJECTS) $(gem_linear_blits_LDADD) $(LIBS)
+
+gem_lut_handle$(EXEEXT): $(gem_lut_handle_OBJECTS) $(gem_lut_handle_DEPENDENCIES) $(EXTRA_gem_lut_handle_DEPENDENCIES)
+ @rm -f gem_lut_handle$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_lut_handle_OBJECTS) $(gem_lut_handle_LDADD) $(LIBS)
+
+gem_madvise$(EXEEXT): $(gem_madvise_OBJECTS) $(gem_madvise_DEPENDENCIES) $(EXTRA_gem_madvise_DEPENDENCIES)
+ @rm -f gem_madvise$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_madvise_OBJECTS) $(gem_madvise_LDADD) $(LIBS)
+
+gem_media_fill$(EXEEXT): $(gem_media_fill_OBJECTS) $(gem_media_fill_DEPENDENCIES) $(EXTRA_gem_media_fill_DEPENDENCIES)
+ @rm -f gem_media_fill$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_media_fill_OBJECTS) $(gem_media_fill_LDADD) $(LIBS)
+
+gem_mmap$(EXEEXT): $(gem_mmap_OBJECTS) $(gem_mmap_DEPENDENCIES) $(EXTRA_gem_mmap_DEPENDENCIES)
+ @rm -f gem_mmap$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_mmap_OBJECTS) $(gem_mmap_LDADD) $(LIBS)
+
+gem_mmap_gtt$(EXEEXT): $(gem_mmap_gtt_OBJECTS) $(gem_mmap_gtt_DEPENDENCIES) $(EXTRA_gem_mmap_gtt_DEPENDENCIES)
+ @rm -f gem_mmap_gtt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_mmap_gtt_OBJECTS) $(gem_mmap_gtt_LDADD) $(LIBS)
+
+gem_mmap_offset_exhaustion$(EXEEXT): $(gem_mmap_offset_exhaustion_OBJECTS) $(gem_mmap_offset_exhaustion_DEPENDENCIES) $(EXTRA_gem_mmap_offset_exhaustion_DEPENDENCIES)
+ @rm -f gem_mmap_offset_exhaustion$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_mmap_offset_exhaustion_OBJECTS) $(gem_mmap_offset_exhaustion_LDADD) $(LIBS)
+
+gem_multi_bsd_sync_loop$(EXEEXT): $(gem_multi_bsd_sync_loop_OBJECTS) $(gem_multi_bsd_sync_loop_DEPENDENCIES) $(EXTRA_gem_multi_bsd_sync_loop_DEPENDENCIES)
+ @rm -f gem_multi_bsd_sync_loop$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_multi_bsd_sync_loop_OBJECTS) $(gem_multi_bsd_sync_loop_LDADD) $(LIBS)
+
+gem_non_secure_batch$(EXEEXT): $(gem_non_secure_batch_OBJECTS) $(gem_non_secure_batch_DEPENDENCIES) $(EXTRA_gem_non_secure_batch_DEPENDENCIES)
+ @rm -f gem_non_secure_batch$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_non_secure_batch_OBJECTS) $(gem_non_secure_batch_LDADD) $(LIBS)
+
+gem_partial_pwrite_pread$(EXEEXT): $(gem_partial_pwrite_pread_OBJECTS) $(gem_partial_pwrite_pread_DEPENDENCIES) $(EXTRA_gem_partial_pwrite_pread_DEPENDENCIES)
+ @rm -f gem_partial_pwrite_pread$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_partial_pwrite_pread_OBJECTS) $(gem_partial_pwrite_pread_LDADD) $(LIBS)
+
+gem_persistent_relocs$(EXEEXT): $(gem_persistent_relocs_OBJECTS) $(gem_persistent_relocs_DEPENDENCIES) $(EXTRA_gem_persistent_relocs_DEPENDENCIES)
+ @rm -f gem_persistent_relocs$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_persistent_relocs_OBJECTS) $(gem_persistent_relocs_LDADD) $(LIBS)
+
+gem_pin$(EXEEXT): $(gem_pin_OBJECTS) $(gem_pin_DEPENDENCIES) $(EXTRA_gem_pin_DEPENDENCIES)
+ @rm -f gem_pin$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_pin_OBJECTS) $(gem_pin_LDADD) $(LIBS)
+
+gem_pipe_control_store_loop$(EXEEXT): $(gem_pipe_control_store_loop_OBJECTS) $(gem_pipe_control_store_loop_DEPENDENCIES) $(EXTRA_gem_pipe_control_store_loop_DEPENDENCIES)
+ @rm -f gem_pipe_control_store_loop$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_pipe_control_store_loop_OBJECTS) $(gem_pipe_control_store_loop_LDADD) $(LIBS)
+
+gem_pread$(EXEEXT): $(gem_pread_OBJECTS) $(gem_pread_DEPENDENCIES) $(EXTRA_gem_pread_DEPENDENCIES)
+ @rm -f gem_pread$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_pread_OBJECTS) $(gem_pread_LDADD) $(LIBS)
+
+gem_pread_after_blit$(EXEEXT): $(gem_pread_after_blit_OBJECTS) $(gem_pread_after_blit_DEPENDENCIES) $(EXTRA_gem_pread_after_blit_DEPENDENCIES)
+ @rm -f gem_pread_after_blit$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_pread_after_blit_OBJECTS) $(gem_pread_after_blit_LDADD) $(LIBS)
+
+gem_pwrite$(EXEEXT): $(gem_pwrite_OBJECTS) $(gem_pwrite_DEPENDENCIES) $(EXTRA_gem_pwrite_DEPENDENCIES)
+ @rm -f gem_pwrite$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_pwrite_OBJECTS) $(gem_pwrite_LDADD) $(LIBS)
+
+gem_pwrite_pread$(EXEEXT): $(gem_pwrite_pread_OBJECTS) $(gem_pwrite_pread_DEPENDENCIES) $(EXTRA_gem_pwrite_pread_DEPENDENCIES)
+ @rm -f gem_pwrite_pread$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_pwrite_pread_OBJECTS) $(gem_pwrite_pread_LDADD) $(LIBS)
+
+gem_readwrite$(EXEEXT): $(gem_readwrite_OBJECTS) $(gem_readwrite_DEPENDENCIES) $(EXTRA_gem_readwrite_DEPENDENCIES)
+ @rm -f gem_readwrite$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_readwrite_OBJECTS) $(gem_readwrite_LDADD) $(LIBS)
+
+gem_reg_read$(EXEEXT): $(gem_reg_read_OBJECTS) $(gem_reg_read_DEPENDENCIES) $(EXTRA_gem_reg_read_DEPENDENCIES)
+ @rm -f gem_reg_read$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_reg_read_OBJECTS) $(gem_reg_read_LDADD) $(LIBS)
+
+gem_reloc_overflow$(EXEEXT): $(gem_reloc_overflow_OBJECTS) $(gem_reloc_overflow_DEPENDENCIES) $(EXTRA_gem_reloc_overflow_DEPENDENCIES)
+ @rm -f gem_reloc_overflow$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_reloc_overflow_OBJECTS) $(gem_reloc_overflow_LDADD) $(LIBS)
+
+gem_reloc_vs_gpu$(EXEEXT): $(gem_reloc_vs_gpu_OBJECTS) $(gem_reloc_vs_gpu_DEPENDENCIES) $(EXTRA_gem_reloc_vs_gpu_DEPENDENCIES)
+ @rm -f gem_reloc_vs_gpu$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_reloc_vs_gpu_OBJECTS) $(gem_reloc_vs_gpu_LDADD) $(LIBS)
+
+gem_render_copy$(EXEEXT): $(gem_render_copy_OBJECTS) $(gem_render_copy_DEPENDENCIES) $(EXTRA_gem_render_copy_DEPENDENCIES)
+ @rm -f gem_render_copy$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_render_copy_OBJECTS) $(gem_render_copy_LDADD) $(LIBS)
+
+gem_render_copy_redux$(EXEEXT): $(gem_render_copy_redux_OBJECTS) $(gem_render_copy_redux_DEPENDENCIES) $(EXTRA_gem_render_copy_redux_DEPENDENCIES)
+ @rm -f gem_render_copy_redux$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_render_copy_redux_OBJECTS) $(gem_render_copy_redux_LDADD) $(LIBS)
+
+gem_render_linear_blits$(EXEEXT): $(gem_render_linear_blits_OBJECTS) $(gem_render_linear_blits_DEPENDENCIES) $(EXTRA_gem_render_linear_blits_DEPENDENCIES)
+ @rm -f gem_render_linear_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_render_linear_blits_OBJECTS) $(gem_render_linear_blits_LDADD) $(LIBS)
+
+gem_render_tiled_blits$(EXEEXT): $(gem_render_tiled_blits_OBJECTS) $(gem_render_tiled_blits_DEPENDENCIES) $(EXTRA_gem_render_tiled_blits_DEPENDENCIES)
+ @rm -f gem_render_tiled_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_render_tiled_blits_OBJECTS) $(gem_render_tiled_blits_LDADD) $(LIBS)
+
+gem_reset_stats$(EXEEXT): $(gem_reset_stats_OBJECTS) $(gem_reset_stats_DEPENDENCIES) $(EXTRA_gem_reset_stats_DEPENDENCIES)
+ @rm -f gem_reset_stats$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_reset_stats_OBJECTS) $(gem_reset_stats_LDADD) $(LIBS)
+
+gem_ring_sync_copy$(EXEEXT): $(gem_ring_sync_copy_OBJECTS) $(gem_ring_sync_copy_DEPENDENCIES) $(EXTRA_gem_ring_sync_copy_DEPENDENCIES)
+ @rm -f gem_ring_sync_copy$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_ring_sync_copy_OBJECTS) $(gem_ring_sync_copy_LDADD) $(LIBS)
+
+gem_ring_sync_loop$(EXEEXT): $(gem_ring_sync_loop_OBJECTS) $(gem_ring_sync_loop_DEPENDENCIES) $(EXTRA_gem_ring_sync_loop_DEPENDENCIES)
+ @rm -f gem_ring_sync_loop$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_ring_sync_loop_OBJECTS) $(gem_ring_sync_loop_LDADD) $(LIBS)
+
+gem_ringfill$(EXEEXT): $(gem_ringfill_OBJECTS) $(gem_ringfill_DEPENDENCIES) $(EXTRA_gem_ringfill_DEPENDENCIES)
+ @rm -f gem_ringfill$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_ringfill_OBJECTS) $(gem_ringfill_LDADD) $(LIBS)
+
+gem_seqno_wrap$(EXEEXT): $(gem_seqno_wrap_OBJECTS) $(gem_seqno_wrap_DEPENDENCIES) $(EXTRA_gem_seqno_wrap_DEPENDENCIES)
+ @rm -f gem_seqno_wrap$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_seqno_wrap_OBJECTS) $(gem_seqno_wrap_LDADD) $(LIBS)
+
+gem_set_tiling_vs_blt$(EXEEXT): $(gem_set_tiling_vs_blt_OBJECTS) $(gem_set_tiling_vs_blt_DEPENDENCIES) $(EXTRA_gem_set_tiling_vs_blt_DEPENDENCIES)
+ @rm -f gem_set_tiling_vs_blt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_set_tiling_vs_blt_OBJECTS) $(gem_set_tiling_vs_blt_LDADD) $(LIBS)
+
+gem_set_tiling_vs_gtt$(EXEEXT): $(gem_set_tiling_vs_gtt_OBJECTS) $(gem_set_tiling_vs_gtt_DEPENDENCIES) $(EXTRA_gem_set_tiling_vs_gtt_DEPENDENCIES)
+ @rm -f gem_set_tiling_vs_gtt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_set_tiling_vs_gtt_OBJECTS) $(gem_set_tiling_vs_gtt_LDADD) $(LIBS)
+
+gem_set_tiling_vs_pwrite$(EXEEXT): $(gem_set_tiling_vs_pwrite_OBJECTS) $(gem_set_tiling_vs_pwrite_DEPENDENCIES) $(EXTRA_gem_set_tiling_vs_pwrite_DEPENDENCIES)
+ @rm -f gem_set_tiling_vs_pwrite$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_set_tiling_vs_pwrite_OBJECTS) $(gem_set_tiling_vs_pwrite_LDADD) $(LIBS)
+
+gem_storedw_batches_loop$(EXEEXT): $(gem_storedw_batches_loop_OBJECTS) $(gem_storedw_batches_loop_DEPENDENCIES) $(EXTRA_gem_storedw_batches_loop_DEPENDENCIES)
+ @rm -f gem_storedw_batches_loop$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_storedw_batches_loop_OBJECTS) $(gem_storedw_batches_loop_LDADD) $(LIBS)
+
+gem_storedw_loop_blt$(EXEEXT): $(gem_storedw_loop_blt_OBJECTS) $(gem_storedw_loop_blt_DEPENDENCIES) $(EXTRA_gem_storedw_loop_blt_DEPENDENCIES)
+ @rm -f gem_storedw_loop_blt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_storedw_loop_blt_OBJECTS) $(gem_storedw_loop_blt_LDADD) $(LIBS)
+
+gem_storedw_loop_bsd$(EXEEXT): $(gem_storedw_loop_bsd_OBJECTS) $(gem_storedw_loop_bsd_DEPENDENCIES) $(EXTRA_gem_storedw_loop_bsd_DEPENDENCIES)
+ @rm -f gem_storedw_loop_bsd$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_storedw_loop_bsd_OBJECTS) $(gem_storedw_loop_bsd_LDADD) $(LIBS)
+
+gem_storedw_loop_render$(EXEEXT): $(gem_storedw_loop_render_OBJECTS) $(gem_storedw_loop_render_DEPENDENCIES) $(EXTRA_gem_storedw_loop_render_DEPENDENCIES)
+ @rm -f gem_storedw_loop_render$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_storedw_loop_render_OBJECTS) $(gem_storedw_loop_render_LDADD) $(LIBS)
+
+gem_storedw_loop_vebox$(EXEEXT): $(gem_storedw_loop_vebox_OBJECTS) $(gem_storedw_loop_vebox_DEPENDENCIES) $(EXTRA_gem_storedw_loop_vebox_DEPENDENCIES)
+ @rm -f gem_storedw_loop_vebox$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_storedw_loop_vebox_OBJECTS) $(gem_storedw_loop_vebox_LDADD) $(LIBS)
+
+gem_stress$(EXEEXT): $(gem_stress_OBJECTS) $(gem_stress_DEPENDENCIES) $(EXTRA_gem_stress_DEPENDENCIES)
+ @rm -f gem_stress$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_stress_OBJECTS) $(gem_stress_LDADD) $(LIBS)
+
+gem_threaded_access_tiled$(EXEEXT): $(gem_threaded_access_tiled_OBJECTS) $(gem_threaded_access_tiled_DEPENDENCIES) $(EXTRA_gem_threaded_access_tiled_DEPENDENCIES)
+ @rm -f gem_threaded_access_tiled$(EXEEXT)
+ $(AM_V_CCLD)$(gem_threaded_access_tiled_LINK) $(gem_threaded_access_tiled_OBJECTS) $(gem_threaded_access_tiled_LDADD) $(LIBS)
+
+gem_tiled_blits$(EXEEXT): $(gem_tiled_blits_OBJECTS) $(gem_tiled_blits_DEPENDENCIES) $(EXTRA_gem_tiled_blits_DEPENDENCIES)
+ @rm -f gem_tiled_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_tiled_blits_OBJECTS) $(gem_tiled_blits_LDADD) $(LIBS)
+
+gem_tiled_fence_blits$(EXEEXT): $(gem_tiled_fence_blits_OBJECTS) $(gem_tiled_fence_blits_DEPENDENCIES) $(EXTRA_gem_tiled_fence_blits_DEPENDENCIES)
+ @rm -f gem_tiled_fence_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_tiled_fence_blits_OBJECTS) $(gem_tiled_fence_blits_LDADD) $(LIBS)
+
+gem_tiled_partial_pwrite_pread$(EXEEXT): $(gem_tiled_partial_pwrite_pread_OBJECTS) $(gem_tiled_partial_pwrite_pread_DEPENDENCIES) $(EXTRA_gem_tiled_partial_pwrite_pread_DEPENDENCIES)
+ @rm -f gem_tiled_partial_pwrite_pread$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_tiled_partial_pwrite_pread_OBJECTS) $(gem_tiled_partial_pwrite_pread_LDADD) $(LIBS)
+
+gem_tiled_pread$(EXEEXT): $(gem_tiled_pread_OBJECTS) $(gem_tiled_pread_DEPENDENCIES) $(EXTRA_gem_tiled_pread_DEPENDENCIES)
+ @rm -f gem_tiled_pread$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_tiled_pread_OBJECTS) $(gem_tiled_pread_LDADD) $(LIBS)
+
+gem_tiled_pread_pwrite$(EXEEXT): $(gem_tiled_pread_pwrite_OBJECTS) $(gem_tiled_pread_pwrite_DEPENDENCIES) $(EXTRA_gem_tiled_pread_pwrite_DEPENDENCIES)
+ @rm -f gem_tiled_pread_pwrite$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_tiled_pread_pwrite_OBJECTS) $(gem_tiled_pread_pwrite_LDADD) $(LIBS)
+
+gem_tiled_swapping$(EXEEXT): $(gem_tiled_swapping_OBJECTS) $(gem_tiled_swapping_DEPENDENCIES) $(EXTRA_gem_tiled_swapping_DEPENDENCIES)
+ @rm -f gem_tiled_swapping$(EXEEXT)
+ $(AM_V_CCLD)$(gem_tiled_swapping_LINK) $(gem_tiled_swapping_OBJECTS) $(gem_tiled_swapping_LDADD) $(LIBS)
+
+gem_tiling_max_stride$(EXEEXT): $(gem_tiling_max_stride_OBJECTS) $(gem_tiling_max_stride_DEPENDENCIES) $(EXTRA_gem_tiling_max_stride_DEPENDENCIES)
+ @rm -f gem_tiling_max_stride$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_tiling_max_stride_OBJECTS) $(gem_tiling_max_stride_LDADD) $(LIBS)
+
+gem_unfence_active_buffers$(EXEEXT): $(gem_unfence_active_buffers_OBJECTS) $(gem_unfence_active_buffers_DEPENDENCIES) $(EXTRA_gem_unfence_active_buffers_DEPENDENCIES)
+ @rm -f gem_unfence_active_buffers$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_unfence_active_buffers_OBJECTS) $(gem_unfence_active_buffers_LDADD) $(LIBS)
+
+gem_unref_active_buffers$(EXEEXT): $(gem_unref_active_buffers_OBJECTS) $(gem_unref_active_buffers_DEPENDENCIES) $(EXTRA_gem_unref_active_buffers_DEPENDENCIES)
+ @rm -f gem_unref_active_buffers$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_unref_active_buffers_OBJECTS) $(gem_unref_active_buffers_LDADD) $(LIBS)
+
+gem_userptr_blits$(EXEEXT): $(gem_userptr_blits_OBJECTS) $(gem_userptr_blits_DEPENDENCIES) $(EXTRA_gem_userptr_blits_DEPENDENCIES)
+ @rm -f gem_userptr_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_userptr_blits_OBJECTS) $(gem_userptr_blits_LDADD) $(LIBS)
+
+gem_wait_render_timeout$(EXEEXT): $(gem_wait_render_timeout_OBJECTS) $(gem_wait_render_timeout_DEPENDENCIES) $(EXTRA_gem_wait_render_timeout_DEPENDENCIES)
+ @rm -f gem_wait_render_timeout$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_wait_render_timeout_OBJECTS) $(gem_wait_render_timeout_LDADD) $(LIBS)
+
+gem_write_read_ring_switch$(EXEEXT): $(gem_write_read_ring_switch_OBJECTS) $(gem_write_read_ring_switch_DEPENDENCIES) $(EXTRA_gem_write_read_ring_switch_DEPENDENCIES)
+ @rm -f gem_write_read_ring_switch$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gem_write_read_ring_switch_OBJECTS) $(gem_write_read_ring_switch_LDADD) $(LIBS)
+
+gen3_mixed_blits$(EXEEXT): $(gen3_mixed_blits_OBJECTS) $(gen3_mixed_blits_DEPENDENCIES) $(EXTRA_gen3_mixed_blits_DEPENDENCIES)
+ @rm -f gen3_mixed_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gen3_mixed_blits_OBJECTS) $(gen3_mixed_blits_LDADD) $(LIBS)
+
+gen3_render_linear_blits$(EXEEXT): $(gen3_render_linear_blits_OBJECTS) $(gen3_render_linear_blits_DEPENDENCIES) $(EXTRA_gen3_render_linear_blits_DEPENDENCIES)
+ @rm -f gen3_render_linear_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gen3_render_linear_blits_OBJECTS) $(gen3_render_linear_blits_LDADD) $(LIBS)
+
+gen3_render_mixed_blits$(EXEEXT): $(gen3_render_mixed_blits_OBJECTS) $(gen3_render_mixed_blits_DEPENDENCIES) $(EXTRA_gen3_render_mixed_blits_DEPENDENCIES)
+ @rm -f gen3_render_mixed_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gen3_render_mixed_blits_OBJECTS) $(gen3_render_mixed_blits_LDADD) $(LIBS)
+
+gen3_render_tiledx_blits$(EXEEXT): $(gen3_render_tiledx_blits_OBJECTS) $(gen3_render_tiledx_blits_DEPENDENCIES) $(EXTRA_gen3_render_tiledx_blits_DEPENDENCIES)
+ @rm -f gen3_render_tiledx_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gen3_render_tiledx_blits_OBJECTS) $(gen3_render_tiledx_blits_LDADD) $(LIBS)
+
+gen3_render_tiledy_blits$(EXEEXT): $(gen3_render_tiledy_blits_OBJECTS) $(gen3_render_tiledy_blits_DEPENDENCIES) $(EXTRA_gen3_render_tiledy_blits_DEPENDENCIES)
+ @rm -f gen3_render_tiledy_blits$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gen3_render_tiledy_blits_OBJECTS) $(gen3_render_tiledy_blits_LDADD) $(LIBS)
+
+gen7_forcewake_mt$(EXEEXT): $(gen7_forcewake_mt_OBJECTS) $(gen7_forcewake_mt_DEPENDENCIES) $(EXTRA_gen7_forcewake_mt_DEPENDENCIES)
+ @rm -f gen7_forcewake_mt$(EXEEXT)
+ $(AM_V_CCLD)$(gen7_forcewake_mt_LINK) $(gen7_forcewake_mt_OBJECTS) $(gen7_forcewake_mt_LDADD) $(LIBS)
+
+igt_fork_helper$(EXEEXT): $(igt_fork_helper_OBJECTS) $(igt_fork_helper_DEPENDENCIES) $(EXTRA_igt_fork_helper_DEPENDENCIES)
+ @rm -f igt_fork_helper$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(igt_fork_helper_OBJECTS) $(igt_fork_helper_LDADD) $(LIBS)
+
+igt_list_only$(EXEEXT): $(igt_list_only_OBJECTS) $(igt_list_only_DEPENDENCIES) $(EXTRA_igt_list_only_DEPENDENCIES)
+ @rm -f igt_list_only$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(igt_list_only_OBJECTS) $(igt_list_only_LDADD) $(LIBS)
+
+igt_no_exit$(EXEEXT): $(igt_no_exit_OBJECTS) $(igt_no_exit_DEPENDENCIES) $(EXTRA_igt_no_exit_DEPENDENCIES)
+ @rm -f igt_no_exit$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(igt_no_exit_OBJECTS) $(igt_no_exit_LDADD) $(LIBS)
+
+igt_no_exit_list_only$(EXEEXT): $(igt_no_exit_list_only_OBJECTS) $(igt_no_exit_list_only_DEPENDENCIES) $(EXTRA_igt_no_exit_list_only_DEPENDENCIES)
+ @rm -f igt_no_exit_list_only$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(igt_no_exit_list_only_OBJECTS) $(igt_no_exit_list_only_LDADD) $(LIBS)
+
+igt_no_subtest$(EXEEXT): $(igt_no_subtest_OBJECTS) $(igt_no_subtest_DEPENDENCIES) $(EXTRA_igt_no_subtest_DEPENDENCIES)
+ @rm -f igt_no_subtest$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(igt_no_subtest_OBJECTS) $(igt_no_subtest_LDADD) $(LIBS)
+
+igt_simulation$(EXEEXT): $(igt_simulation_OBJECTS) $(igt_simulation_DEPENDENCIES) $(EXTRA_igt_simulation_DEPENDENCIES)
+ @rm -f igt_simulation$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(igt_simulation_OBJECTS) $(igt_simulation_LDADD) $(LIBS)
+
+kms_addfb$(EXEEXT): $(kms_addfb_OBJECTS) $(kms_addfb_DEPENDENCIES) $(EXTRA_kms_addfb_DEPENDENCIES)
+ @rm -f kms_addfb$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_addfb_OBJECTS) $(kms_addfb_LDADD) $(LIBS)
+
+kms_cursor_crc$(EXEEXT): $(kms_cursor_crc_OBJECTS) $(kms_cursor_crc_DEPENDENCIES) $(EXTRA_kms_cursor_crc_DEPENDENCIES)
+ @rm -f kms_cursor_crc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_cursor_crc_OBJECTS) $(kms_cursor_crc_LDADD) $(LIBS)
+
+kms_fbc_crc$(EXEEXT): $(kms_fbc_crc_OBJECTS) $(kms_fbc_crc_DEPENDENCIES) $(EXTRA_kms_fbc_crc_DEPENDENCIES)
+ @rm -f kms_fbc_crc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_fbc_crc_OBJECTS) $(kms_fbc_crc_LDADD) $(LIBS)
+
+kms_fence_pin_leak$(EXEEXT): $(kms_fence_pin_leak_OBJECTS) $(kms_fence_pin_leak_DEPENDENCIES) $(EXTRA_kms_fence_pin_leak_DEPENDENCIES)
+ @rm -f kms_fence_pin_leak$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_fence_pin_leak_OBJECTS) $(kms_fence_pin_leak_LDADD) $(LIBS)
+
+kms_flip$(EXEEXT): $(kms_flip_OBJECTS) $(kms_flip_DEPENDENCIES) $(EXTRA_kms_flip_DEPENDENCIES)
+ @rm -f kms_flip$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_flip_OBJECTS) $(kms_flip_LDADD) $(LIBS)
+
+kms_flip_tiling$(EXEEXT): $(kms_flip_tiling_OBJECTS) $(kms_flip_tiling_DEPENDENCIES) $(EXTRA_kms_flip_tiling_DEPENDENCIES)
+ @rm -f kms_flip_tiling$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_flip_tiling_OBJECTS) $(kms_flip_tiling_LDADD) $(LIBS)
+
+kms_mmio_vs_cs_flip$(EXEEXT): $(kms_mmio_vs_cs_flip_OBJECTS) $(kms_mmio_vs_cs_flip_DEPENDENCIES) $(EXTRA_kms_mmio_vs_cs_flip_DEPENDENCIES)
+ @rm -f kms_mmio_vs_cs_flip$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_mmio_vs_cs_flip_OBJECTS) $(kms_mmio_vs_cs_flip_LDADD) $(LIBS)
+
+kms_pipe_crc_basic$(EXEEXT): $(kms_pipe_crc_basic_OBJECTS) $(kms_pipe_crc_basic_DEPENDENCIES) $(EXTRA_kms_pipe_crc_basic_DEPENDENCIES)
+ @rm -f kms_pipe_crc_basic$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_pipe_crc_basic_OBJECTS) $(kms_pipe_crc_basic_LDADD) $(LIBS)
+
+kms_plane$(EXEEXT): $(kms_plane_OBJECTS) $(kms_plane_DEPENDENCIES) $(EXTRA_kms_plane_DEPENDENCIES)
+ @rm -f kms_plane$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_plane_OBJECTS) $(kms_plane_LDADD) $(LIBS)
+
+kms_render$(EXEEXT): $(kms_render_OBJECTS) $(kms_render_DEPENDENCIES) $(EXTRA_kms_render_DEPENDENCIES)
+ @rm -f kms_render$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_render_OBJECTS) $(kms_render_LDADD) $(LIBS)
+
+kms_setmode$(EXEEXT): $(kms_setmode_OBJECTS) $(kms_setmode_DEPENDENCIES) $(EXTRA_kms_setmode_DEPENDENCIES)
+ @rm -f kms_setmode$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_setmode_OBJECTS) $(kms_setmode_LDADD) $(LIBS)
+
+kms_sink_crc_basic$(EXEEXT): $(kms_sink_crc_basic_OBJECTS) $(kms_sink_crc_basic_DEPENDENCIES) $(EXTRA_kms_sink_crc_basic_DEPENDENCIES)
+ @rm -f kms_sink_crc_basic$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(kms_sink_crc_basic_OBJECTS) $(kms_sink_crc_basic_LDADD) $(LIBS)
+
+pm_lpsp$(EXEEXT): $(pm_lpsp_OBJECTS) $(pm_lpsp_DEPENDENCIES) $(EXTRA_pm_lpsp_DEPENDENCIES)
+ @rm -f pm_lpsp$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pm_lpsp_OBJECTS) $(pm_lpsp_LDADD) $(LIBS)
+
+pm_psr$(EXEEXT): $(pm_psr_OBJECTS) $(pm_psr_DEPENDENCIES) $(EXTRA_pm_psr_DEPENDENCIES)
+ @rm -f pm_psr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pm_psr_OBJECTS) $(pm_psr_LDADD) $(LIBS)
+
+pm_rc6_residency$(EXEEXT): $(pm_rc6_residency_OBJECTS) $(pm_rc6_residency_DEPENDENCIES) $(EXTRA_pm_rc6_residency_DEPENDENCIES)
+ @rm -f pm_rc6_residency$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pm_rc6_residency_OBJECTS) $(pm_rc6_residency_LDADD) $(LIBS)
+
+pm_rpm$(EXEEXT): $(pm_rpm_OBJECTS) $(pm_rpm_DEPENDENCIES) $(EXTRA_pm_rpm_DEPENDENCIES)
+ @rm -f pm_rpm$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pm_rpm_OBJECTS) $(pm_rpm_LDADD) $(LIBS)
+
+pm_rps$(EXEEXT): $(pm_rps_OBJECTS) $(pm_rps_DEPENDENCIES) $(EXTRA_pm_rps_DEPENDENCIES)
+ @rm -f pm_rps$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pm_rps_OBJECTS) $(pm_rps_LDADD) $(LIBS)
+
+prime_nv_api$(EXEEXT): $(prime_nv_api_OBJECTS) $(prime_nv_api_DEPENDENCIES) $(EXTRA_prime_nv_api_DEPENDENCIES)
+ @rm -f prime_nv_api$(EXEEXT)
+ $(AM_V_CCLD)$(prime_nv_api_LINK) $(prime_nv_api_OBJECTS) $(prime_nv_api_LDADD) $(LIBS)
+
+prime_nv_pcopy$(EXEEXT): $(prime_nv_pcopy_OBJECTS) $(prime_nv_pcopy_DEPENDENCIES) $(EXTRA_prime_nv_pcopy_DEPENDENCIES)
+ @rm -f prime_nv_pcopy$(EXEEXT)
+ $(AM_V_CCLD)$(prime_nv_pcopy_LINK) $(prime_nv_pcopy_OBJECTS) $(prime_nv_pcopy_LDADD) $(LIBS)
+
+prime_nv_test$(EXEEXT): $(prime_nv_test_OBJECTS) $(prime_nv_test_DEPENDENCIES) $(EXTRA_prime_nv_test_DEPENDENCIES)
+ @rm -f prime_nv_test$(EXEEXT)
+ $(AM_V_CCLD)$(prime_nv_test_LINK) $(prime_nv_test_OBJECTS) $(prime_nv_test_LDADD) $(LIBS)
+
+prime_self_import$(EXEEXT): $(prime_self_import_OBJECTS) $(prime_self_import_DEPENDENCIES) $(EXTRA_prime_self_import_DEPENDENCIES)
+ @rm -f prime_self_import$(EXEEXT)
+ $(AM_V_CCLD)$(prime_self_import_LINK) $(prime_self_import_OBJECTS) $(prime_self_import_LDADD) $(LIBS)
+
+prime_udl$(EXEEXT): $(prime_udl_OBJECTS) $(prime_udl_DEPENDENCIES) $(EXTRA_prime_udl_DEPENDENCIES)
+ @rm -f prime_udl$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(prime_udl_OBJECTS) $(prime_udl_LDADD) $(LIBS)
+
+template$(EXEEXT): $(template_OBJECTS) $(template_DEPENDENCIES) $(EXTRA_template_DEPENDENCIES)
+ @rm -f template$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(template_OBJECTS) $(template_LDADD) $(LIBS)
+
+testdisplay$(EXEEXT): $(testdisplay_OBJECTS) $(testdisplay_DEPENDENCIES) $(EXTRA_testdisplay_DEPENDENCIES)
+ @rm -f testdisplay$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testdisplay_OBJECTS) $(testdisplay_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_get_client_auth.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_getclient.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_getstats.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_getversion.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ddi_compute_wrpll.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drm_vma_limiter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drm_vma_limiter_cached.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drm_vma_limiter_cpu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drm_vma_limiter_gtt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_hangman.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_suspend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_alive.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_bad_address.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_bad_batch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_bad_blit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_bad_length.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_bad_reloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_basic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_caching.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_close_race-gem_close_race.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_concurrent_blit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_cpu_reloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_cs_prefetch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_cs_tlb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_ctx_bad_destroy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_ctx_bad_exec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_ctx_basic-gem_ctx_basic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_ctx_create.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_ctx_exec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_double_irq_loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_dummy_reloc_loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_evict_alignment.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_evict_everything.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_exec_bad_domains.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_exec_big.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_exec_blt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_exec_faulting_reloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_exec_lut_handle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_exec_nop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_exec_params.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_exec_parse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_fd_exhaustion.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_fence_thrash-gem_fence_thrash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_fenced_exec_thrash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_flink.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_flink_race-gem_flink_race.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_gtt_cpu_tlb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_gtt_hog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_gtt_speed.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_hang.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_hangcheck_forcewake.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_largeobject.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_linear_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_lut_handle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_madvise.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_media_fill.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_mmap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_mmap_gtt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_mmap_offset_exhaustion.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_multi_bsd_sync_loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_non_secure_batch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_partial_pwrite_pread.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_persistent_relocs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_pin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_pipe_control_store_loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_pread.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_pread_after_blit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_pwrite.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_pwrite_pread.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_readwrite.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_reg_read.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_reloc_overflow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_reloc_vs_gpu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_render_copy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_render_copy_redux.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_render_linear_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_render_tiled_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_reset_stats.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_ring_sync_copy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_ring_sync_loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_ringfill.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_seqno_wrap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_set_tiling_vs_blt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_set_tiling_vs_gtt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_set_tiling_vs_pwrite.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_storedw_batches_loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_storedw_loop_blt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_storedw_loop_bsd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_storedw_loop_render.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_storedw_loop_vebox.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_stress.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_threaded_access_tiled-gem_threaded_access_tiled.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_tiled_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_tiled_fence_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_tiled_partial_pwrite_pread.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_tiled_pread.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_tiled_pread_pwrite.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_tiled_swapping-gem_tiled_swapping.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_tiling_max_stride.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_unfence_active_buffers.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_unref_active_buffers.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_userptr_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_wait_render_timeout.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gem_write_read_ring_switch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen3_mixed_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen3_render_linear_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen3_render_mixed_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen3_render_tiledx_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen3_render_tiledy_blits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen7_forcewake_mt-gen7_forcewake_mt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igt_fork_helper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igt_list_only.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igt_no_exit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igt_no_exit_list_only.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igt_no_subtest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igt_simulation.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_addfb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_cursor_crc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_fbc_crc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_fence_pin_leak.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_flip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_flip_tiling.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_mmio_vs_cs_flip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_pipe_crc_basic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_plane.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_render.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_setmode.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kms_sink_crc_basic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pm_lpsp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pm_psr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pm_rc6_residency.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pm_rpm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pm_rps.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime_nv_api-prime_nv_api.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime_nv_pcopy-prime_nv_pcopy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime_nv_test-prime_nv_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime_self_import-prime_self_import.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime_udl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/template.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testdisplay.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testdisplay_hotplug.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+gem_close_race-gem_close_race.o: gem_close_race.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_close_race_CFLAGS) $(CFLAGS) -MT gem_close_race-gem_close_race.o -MD -MP -MF $(DEPDIR)/gem_close_race-gem_close_race.Tpo -c -o gem_close_race-gem_close_race.o `test -f 'gem_close_race.c' || echo '$(srcdir)/'`gem_close_race.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_close_race-gem_close_race.Tpo $(DEPDIR)/gem_close_race-gem_close_race.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_close_race.c' object='gem_close_race-gem_close_race.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_close_race_CFLAGS) $(CFLAGS) -c -o gem_close_race-gem_close_race.o `test -f 'gem_close_race.c' || echo '$(srcdir)/'`gem_close_race.c
+
+gem_close_race-gem_close_race.obj: gem_close_race.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_close_race_CFLAGS) $(CFLAGS) -MT gem_close_race-gem_close_race.obj -MD -MP -MF $(DEPDIR)/gem_close_race-gem_close_race.Tpo -c -o gem_close_race-gem_close_race.obj `if test -f 'gem_close_race.c'; then $(CYGPATH_W) 'gem_close_race.c'; else $(CYGPATH_W) '$(srcdir)/gem_close_race.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_close_race-gem_close_race.Tpo $(DEPDIR)/gem_close_race-gem_close_race.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_close_race.c' object='gem_close_race-gem_close_race.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_close_race_CFLAGS) $(CFLAGS) -c -o gem_close_race-gem_close_race.obj `if test -f 'gem_close_race.c'; then $(CYGPATH_W) 'gem_close_race.c'; else $(CYGPATH_W) '$(srcdir)/gem_close_race.c'; fi`
+
+gem_ctx_basic-gem_ctx_basic.o: gem_ctx_basic.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_ctx_basic_CFLAGS) $(CFLAGS) -MT gem_ctx_basic-gem_ctx_basic.o -MD -MP -MF $(DEPDIR)/gem_ctx_basic-gem_ctx_basic.Tpo -c -o gem_ctx_basic-gem_ctx_basic.o `test -f 'gem_ctx_basic.c' || echo '$(srcdir)/'`gem_ctx_basic.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_ctx_basic-gem_ctx_basic.Tpo $(DEPDIR)/gem_ctx_basic-gem_ctx_basic.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_ctx_basic.c' object='gem_ctx_basic-gem_ctx_basic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_ctx_basic_CFLAGS) $(CFLAGS) -c -o gem_ctx_basic-gem_ctx_basic.o `test -f 'gem_ctx_basic.c' || echo '$(srcdir)/'`gem_ctx_basic.c
+
+gem_ctx_basic-gem_ctx_basic.obj: gem_ctx_basic.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_ctx_basic_CFLAGS) $(CFLAGS) -MT gem_ctx_basic-gem_ctx_basic.obj -MD -MP -MF $(DEPDIR)/gem_ctx_basic-gem_ctx_basic.Tpo -c -o gem_ctx_basic-gem_ctx_basic.obj `if test -f 'gem_ctx_basic.c'; then $(CYGPATH_W) 'gem_ctx_basic.c'; else $(CYGPATH_W) '$(srcdir)/gem_ctx_basic.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_ctx_basic-gem_ctx_basic.Tpo $(DEPDIR)/gem_ctx_basic-gem_ctx_basic.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_ctx_basic.c' object='gem_ctx_basic-gem_ctx_basic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_ctx_basic_CFLAGS) $(CFLAGS) -c -o gem_ctx_basic-gem_ctx_basic.obj `if test -f 'gem_ctx_basic.c'; then $(CYGPATH_W) 'gem_ctx_basic.c'; else $(CYGPATH_W) '$(srcdir)/gem_ctx_basic.c'; fi`
+
+gem_fence_thrash-gem_fence_thrash.o: gem_fence_thrash.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_fence_thrash_CFLAGS) $(CFLAGS) -MT gem_fence_thrash-gem_fence_thrash.o -MD -MP -MF $(DEPDIR)/gem_fence_thrash-gem_fence_thrash.Tpo -c -o gem_fence_thrash-gem_fence_thrash.o `test -f 'gem_fence_thrash.c' || echo '$(srcdir)/'`gem_fence_thrash.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_fence_thrash-gem_fence_thrash.Tpo $(DEPDIR)/gem_fence_thrash-gem_fence_thrash.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_fence_thrash.c' object='gem_fence_thrash-gem_fence_thrash.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_fence_thrash_CFLAGS) $(CFLAGS) -c -o gem_fence_thrash-gem_fence_thrash.o `test -f 'gem_fence_thrash.c' || echo '$(srcdir)/'`gem_fence_thrash.c
+
+gem_fence_thrash-gem_fence_thrash.obj: gem_fence_thrash.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_fence_thrash_CFLAGS) $(CFLAGS) -MT gem_fence_thrash-gem_fence_thrash.obj -MD -MP -MF $(DEPDIR)/gem_fence_thrash-gem_fence_thrash.Tpo -c -o gem_fence_thrash-gem_fence_thrash.obj `if test -f 'gem_fence_thrash.c'; then $(CYGPATH_W) 'gem_fence_thrash.c'; else $(CYGPATH_W) '$(srcdir)/gem_fence_thrash.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_fence_thrash-gem_fence_thrash.Tpo $(DEPDIR)/gem_fence_thrash-gem_fence_thrash.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_fence_thrash.c' object='gem_fence_thrash-gem_fence_thrash.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_fence_thrash_CFLAGS) $(CFLAGS) -c -o gem_fence_thrash-gem_fence_thrash.obj `if test -f 'gem_fence_thrash.c'; then $(CYGPATH_W) 'gem_fence_thrash.c'; else $(CYGPATH_W) '$(srcdir)/gem_fence_thrash.c'; fi`
+
+gem_flink_race-gem_flink_race.o: gem_flink_race.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_flink_race_CFLAGS) $(CFLAGS) -MT gem_flink_race-gem_flink_race.o -MD -MP -MF $(DEPDIR)/gem_flink_race-gem_flink_race.Tpo -c -o gem_flink_race-gem_flink_race.o `test -f 'gem_flink_race.c' || echo '$(srcdir)/'`gem_flink_race.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_flink_race-gem_flink_race.Tpo $(DEPDIR)/gem_flink_race-gem_flink_race.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_flink_race.c' object='gem_flink_race-gem_flink_race.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_flink_race_CFLAGS) $(CFLAGS) -c -o gem_flink_race-gem_flink_race.o `test -f 'gem_flink_race.c' || echo '$(srcdir)/'`gem_flink_race.c
+
+gem_flink_race-gem_flink_race.obj: gem_flink_race.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_flink_race_CFLAGS) $(CFLAGS) -MT gem_flink_race-gem_flink_race.obj -MD -MP -MF $(DEPDIR)/gem_flink_race-gem_flink_race.Tpo -c -o gem_flink_race-gem_flink_race.obj `if test -f 'gem_flink_race.c'; then $(CYGPATH_W) 'gem_flink_race.c'; else $(CYGPATH_W) '$(srcdir)/gem_flink_race.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_flink_race-gem_flink_race.Tpo $(DEPDIR)/gem_flink_race-gem_flink_race.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_flink_race.c' object='gem_flink_race-gem_flink_race.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_flink_race_CFLAGS) $(CFLAGS) -c -o gem_flink_race-gem_flink_race.obj `if test -f 'gem_flink_race.c'; then $(CYGPATH_W) 'gem_flink_race.c'; else $(CYGPATH_W) '$(srcdir)/gem_flink_race.c'; fi`
+
+gem_threaded_access_tiled-gem_threaded_access_tiled.o: gem_threaded_access_tiled.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_threaded_access_tiled_CFLAGS) $(CFLAGS) -MT gem_threaded_access_tiled-gem_threaded_access_tiled.o -MD -MP -MF $(DEPDIR)/gem_threaded_access_tiled-gem_threaded_access_tiled.Tpo -c -o gem_threaded_access_tiled-gem_threaded_access_tiled.o `test -f 'gem_threaded_access_tiled.c' || echo '$(srcdir)/'`gem_threaded_access_tiled.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_threaded_access_tiled-gem_threaded_access_tiled.Tpo $(DEPDIR)/gem_threaded_access_tiled-gem_threaded_access_tiled.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_threaded_access_tiled.c' object='gem_threaded_access_tiled-gem_threaded_access_tiled.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_threaded_access_tiled_CFLAGS) $(CFLAGS) -c -o gem_threaded_access_tiled-gem_threaded_access_tiled.o `test -f 'gem_threaded_access_tiled.c' || echo '$(srcdir)/'`gem_threaded_access_tiled.c
+
+gem_threaded_access_tiled-gem_threaded_access_tiled.obj: gem_threaded_access_tiled.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_threaded_access_tiled_CFLAGS) $(CFLAGS) -MT gem_threaded_access_tiled-gem_threaded_access_tiled.obj -MD -MP -MF $(DEPDIR)/gem_threaded_access_tiled-gem_threaded_access_tiled.Tpo -c -o gem_threaded_access_tiled-gem_threaded_access_tiled.obj `if test -f 'gem_threaded_access_tiled.c'; then $(CYGPATH_W) 'gem_threaded_access_tiled.c'; else $(CYGPATH_W) '$(srcdir)/gem_threaded_access_tiled.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_threaded_access_tiled-gem_threaded_access_tiled.Tpo $(DEPDIR)/gem_threaded_access_tiled-gem_threaded_access_tiled.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_threaded_access_tiled.c' object='gem_threaded_access_tiled-gem_threaded_access_tiled.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_threaded_access_tiled_CFLAGS) $(CFLAGS) -c -o gem_threaded_access_tiled-gem_threaded_access_tiled.obj `if test -f 'gem_threaded_access_tiled.c'; then $(CYGPATH_W) 'gem_threaded_access_tiled.c'; else $(CYGPATH_W) '$(srcdir)/gem_threaded_access_tiled.c'; fi`
+
+gem_tiled_swapping-gem_tiled_swapping.o: gem_tiled_swapping.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_tiled_swapping_CFLAGS) $(CFLAGS) -MT gem_tiled_swapping-gem_tiled_swapping.o -MD -MP -MF $(DEPDIR)/gem_tiled_swapping-gem_tiled_swapping.Tpo -c -o gem_tiled_swapping-gem_tiled_swapping.o `test -f 'gem_tiled_swapping.c' || echo '$(srcdir)/'`gem_tiled_swapping.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_tiled_swapping-gem_tiled_swapping.Tpo $(DEPDIR)/gem_tiled_swapping-gem_tiled_swapping.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_tiled_swapping.c' object='gem_tiled_swapping-gem_tiled_swapping.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_tiled_swapping_CFLAGS) $(CFLAGS) -c -o gem_tiled_swapping-gem_tiled_swapping.o `test -f 'gem_tiled_swapping.c' || echo '$(srcdir)/'`gem_tiled_swapping.c
+
+gem_tiled_swapping-gem_tiled_swapping.obj: gem_tiled_swapping.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_tiled_swapping_CFLAGS) $(CFLAGS) -MT gem_tiled_swapping-gem_tiled_swapping.obj -MD -MP -MF $(DEPDIR)/gem_tiled_swapping-gem_tiled_swapping.Tpo -c -o gem_tiled_swapping-gem_tiled_swapping.obj `if test -f 'gem_tiled_swapping.c'; then $(CYGPATH_W) 'gem_tiled_swapping.c'; else $(CYGPATH_W) '$(srcdir)/gem_tiled_swapping.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gem_tiled_swapping-gem_tiled_swapping.Tpo $(DEPDIR)/gem_tiled_swapping-gem_tiled_swapping.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem_tiled_swapping.c' object='gem_tiled_swapping-gem_tiled_swapping.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gem_tiled_swapping_CFLAGS) $(CFLAGS) -c -o gem_tiled_swapping-gem_tiled_swapping.obj `if test -f 'gem_tiled_swapping.c'; then $(CYGPATH_W) 'gem_tiled_swapping.c'; else $(CYGPATH_W) '$(srcdir)/gem_tiled_swapping.c'; fi`
+
+gen7_forcewake_mt-gen7_forcewake_mt.o: gen7_forcewake_mt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gen7_forcewake_mt_CFLAGS) $(CFLAGS) -MT gen7_forcewake_mt-gen7_forcewake_mt.o -MD -MP -MF $(DEPDIR)/gen7_forcewake_mt-gen7_forcewake_mt.Tpo -c -o gen7_forcewake_mt-gen7_forcewake_mt.o `test -f 'gen7_forcewake_mt.c' || echo '$(srcdir)/'`gen7_forcewake_mt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gen7_forcewake_mt-gen7_forcewake_mt.Tpo $(DEPDIR)/gen7_forcewake_mt-gen7_forcewake_mt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen7_forcewake_mt.c' object='gen7_forcewake_mt-gen7_forcewake_mt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gen7_forcewake_mt_CFLAGS) $(CFLAGS) -c -o gen7_forcewake_mt-gen7_forcewake_mt.o `test -f 'gen7_forcewake_mt.c' || echo '$(srcdir)/'`gen7_forcewake_mt.c
+
+gen7_forcewake_mt-gen7_forcewake_mt.obj: gen7_forcewake_mt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gen7_forcewake_mt_CFLAGS) $(CFLAGS) -MT gen7_forcewake_mt-gen7_forcewake_mt.obj -MD -MP -MF $(DEPDIR)/gen7_forcewake_mt-gen7_forcewake_mt.Tpo -c -o gen7_forcewake_mt-gen7_forcewake_mt.obj `if test -f 'gen7_forcewake_mt.c'; then $(CYGPATH_W) 'gen7_forcewake_mt.c'; else $(CYGPATH_W) '$(srcdir)/gen7_forcewake_mt.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gen7_forcewake_mt-gen7_forcewake_mt.Tpo $(DEPDIR)/gen7_forcewake_mt-gen7_forcewake_mt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen7_forcewake_mt.c' object='gen7_forcewake_mt-gen7_forcewake_mt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gen7_forcewake_mt_CFLAGS) $(CFLAGS) -c -o gen7_forcewake_mt-gen7_forcewake_mt.obj `if test -f 'gen7_forcewake_mt.c'; then $(CYGPATH_W) 'gen7_forcewake_mt.c'; else $(CYGPATH_W) '$(srcdir)/gen7_forcewake_mt.c'; fi`
+
+prime_nv_api-prime_nv_api.o: prime_nv_api.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_api_CFLAGS) $(CFLAGS) -MT prime_nv_api-prime_nv_api.o -MD -MP -MF $(DEPDIR)/prime_nv_api-prime_nv_api.Tpo -c -o prime_nv_api-prime_nv_api.o `test -f 'prime_nv_api.c' || echo '$(srcdir)/'`prime_nv_api.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prime_nv_api-prime_nv_api.Tpo $(DEPDIR)/prime_nv_api-prime_nv_api.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prime_nv_api.c' object='prime_nv_api-prime_nv_api.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_api_CFLAGS) $(CFLAGS) -c -o prime_nv_api-prime_nv_api.o `test -f 'prime_nv_api.c' || echo '$(srcdir)/'`prime_nv_api.c
+
+prime_nv_api-prime_nv_api.obj: prime_nv_api.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_api_CFLAGS) $(CFLAGS) -MT prime_nv_api-prime_nv_api.obj -MD -MP -MF $(DEPDIR)/prime_nv_api-prime_nv_api.Tpo -c -o prime_nv_api-prime_nv_api.obj `if test -f 'prime_nv_api.c'; then $(CYGPATH_W) 'prime_nv_api.c'; else $(CYGPATH_W) '$(srcdir)/prime_nv_api.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prime_nv_api-prime_nv_api.Tpo $(DEPDIR)/prime_nv_api-prime_nv_api.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prime_nv_api.c' object='prime_nv_api-prime_nv_api.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_api_CFLAGS) $(CFLAGS) -c -o prime_nv_api-prime_nv_api.obj `if test -f 'prime_nv_api.c'; then $(CYGPATH_W) 'prime_nv_api.c'; else $(CYGPATH_W) '$(srcdir)/prime_nv_api.c'; fi`
+
+prime_nv_pcopy-prime_nv_pcopy.o: prime_nv_pcopy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_pcopy_CFLAGS) $(CFLAGS) -MT prime_nv_pcopy-prime_nv_pcopy.o -MD -MP -MF $(DEPDIR)/prime_nv_pcopy-prime_nv_pcopy.Tpo -c -o prime_nv_pcopy-prime_nv_pcopy.o `test -f 'prime_nv_pcopy.c' || echo '$(srcdir)/'`prime_nv_pcopy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prime_nv_pcopy-prime_nv_pcopy.Tpo $(DEPDIR)/prime_nv_pcopy-prime_nv_pcopy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prime_nv_pcopy.c' object='prime_nv_pcopy-prime_nv_pcopy.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_pcopy_CFLAGS) $(CFLAGS) -c -o prime_nv_pcopy-prime_nv_pcopy.o `test -f 'prime_nv_pcopy.c' || echo '$(srcdir)/'`prime_nv_pcopy.c
+
+prime_nv_pcopy-prime_nv_pcopy.obj: prime_nv_pcopy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_pcopy_CFLAGS) $(CFLAGS) -MT prime_nv_pcopy-prime_nv_pcopy.obj -MD -MP -MF $(DEPDIR)/prime_nv_pcopy-prime_nv_pcopy.Tpo -c -o prime_nv_pcopy-prime_nv_pcopy.obj `if test -f 'prime_nv_pcopy.c'; then $(CYGPATH_W) 'prime_nv_pcopy.c'; else $(CYGPATH_W) '$(srcdir)/prime_nv_pcopy.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prime_nv_pcopy-prime_nv_pcopy.Tpo $(DEPDIR)/prime_nv_pcopy-prime_nv_pcopy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prime_nv_pcopy.c' object='prime_nv_pcopy-prime_nv_pcopy.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_pcopy_CFLAGS) $(CFLAGS) -c -o prime_nv_pcopy-prime_nv_pcopy.obj `if test -f 'prime_nv_pcopy.c'; then $(CYGPATH_W) 'prime_nv_pcopy.c'; else $(CYGPATH_W) '$(srcdir)/prime_nv_pcopy.c'; fi`
+
+prime_nv_test-prime_nv_test.o: prime_nv_test.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_test_CFLAGS) $(CFLAGS) -MT prime_nv_test-prime_nv_test.o -MD -MP -MF $(DEPDIR)/prime_nv_test-prime_nv_test.Tpo -c -o prime_nv_test-prime_nv_test.o `test -f 'prime_nv_test.c' || echo '$(srcdir)/'`prime_nv_test.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prime_nv_test-prime_nv_test.Tpo $(DEPDIR)/prime_nv_test-prime_nv_test.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prime_nv_test.c' object='prime_nv_test-prime_nv_test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_test_CFLAGS) $(CFLAGS) -c -o prime_nv_test-prime_nv_test.o `test -f 'prime_nv_test.c' || echo '$(srcdir)/'`prime_nv_test.c
+
+prime_nv_test-prime_nv_test.obj: prime_nv_test.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_test_CFLAGS) $(CFLAGS) -MT prime_nv_test-prime_nv_test.obj -MD -MP -MF $(DEPDIR)/prime_nv_test-prime_nv_test.Tpo -c -o prime_nv_test-prime_nv_test.obj `if test -f 'prime_nv_test.c'; then $(CYGPATH_W) 'prime_nv_test.c'; else $(CYGPATH_W) '$(srcdir)/prime_nv_test.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prime_nv_test-prime_nv_test.Tpo $(DEPDIR)/prime_nv_test-prime_nv_test.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prime_nv_test.c' object='prime_nv_test-prime_nv_test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_nv_test_CFLAGS) $(CFLAGS) -c -o prime_nv_test-prime_nv_test.obj `if test -f 'prime_nv_test.c'; then $(CYGPATH_W) 'prime_nv_test.c'; else $(CYGPATH_W) '$(srcdir)/prime_nv_test.c'; fi`
+
+prime_self_import-prime_self_import.o: prime_self_import.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_self_import_CFLAGS) $(CFLAGS) -MT prime_self_import-prime_self_import.o -MD -MP -MF $(DEPDIR)/prime_self_import-prime_self_import.Tpo -c -o prime_self_import-prime_self_import.o `test -f 'prime_self_import.c' || echo '$(srcdir)/'`prime_self_import.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prime_self_import-prime_self_import.Tpo $(DEPDIR)/prime_self_import-prime_self_import.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prime_self_import.c' object='prime_self_import-prime_self_import.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_self_import_CFLAGS) $(CFLAGS) -c -o prime_self_import-prime_self_import.o `test -f 'prime_self_import.c' || echo '$(srcdir)/'`prime_self_import.c
+
+prime_self_import-prime_self_import.obj: prime_self_import.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_self_import_CFLAGS) $(CFLAGS) -MT prime_self_import-prime_self_import.obj -MD -MP -MF $(DEPDIR)/prime_self_import-prime_self_import.Tpo -c -o prime_self_import-prime_self_import.obj `if test -f 'prime_self_import.c'; then $(CYGPATH_W) 'prime_self_import.c'; else $(CYGPATH_W) '$(srcdir)/prime_self_import.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prime_self_import-prime_self_import.Tpo $(DEPDIR)/prime_self_import-prime_self_import.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prime_self_import.c' object='prime_self_import-prime_self_import.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(prime_self_import_CFLAGS) $(CFLAGS) -c -o prime_self_import-prime_self_import.obj `if test -f 'prime_self_import.c'; then $(CYGPATH_W) 'prime_self_import.c'; else $(CYGPATH_W) '$(srcdir)/prime_self_import.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ else \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+igt_no_exit.log: igt_no_exit$(EXEEXT)
+ @p='igt_no_exit$(EXEEXT)'; \
+ b='igt_no_exit'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+igt_no_exit_list_only.log: igt_no_exit_list_only$(EXEEXT)
+ @p='igt_no_exit_list_only$(EXEEXT)'; \
+ b='igt_no_exit_list_only'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+igt_fork_helper.log: igt_fork_helper$(EXEEXT)
+ @p='igt_fork_helper$(EXEEXT)'; \
+ b='igt_fork_helper'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+igt_list_only.log: igt_list_only$(EXEEXT)
+ @p='igt_list_only$(EXEEXT)'; \
+ b='igt_list_only'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+igt_no_subtest.log: igt_no_subtest$(EXEEXT)
+ @p='igt_no_subtest$(EXEEXT)'; \
+ b='igt_no_subtest'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+igt_simulation.log: igt_simulation$(EXEEXT)
+ @p='igt_simulation$(EXEEXT)'; \
+ b='igt_simulation'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+@BUILD_TESTS_FALSE@all-local:
+all-am: Makefile $(PROGRAMS) all-local
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am all-local check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am
+
+
+@BUILD_TESTS_TRUE@all-local: single-tests.txt multi-tests.txt
+
+@BUILD_TESTS_TRUE@list-single-tests:
+@BUILD_TESTS_TRUE@ @echo TESTLIST
+@BUILD_TESTS_TRUE@ @echo ${single_kernel_tests}
+@BUILD_TESTS_TRUE@ @echo END TESTLIST
+
+@BUILD_TESTS_TRUE@list-multi-tests:
+@BUILD_TESTS_TRUE@ @echo TESTLIST
+@BUILD_TESTS_TRUE@ @echo ${multi_kernel_tests}
+@BUILD_TESTS_TRUE@ @echo END TESTLIST
+
+@BUILD_TESTS_TRUE@single-tests.txt: Makefile.sources
+@BUILD_TESTS_TRUE@ @echo TESTLIST > $@
+@BUILD_TESTS_TRUE@ @echo ${single_kernel_tests} >> $@
+@BUILD_TESTS_TRUE@ @echo END TESTLIST >> $@
+
+@BUILD_TESTS_TRUE@multi-tests.txt: Makefile.sources
+@BUILD_TESTS_TRUE@ @echo TESTLIST > $@
+@BUILD_TESTS_TRUE@ @echo ${multi_kernel_tests} >> $@
+@BUILD_TESTS_TRUE@ @echo END TESTLIST >> $@
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
new file mode 100644
index 00000000..e4c23b3f
--- /dev/null
+++ b/tests/Makefile.sources
@@ -0,0 +1,237 @@
+noinst_PROGRAMS = \
+ gem_alive \
+ gem_stress \
+ ddi_compute_wrpll \
+ $(TESTS_progs) \
+ $(TESTS_progs_M) \
+ $(HANG) \
+ $(TESTS_testsuite) \
+ $(NULL)
+
+NOUVEAU_TESTS_M = \
+ prime_nv_api \
+ prime_nv_pcopy \
+ prime_nv_test \
+ $(NULL)
+
+TESTS_progs_M = \
+ core_get_client_auth \
+ drv_suspend \
+ drv_hangman \
+ gem_bad_reloc \
+ gem_basic \
+ gem_caching \
+ gem_close_race \
+ gem_concurrent_blit \
+ gem_cs_tlb \
+ gem_ctx_bad_exec \
+ gem_ctx_exec \
+ gem_dummy_reloc_loop \
+ gem_evict_alignment \
+ gem_evict_everything \
+ gem_exec_bad_domains \
+ gem_exec_faulting_reloc \
+ gem_exec_nop \
+ gem_exec_params \
+ gem_exec_parse \
+ gem_fenced_exec_thrash \
+ gem_fence_thrash \
+ gem_flink \
+ gem_flink_race \
+ gem_linear_blits \
+ gem_madvise \
+ gem_mmap \
+ gem_mmap_gtt \
+ gem_partial_pwrite_pread \
+ gem_persistent_relocs \
+ gem_pipe_control_store_loop \
+ gem_pread \
+ gem_pread_after_blit \
+ gem_pwrite \
+ gem_pwrite_pread \
+ gem_readwrite \
+ gem_reloc_overflow \
+ gem_reloc_vs_gpu \
+ gem_reset_stats \
+ gem_ringfill \
+ gem_set_tiling_vs_blt \
+ gem_storedw_batches_loop \
+ gem_tiled_blits \
+ gem_tiled_partial_pwrite_pread \
+ gem_write_read_ring_switch \
+ kms_addfb \
+ kms_cursor_crc \
+ kms_fbc_crc \
+ kms_flip \
+ kms_flip_tiling \
+ kms_mmio_vs_cs_flip \
+ kms_pipe_crc_basic \
+ kms_plane \
+ kms_render \
+ kms_setmode \
+ pm_lpsp \
+ pm_rpm \
+ pm_rps \
+ prime_self_import \
+ template \
+ $(NULL)
+
+TESTS_progs = \
+ core_getclient \
+ core_getstats \
+ core_getversion \
+ drm_vma_limiter \
+ drm_vma_limiter_cached \
+ drm_vma_limiter_cpu \
+ drm_vma_limiter_gtt \
+ gem_bad_length \
+ gem_cpu_reloc \
+ gem_cs_prefetch \
+ gem_ctx_bad_destroy \
+ gem_ctx_basic \
+ gem_ctx_create \
+ gem_double_irq_loop \
+ gem_exec_big \
+ gem_exec_blt \
+ gem_exec_lut_handle \
+ gem_fd_exhaustion \
+ gem_gtt_cpu_tlb \
+ gem_gtt_hog \
+ gem_gtt_speed \
+ gem_hangcheck_forcewake \
+ gem_largeobject \
+ gem_lut_handle \
+ gem_mmap_offset_exhaustion \
+ gem_media_fill \
+ gem_pin \
+ gem_reg_read \
+ gem_render_copy \
+ gem_render_copy_redux \
+ gem_render_linear_blits \
+ gem_render_tiled_blits \
+ gem_ring_sync_copy \
+ gem_ring_sync_loop \
+ gem_multi_bsd_sync_loop \
+ gem_seqno_wrap \
+ gem_set_tiling_vs_gtt \
+ gem_set_tiling_vs_pwrite \
+ gem_storedw_loop_blt \
+ gem_storedw_loop_bsd \
+ gem_storedw_loop_render \
+ gem_storedw_loop_vebox \
+ gem_threaded_access_tiled \
+ gem_tiled_fence_blits \
+ gem_tiled_pread \
+ gem_tiled_pread_pwrite \
+ gem_tiled_swapping \
+ gem_tiling_max_stride \
+ gem_unfence_active_buffers \
+ gem_unref_active_buffers \
+ gem_userptr_blits \
+ gem_wait_render_timeout \
+ gen3_mixed_blits \
+ gen3_render_linear_blits \
+ gen3_render_mixed_blits \
+ gen3_render_tiledx_blits \
+ gen3_render_tiledy_blits \
+ gen7_forcewake_mt \
+ kms_sink_crc_basic \
+ kms_fence_pin_leak \
+ pm_psr \
+ pm_rc6_residency \
+ prime_udl \
+ $(NULL)
+
+# IMPORTANT: The ZZ_ tests need to be run last!
+# ... and make can't deal with inlined comments ...
+TESTS_scripts_M = \
+ $(NULL)
+
+TESTS_scripts = \
+ debugfs_emon_crash \
+ drv_debugfs_reader \
+ drv_missed_irq_hang \
+ drv_module_reload \
+ kms_sysfs_edid_timing \
+ sysfs_l3_parity \
+ test_rte_check \
+ tools_test \
+ $(NULL)
+
+# This target contains testcases which support automagic subtest enumeration
+# from the piglit testrunner with --list-subtests and running individual
+# subtests with --run-subtest <testname>
+#
+# Your testcase should probably use an igt_main and igt_fixture and should have
+# a pile of igt_subtest blocks.
+multi_kernel_tests = \
+ $(TESTS_progs_M) \
+ $(TESTS_scripts_M) \
+ $(NULL)
+
+# This target is for simple testcase which don't expose any subtest.
+#
+# Your testcase should probably use igt_simple_main, but none of the other magic
+# blocks like igt_fixture or igt_subtest.
+single_kernel_tests = \
+ $(TESTS_progs) \
+ $(TESTS_scripts) \
+ $(NULL)
+
+kernel_tests = \
+ $(single_kernel_tests) \
+ $(multi_kernel_tests) \
+ $(NULL)
+
+TESTS_testsuite = \
+ igt_no_exit \
+ igt_no_exit_list_only \
+ igt_fork_helper \
+ igt_list_only \
+ igt_no_subtest \
+ igt_simulation \
+ $(NULL)
+
+TESTS = \
+ $(TESTS_testsuite) \
+ $(NULL)
+
+# Test that exercise specific asserts in the test framework library and are
+# hence expected to fail.
+XFAIL_TESTS = \
+ igt_no_exit \
+ igt_no_exit_list_only \
+ igt_no_subtest \
+ $(NULL)
+
+# IMPORTANT: These tests here are all disabled because the result in sometime
+# unrecoverable gpu hangs. Don't put real testcases here.
+HANG = \
+ gem_bad_batch \
+ gem_hang \
+ gem_bad_blit \
+ gem_bad_address \
+ gem_non_secure_batch \
+ $(NULL)
+
+scripts = \
+ check_drm_clients \
+ ddx_intel_after_fbdev \
+ debugfs_wedged \
+ drm_lib.sh \
+ $(NULL)
+
+IMAGES = pass.png 1080p-left.png 1080p-right.png
+
+testdisplay_SOURCES = \
+ testdisplay.c \
+ testdisplay.h \
+ testdisplay_hotplug.c \
+ $(NULL)
+
+TESTS_progs += testdisplay
+
+common_files = \
+ eviction_common.c \
+ $(NULL)
+
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/ZZ_hangman b/tests/ZZ_hangman
deleted file mode 100755
index b8f4a682..00000000
--- a/tests/ZZ_hangman
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-#
-# Testcase: Simulate gpu hang
-#
-# This check uses the stop_rings facility to exercise the gpu hang code.
-# by reading /sys/kernel/debug/dri/0/i915_emon_status too quickly
-#
-
-SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )"
-. $SOURCE_DIR/drm_lib.sh
-
-oldpath=`pwd`
-
-cd $i915_path
-
-if [ ! -f i915_ring_stop ] ; then
- echo "kernel doesn't support ring stopping"
- exit 77
-fi
-
-if cat i915_error_state | grep -v "no error state collected" > /dev/null ; then
- echo "gpu hang dectected"
- exit 1
-fi
-
-# stop rings
-echo 0xf > i915_ring_stop
-echo "rings stopped"
-
-(cd $oldpath; $SOURCE_DIR/gem_exec_nop) > /dev/null
-
-if cat i915_error_state | grep -v "no error state collected" > /dev/null ; then
- echo "gpu hang correctly dectected"
-else
- echo "gpu hang not dectected"
- exit 2
-fi
-
-# clear error state
-echo > i915_error_state
-
-exit 0
diff --git a/tests/core_get_client_auth.c b/tests/core_get_client_auth.c
new file mode 100644
index 00000000..eef97e02
--- /dev/null
+++ b/tests/core_get_client_auth.c
@@ -0,0 +1,100 @@
+/*
+ * 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>
+# include <sys/syscall.h>
+
+#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 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/getclient.c b/tests/core_getclient.c
index 481ce119..ed46e519 100644
--- a/tests/getclient.c
+++ b/tests/core_getclient.c
@@ -27,12 +27,15 @@
#include <limits.h>
#include <sys/ioctl.h>
+#include <stdlib.h>
+#include <errno.h>
+
#include "drmtest.h"
/**
* Checks DRM_IOCTL_GET_CLIENT.
*/
-int main(int argc, char **argv)
+igt_simple_main
{
int fd, ret;
drm_client_t client;
@@ -45,7 +48,7 @@ int main(int argc, char **argv)
*/
client.idx = 0;
ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
- assert(ret == 0);
+ 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
@@ -54,8 +57,7 @@ int main(int argc, char **argv)
*/
client.idx = 0x7fffffff;
ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
- assert(ret == -1 && errno == EINVAL);
+ igt_assert(ret == -1 && errno == EINVAL);
close(fd);
- return 0;
}
diff --git a/tests/getstats.c b/tests/core_getstats.c
index 8a7d2999..1e2c5651 100644
--- a/tests/getstats.c
+++ b/tests/core_getstats.c
@@ -27,6 +27,11 @@
#include <limits.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <drm.h>
+
+#include "igt_core.h"
#include "drmtest.h"
/**
@@ -35,7 +40,7 @@
* I don't care too much about the actual contents, just that the kernel
* doesn't crash.
*/
-int main(int argc, char **argv)
+igt_simple_main
{
int fd, ret;
drm_stats_t stats;
@@ -43,8 +48,7 @@ int main(int argc, char **argv)
fd = drm_open_any();
ret = ioctl(fd, DRM_IOCTL_GET_STATS, &stats);
- assert(ret == 0);
+ igt_assert(ret == 0);
close(fd);
- return 0;
}
diff --git a/tests/getversion.c b/tests/core_getversion.c
index 4847e796..7058c897 100644
--- a/tests/getversion.c
+++ b/tests/core_getversion.c
@@ -32,18 +32,17 @@
/**
* Checks DRM_IOCTL_GET_VERSION and libdrm's drmGetVersion() interface to it.
*/
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
drmVersionPtr v;
fd = drm_open_any();
v = drmGetVersion(fd);
- assert(strlen(v->name) != 0);
- assert(strlen(v->date) != 0);
- assert(strlen(v->desc) != 0);
- assert(v->version_major >= 1);
+ 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);
- return 0;
}
diff --git a/tests/ddi_compute_wrpll.c b/tests/ddi_compute_wrpll.c
new file mode 100644
index 00000000..02a96547
--- /dev/null
+++ b/tests/ddi_compute_wrpll.c
@@ -0,0 +1,634 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "intel_io.h"
+#include "drmtest.h"
+
+#define LC_FREQ 2700
+#define LC_FREQ_2K (LC_FREQ * 2000)
+
+#define P_MIN 2
+#define P_MAX 64
+#define P_INC 2
+
+/* Constraints for PLL good behavior */
+#define REF_MIN 48
+#define REF_MAX 400
+#define VCO_MIN 2400
+#define VCO_MAX 4800
+
+#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a))
+
+struct wrpll_rnp {
+ unsigned p, n2, r2;
+};
+
+static unsigned wrpll_get_budget_for_freq(int clock)
+{
+ unsigned budget;
+
+ switch (clock) {
+ case 25175000:
+ case 25200000:
+ case 27000000:
+ case 27027000:
+ case 37762500:
+ case 37800000:
+ case 40500000:
+ case 40541000:
+ case 54000000:
+ case 54054000:
+ case 59341000:
+ case 59400000:
+ case 72000000:
+ case 74176000:
+ case 74250000:
+ case 81000000:
+ case 81081000:
+ case 89012000:
+ case 89100000:
+ case 108000000:
+ case 108108000:
+ case 111264000:
+ case 111375000:
+ case 148352000:
+ case 148500000:
+ case 162000000:
+ case 162162000:
+ case 222525000:
+ case 222750000:
+ case 296703000:
+ case 297000000:
+ budget = 0;
+ break;
+ case 233500000:
+ case 245250000:
+ case 247750000:
+ case 253250000:
+ case 298000000:
+ budget = 1500;
+ break;
+ case 169128000:
+ case 169500000:
+ case 179500000:
+ case 202000000:
+ budget = 2000;
+ break;
+ case 256250000:
+ case 262500000:
+ case 270000000:
+ case 272500000:
+ case 273750000:
+ case 280750000:
+ case 281250000:
+ case 286000000:
+ case 291750000:
+ budget = 4000;
+ break;
+ case 267250000:
+ case 268500000:
+ budget = 5000;
+ break;
+ default:
+ budget = 1000;
+ break;
+ }
+
+ return budget;
+}
+
+static void wrpll_update_rnp(uint64_t freq2k, unsigned budget,
+ unsigned r2, unsigned n2, unsigned p,
+ struct wrpll_rnp *best)
+{
+ uint64_t a, b, c, d, diff, diff_best;
+
+ /* No best (r,n,p) yet */
+ if (best->p == 0) {
+ best->p = p;
+ best->n2 = n2;
+ best->r2 = r2;
+ return;
+ }
+
+ /*
+ * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
+ * freq2k.
+ *
+ * delta = 1e6 *
+ * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
+ * freq2k;
+ *
+ * and we would like delta <= budget.
+ *
+ * If the discrepancy is above the PPM-based budget, always prefer to
+ * improve upon the previous solution. However, if you're within the
+ * budget, try to maximize Ref * VCO, that is N / (P * R^2).
+ */
+ a = freq2k * budget * p * r2;
+ b = freq2k * budget * best->p * best->r2;
+ diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2));
+ diff_best = ABS_DIFF((freq2k * best->p * best->r2),
+ (LC_FREQ_2K * best->n2));
+ c = 1000000 * diff;
+ d = 1000000 * diff_best;
+
+ if (a < c && b < d) {
+ /* If both are above the budget, pick the closer */
+ if (best->p * best->r2 * diff < p * r2 * diff_best) {
+ best->p = p;
+ best->n2 = n2;
+ best->r2 = r2;
+ }
+ } else if (a >= c && b < d) {
+ /* If A is below the threshold but B is above it? Update. */
+ best->p = p;
+ best->n2 = n2;
+ best->r2 = r2;
+ } else if (a >= c && b >= d) {
+ /* Both are below the limit, so pick the higher n2/(r2*r2) */
+ if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
+ best->p = p;
+ best->n2 = n2;
+ best->r2 = r2;
+ }
+ }
+ /* Otherwise a < c && b >= d, do nothing */
+}
+
+static void
+wrpll_compute_rnp(int clock /* in Hz */,
+ unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
+{
+ uint64_t freq2k;
+ unsigned p, n2, r2;
+ struct wrpll_rnp best = { 0, 0, 0 };
+ unsigned budget;
+
+ freq2k = clock / 100;
+
+ budget = wrpll_get_budget_for_freq(clock);
+
+ /* Special case handling for 540 pixel clock: bypass WR PLL entirely
+ * and directly pass the LC PLL to it. */
+ if (freq2k == 5400000) {
+ *n2_out = 2;
+ *p_out = 1;
+ *r2_out = 2;
+ return;
+ }
+
+ /*
+ * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
+ * the WR PLL.
+ *
+ * We want R so that REF_MIN <= Ref <= REF_MAX.
+ * Injecting R2 = 2 * R gives:
+ * REF_MAX * r2 > LC_FREQ * 2 and
+ * REF_MIN * r2 < LC_FREQ * 2
+ *
+ * Which means the desired boundaries for r2 are:
+ * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
+ *
+ */
+ for (r2 = LC_FREQ * 2 / REF_MAX + 1;
+ r2 <= LC_FREQ * 2 / REF_MIN;
+ r2++) {
+
+ /*
+ * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
+ *
+ * Once again we want VCO_MIN <= VCO <= VCO_MAX.
+ * Injecting R2 = 2 * R and N2 = 2 * N, we get:
+ * VCO_MAX * r2 > n2 * LC_FREQ and
+ * VCO_MIN * r2 < n2 * LC_FREQ)
+ *
+ * Which means the desired boundaries for n2 are:
+ * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
+ */
+ for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
+ n2 <= VCO_MAX * r2 / LC_FREQ;
+ n2++) {
+
+ for (p = P_MIN; p <= P_MAX; p += P_INC)
+ wrpll_update_rnp(freq2k, budget,
+ r2, n2, p, &best);
+ }
+ }
+
+ *n2_out = best.n2;
+ *p_out = best.p;
+ *r2_out = best.r2;
+}
+
+/* WRPLL clock dividers */
+struct wrpll_tmds_clock {
+ uint32_t clock;
+ uint16_t p; /* Post divider */
+ uint16_t n2; /* Feedback divider */
+ uint16_t r2; /* Reference divider */
+};
+
+/* Table of matching values for WRPLL clocks programming for each frequency.
+ * The code assumes this table is sorted. */
+static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
+ {19750000, 38, 25, 18},
+ {20000000, 48, 32, 18},
+ {21000000, 36, 21, 15},
+ {21912000, 42, 29, 17},
+ {22000000, 36, 22, 15},
+ {23000000, 36, 23, 15},
+ {23500000, 40, 40, 23},
+ {23750000, 26, 16, 14},
+ {24000000, 36, 24, 15},
+ {25000000, 36, 25, 15},
+ {25175000, 26, 40, 33},
+ {25200000, 30, 21, 15},
+ {26000000, 36, 26, 15},
+ {27000000, 30, 21, 14},
+ {27027000, 18, 100, 111},
+ {27500000, 30, 29, 19},
+ {28000000, 34, 30, 17},
+ {28320000, 26, 30, 22},
+ {28322000, 32, 42, 25},
+ {28750000, 24, 23, 18},
+ {29000000, 30, 29, 18},
+ {29750000, 32, 30, 17},
+ {30000000, 30, 25, 15},
+ {30750000, 30, 41, 24},
+ {31000000, 30, 31, 18},
+ {31500000, 30, 28, 16},
+ {32000000, 30, 32, 18},
+ {32500000, 28, 32, 19},
+ {33000000, 24, 22, 15},
+ {34000000, 28, 30, 17},
+ {35000000, 26, 32, 19},
+ {35500000, 24, 30, 19},
+ {36000000, 26, 26, 15},
+ {36750000, 26, 46, 26},
+ {37000000, 24, 23, 14},
+ {37762500, 22, 40, 26},
+ {37800000, 20, 21, 15},
+ {38000000, 24, 27, 16},
+ {38250000, 24, 34, 20},
+ {39000000, 24, 26, 15},
+ {40000000, 24, 32, 18},
+ {40500000, 20, 21, 14},
+ {40541000, 22, 147, 89},
+ {40750000, 18, 19, 14},
+ {41000000, 16, 17, 14},
+ {41500000, 22, 44, 26},
+ {41540000, 22, 44, 26},
+ {42000000, 18, 21, 15},
+ {42500000, 22, 45, 26},
+ {43000000, 20, 43, 27},
+ {43163000, 20, 24, 15},
+ {44000000, 18, 22, 15},
+ {44900000, 20, 108, 65},
+ {45000000, 20, 25, 15},
+ {45250000, 20, 52, 31},
+ {46000000, 18, 23, 15},
+ {46750000, 20, 45, 26},
+ {47000000, 20, 40, 23},
+ {48000000, 18, 24, 15},
+ {49000000, 18, 49, 30},
+ {49500000, 16, 22, 15},
+ {50000000, 18, 25, 15},
+ {50500000, 18, 32, 19},
+ {51000000, 18, 34, 20},
+ {52000000, 18, 26, 15},
+ {52406000, 14, 34, 25},
+ {53000000, 16, 22, 14},
+ {54000000, 16, 24, 15},
+ {54054000, 16, 173, 108},
+ {54500000, 14, 24, 17},
+ {55000000, 12, 22, 18},
+ {56000000, 14, 45, 31},
+ {56250000, 16, 25, 15},
+ {56750000, 14, 25, 17},
+ {57000000, 16, 27, 16},
+ {58000000, 16, 43, 25},
+ {58250000, 16, 38, 22},
+ {58750000, 16, 40, 23},
+ {59000000, 14, 26, 17},
+ {59341000, 14, 40, 26},
+ {59400000, 16, 44, 25},
+ {60000000, 16, 32, 18},
+ {60500000, 12, 39, 29},
+ {61000000, 14, 49, 31},
+ {62000000, 14, 37, 23},
+ {62250000, 14, 42, 26},
+ {63000000, 12, 21, 15},
+ {63500000, 14, 28, 17},
+ {64000000, 12, 27, 19},
+ {65000000, 14, 32, 19},
+ {65250000, 12, 29, 20},
+ {65500000, 12, 32, 22},
+ {66000000, 12, 22, 15},
+ {66667000, 14, 38, 22},
+ {66750000, 10, 21, 17},
+ {67000000, 14, 33, 19},
+ {67750000, 14, 58, 33},
+ {68000000, 14, 30, 17},
+ {68179000, 14, 46, 26},
+ {68250000, 14, 46, 26},
+ {69000000, 12, 23, 15},
+ {70000000, 12, 28, 18},
+ {71000000, 12, 30, 19},
+ {72000000, 12, 24, 15},
+ {73000000, 10, 23, 17},
+ {74000000, 12, 23, 14},
+ {74176000, 8, 100, 91},
+ {74250000, 10, 22, 16},
+ {74481000, 12, 43, 26},
+ {74500000, 10, 29, 21},
+ {75000000, 12, 25, 15},
+ {75250000, 10, 39, 28},
+ {76000000, 12, 27, 16},
+ {77000000, 12, 53, 31},
+ {78000000, 12, 26, 15},
+ {78750000, 12, 28, 16},
+ {79000000, 10, 38, 26},
+ {79500000, 10, 28, 19},
+ {80000000, 12, 32, 18},
+ {81000000, 10, 21, 14},
+ {81081000, 6, 100, 111},
+ {81624000, 8, 29, 24},
+ {82000000, 8, 17, 14},
+ {83000000, 10, 40, 26},
+ {83950000, 10, 28, 18},
+ {84000000, 10, 28, 18},
+ {84750000, 6, 16, 17},
+ {85000000, 6, 17, 18},
+ {85250000, 10, 30, 19},
+ {85750000, 10, 27, 17},
+ {86000000, 10, 43, 27},
+ {87000000, 10, 29, 18},
+ {88000000, 10, 44, 27},
+ {88500000, 10, 41, 25},
+ {89000000, 10, 28, 17},
+ {89012000, 6, 90, 91},
+ {89100000, 10, 33, 20},
+ {90000000, 10, 25, 15},
+ {91000000, 10, 32, 19},
+ {92000000, 10, 46, 27},
+ {93000000, 10, 31, 18},
+ {94000000, 10, 40, 23},
+ {94500000, 10, 28, 16},
+ {95000000, 10, 44, 25},
+ {95654000, 10, 39, 22},
+ {95750000, 10, 39, 22},
+ {96000000, 10, 32, 18},
+ {97000000, 8, 23, 16},
+ {97750000, 8, 42, 29},
+ {98000000, 8, 45, 31},
+ {99000000, 8, 22, 15},
+ {99750000, 8, 34, 23},
+ {100000000, 6, 20, 18},
+ {100500000, 6, 19, 17},
+ {101000000, 6, 37, 33},
+ {101250000, 8, 21, 14},
+ {102000000, 6, 17, 15},
+ {102250000, 6, 25, 22},
+ {103000000, 8, 29, 19},
+ {104000000, 8, 37, 24},
+ {105000000, 8, 28, 18},
+ {106000000, 8, 22, 14},
+ {107000000, 8, 46, 29},
+ {107214000, 8, 27, 17},
+ {108000000, 8, 24, 15},
+ {108108000, 8, 173, 108},
+ {109000000, 6, 23, 19},
+ {110000000, 6, 22, 18},
+ {110013000, 6, 22, 18},
+ {110250000, 8, 49, 30},
+ {110500000, 8, 36, 22},
+ {111000000, 8, 23, 14},
+ {111264000, 8, 150, 91},
+ {111375000, 8, 33, 20},
+ {112000000, 8, 63, 38},
+ {112500000, 8, 25, 15},
+ {113100000, 8, 57, 34},
+ {113309000, 8, 42, 25},
+ {114000000, 8, 27, 16},
+ {115000000, 6, 23, 18},
+ {116000000, 8, 43, 25},
+ {117000000, 8, 26, 15},
+ {117500000, 8, 40, 23},
+ {118000000, 6, 38, 29},
+ {119000000, 8, 30, 17},
+ {119500000, 8, 46, 26},
+ {119651000, 8, 39, 22},
+ {120000000, 8, 32, 18},
+ {121000000, 6, 39, 29},
+ {121250000, 6, 31, 23},
+ {121750000, 6, 23, 17},
+ {122000000, 6, 42, 31},
+ {122614000, 6, 30, 22},
+ {123000000, 6, 41, 30},
+ {123379000, 6, 37, 27},
+ {124000000, 6, 51, 37},
+ {125000000, 6, 25, 18},
+ {125250000, 4, 13, 14},
+ {125750000, 4, 27, 29},
+ {126000000, 6, 21, 15},
+ {127000000, 6, 24, 17},
+ {127250000, 6, 41, 29},
+ {128000000, 6, 27, 19},
+ {129000000, 6, 43, 30},
+ {129859000, 4, 25, 26},
+ {130000000, 6, 26, 18},
+ {130250000, 6, 42, 29},
+ {131000000, 6, 32, 22},
+ {131500000, 6, 38, 26},
+ {131850000, 6, 41, 28},
+ {132000000, 6, 22, 15},
+ {132750000, 6, 28, 19},
+ {133000000, 6, 34, 23},
+ {133330000, 6, 37, 25},
+ {134000000, 6, 61, 41},
+ {135000000, 6, 21, 14},
+ {135250000, 6, 167, 111},
+ {136000000, 6, 62, 41},
+ {137000000, 6, 35, 23},
+ {138000000, 6, 23, 15},
+ {138500000, 6, 40, 26},
+ {138750000, 6, 37, 24},
+ {139000000, 6, 34, 22},
+ {139050000, 6, 34, 22},
+ {139054000, 6, 34, 22},
+ {140000000, 6, 28, 18},
+ {141000000, 6, 36, 23},
+ {141500000, 6, 22, 14},
+ {142000000, 6, 30, 19},
+ {143000000, 6, 27, 17},
+ {143472000, 4, 17, 16},
+ {144000000, 6, 24, 15},
+ {145000000, 6, 29, 18},
+ {146000000, 6, 47, 29},
+ {146250000, 6, 26, 16},
+ {147000000, 6, 49, 30},
+ {147891000, 6, 23, 14},
+ {148000000, 6, 23, 14},
+ {148250000, 6, 28, 17},
+ {148352000, 4, 100, 91},
+ {148500000, 6, 33, 20},
+ {149000000, 6, 48, 29},
+ {150000000, 6, 25, 15},
+ {151000000, 4, 19, 17},
+ {152000000, 6, 27, 16},
+ {152280000, 6, 44, 26},
+ {153000000, 6, 34, 20},
+ {154000000, 6, 53, 31},
+ {155000000, 6, 31, 18},
+ {155250000, 6, 50, 29},
+ {155750000, 6, 45, 26},
+ {156000000, 6, 26, 15},
+ {157000000, 6, 61, 35},
+ {157500000, 6, 28, 16},
+ {158000000, 6, 65, 37},
+ {158250000, 6, 44, 25},
+ {159000000, 6, 53, 30},
+ {159500000, 6, 39, 22},
+ {160000000, 6, 32, 18},
+ {161000000, 4, 31, 26},
+ {162000000, 4, 18, 15},
+ {162162000, 4, 131, 109},
+ {162500000, 4, 53, 44},
+ {163000000, 4, 29, 24},
+ {164000000, 4, 17, 14},
+ {165000000, 4, 22, 18},
+ {166000000, 4, 32, 26},
+ {167000000, 4, 26, 21},
+ {168000000, 4, 46, 37},
+ {169000000, 4, 104, 83},
+ {169128000, 4, 64, 51},
+ {169500000, 4, 39, 31},
+ {170000000, 4, 34, 27},
+ {171000000, 4, 19, 15},
+ {172000000, 4, 51, 40},
+ {172750000, 4, 32, 25},
+ {172800000, 4, 32, 25},
+ {173000000, 4, 41, 32},
+ {174000000, 4, 49, 38},
+ {174787000, 4, 22, 17},
+ {175000000, 4, 35, 27},
+ {176000000, 4, 30, 23},
+ {177000000, 4, 38, 29},
+ {178000000, 4, 29, 22},
+ {178500000, 4, 37, 28},
+ {179000000, 4, 53, 40},
+ {179500000, 4, 73, 55},
+ {180000000, 4, 20, 15},
+ {181000000, 4, 55, 41},
+ {182000000, 4, 31, 23},
+ {183000000, 4, 42, 31},
+ {184000000, 4, 30, 22},
+ {184750000, 4, 26, 19},
+ {185000000, 4, 37, 27},
+ {186000000, 4, 51, 37},
+ {187000000, 4, 36, 26},
+ {188000000, 4, 32, 23},
+ {189000000, 4, 21, 15},
+ {190000000, 4, 38, 27},
+ {190960000, 4, 41, 29},
+ {191000000, 4, 41, 29},
+ {192000000, 4, 27, 19},
+ {192250000, 4, 37, 26},
+ {193000000, 4, 20, 14},
+ {193250000, 4, 53, 37},
+ {194000000, 4, 23, 16},
+ {194208000, 4, 23, 16},
+ {195000000, 4, 26, 18},
+ {196000000, 4, 45, 31},
+ {197000000, 4, 35, 24},
+ {197750000, 4, 41, 28},
+ {198000000, 4, 22, 15},
+ {198500000, 4, 25, 17},
+ {199000000, 4, 28, 19},
+ {200000000, 4, 37, 25},
+ {201000000, 4, 61, 41},
+ {202000000, 4, 112, 75},
+ {202500000, 4, 21, 14},
+ {203000000, 4, 146, 97},
+ {204000000, 4, 62, 41},
+ {204750000, 4, 44, 29},
+ {205000000, 4, 38, 25},
+ {206000000, 4, 29, 19},
+ {207000000, 4, 23, 15},
+ {207500000, 4, 40, 26},
+ {208000000, 4, 37, 24},
+ {208900000, 4, 48, 31},
+ {209000000, 4, 48, 31},
+ {209250000, 4, 31, 20},
+ {210000000, 4, 28, 18},
+ {211000000, 4, 25, 16},
+ {212000000, 4, 22, 14},
+ {213000000, 4, 30, 19},
+ {213750000, 4, 38, 24},
+ {214000000, 4, 46, 29},
+ {214750000, 4, 35, 22},
+ {215000000, 4, 43, 27},
+ {216000000, 4, 24, 15},
+ {217000000, 4, 37, 23},
+ {218000000, 4, 42, 26},
+ {218250000, 4, 42, 26},
+ {218750000, 4, 34, 21},
+ {219000000, 4, 47, 29},
+ {220000000, 4, 44, 27},
+ {220640000, 4, 49, 30},
+ {220750000, 4, 36, 22},
+ {221000000, 4, 36, 22},
+ {222000000, 4, 23, 14},
+ {222525000, 4, 150, 91},
+ {222750000, 4, 33, 20},
+ {227000000, 4, 37, 22},
+ {230250000, 4, 29, 17},
+ {233500000, 4, 38, 22},
+ {235000000, 4, 40, 23},
+ {238000000, 4, 30, 17},
+ {241500000, 2, 17, 19},
+ {245250000, 2, 20, 22},
+ {247750000, 2, 22, 24},
+ {253250000, 2, 15, 16},
+ {256250000, 2, 18, 19},
+ {262500000, 2, 31, 32},
+ {267250000, 2, 66, 67},
+ {268500000, 2, 94, 95},
+ {270000000, 2, 14, 14},
+ {272500000, 2, 77, 76},
+ {273750000, 2, 57, 56},
+ {280750000, 2, 24, 23},
+ {281250000, 2, 23, 22},
+ {286000000, 2, 17, 16},
+ {291750000, 2, 26, 24},
+ {296703000, 2, 100, 91},
+ {297000000, 2, 22, 20},
+ {298000000, 2, 21, 19},
+};
+
+int main(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) {
+ const struct wrpll_tmds_clock *ref = &wrpll_tmds_clock_table[i];
+ unsigned r2, n2, p;
+
+ wrpll_compute_rnp(ref->clock, &r2, &n2, &p);
+ if (ref->r2 != r2 || ref->n2 != n2 || ref->p != p) {
+ printf("Computed value differs for %li Hz:\n"
+ " Reference: (%u,%u,%u)\n"
+ " Computed: (%u,%u,%u)\n",
+ (int64_t)ref->clock * 1000,
+ ref->r2, ref->n2, ref->p,
+ r2, n2, p);
+
+ abort();
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/ddx_intel_after_fbdev b/tests/ddx_intel_after_fbdev
new file mode 100755
index 00000000..bcd2c29d
--- /dev/null
+++ b/tests/ddx_intel_after_fbdev
@@ -0,0 +1,73 @@
+#!/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
index 6e139a41..809bfab3 100755
--- a/tests/debugfs_emon_crash
+++ b/tests/debugfs_emon_crash
@@ -8,7 +8,7 @@ SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )"
. $SOURCE_DIR/drm_lib.sh
for z in $(seq 1 1000); do
- cat $i915_path/i915_emon_status > /dev/null 2&>1
+ cat $i915_dfs_path/i915_emon_status > /dev/null 2&>1
done
# If we got here, we haven't crashed
diff --git a/tests/debugfs_wedged b/tests/debugfs_wedged
index 80a32f61..903a0a20 100755
--- a/tests/debugfs_wedged
+++ b/tests/debugfs_wedged
@@ -6,5 +6,5 @@ SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )"
# 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_path}/i915_wedged
-cat $i915_path/i915_error_state > /dev/null 2>&1
+echo 1 > ${i915_dfs_path}/i915_wedged
+cat $i915_dfs_path/i915_error_state > /dev/null 2>&1
diff --git a/tests/drm_lib.sh b/tests/drm_lib.sh
index a76fd474..97f6f925 100755
--- a/tests/drm_lib.sh
+++ b/tests/drm_lib.sh
@@ -4,6 +4,10 @@ die() {
exit 1
}
+do_or_die() {
+ $@ > /dev/null 2>&1 || (echo "FAIL: $@ ($?)" && exit -1)
+}
+
if [ -d /debug/dri ] ; then
debugfs_path=/debug/dri
fi
@@ -12,21 +16,36 @@ if [ -d /sys/kernel/debug/dri ] ; then
debugfs_path=/sys/kernel/debug/dri
fi
-i915_path=x
-for dir in `ls $debugfs_path` ; do
- if [ -f $debugfs_path/$dir/i915_error_state ] ; then
- i915_path=$debugfs_path/$dir
+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_path = "x" ] ; then
+if [ $i915_dfs_path = "x" ] ; then
die " i915 debugfs path not found."
fi
# read everything we can
-if [ `cat $i915_path/clients | wc -l` -gt "2" ] ; then
- die "ERROR: other drm clients running"
+if [ `cat $i915_dfs_path/clients | wc -l` -gt "2" ] ; then
+ [ -n "$DRM_LIB_ALLOW_NO_MASTER" ] || \
+ die "ERROR: other drm clients running"
fi
+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_vma_limiter.c b/tests/drm_vma_limiter.c
index 1971e2dc..e1381fe3 100644
--- a/tests/drm_vma_limiter.c
+++ b/tests/drm_vma_limiter.c
@@ -27,18 +27,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -54,12 +54,14 @@ struct intel_batchbuffer *batch;
#define BO_ARRAY_SIZE 35000
drm_intel_bo *bos[BO_ARRAY_SIZE];
-int main(int argc, char **argv)
+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);
@@ -70,17 +72,17 @@ int main(int argc, char **argv)
for (i = 0; i < BO_ARRAY_SIZE; i++) {
bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096);
- assert(bos[i]);
+ igt_assert(bos[i]);
drm_intel_bo_map(bos[i], 1);
ptr = bos[i]->virtual;
- assert(ptr);
+ igt_assert(ptr);
*ptr = 'c';
drm_intel_bo_unmap(bos[i]);
drm_intel_gem_bo_map_gtt(bos[i]);
ptr = bos[i]->virtual;
- assert(ptr);
+ igt_assert(ptr);
*ptr = 'c';
drm_intel_gem_bo_unmap_gtt(bos[i]);
}
@@ -88,16 +90,16 @@ int main(int argc, char **argv)
/* 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);
- assert(bos[i]);
+ igt_assert(bos[i]);
drm_intel_bo_map(bos[i], 1);
ptr = bos[i]->virtual;
- assert(*ptr = 'c');
+ igt_assert(*ptr = 'c');
drm_intel_bo_unmap(bos[i]);
drm_intel_gem_bo_map_gtt(bos[i]);
ptr = bos[i]->virtual;
- assert(*ptr = 'c');
+ igt_assert(*ptr = 'c');
drm_intel_gem_bo_unmap_gtt(bos[i]);
}
@@ -105,6 +107,4 @@ int main(int argc, char **argv)
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/drm_vma_limiter_cached.c b/tests/drm_vma_limiter_cached.c
index 37976185..3b41caad 100644
--- a/tests/drm_vma_limiter_cached.c
+++ b/tests/drm_vma_limiter_cached.c
@@ -27,18 +27,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -54,13 +54,15 @@ struct intel_batchbuffer *batch;
/* we do both cpu and gtt maps, so only need half of 64k to exhaust */
-int main(int argc, char **argv)
+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);
@@ -68,7 +70,7 @@ int main(int argc, char **argv)
batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd));
load_bo = drm_intel_bo_alloc(bufmgr, "target bo", 1024*4096, 4096);
- assert(load_bo);
+ igt_assert(load_bo);
drm_intel_bufmgr_gem_set_vma_cache_size(bufmgr, 500);
@@ -79,19 +81,18 @@ int main(int argc, char **argv)
/* put some load onto the gpu to keep the light buffers active for long
* enough */
for (i = 0; i < 10000; i++) {
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(batch->devid, 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);
+ BLIT_RELOC_UDW(batch->devid);
OUT_BATCH((0 << 16) | 512); /* src x1, y1 */
OUT_BATCH(4096);
OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(batch->devid);
ADVANCE_BATCH();
}
@@ -102,24 +103,22 @@ int main(int argc, char **argv)
for (j = 0; j < GROUP_SZ; j++, i++) {
bo[j] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096);
- assert(bo[j]);
+ igt_assert(bo[j]);
drm_intel_gem_bo_map_gtt(bo[j]);
ptr = bo[j]->virtual;
- assert(ptr);
+ igt_assert(ptr);
*ptr = 'c';
drm_intel_gem_bo_unmap_gtt(bo[j]);
/* put it onto the active list ... */
- BEGIN_BATCH(6);
- OUT_BATCH(XY_COLOR_BLT_CMD |
- XY_COLOR_BLT_WRITE_ALPHA |
- XY_COLOR_BLT_WRITE_RGB);
+ COLOR_BLIT_COPY_BATCH_START(intel_get_drm_devid(fd), 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);
+ BLIT_RELOC_UDW(intel_get_drm_devid(fd));
OUT_BATCH(0xffffffff); /* color */
ADVANCE_BATCH();
}
@@ -133,6 +132,4 @@ int main(int argc, char **argv)
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/drm_vma_limiter_cpu.c b/tests/drm_vma_limiter_cpu.c
index 24ce188e..e17a679d 100644
--- a/tests/drm_vma_limiter_cpu.c
+++ b/tests/drm_vma_limiter_cpu.c
@@ -27,18 +27,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -55,12 +55,14 @@ struct intel_batchbuffer *batch;
#define BO_ARRAY_SIZE 68000
drm_intel_bo *bos[BO_ARRAY_SIZE];
-int main(int argc, char **argv)
+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);
@@ -71,11 +73,11 @@ int main(int argc, char **argv)
for (i = 0; i < BO_ARRAY_SIZE; i++) {
bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096);
- assert(bos[i]);
+ igt_assert(bos[i]);
drm_intel_bo_map(bos[i], 1);
ptr = bos[i]->virtual;
- assert(ptr);
+ igt_assert(ptr);
*ptr = 'c';
drm_intel_bo_unmap(bos[i]);
}
@@ -83,11 +85,11 @@ int main(int argc, char **argv)
/* 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);
- assert(bos[i]);
+ igt_assert(bos[i]);
drm_intel_bo_map(bos[i], 1);
ptr = bos[i]->virtual;
- assert(*ptr = 'c');
+ igt_assert(*ptr = 'c');
drm_intel_bo_unmap(bos[i]);
}
@@ -95,6 +97,4 @@ int main(int argc, char **argv)
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/drm_vma_limiter_gtt.c b/tests/drm_vma_limiter_gtt.c
index 540ea917..303e86da 100644
--- a/tests/drm_vma_limiter_gtt.c
+++ b/tests/drm_vma_limiter_gtt.c
@@ -27,18 +27,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -56,12 +56,14 @@ struct intel_batchbuffer *batch;
#define BO_ARRAY_SIZE 68000
drm_intel_bo *bos[BO_ARRAY_SIZE];
-int main(int argc, char **argv)
+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);
@@ -72,11 +74,11 @@ int main(int argc, char **argv)
for (i = 0; i < BO_ARRAY_SIZE; i++) {
bos[i] = drm_intel_bo_alloc(bufmgr, "mmap bo", 4096, 4096);
- assert(bos[i]);
+ igt_assert(bos[i]);
drm_intel_gem_bo_map_gtt(bos[i]);
ptr = bos[i]->virtual;
- assert(ptr);
+ igt_assert(ptr);
*ptr = 'c';
drm_intel_gem_bo_unmap_gtt(bos[i]);
}
@@ -84,11 +86,11 @@ int main(int argc, char **argv)
/* 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);
- assert(bos[i]);
+ igt_assert(bos[i]);
drm_intel_gem_bo_map_gtt(bos[i]);
ptr = bos[i]->virtual;
- assert(*ptr = 'c');
+ igt_assert(*ptr = 'c');
drm_intel_gem_bo_unmap_gtt(bos[i]);
}
@@ -96,6 +98,4 @@ int main(int argc, char **argv)
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/debugfs_reader b/tests/drv_debugfs_reader
index 80d59988..9e2845eb 100755
--- a/tests/debugfs_reader
+++ b/tests/drv_debugfs_reader
@@ -4,6 +4,6 @@ SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )"
. $SOURCE_DIR/drm_lib.sh
# read everything we can
-cat $i915_path/* > /dev/null 2>&1
+cat $i915_dfs_path/* > /dev/null 2>&1
exit 0
diff --git a/tests/drv_hangman.c b/tests/drv_hangman.c
new file mode 100644
index 00000000..d74ed483
--- /dev/null
+++ b/tests/drv_hangman.c
@@ -0,0 +1,428 @@
+/*
+ * 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_debugfs.h"
+#include "ioctl_wrappers.h"
+
+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 = strlen(s) < sizeof(tmp) ?
+ strlen(s) : sizeof(tmp);
+
+ read_dfs(fname, tmp, l + 1);
+ if (!inverse) {
+ if (strncmp(tmp, s, l) != 0) {
+ fprintf(stderr, "contents of %s: '%s' (expected '%s')\n",
+ fname, tmp, s);
+ igt_fail(1);
+ }
+ } else {
+ if (strncmp(tmp, s, l) == 0) {
+ fprintf(stderr, "contents of %s: '%s' (expected not '%s'\n",
+ fname, tmp, s);
+ igt_fail(1);
+ }
+ }
+}
+
+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");
+}
+
+static int get_line_count(const char *s)
+{
+ int count = 0;
+
+ while (*s) {
+ if (*s == '\n')
+ count++;
+ s++;
+ }
+
+ return count;
+}
+
+static void check_other_clients(void)
+{
+ char tmp[1024];
+ char *s;
+ int dev, pid, uid, magic;
+
+ read_dfs("clients", tmp, sizeof(tmp));
+ if (get_line_count(tmp) <= 2)
+ return;
+
+ s = strstr(tmp, "y");
+ igt_assert(s != NULL);
+ igt_assert(sscanf(s, "y %d %d %d %d",
+ &dev, &pid, &uid, &magic) == 4);
+
+ igt_debug("client %d %d %d %d\n", dev, pid, uid, magic);
+ igt_assert(pid == getpid());
+ igt_debug("found myself in client list\n");
+}
+
+#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;
+
+ check_other_clients();
+ 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 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",
+ &gtt_offset);
+ if (bb_matched == 1) {
+ char expected_line[32];
+
+ igt_assert(strstr(ring_name, expected_ring_name));
+ 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",
+ &gtt_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 (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 void test_error_state_capture(unsigned ring_id,
+ const char *ring_name)
+{
+ int fd, gen;
+ uint64_t offset;
+
+ check_other_clients();
+ clear_error_state();
+
+ fd = drm_open_any();
+ gen = intel_gen(intel_get_drm_devid(fd));
+
+ offset = submit_batch(fd, ring_id, true);
+ close(fd);
+
+ check_error_state(gen, 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
new file mode 100755
index 00000000..484e1514
--- /dev/null
+++ b/tests/drv_missed_irq_hang
@@ -0,0 +1,70 @@
+#!/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 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
+
+(cd $oldpath; $SOURCE_DIR/gem_exec_blt) > /dev/null
+
+check_for_missed_irq
+check_for_hang
+
+(cd $oldpath; $SOURCE_DIR/gem_exec_blt) > /dev/null
+
+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
+
+(cd $oldpath; $SOURCE_DIR/gem_exec_blt) > /dev/null
+
+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/module_reload b/tests/drv_module_reload
index 400fdd04..c1fd3957 100755
--- a/tests/module_reload
+++ b/tests/drv_module_reload
@@ -18,13 +18,18 @@ if ! echo 0 > /sys/class/vtconsole/vtcon1/bind ; then
exit 77
fi
+# 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
-rmmod drm_kms_helper
-rmmod drm
+# 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!
@@ -37,5 +42,9 @@ fi
modprobe i915
echo 1 > /sys/class/vtconsole/vtcon1/bind
+modprobe snd_hda_intel
+
# try to run something
$SOURCE_DIR/gem_exec_nop > /dev/null && echo "module successfully loaded again"
+
+exit $exitcode
diff --git a/tests/drv_suspend.c b/tests/drv_suspend.c
new file mode 100644
index 00000000..80f6a225
--- /dev/null
+++ b/tests/drv_suspend.c
@@ -0,0 +1,189 @@
+/*
+ * 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 "igt_debugfs.h"
+#include "igt_aux.h"
+
+#define OBJECT_SIZE (16*1024*1024)
+
+static void
+test_fence_restore(int fd, bool tiled2untiled)
+{
+ 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);
+
+ 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(void)
+{
+ 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);
+
+ igt_system_suspend_autoresume();
+
+ sleep(1);
+
+ igt_stop_helper(&reader);
+}
+
+static void
+test_sysfs_reader(void)
+{
+ 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);
+
+ igt_system_suspend_autoresume();
+
+ sleep(1);
+
+ igt_stop_helper(&reader);
+}
+
+static void
+test_forcewake(void)
+{
+ int fw_fd;
+
+ fw_fd = igt_open_forcewake_handle();
+ igt_assert(fw_fd >= 0);
+ 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);
+
+ igt_subtest("fence-restore-untiled")
+ test_fence_restore(fd, false);
+
+ igt_subtest("debugfs-reader")
+ test_debugfs_reader();
+
+ igt_subtest("sysfs-reader")
+ test_sysfs_reader();
+
+ igt_subtest("forcewake")
+ test_forcewake();
+
+ igt_fixture
+ close(fd);
+}
diff --git a/tests/eviction_common.c b/tests/eviction_common.c
new file mode 100644
index 00000000..6c6eab46
--- /dev/null
+++ b/tests/eviction_common.c
@@ -0,0 +1,251 @@
+/*
+ * 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 (*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;
+ uint32_t i_tmp;
+
+ i_tmp = i_arr[i];
+ i_arr[i] = i_arr[j];
+ i_arr[j] = i_tmp;
+}
+
+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);
+ igt_require(intel_check_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;
+
+ igt_require(intel_check_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;
+
+ igt_require(intel_check_memory(working_surfaces, surface_size, CHECK_RAM));
+
+ if (trash_surfaces < working_surfaces)
+ trash_surfaces = working_surfaces;
+
+ igt_require(intel_check_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;
+}
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+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;
+
+ igt_require(intel_check_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_require(intel_check_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 flink;
+
+ flink = gem_flink(fd, bo[l]);
+ bo[l] = gem_open(realfd, flink);
+ }
+ }
+
+ 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/flip_test.c b/tests/flip_test.c
deleted file mode 100644
index 67105905..00000000
--- a/tests/flip_test.c
+++ /dev/null
@@ -1,317 +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.
- */
-
-#include "config.h"
-
-#include <assert.h>
-#include <cairo.h>
-#include <errno.h>
-#include <math.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-
-#include "i915_drm.h"
-#include "drmtest.h"
-#include "testdisplay.h"
-
-drmModeRes *resources;
-int drm_fd;
-int test_time = 3;
-
-uint32_t *fb_ptr;
-
-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-
-struct type_name {
- int type;
- const char *name;
-};
-
-struct test_output {
- uint32_t id;
- int mode_valid;
- drmModeModeInfo mode;
- drmModeEncoder *encoder;
- drmModeConnector *connector;
- int crtc;
- int pipe;
- unsigned int current_fb_id;
- unsigned int fb_ids[2];
-};
-
-static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
- unsigned int usec, void *data)
-{
- struct test_output *o = data;
- unsigned int new_fb_id;
-
- if (o->current_fb_id == o->fb_ids[0])
- new_fb_id = o->fb_ids[1];
- else
- new_fb_id = o->fb_ids[0];
-
- drmModePageFlip(drm_fd, o->crtc, new_fb_id,
- DRM_MODE_PAGE_FLIP_EVENT, o);
- o->current_fb_id = new_fb_id;
-}
-
-static void connector_find_preferred_mode(struct test_output *o, int crtc_id)
-{
- drmModeConnector *connector;
- drmModeEncoder *encoder = NULL;
- int i, j;
-
- /* First, find the connector & mode */
- o->mode_valid = 0;
- o->crtc = 0;
- connector = drmModeGetConnector(drm_fd, o->id);
- assert(connector);
-
- if (connector->connection != DRM_MODE_CONNECTED) {
- drmModeFreeConnector(connector);
- return;
- }
-
- if (!connector->count_modes) {
- fprintf(stderr, "connector %d has no modes\n", o->id);
- drmModeFreeConnector(connector);
- return;
- }
-
- if (connector->connector_id != o->id) {
- fprintf(stderr, "connector id doesn't match (%d != %d)\n",
- connector->connector_id, o->id);
- drmModeFreeConnector(connector);
- return;
- }
-
- for (j = 0; j < connector->count_modes; j++) {
- o->mode = connector->modes[j];
- if (o->mode.type & DRM_MODE_TYPE_PREFERRED) {
- o->mode_valid = 1;
- break;
- }
- }
-
- if (!o->mode_valid) {
- if (connector->count_modes > 0) {
- /* use the first mode as test mode */
- o->mode = connector->modes[0];
- o->mode_valid = 1;
- }
- else {
- fprintf(stderr, "failed to find any modes on connector %d\n",
- o->id);
- return;
- }
- }
-
- /* Now get the encoder */
- for (i = 0; i < connector->count_encoders; i++) {
- encoder = drmModeGetEncoder(drm_fd, connector->encoders[i]);
-
- if (!encoder) {
- fprintf(stderr, "could not get encoder %i: %s\n",
- resources->encoders[i], strerror(errno));
- drmModeFreeEncoder(encoder);
- continue;
- }
-
- break;
- }
-
- o->encoder = encoder;
-
- if (i == resources->count_encoders) {
- fprintf(stderr, "failed to find encoder\n");
- o->mode_valid = 0;
- return;
- }
-
- /* Find first CRTC not in use */
- for (i = 0; i < resources->count_crtcs; i++) {
- if (resources->crtcs[i] != crtc_id)
- continue;
- if (resources->crtcs[i] &&
- (o->encoder->possible_crtcs & (1<<i))) {
- o->crtc = resources->crtcs[i];
- break;
- }
- }
-
- if (!o->crtc) {
- fprintf(stderr, "could not find requested crtc %d\n", crtc_id);
- o->mode_valid = 0;
- return;
- }
-
- o->pipe = i;
-
- o->connector = connector;
-}
-
-static void
-paint_flip_mode(cairo_t *cr, int width, int height, void *priv)
-{
- bool odd_frame = (bool) priv;
-
- 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);
-}
-
-static void set_mode(struct test_output *o, int crtc)
-{
- int ret;
- int bpp = 32, depth = 24;
- drmEventContext evctx;
- int width, height;
- struct timeval end;
- struct kmstest_fb fb_info[2];
-
- connector_find_preferred_mode(o, crtc);
- if (!o->mode_valid)
- return;
-
- width = o->mode.hdisplay;
- height = o->mode.vdisplay;
-
- o->fb_ids[0] = kmstest_create_fb(drm_fd, width, height, bpp, depth,
- false, &fb_info[0],
- paint_flip_mode, (void *)false);
- o->fb_ids[1] = kmstest_create_fb(drm_fd, width, height, bpp, depth,
- false, &fb_info[1],
- paint_flip_mode, (void *)true);
- if (!o->fb_ids[0] || !o->fb_ids[1]) {
- fprintf(stderr, "failed to create fbs\n");
- exit(3);
- }
-
- gem_close(drm_fd, fb_info[0].gem_handle);
- gem_close(drm_fd, fb_info[1].gem_handle);
-
- kmstest_dump_mode(&o->mode);
- if (drmModeSetCrtc(drm_fd, o->crtc, o->fb_ids[0], 0, 0,
- &o->id, 1, &o->mode)) {
- fprintf(stderr, "failed to set mode (%dx%d@%dHz): %s\n",
- width, height, o->mode.vrefresh,
- strerror(errno));
- exit(3);
- }
-
- ret = drmModePageFlip(drm_fd, o->crtc, o->fb_ids[1],
- DRM_MODE_PAGE_FLIP_EVENT, o);
- if (ret) {
- fprintf(stderr, "failed to page flip: %s\n", strerror(errno));
- exit(4);
- }
- o->current_fb_id = o->fb_ids[1];
-
- memset(&evctx, 0, sizeof evctx);
- evctx.version = DRM_EVENT_CONTEXT_VERSION;
- evctx.vblank_handler = NULL;
- evctx.page_flip_handler = page_flip_handler;
-
- gettimeofday(&end, NULL);
- end.tv_sec += 3;
-
- while (1) {
- struct timeval now, timeout = { .tv_sec = 3, .tv_usec = 0 };
- fd_set fds;
-
- FD_ZERO(&fds);
- FD_SET(0, &fds);
- FD_SET(drm_fd, &fds);
- ret = select(drm_fd + 1, &fds, NULL, NULL, &timeout);
-
- if (ret <= 0) {
- fprintf(stderr, "select timed out or error (ret %d)\n",
- ret);
- exit(1);
- } else if (FD_ISSET(0, &fds)) {
- fprintf(stderr, "no fds active, breaking\n");
- exit(2);
- }
-
- gettimeofday(&now, NULL);
- if (now.tv_sec > end.tv_sec ||
- (now.tv_sec == end.tv_sec && now.tv_usec >= end.tv_usec)) {
- ret = 0;
- break;
- }
-
- drmHandleEvent(drm_fd, &evctx);
- }
-
- fprintf(stdout, "page flipping on crtc %d, connector %d: PASSED\n",
- crtc, o->id);
-
- drmModeFreeEncoder(o->encoder);
- drmModeFreeConnector(o->connector);
-}
-
-static int run_test(void)
-{
- struct test_output *connectors;
- int c, i;
-
- resources = drmModeGetResources(drm_fd);
- if (!resources) {
- fprintf(stderr, "drmModeGetResources failed: %s\n",
- strerror(errno));
- exit(5);
- }
-
- connectors = calloc(resources->count_connectors,
- sizeof(struct test_output));
- assert(connectors);
-
- /* Find any connected displays */
- for (c = 0; c < resources->count_connectors; c++) {
- connectors[c].id = resources->connectors[c];
- for (i = 0; i < resources->count_crtcs; i++)
- set_mode(&connectors[c], resources->crtcs[i]);
- }
-
- drmModeFreeResources(resources);
- return 1;
-}
-
-int main(int argc, char **argv)
-{
- drm_fd = drm_open_any();
-
- run_test();
-
- close(drm_fd);
-
- return 0;
-}
diff --git a/tests/gem_alive.c b/tests/gem_alive.c
new file mode 100644
index 00000000..f87b1cbb
--- /dev/null
+++ b/tests/gem_alive.c
@@ -0,0 +1,35 @@
+#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
index fbb96497..f8fda90d 100644
--- a/tests/gem_bad_address.c
+++ b/tests/gem_bad_address.c
@@ -29,18 +29,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
+#include "intel_chipset.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
diff --git a/tests/gem_bad_batch.c b/tests/gem_bad_batch.c
index db6636ae..33b3241f 100644
--- a/tests/gem_bad_batch.c
+++ b/tests/gem_bad_batch.c
@@ -29,18 +29,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
diff --git a/tests/gem_bad_blit.c b/tests/gem_bad_blit.c
index 22165270..9c031179 100644
--- a/tests/gem_bad_blit.c
+++ b/tests/gem_bad_blit.c
@@ -44,18 +44,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -78,20 +78,18 @@ bad_blit(drm_intel_bo *src_bo, uint32_t devid)
cmd_bits |= XY_SRC_COPY_BLT_DST_TILED;
}
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB |
- cmd_bits);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0); /* src x1,y1 */
OUT_BATCH(src_pitch);
OUT_RELOC(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
diff --git a/tests/gem_bad_length.c b/tests/gem_bad_length.c
index 41f44d7f..11cc197a 100644
--- a/tests/gem_bad_length.c
+++ b/tests/gem_bad_length.c
@@ -29,19 +29,15 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#define MI_BATCH_BUFFER_END (0xA<<23)
-
/*
* Testcase: Minmal bo_create and batchbuffer exec
*
@@ -57,26 +53,29 @@ static uint32_t do_gem_create(int fd, int size, int *retval)
create.handle = 0;
create.size = (size + 4095) & -4096;
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
- assert(retval || ret == 0);
+ 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;
- printf("trying to create a zero-length gem object\n");
+ igt_info("trying to create a zero-length gem object\n");
do_gem_create(fd, 0, &retval);
- assert(retval == EINVAL);
+ igt_assert(retval == EINVAL);
}
+#if 0
static void exec0(int fd)
{
struct drm_i915_gem_execbuffer2 execbuf;
@@ -110,16 +109,19 @@ static void exec0(int fd)
i915_execbuffer2_set_context_id(execbuf, 0);
execbuf.rsvd2 = 0;
- printf("trying to run an empty batchbuffer\n");
+ igt_info("trying to run an empty batchbuffer\n");
gem_exec(fd, &execbuf);
gem_close(fd, exec[0].handle);
}
+#endif
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
+ igt_skip_on_simulation();
+
fd = drm_open_any();
create0(fd);
@@ -127,6 +129,4 @@ int main(int argc, char **argv)
//exec0(fd);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_bad_reloc.c b/tests/gem_bad_reloc.c
new file mode 100644
index 00000000..26ebd11e
--- /dev/null
+++ b/tests/gem_bad_reloc.c
@@ -0,0 +1,137 @@
+/*
+ * 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"
+
+#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);
+
+ printf("Found offset %ld for 4k batch\n", (long)gem_exec[0].offset);
+ igt_require(gem_exec[0].offset < BIAS);
+
+ 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));
+
+ printf("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;
+}
+
+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_fixture {
+ close(fd);
+ }
+}
diff --git a/tests/gem_basic.c b/tests/gem_basic.c
index 24ad445f..f79b0669 100644
--- a/tests/gem_basic.c
+++ b/tests/gem_basic.c
@@ -29,14 +29,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
static void
@@ -45,12 +44,12 @@ test_bad_close(int fd)
struct drm_gem_close close_bo;
int ret;
- printf("Testing error return on bad close ioctl.\n");
+ igt_info("Testing error return on bad close ioctl.\n");
close_bo.handle = 0x10101010;
ret = ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
- assert(ret == -1 && errno == EINVAL);
+ igt_assert(ret == -1 && errno == EINVAL);
}
static void
@@ -58,7 +57,7 @@ test_create_close(int fd)
{
uint32_t handle;
- printf("Testing creating and closing an object.\n");
+ igt_info("Testing creating and closing an object.\n");
handle = gem_create(fd, 16*1024);
@@ -68,7 +67,7 @@ test_create_close(int fd)
static void
test_create_fd_close(int fd)
{
- printf("Testing closing with an object allocated.\n");
+ igt_info("Testing closing with an object allocated.\n");
gem_create(fd, 16*1024);
/* leak it */
@@ -76,15 +75,17 @@ test_create_fd_close(int fd)
close(fd);
}
-int main(int argc, char **argv)
-{
- int fd;
-
- fd = drm_open_any();
+int fd;
- test_bad_close(fd);
- test_create_close(fd);
- test_create_fd_close(fd);
-
- return 0;
+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
new file mode 100644
index 00000000..e3692b8b
--- /dev/null
+++ b/tests/gem_caching.c
@@ -0,0 +1,289 @@
+/*
+ * 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"
+
+/*
+ * 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(devid, 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);
+ BLIT_RELOC_UDW(devid);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(4096);
+ OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
+ 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
new file mode 100644
index 00000000..e46e2c15
--- /dev/null
+++ b/tests/gem_close_race.c
@@ -0,0 +1,280 @@
+/*
+ * 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 1024*1024*4
+
+#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++ = 512 << 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, 30);
+ 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 fds[NUM_FD];
+ int done;
+};
+
+static void *thread_run(void *_data)
+{
+ struct thread *t = _data;
+
+ pthread_mutex_lock(&t->mutex);
+ while (!t->done) {
+ pthread_mutex_unlock(&t->mutex);
+
+ for (int n = 0; n < NUM_FD; n++) {
+ struct drm_i915_gem_create create;
+
+ create.handle = 0;
+ create.size = OBJECT_SIZE;
+ drmIoctl(t->fds[n], DRM_IOCTL_I915_GEM_CREATE, &create);
+ if (create.handle == 0)
+ continue;
+
+ selfcopy(t->fds[n], create.handle, 10);
+
+ drmIoctl(t->fds[n], DRM_IOCTL_GEM_CLOSE, &create.handle);
+ }
+
+ pthread_mutex_lock(&t->mutex);
+ }
+ pthread_mutex_unlock(&t->mutex);
+
+ return 0;
+}
+
+static void *thread_busy(void *_data)
+{
+ struct thread *t = _data;
+ int n;
+
+ pthread_mutex_lock(&t->mutex);
+ while (!t->done) {
+ struct drm_i915_gem_create create;
+ struct drm_i915_gem_busy busy;
+
+ pthread_mutex_unlock(&t->mutex);
+
+ n = rand() % NUM_FD;
+
+ create.handle = 0;
+ create.size = OBJECT_SIZE;
+ drmIoctl(t->fds[n], DRM_IOCTL_I915_GEM_CREATE, &create);
+ if (create.handle == 0)
+ continue;
+
+ selfcopy(t->fds[n], create.handle, 1);
+
+ busy.handle = create.handle;
+ drmIoctl(t->fds[n], DRM_IOCTL_I915_GEM_BUSY, &busy);
+
+ drmIoctl(t->fds[n], DRM_IOCTL_GEM_CLOSE, &create.handle);
+
+ usleep(10*1000);
+
+ pthread_mutex_lock(&t->mutex);
+ }
+ pthread_mutex_unlock(&t->mutex);
+
+ 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);
+ 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]);
+ free(data);
+ }
+}
diff --git a/tests/gem_concurrent_blit.c b/tests/gem_concurrent_blit.c
new file mode 100644
index 00000000..61b1c2a0
--- /dev/null
+++ b/tests/gem_concurrent_blit.c
@@ -0,0 +1,398 @@
+/*
+ * 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 "intel_bufmgr.h"
+#include "intel_batchbuffer.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
+#include "igt_aux.h"
+
+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)
+{
+ int size = width * height, i;
+ uint32_t *tmp;
+
+ tmp = malloc(4*size);
+ if (tmp) {
+ memset(tmp, 0, 4*size);
+ do_or_die(drm_intel_bo_get_subdata(bo, 0, 4*size, tmp));
+ for (i = 0; i < size; i++)
+ igt_assert(tmp[i] == val);
+ free(tmp);
+ } else {
+ uint32_t t;
+ for (i = 0; i < size; i++) {
+ t = 0;
+ do_or_die(drm_intel_bo_get_subdata(bo, 4*i, 4, &t));
+ igt_assert(t == val);
+ }
+ }
+}
+
+static drm_intel_bo *
+unmapped_create_bo(drm_intel_bufmgr *bufmgr, uint32_t val, 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)
+{
+ 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
+gtt_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(*vaddr++ == val);
+}
+
+static drm_intel_bo *
+gtt_create_bo(drm_intel_bufmgr *bufmgr, uint32_t val, int width, int height)
+{
+ drm_intel_bo *bo;
+
+ bo = drm_intel_bo_alloc(bufmgr, "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. */
+ do_or_die(drm_intel_gem_bo_map_gtt(bo));
+
+ return bo;
+}
+
+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)
+{
+ int size = width * height;
+ uint32_t *vaddr;
+
+ do_or_die(drm_intel_bo_map(bo, false));
+ vaddr = bo->virtual;
+ while (size--)
+ igt_assert(*vaddr++ == val);
+ drm_intel_bo_unmap(bo);
+}
+
+struct access_mode {
+ 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 *(*create_bo)(drm_intel_bufmgr *bufmgr,
+ uint32_t val, int width, int height);
+ const char *name;
+};
+
+struct access_mode access_modes[] = {
+ { .set_bo = prw_set_bo, .cmp_bo = prw_cmp_bo,
+ .create_bo = unmapped_create_bo, .name = "prw" },
+ { .set_bo = cpu_set_bo, .cmp_bo = cpu_cmp_bo,
+ .create_bo = unmapped_create_bo, .name = "cpu" },
+ { .set_bo = gtt_set_bo, .cmp_bo = gtt_cmp_bo,
+ .create_bo = gtt_create_bo, .name = "gtt" },
+};
+
+#define MAX_NUM_BUFFERS 1024
+int num_buffers = MAX_NUM_BUFFERS, fd;
+drm_intel_bufmgr *bufmgr;
+struct intel_batchbuffer *batch;
+int width = 512, height = 512;
+
+static void do_overwrite_source(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy)
+{
+ 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++)
+ intel_copy_bo(batch, dst[i], src[i], width*height*4);
+ 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);
+}
+
+static void do_early_read(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy)
+{
+ 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++)
+ intel_copy_bo(batch, dst[i], src[i], width*height*4);
+ for (i = num_buffers; i--; )
+ mode->cmp_bo(dst[i], 0xdeadbeef, width, height);
+}
+
+static void do_gpu_read_after_write(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy)
+{
+ 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++)
+ intel_copy_bo(batch, dst[i], src[i], width*height*4);
+ for (i = num_buffers; i--; )
+ intel_copy_bo(batch, dummy, dst[i], width*height*4);
+ for (i = num_buffers; i--; )
+ mode->cmp_bo(dst[i], 0xabcdabcd, width, height);
+}
+
+typedef void (*do_test)(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy);
+
+typedef void (*run_wrap)(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy,
+ do_test do_test_func);
+
+static void run_single(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy,
+ do_test do_test_func)
+{
+ do_test_func(mode, src, dst, dummy);
+}
+
+
+static void run_interruptible(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy,
+ do_test do_test_func)
+{
+ int loop;
+
+ igt_fork_signal_helper();
+
+ for (loop = 0; loop < 10; loop++)
+ do_test_func(mode, src, dst, dummy);
+
+ igt_stop_signal_helper();
+}
+
+static void run_forked(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy,
+ do_test do_test_func)
+{
+ const int old_num_buffers = num_buffers;
+
+ num_buffers /= 16;
+ num_buffers += 2;
+
+ igt_fork_signal_helper();
+
+ igt_fork(child, 16) {
+ /* recreate process local variables */
+ 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 (int i = 0; i < num_buffers; i++) {
+ src[i] = mode->create_bo(bufmgr, i, width, height);
+ dst[i] = mode->create_bo(bufmgr, ~i, width, height);
+ }
+ dummy = mode->create_bo(bufmgr, 0, width, height);
+ for (int loop = 0; loop < 10; loop++)
+ do_test_func(mode, src, dst, dummy);
+ /* as we borrow the fd, we need to reap our bo */
+ for (int i = 0; i < num_buffers; i++) {
+ drm_intel_bo_unreference(src[i]);
+ drm_intel_bo_unreference(dst[i]);
+ }
+ drm_intel_bo_unreference(dummy);
+ intel_batchbuffer_free(batch);
+ drm_intel_bufmgr_destroy(bufmgr);
+ }
+
+ igt_waitchildren();
+
+ igt_stop_signal_helper();
+
+ num_buffers = old_num_buffers;
+}
+
+static void
+run_basic_modes(struct access_mode *mode,
+ drm_intel_bo **src, drm_intel_bo **dst,
+ drm_intel_bo *dummy, const char *suffix,
+ run_wrap run_wrap_func)
+{
+ /* try to overwrite the source values */
+ igt_subtest_f("%s-overwrite-source%s", mode->name, suffix)
+ run_wrap_func(mode, src, dst, dummy, do_overwrite_source);
+
+ /* try to read the results before the copy completes */
+ igt_subtest_f("%s-early-read%s", mode->name, suffix)
+ run_wrap_func(mode, src, dst, dummy, do_early_read);
+
+ /* and finally try to trick the kernel into loosing the pending write */
+ igt_subtest_f("%s-gpu-read-after-write%s", mode->name, suffix)
+ run_wrap_func(mode, src, dst, dummy, do_gpu_read_after_write);
+}
+
+static void
+run_modes(struct access_mode *mode)
+{
+ drm_intel_bo *src[MAX_NUM_BUFFERS], *dst[MAX_NUM_BUFFERS], *dummy = NULL;
+
+ igt_fixture {
+ 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 (int i = 0; i < num_buffers; i++) {
+ src[i] = mode->create_bo(bufmgr, i, width, height);
+ dst[i] = mode->create_bo(bufmgr, ~i, width, height);
+ }
+ dummy = mode->create_bo(bufmgr, 0, width, height);
+ }
+
+ run_basic_modes(mode, src, dst, dummy, "", run_single);
+ run_basic_modes(mode, src, dst, dummy, "-interruptible", run_interruptible);
+
+ igt_fixture {
+ for (int i = 0; i < num_buffers; i++) {
+ drm_intel_bo_unreference(src[i]);
+ drm_intel_bo_unreference(dst[i]);
+ }
+ drm_intel_bo_unreference(dummy);
+ intel_batchbuffer_free(batch);
+ drm_intel_bufmgr_destroy(bufmgr);
+ }
+
+ run_basic_modes(mode, src, dst, dummy, "-forked", run_forked);
+}
+
+igt_main
+{
+ int max, i;
+
+ igt_skip_on_simulation();
+
+ igt_fixture {
+ fd = drm_open_any();
+
+ 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_concurrent_blit.c b/tests/gem_cpu_concurrent_blit.c
deleted file mode 100644
index fd517d00..00000000
--- a/tests/gem_cpu_concurrent_blit.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright © 2009,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:
- * Eric Anholt <eric@anholt.net>
- * Chris Wilson <chris@chris-wilson.co.uk>
- *
- */
-
-/** @file gem_cpu_concurrent_blit.c
- *
- * This is a test of CPU read/write behavior when writing to active
- * buffers.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
-#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
-
-static void
-set_bo(drm_intel_bo *bo, uint32_t val, int width, int height)
-{
- int size = width * height;
- uint32_t *vaddr;
-
- drm_intel_bo_map(bo, true);
- vaddr = bo->virtual;
- while (size--)
- *vaddr++ = val;
- drm_intel_bo_unmap(bo);
-}
-
-static void
-cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height)
-{
- int size = width * height;
- uint32_t *vaddr;
-
- drm_intel_bo_map(bo, false);
- vaddr = bo->virtual;
- while (size--)
- assert(*vaddr++ == val);
- drm_intel_bo_unmap(bo);
-}
-
-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", 4*width*height, 0);
- assert(bo);
-
- set_bo(bo, val, width, height);
-
- return bo;
-}
-
-int
-main(int argc, char **argv)
-{
- drm_intel_bufmgr *bufmgr;
- struct intel_batchbuffer *batch;
- int num_buffers = 128, max;
- drm_intel_bo *src[128], *dst[128], *dummy;
- int width = 512, height = 512;
- int fd;
- int i;
-
- fd = drm_open_any();
-
- 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 = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd));
-
- for (i = 0; i < num_buffers; i++) {
- src[i] = create_bo(bufmgr, i, width, height);
- dst[i] = create_bo(bufmgr, ~i, width, height);
- }
- dummy = create_bo(bufmgr, 0, width, height);
-
- /* try to overwrite the source values */
- for (i = 0; i < num_buffers; i++)
- intel_copy_bo(batch, dst[i], src[i], width, height);
- for (i = num_buffers; i--; )
- set_bo(src[i], 0xdeadbeef, width, height);
- for (i = 0; i < num_buffers; i++)
- cmp_bo(dst[i], i, width, height);
-
- /* try to read the results before the copy completes */
- for (i = 0; i < num_buffers; i++)
- intel_copy_bo(batch, dst[i], src[i], width, height);
- for (i = num_buffers; i--; )
- cmp_bo(dst[i], 0xdeadbeef, width, height);
-
- /* and finally try to trick the kernel into loosing the pending write */
- for (i = num_buffers; i--; )
- set_bo(src[i], 0xabcdabcd, width, height);
- for (i = 0; i < num_buffers; i++)
- intel_copy_bo(batch, dst[i], src[i], width, height);
- for (i = num_buffers; i--; )
- intel_copy_bo(batch, dummy, dst[i], width, height);
- for (i = num_buffers; i--; )
- cmp_bo(dst[i], 0xabcdabcd, width, height);
-
- return 0;
-}
diff --git a/tests/gem_cpu_reloc.c b/tests/gem_cpu_reloc.c
new file mode 100644
index 00000000..46183231
--- /dev/null
+++ b/tests/gem_cpu_reloc.c
@@ -0,0 +1,247 @@
+/*
+ * 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"
+
+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();
+ igt_skip_on_f(intel_get_total_ram_mb() < aper_size / (1024*1024) * 2,
+ "not enough mem to run test\n");
+
+ count = aper_size / 4096 * 2;
+ if (igt_run_in_simulation())
+ count = 10;
+
+ 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));
+
+ /* 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));
+
+ /* 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));
+
+ /* 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
index 4fb2fc4e..2fd83c9e 100644
--- a/tests/gem_cs_prefetch.c
+++ b/tests/gem_cs_prefetch.c
@@ -31,22 +31,28 @@
* 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 <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
+#include "igt_aux.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -82,10 +88,10 @@ static void exec(int fd, uint32_t handle)
DRM_IOCTL_I915_GEM_EXECBUFFER2,
&execbuf);
gem_sync(fd, handle);
- assert(ret == 0);
+ igt_assert(ret == 0);
}
-int main(int argc, char **argv)
+igt_simple_main
{
uint32_t batch_end[4] = {MI_BATCH_BUFFER_END, 0, 0, 0};
int fd, i, ret;
@@ -93,57 +99,53 @@ int main(int argc, char **argv)
int count;
drm_intel_bo *sample_batch_bo;
+ igt_skip_on_simulation();
+
fd = drm_open_any();
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
+ igt_assert(bufmgr);
drm_intel_bufmgr_gem_enable_reuse(bufmgr);
aper_size = gem_aperture_size(fd);
/* presume a big per-bo overhead */
- if (intel_get_total_ram_mb() < (aper_size / (1024*1024)) * 3 / 2) {
- fprintf(stderr, "not enough mem to run test\n");
- return 77;
- }
+ 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));
- assert(batch);
+ igt_assert(batch);
sample_batch_bo = drm_intel_bo_alloc(bufmgr, "", 4096, 4096);
- assert(sample_batch_bo);
+ igt_assert(sample_batch_bo);
ret = drm_intel_bo_subdata(sample_batch_bo, 4096-sizeof(batch_end),
sizeof(batch_end), batch_end);
- assert(ret == 0);
+ 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);
- assert(batch_bo);
+ 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. */
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(batch->devid, 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(batch_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ BLIT_RELOC_UDW(batch->devid);
OUT_BATCH((0 << 16) | 0); /* src x1, y1 */
OUT_BATCH(4096);
OUT_RELOC(sample_batch_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(batch->devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
@@ -157,13 +159,11 @@ int main(int argc, char **argv)
// leak buffers
//drm_intel_bo_unreference(batch_bo);
- drmtest_progress("gem_cs_prefetch: ", i, count);
+ igt_progress("gem_cs_prefetch: ", i, count);
}
- fprintf(stderr, "Test suceeded, cleanup up - this might take a while.\n");
+ igt_info("Test suceeded, cleanup up - this might take a while.\n");
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_cs_tlb.c b/tests/gem_cs_tlb.c
new file mode 100644
index 00000000..b1c50584
--- /dev/null
+++ b/tests/gem_cs_tlb.c
@@ -0,0 +1,179 @@
+/*
+ * 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"
+
+#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, 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, &gtt_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
index 02d24eb3..77091314 100644
--- a/tests/gem_ctx_bad_destroy.c
+++ b/tests/gem_ctx_bad_destroy.c
@@ -31,79 +31,48 @@
#include <stdio.h>
#include <string.h>
-#include "i915_drm.h"
-#include "drmtest.h"
+#include <errno.h>
-struct local_drm_i915_context_create {
- __u32 ctx_id;
- __u32 pad;
-};
+#include "ioctl_wrappers.h"
+#include "drmtest.h"
struct local_drm_i915_context_destroy {
__u32 ctx_id;
__u32 pad;
};
-#define CONTEXT_CREATE_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2d, struct local_drm_i915_context_create)
#define CONTEXT_DESTROY_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2e, struct local_drm_i915_context_destroy)
-static uint32_t context_create(int fd)
-{
- struct local_drm_i915_context_create create;
- int ret;
-
- ret = drmIoctl(fd, CONTEXT_CREATE_IOCTL, &create);
- if (ret == -1 && (errno == ENODEV || errno == EINVAL))
- exit(77);
- else if (ret)
- abort();
-
- return create.ctx_id;
-}
-
-static void handle_bad(int ret, int lerrno, int expected, const char *desc)
-{
- if (ret != 0 && lerrno != expected) {
- fprintf(stderr, "%s - errno was %d, but should have been %d\n",
- desc, lerrno, expected);
- exit(EXIT_FAILURE);
- } else if (ret == 0) {
- fprintf(stderr, "%s - Command succeeded, but should have failed\n",
- desc);
- exit(EXIT_FAILURE);
- }
-}
-
-int main(int argc, char *argv[])
+igt_simple_main
{
struct local_drm_i915_context_destroy destroy;
uint32_t ctx_id;
int ret, fd;
- fd = drm_open_any();
+ igt_skip_on_simulation();
+
+ fd = drm_open_any_render();
- ctx_id = context_create(fd);
+ ctx_id = gem_context_create(fd);
destroy.ctx_id = ctx_id;
/* Make sure a proper destroy works first */
ret = drmIoctl(fd, CONTEXT_DESTROY_IOCTL, &destroy);
- assert(ret == 0);
+ igt_assert(ret == 0);
/* try double destroy */
ret = drmIoctl(fd, CONTEXT_DESTROY_IOCTL, &destroy);
- handle_bad(ret, errno, ENOENT, "double destroy");
+ igt_assert(ret != 0 && errno == ENOENT);
/* destroy something random */
destroy.ctx_id = 2;
ret = drmIoctl(fd, CONTEXT_DESTROY_IOCTL, &destroy);
- handle_bad(ret, errno, ENOENT, "random destroy");
+ igt_assert(ret != 0 && errno == ENOENT);
/* Try to destroy the default context */
destroy.ctx_id = 0;
ret = drmIoctl(fd, CONTEXT_DESTROY_IOCTL, &destroy);
- handle_bad(ret, errno, ENOENT, "default destroy");
+ igt_assert(ret != 0 && errno == ENOENT);
close(fd);
-
- exit(EXIT_SUCCESS);
}
diff --git a/tests/gem_ctx_bad_exec.c b/tests/gem_ctx_bad_exec.c
index 8a57fd41..f0bb0fc9 100644
--- a/tests/gem_ctx_bad_exec.c
+++ b/tests/gem_ctx_bad_exec.c
@@ -35,40 +35,16 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-struct local_drm_i915_gem_context_create {
- __u32 ctx_id;
- __u32 pad;
-};
-
-#define CONTEXT_CREATE_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2d, struct local_drm_i915_gem_context_create)
-
-static uint32_t context_create(int fd)
-{
- struct local_drm_i915_gem_context_create create;
- int ret;
-
- ret = drmIoctl(fd, CONTEXT_CREATE_IOCTL, &create);
- if (ret == -1 && (errno == ENODEV || errno == EINVAL)) {
- exit(77);
- } else if (ret) {
- abort();
- }
-
- return create.ctx_id;
-}
-
/* Copied from gem_exec_nop.c */
static int exec(int fd, uint32_t handle, int ring, int ctx_id)
{
@@ -104,22 +80,34 @@ static int exec(int fd, uint32_t handle, int ring, int ctx_id)
return ret;
}
-#define MI_BATCH_BUFFER_END (0xA<<23)
-int main(int argc, char *argv[])
+uint32_t handle;
+uint32_t batch[2] = {MI_BATCH_BUFFER_END};
+uint32_t ctx_id;
+int fd;
+
+igt_main
{
- uint32_t handle;
- uint32_t batch[2] = {MI_BATCH_BUFFER_END};
- uint32_t ctx_id;
- int fd;
- fd = drm_open_any();
+ igt_skip_on_simulation();
- ctx_id = context_create(fd);
+ igt_fixture {
+ fd = drm_open_any_render();
- handle = gem_create(fd, 4096);
- gem_write(fd, handle, 0, batch, sizeof(batch));
- assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0);
- assert(exec(fd, handle, I915_EXEC_BSD, ctx_id) != 0);
- assert(exec(fd, handle, I915_EXEC_BLT, ctx_id) != 0);
+ ctx_id = gem_context_create(fd);
+
+ handle = gem_create(fd, 4096);
+ gem_write(fd, handle, 0, batch, sizeof(batch));
+ }
- exit(EXIT_SUCCESS);
+ 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
index 632651ae..3e9b6880 100644
--- a/tests/gem_ctx_basic.c
+++ b/tests/gem_ctx_basic.c
@@ -30,7 +30,23 @@
*/
#include <pthread.h>
-#include "rendercopy.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 <getopt.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"
/* options */
int num_contexts = 10;
@@ -40,17 +56,16 @@ int iter = 10000;
/* globals */
pthread_t *threads;
-int *returns;
int devid;
int fd;
static void init_buffer(drm_intel_bufmgr *bufmgr,
- struct scratch_buf *buf,
+ struct igt_buf *buf,
uint32_t size)
{
buf->bo = drm_intel_bo_alloc(bufmgr, "", size, 4096);
buf->size = size;
- assert(buf->bo);
+ igt_assert(buf->bo);
buf->tiling = I915_TILING_NONE;
buf->stride = 4096;
}
@@ -58,46 +73,42 @@ static void init_buffer(drm_intel_bufmgr *bufmgr,
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 thread_id = *(int *)arg;
int td_fd;
int i;
if (multiple_fds)
- td_fd = fd = drm_open_any();
+ td_fd = fd = drm_open_any_render();
else
td_fd = fd;
- assert(td_fd >= 0);
+ 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);
-
- if (!context) {
- returns[thread_id] = 77;
- goto out;
- }
+ igt_require(context);
for (i = 0; i < iter; i++) {
- struct scratch_buf src, dst;
+ struct igt_buf src, dst;
init_buffer(bufmgr, &src, 4096);
init_buffer(bufmgr, &dst, 4096);
if (uncontexted) {
- gen6_render_copyfunc(batch, &src, 0, 0, 0, 0, &dst, 0, 0);
+ 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);
- assert(ret == 0);
+ igt_assert(ret == 0);
intel_batchbuffer_flush_with_context(batch, context);
}
}
-out:
drm_intel_gem_context_destroy(context);
intel_batchbuffer_free(batch);
drm_intel_bufmgr_destroy(bufmgr);
@@ -105,7 +116,7 @@ out:
if (multiple_fds)
close(td_fd);
- pthread_exit(&returns[thread_id]);
+ pthread_exit(NULL);
}
static void parse(int argc, char *argv[])
@@ -128,7 +139,7 @@ static void parse(int argc, char *argv[])
case 'h':
case '?':
default:
- exit(EXIT_SUCCESS);
+ igt_success();
break;
}
}
@@ -138,29 +149,30 @@ int main(int argc, char *argv[])
{
int i;
- fd = drm_open_any();
+ igt_simple_init();
+
+ fd = drm_open_any_render();
devid = intel_get_drm_devid(fd);
+ if (igt_run_in_simulation()) {
+ num_contexts = 2;
+ iter = 4;
+ }
+
parse(argc, argv);
threads = calloc(num_contexts, sizeof(*threads));
- returns = calloc(num_contexts, sizeof(*returns));
for (i = 0; i < num_contexts; i++)
pthread_create(&threads[i], NULL, work, &i);
for (i = 0; i < num_contexts; i++) {
- int thread_status, ret;
void *retval;
- ret = pthread_join(threads[i], &retval);
- thread_status = *(int *)retval;
- if (!ret && thread_status)
- exit(thread_status);
+ igt_assert(pthread_join(threads[i], &retval) == 0);
}
- free(returns);
free(threads);
close(fd);
- exit(EXIT_SUCCESS);
+ return 0;
}
diff --git a/tests/gem_ctx_create.c b/tests/gem_ctx_create.c
index def76d34..522e7b1c 100644
--- a/tests/gem_ctx_create.c
+++ b/tests/gem_ctx_create.c
@@ -27,7 +27,9 @@
#include <stdio.h>
#include <string.h>
-#include "i915_drm.h"
+#include <errno.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
struct local_drm_i915_gem_context_create {
@@ -37,28 +39,22 @@ struct local_drm_i915_gem_context_create {
#define CONTEXT_CREATE_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2d, struct local_drm_i915_gem_context_create)
-int main(int argc, char *argv[])
+igt_simple_main
{
int ret, fd;
struct local_drm_i915_gem_context_create create;
+ igt_skip_on_simulation();
+
create.ctx_id = rand();
create.pad = rand();
- fd = drm_open_any();
+ fd = drm_open_any_render();
ret = drmIoctl(fd, CONTEXT_CREATE_IOCTL, &create);
- if (ret != 0 && (errno == ENODEV || errno == EINVAL)) {
- fprintf(stderr, "Kernel is too old, or contexts not supported: %s\n",
- strerror(errno));
- exit(77);
- } else if (ret != 0) {
- fprintf(stderr, "%s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
- assert(create.ctx_id != 0);
+ igt_skip_on(ret != 0 && (errno == ENODEV || errno == EINVAL));
+ igt_assert(ret == 0);
+ igt_assert(create.ctx_id != 0);
close(fd);
-
- exit(EXIT_SUCCESS);
}
diff --git a/tests/gem_ctx_exec.c b/tests/gem_ctx_exec.c
index 423f1eec..da49a2fb 100644
--- a/tests/gem_ctx_exec.c
+++ b/tests/gem_ctx_exec.c
@@ -34,50 +34,32 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
-#include "drmtest.h"
-struct local_drm_i915_gem_context_create {
- __u32 ctx_id;
- __u32 pad;
-};
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
+#include "drmtest.h"
+#include "igt_aux.h"
struct local_drm_i915_gem_context_destroy {
__u32 ctx_id;
__u32 pad;
};
-#define CONTEXT_CREATE_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2d, struct local_drm_i915_gem_context_create)
-#define CONTEXT_DESTROY_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x23, struct local_drm_i915_gem_context_destroy)
-
-static uint32_t context_create(int fd)
-{
- struct local_drm_i915_gem_context_create create;
- int ret;
-
- ret = drmIoctl(fd, CONTEXT_CREATE_IOCTL, &create);
- if (ret == -1 && (errno == ENODEV || errno == EINVAL))
- exit(77);
- else if (ret)
- abort();
-
- return create.ctx_id;
-}
+#define CONTEXT_DESTROY_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2e, struct local_drm_i915_gem_context_destroy)
static void context_destroy(int fd, uint32_t ctx_id)
{
struct local_drm_i915_gem_context_destroy destroy;
destroy.ctx_id = ctx_id;
do_ioctl(fd, CONTEXT_DESTROY_IOCTL, &destroy);
+#include "igt_aux.h"
}
/* Copied from gem_exec_nop.c */
@@ -115,25 +97,106 @@ static int exec(int fd, uint32_t handle, int ring, int ctx_id)
return ret;
}
-#define MI_BATCH_BUFFER_END (0xA<<23)
-int main(int argc, char *argv[])
+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
{
- uint32_t handle;
- uint32_t batch[2] = {0, MI_BATCH_BUFFER_END};
- uint32_t ctx_id;
- int fd;
- fd = drm_open_any();
+ 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);
+ context_destroy(fd, ctx_id);
+ gem_write(fd, handle, 0, batch, sizeof(batch));
+ }
- ctx_id = context_create(fd);
- handle = gem_create(fd, 4096);
+ igt_subtest("basic") {
+ ctx_id = gem_context_create(fd);
+ igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0);
+ context_destroy(fd, ctx_id);
- gem_write(fd, handle, 0, batch, sizeof(batch));
- assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0);
- context_destroy(fd, ctx_id);
+ ctx_id = gem_context_create(fd);
+ igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0);
+ context_destroy(fd, ctx_id);
- ctx_id = context_create(fd);
- assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) == 0);
- context_destroy(fd, ctx_id);
+ igt_assert(exec(fd, handle, I915_EXEC_RENDER, ctx_id) < 0);
+ }
- exit(EXIT_SUCCESS);
+ igt_subtest("eviction")
+ big_exec(fd, handle, I915_EXEC_RENDER);
}
diff --git a/tests/gem_double_irq_loop.c b/tests/gem_double_irq_loop.c
index f2f8b1a8..ee9846c3 100644
--- a/tests/gem_double_irq_loop.c
+++ b/tests/gem_double_irq_loop.c
@@ -28,19 +28,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
#include "i830_reg.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -62,19 +62,18 @@ dummy_reloc_loop(void)
int i;
for (i = 0; i < 0x800; i++) {
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(batch->devid, 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);
+ BLIT_RELOC_UDW(batch->devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(4*4096);
OUT_RELOC_FENCED(blt_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(batch->devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
@@ -93,47 +92,30 @@ dummy_reloc_loop(void)
}
}
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
int devid;
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", argv[0]);
- exit(-1);
- }
+ igt_skip_on_simulation();
fd = drm_open_any();
devid = intel_get_drm_devid(fd);
- if (!HAS_BLT_RING(devid)) {
- fprintf(stderr, "not (yet) implemented for pre-snb\n");
- return 77;
- }
+ igt_require_f(HAS_BLT_RING(devid),
+ "not (yet) implemented for pre-snb\n");
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
+ igt_assert(bufmgr);
drm_intel_bufmgr_gem_enable_reuse(bufmgr);
batch = intel_batchbuffer_alloc(bufmgr, devid);
- if (!batch) {
- fprintf(stderr, "failed to create batch buffer\n");
- exit(-1);
- }
+ igt_assert(batch);
target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
- if (!target_buffer) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
- }
+ igt_assert(target_buffer);
blt_bo = drm_intel_bo_alloc(bufmgr, "target bo", 4*4096*4096, 4096);
- if (!blt_bo) {
- fprintf(stderr, "failed to alloc blt buffer\n");
- exit(-1);
- }
+ igt_assert(blt_bo);
dummy_reloc_loop();
@@ -142,6 +124,4 @@ int main(int argc, char **argv)
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_dummy_reloc_loop.c b/tests/gem_dummy_reloc_loop.c
index 82d8f77e..4fe07860 100644
--- a/tests/gem_dummy_reloc_loop.c
+++ b/tests/gem_dummy_reloc_loop.c
@@ -28,24 +28,33 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
#include "i830_reg.h"
+#include "intel_chipset.h"
+
+#define LOCAL_I915_EXEC_VEBOX (4<<0)
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
*
@@ -88,14 +97,14 @@ dummy_reloc_loop(int ring)
}
static void
-dummy_reloc_loop_random_ring(void)
+dummy_reloc_loop_random_ring(int num_rings)
{
int i;
srandom(0xdeadbeef);
for (i = 0; i < 0x100000; i++) {
- int ring = random() % 3 + 1;
+ int ring = random() % num_rings + 1;
if (ring == I915_EXEC_RENDER) {
BEGIN_BATCH(4);
@@ -122,73 +131,173 @@ dummy_reloc_loop_random_ring(void)
}
}
-int main(int argc, char **argv)
+static void
+dummy_reloc_loop_random_ring_multi_fd(int num_rings)
{
- int fd;
- int devid;
+ int i;
+ struct intel_batchbuffer *saved_batch;
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", argv[0]);
- exit(-1);
- }
+ saved_batch = batch;
- fd = drm_open_any();
- devid = intel_get_drm_devid(fd);
- if (!HAS_BLT_RING(devid)) {
- fprintf(stderr, "not (yet) implemented for pre-snb\n");
- return 77;
- }
+ srandom(0xdeadbeef);
- bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
- drm_intel_bufmgr_gem_enable_reuse(bufmgr);
+ for (i = 0; i < 0x100000; i++) {
+ int mindex;
+ int ring = random() % num_rings + 1;
- batch = intel_batchbuffer_alloc(bufmgr, devid);
- if (!batch) {
- fprintf(stderr, "failed to create batch buffer\n");
- exit(-1);
- }
+ mindex = random() % NUM_FD;
+ batch = mbatch[mindex];
- target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
- if (!target_buffer) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
+ if (ring == I915_EXEC_RENDER) {
+ BEGIN_BATCH(4);
+ 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);
+ 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);
}
- fprintf(stderr, "running dummy loop on render\n");
- dummy_reloc_loop(I915_EXEC_RENDER);
- fprintf(stderr, "dummy loop run on render completed\n");
+ batch = saved_batch;
+}
- if (!HAS_BSD_RING(devid))
- goto skip;
+int fd;
+int devid;
+int num_rings;
- sleep(2);
- fprintf(stderr, "running dummy loop on bsd\n");
- dummy_reloc_loop(I915_EXEC_BSD);
- fprintf(stderr, "dummy loop run on bsd completed\n");
+igt_main
+{
+ igt_skip_on_simulation();
- if (!HAS_BLT_RING(devid))
- goto skip;
+ 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));
- sleep(2);
- fprintf(stderr, "running dummy loop on blt\n");
- dummy_reloc_loop(I915_EXEC_BLT);
- fprintf(stderr, "dummy loop run on blt completed\n");
+ bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
+ igt_assert(bufmgr);
+ drm_intel_bufmgr_gem_enable_reuse(bufmgr);
- sleep(2);
- fprintf(stderr, "running dummy loop on random rings\n");
- dummy_reloc_loop_random_ring();
- fprintf(stderr, "dummy loop run on random rings completed\n");
+ batch = intel_batchbuffer_alloc(bufmgr, devid);
+ igt_assert(batch);
-skip:
- drm_intel_bo_unreference(target_buffer);
- intel_batchbuffer_free(batch);
- drm_intel_bufmgr_destroy(bufmgr);
+ target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
+ igt_assert(target_buffer);
- close(fd);
+ /* 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);
- return 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("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
new file mode 100644
index 00000000..e814f36c
--- /dev/null
+++ b/tests/gem_evict_alignment.c
@@ -0,0 +1,228 @@
+/*
+ * 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"
+
+#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;
+
+ igt_require(intel_check_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;
+
+ igt_require(intel_check_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_skip_on_simulation();
+
+ 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);
+ }
+ igt_stop_signal_helper();
+
+ igt_fixture
+ close(fd);
+}
diff --git a/tests/gem_evict_everything.c b/tests/gem_evict_everything.c
new file mode 100644
index 00000000..c1eb3bde
--- /dev/null
+++ b/tests/gem_evict_everything.c
@@ -0,0 +1,242 @@
+/*
+ * 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 "eviction_common.c"
+
+#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, 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;
+ igt_require(intel_check_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;
+ igt_require(intel_check_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_skip_on_simulation();
+
+ 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);
+ }
+
+ igt_stop_signal_helper();
+
+ igt_fixture {
+ close(fd);
+ }
+}
diff --git a/tests/gem_exec_bad_domains.c b/tests/gem_exec_bad_domains.c
index f3ee08b7..7641f8f8 100644
--- a/tests/gem_exec_bad_domains.c
+++ b/tests/gem_exec_bad_domains.c
@@ -28,18 +28,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
/* Testcase: Test whether the kernel rejects relocations with non-gpu domains
*
@@ -72,7 +72,7 @@ run_batch(void)
used = batch->ptr - batch->buffer;
ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->buffer);
- assert(ret == 0);
+ igt_assert(ret == 0);
batch->ptr = NULL;
@@ -83,63 +83,150 @@ run_batch(void)
return ret;
}
-int main(int argc, char **argv)
+#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)
{
- int fd, ret;
- drm_intel_bo *tmp;
+ 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;
- fd = drm_open_any();
+ 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);
+}
- 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));
+int fd;
+drm_intel_bo *tmp;
- tmp = drm_intel_bo_alloc(bufmgr, "tmp", 128 * 128, 4096);
+igt_main
+{
+ igt_fixture {
+ fd = drm_open_any();
- BEGIN_BATCH(2);
- OUT_BATCH(0);
- OUT_RELOC(tmp, I915_GEM_DOMAIN_CPU, 0, 0);
- ADVANCE_BATCH();
- ret = run_batch();
- if (ret != -EINVAL) {
- fprintf(stderr, "(cpu, 0) reloc not rejected\n");
- exit(1);
+ 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);
}
- BEGIN_BATCH(2);
- OUT_BATCH(0);
- OUT_RELOC(tmp, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU, 0);
- ADVANCE_BATCH();
- ret = run_batch();
- if (ret != -EINVAL) {
- fprintf(stderr, "(cpu, cpu) reloc not rejected\n");
- exit(1);
+ igt_subtest("cpu-domain") {
+ BEGIN_BATCH(2);
+ OUT_BATCH(0);
+ OUT_RELOC(tmp, I915_GEM_DOMAIN_CPU, 0, 0);
+ ADVANCE_BATCH();
+ igt_assert(run_batch() == -EINVAL);
+
+ BEGIN_BATCH(2);
+ OUT_BATCH(0);
+ OUT_RELOC(tmp, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU, 0);
+ ADVANCE_BATCH();
+ igt_assert(run_batch() == -EINVAL);
}
- BEGIN_BATCH(2);
- OUT_BATCH(0);
- OUT_RELOC(tmp, I915_GEM_DOMAIN_GTT, 0, 0);
- ADVANCE_BATCH();
- ret = run_batch();
- if (ret != -EINVAL) {
- fprintf(stderr, "(gtt, 0) reloc not rejected\n");
- exit(1);
+ igt_subtest("gtt-domain") {
+ BEGIN_BATCH(2);
+ OUT_BATCH(0);
+ OUT_RELOC(tmp, I915_GEM_DOMAIN_GTT, 0, 0);
+ ADVANCE_BATCH();
+ igt_assert(run_batch() == -EINVAL);
+
+ BEGIN_BATCH(2);
+ OUT_BATCH(0);
+ OUT_RELOC(tmp, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT, 0);
+ ADVANCE_BATCH();
+ igt_assert(run_batch() == -EINVAL);
}
- BEGIN_BATCH(2);
- OUT_BATCH(0);
- OUT_RELOC(tmp, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT, 0);
- ADVANCE_BATCH();
- ret = run_batch();
- if (ret != -EINVAL) {
- fprintf(stderr, "(gtt, gtt) reloc not rejected\n");
- exit(1);
+ /* Note: Older kernels disallow this. Punt on the skip check though
+ * since this is too old. */
+ igt_subtest("conflicting-write-domain") {
+ BEGIN_BATCH(4);
+ 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);
}
- intel_batchbuffer_free(batch);
- drm_intel_bufmgr_destroy(bufmgr);
+ igt_subtest("double-write-domain")
+ multi_write_domain(fd);
+
+ igt_subtest("invalid-gpu-domain") {
+ BEGIN_BATCH(2);
+ 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);
+ OUT_BATCH(0);
+ OUT_RELOC(tmp, I915_GEM_DOMAIN_GTT << 1,
+ I915_GEM_DOMAIN_GTT << 1, 0);
+ ADVANCE_BATCH();
+ igt_assert(run_batch() == -EINVAL);
+ }
- close(fd);
+ igt_fixture {
+ intel_batchbuffer_free(batch);
+ drm_intel_bufmgr_destroy(bufmgr);
- return 0;
+ close(fd);
+ }
}
diff --git a/tests/gem_exec_big.c b/tests/gem_exec_big.c
new file mode 100644
index 00000000..70753164
--- /dev/null
+++ b/tests/gem_exec_big.c
@@ -0,0 +1,123 @@
+/*
+ * 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"
+
+#define BATCH_SIZE (1024*1024)
+
+static int exec(int fd, uint32_t handle, uint32_t reloc_ofs)
+{
+ 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;
+ int ret = 0;
+
+ 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 = 0;
+ i915_execbuffer2_set_context_id(execbuf, 0);
+ execbuf.rsvd2 = 0;
+
+ ret = drmIoctl(fd,
+ DRM_IOCTL_I915_GEM_EXECBUFFER2,
+ &execbuf);
+ gem_sync(fd, handle);
+
+ gem_read(fd, handle, reloc_ofs, &tmp, 4);
+
+ igt_assert(tmp == gem_reloc[0].presumed_offset);
+
+ return ret;
+}
+
+igt_simple_main
+{
+ uint32_t batch[2] = {MI_BATCH_BUFFER_END};
+ uint32_t handle;
+ int fd;
+ uint32_t reloc_ofs;
+ unsigned batch_size;
+
+ igt_skip_on_simulation();
+
+ fd = drm_open_any();
+
+ for (batch_size = BATCH_SIZE/4; batch_size <= BATCH_SIZE; batch_size += 4096) {
+ handle = gem_create(fd, batch_size);
+ gem_write(fd, handle, 0, batch, sizeof(batch));
+
+ for (reloc_ofs = 4096; reloc_ofs < batch_size; reloc_ofs += 4096)
+ igt_assert(exec(fd, handle, reloc_ofs) == 0);
+ }
+
+ gem_close(fd, handle);
+
+ close(fd);
+}
diff --git a/tests/gem_exec_blt.c b/tests/gem_exec_blt.c
index eb5ae668..3bcef183 100644
--- a/tests/gem_exec_blt.c
+++ b/tests/gem_exec_blt.c
@@ -30,19 +30,17 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_chipset.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
#define OBJECT_SIZE 16384
@@ -52,7 +50,8 @@
#define BLT_SRC_TILED (1<<15)
#define BLT_DST_TILED (1<<11)
-static int gem_linear_blt(uint32_t *batch,
+static int gem_linear_blt(int fd,
+ uint32_t *batch,
uint32_t src,
uint32_t dst,
uint32_t length,
@@ -61,14 +60,17 @@ static int gem_linear_blt(uint32_t *batch,
uint32_t *b = batch;
int height = length / (16 * 1024);
- assert(height <= 1<<16);
+ igt_assert(height <= 1<<16);
if (height) {
- b[0] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
- b[1] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024);
- b[2] = 0;
- b[3] = height << 16 | (4*1024);
- b[4] = 0;
+ 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;
@@ -76,28 +78,37 @@ static int gem_linear_blt(uint32_t *batch,
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[5] = 0;
- b[6] = 16*1024;
- b[7] = 0;
+ 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 += 8;
+ b += i;
length -= height * 16*1024;
}
-
+
if (length) {
- b[0] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
- b[1] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024);
- b[2] = height << 16;
- b[3] = (1+height) << 16 | (length / 4);
- b[4] = 0;
+ 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;
@@ -105,19 +116,25 @@ static int gem_linear_blt(uint32_t *batch,
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[5] = height << 16;
- b[6] = 16*1024;
- b[7] = 0;
+ 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 += 8;
+ b += i;
}
b[0] = MI_BATCH_BUFFER_END;
@@ -126,19 +143,6 @@ static int gem_linear_blt(uint32_t *batch,
return (b+2 - batch) * sizeof(uint32_t);
}
-static int gem_exec(int fd, struct drm_i915_gem_execbuffer2 *execbuf, int loops)
-{
- int ret = 0;
-
- while (loops-- && ret == 0) {
- ret = drmIoctl(fd,
- DRM_IOCTL_I915_GEM_EXECBUFFER2,
- execbuf);
- }
-
- return ret;
-}
-
static double elapsed(const struct timeval *start,
const struct timeval *end,
int loop)
@@ -181,7 +185,7 @@ static void run(int object_size)
src = gem_create(fd, object_size);
dst = gem_create(fd, object_size);
- len = gem_linear_blt(buf, src, dst, object_size, reloc);
+ len = gem_linear_blt(fd, buf, src, dst, object_size, reloc);
gem_write(fd, handle, 0, buf, len);
exec[0].handle = src;
@@ -203,7 +207,10 @@ static void run(int object_size)
exec[1].rsvd2 = 0;
exec[2].handle = handle;
- exec[2].relocation_count = len > 40 ? 4 : 2;
+ 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;
@@ -227,18 +234,18 @@ static void run(int object_size)
i915_execbuffer2_set_context_id(execbuf, 0);
execbuf.rsvd2 = 0;
- for (count = 1; count <= 1<<17; count <<= 1) {
+ for (count = 1; count <= 1<<12; count <<= 1) {
struct timeval start, end;
gettimeofday(&start, NULL);
- if (gem_exec(fd, &execbuf, count))
- exit(1);
+ for (int loop = 0; loop < count; loop++)
+ gem_execbuf(fd, &execbuf);
gem_sync(fd, handle);
gettimeofday(&end, NULL);
- printf("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));
+ 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);
@@ -250,6 +257,10 @@ int main(int argc, char **argv)
{
int i;
+ igt_simple_init();
+
+ igt_skip_on_simulation();
+
if (argc > 1) {
for (i = 1; i < argc; i++) {
int object_size = atoi(argv[i]);
diff --git a/tests/gem_exec_faulting_reloc.c b/tests/gem_exec_faulting_reloc.c
index 863a1b03..acd703b6 100644
--- a/tests/gem_exec_faulting_reloc.c
+++ b/tests/gem_exec_faulting_reloc.c
@@ -30,19 +30,18 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_chipset.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "igt_debugfs.h"
/* Testcase: Submit patches with relocations in memory that will fault
*
@@ -51,12 +50,14 @@
#define OBJECT_SIZE 16384
-#define COPY_BLT_CMD (2<<29|0x53<<22|0x6)
+#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,
@@ -66,14 +67,19 @@ static int gem_linear_blt(uint32_t *batch,
uint32_t *b = batch;
int height = length / (16 * 1024);
- assert(height <= 1<<16);
+ igt_assert(height <= 1<<16);
if (height) {
- b[0] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
- b[1] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024);
- b[2] = 0;
- b[3] = height << 16 | (4*1024);
- b[4] = 0;
+ 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;
@@ -82,10 +88,17 @@ static int gem_linear_blt(uint32_t *batch,
reloc->presumed_offset = 0;
reloc++;
- b[5] = 0;
- b[6] = 16*1024;
- b[7] = 0;
+ 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;
@@ -93,16 +106,24 @@ static int gem_linear_blt(uint32_t *batch,
reloc->presumed_offset = 0;
reloc++;
- b += 8;
+ if (intel_gen(devid) >= 8)
+ b += 10;
+ else
+ b += 8;
length -= height * 16*1024;
}
if (length) {
- b[0] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
- b[1] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024);
- b[2] = height << 16;
- b[3] = (1+height) << 16 | (length / 4);
- b[4] = 0;
+ 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;
@@ -110,11 +131,17 @@ static int gem_linear_blt(uint32_t *batch,
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[5] = height << 16;
- b[6] = 16*1024;
- b[7] = 0;
+ 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;
@@ -122,7 +149,10 @@ static int gem_linear_blt(uint32_t *batch,
reloc->presumed_offset = 0;
reloc++;
- b += 8;
+ if (intel_gen(devid) >= 8)
+ b += 10;
+ else
+ b += 8;
}
b[0] = MI_BATCH_BUFFER_END;
@@ -131,28 +161,19 @@ static int gem_linear_blt(uint32_t *batch,
return (b+2 - batch) * sizeof(uint32_t);
}
-static void gem_exec(int fd, struct drm_i915_gem_execbuffer2 *execbuf)
-{
- int ret;
-
- ret = drmIoctl(fd,
- DRM_IOCTL_I915_GEM_EXECBUFFER2,
- execbuf);
- assert(ret == 0);
-}
-
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[20];
+ 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);
@@ -182,10 +203,13 @@ static void run(int object_size)
gem_write(fd, handle_relocs, 0, reloc, sizeof(reloc));
gtt_relocs = gem_mmap(fd, handle_relocs, 4096,
PROT_READ | PROT_WRITE);
- assert(gtt_relocs);
+ igt_assert(gtt_relocs);
exec[2].handle = handle;
- exec[2].relocation_count = len > 40 ? 4 : 2;
+ 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;
@@ -195,7 +219,7 @@ static void run(int object_size)
exec[2].rsvd2 = 0;
ring = 0;
- if (HAS_BLT_RING(intel_get_drm_devid(fd)))
+ if (HAS_BLT_RING(devid))
ring = I915_EXEC_BLT;
execbuf.buffers_ptr = (uintptr_t)exec;
@@ -210,7 +234,7 @@ static void run(int object_size)
i915_execbuffer2_set_context_id(execbuf, 0);
execbuf.rsvd2 = 0;
- gem_exec(fd, &execbuf);
+ gem_execbuf(fd, &execbuf);
gem_sync(fd, handle);
gem_close(fd, handle);
@@ -218,9 +242,13 @@ static void run(int object_size)
close(fd);
}
-int main(int argc, char **argv)
+igt_main
{
- run(OBJECT_SIZE);
-
- return 0;
+ 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
new file mode 100644
index 00000000..6ee75274
--- /dev/null
+++ b/tests/gem_exec_lut_handle.c
@@ -0,0 +1,204 @@
+/*
+ * 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 theh andle 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"
+
+#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
index 9dd055cf..542f98c3 100644
--- a/tests/gem_exec_nop.c
+++ b/tests/gem_exec_nop.c
@@ -30,19 +30,18 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
+#include "intel_io.h"
-#define MI_BATCH_BUFFER_END (0xA<<23)
+#define LOCAL_I915_EXEC_VEBOX (4<<0)
static double elapsed(const struct timeval *start,
const struct timeval *end,
@@ -51,7 +50,7 @@ static double elapsed(const struct timeval *start,
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)
+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];
@@ -74,7 +73,7 @@ static int exec(int fd, uint32_t handle, int loops)
execbuf.num_cliprects = 0;
execbuf.DR1 = 0;
execbuf.DR4 = 0;
- execbuf.flags = 0;
+ execbuf.flags = ring_id;
i915_execbuffer2_set_context_id(execbuf, 0);
execbuf.rsvd2 = 0;
@@ -88,32 +87,52 @@ static int exec(int fd, uint32_t handle, int loops)
return ret;
}
-int main(int argc, char **argv)
+static void loop(int fd, uint32_t handle, unsigned ring_id, const char *ring_name)
{
- uint32_t batch[2] = {MI_BATCH_BUFFER_END};
- uint32_t handle;
int count;
- int fd;
- fd = drm_open_any();
+ gem_require_ring(fd, ring_id);
- handle = gem_create(fd, 4096);
- gem_write(fd, handle, 0, batch, sizeof(batch));
-
- for (count = 1; count <= 1<<17; count <<= 1) {
+ for (count = 1; count <= SLOW_QUICK(1<<17, 1<<4); count <<= 1) {
struct timeval start, end;
gettimeofday(&start, NULL);
- if (exec(fd, handle, count))
- exit(1);
+ igt_assert(exec(fd, handle, count, ring_id) == 0);
gettimeofday(&end, NULL);
- printf("Time to exec x %d: %7.3fµs\n",
- count, elapsed(&start, &end, count));
+ igt_info("Time to exec x %d: %7.3fµs (ring=%s)\n",
+ count, elapsed(&start, &end, count), ring_name);
fflush(stdout);
}
- gem_close(fd, handle);
+}
+
+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");
- close(fd);
+ igt_subtest("blt")
+ loop(fd, handle, I915_EXEC_BLT, "blt");
- return 0;
+ 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
new file mode 100644
index 00000000..769969d3
--- /dev/null
+++ b/tests/gem_exec_params.c
@@ -0,0 +1,217 @@
+/*
+ * 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)
+
+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_cmpint(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("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
new file mode 100644
index 00000000..35d579d6
--- /dev/null
+++ b/tests/gem_exec_parse.c
@@ -0,0 +1,397 @@
+/*
+ * 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 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(expected_value == actual_value);
+
+ gem_close(fd, target_bo);
+
+ return 1;
+}
+
+static int 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];
+ int ret;
+
+ 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;
+
+ ret = drmIoctl(fd,
+ DRM_IOCTL_I915_GEM_EXECBUFFER2,
+ &execbuf);
+ if (ret == 0)
+ igt_assert(expected_ret == 0);
+ else
+ igt_assert(-errno == expected_ret);
+
+ gem_sync(fd, cmd_bo);
+
+ return 1;
+}
+
+static int 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 };
+ int ret;
+
+ // Allocate and fill a 2-page batch with noops
+ cmd_bo = gem_create(fd, 4096 * 2);
+ 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, 4096-sizeof(uint32_t), 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;
+
+ ret = drmIoctl(fd,
+ DRM_IOCTL_I915_GEM_EXECBUFFER2,
+ &execbuf);
+ if (ret == 0)
+ igt_assert(expected_ret == 0);
+ else
+ igt_assert(-errno == expected_ret);
+
+ gem_sync(fd, cmd_bo);
+ gem_close(fd, cmd_bo);
+
+ return 1;
+}
+
+uint32_t handle;
+int fd;
+
+#define MI_ARB_ON_OFF (0x8 << 23)
+#define MI_DISPLAY_FLIP ((0x14 << 23) | 1)
+#define MI_LOAD_REGISTER_IMM ((0x22 << 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);
+
+ 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,
+ };
+ igt_assert(
+ 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
+ };
+ igt_assert(
+ exec_batch(fd, handle,
+ arb_on_off, sizeof(arb_on_off),
+ I915_EXEC_RENDER,
+ -EINVAL));
+ igt_assert(
+ exec_batch(fd, handle,
+ arb_on_off, sizeof(arb_on_off),
+ I915_EXEC_BSD,
+ -EINVAL));
+ if (gem_has_vebox(fd)) {
+ igt_assert(
+ exec_batch(fd, handle,
+ arb_on_off, sizeof(arb_on_off),
+ I915_EXEC_VEBOX,
+ -EINVAL));
+ }
+ igt_assert(
+ 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,
+ };
+ igt_assert(
+ exec_batch(fd, handle,
+ lri_bad, sizeof(lri_bad),
+ I915_EXEC_RENDER,
+ -EINVAL));
+ igt_assert(
+ 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,
+ };
+ igt_assert(
+ exec_batch(fd, handle,
+ pc, sizeof(pc),
+ I915_EXEC_RENDER,
+ -EINVAL));
+ }
+
+ igt_subtest("batch-without-end") {
+ uint32_t noop[1024] = { 0 };
+ igt_assert(
+ 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,
+ };
+ igt_assert(
+ 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,
+ };
+ igt_assert(
+ exec_batch(fd, handle,
+ lri_ok, sizeof(lri_ok),
+ I915_EXEC_RENDER,
+ 0));
+ igt_assert(
+ exec_batch(fd, handle,
+ lri_bad, sizeof(lri_bad),
+ I915_EXEC_RENDER,
+ -EINVAL));
+ igt_assert(
+ exec_batch(fd, handle,
+ lri_extra_bad, sizeof(lri_extra_bad),
+ I915_EXEC_RENDER,
+ -EINVAL));
+ }
+
+ igt_fixture {
+ gem_close(fd, handle);
+
+ close(fd);
+ }
+}
diff --git a/tests/gem_fd_exhaustion.c b/tests/gem_fd_exhaustion.c
new file mode 100644
index 00000000..8ba631f6
--- /dev/null
+++ b/tests/gem_fd_exhaustion.c
@@ -0,0 +1,94 @@
+/*
+ * 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
index 3d50e334..84b0f555 100644
--- a/tests/gem_fence_thrash.c
+++ b/tests/gem_fence_thrash.c
@@ -26,22 +26,22 @@
*
*/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include <pthread.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#define OBJECT_SIZE (128*1024) /* restricted to 1MiB alignment on i915 fences */
@@ -53,17 +53,30 @@
* 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)
+bo_create (int fd, int tiling)
{
void *ptr;
int handle;
handle = gem_create(fd, OBJECT_SIZE);
- gem_set_tiling(fd, handle, I915_TILING_X, 1024);
+ /* dirty cpu caches a bit ... */
+ ptr = gem_mmap__cpu(fd, handle, 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);
@@ -74,12 +87,13 @@ bo_create (int fd)
static void *
bo_copy (void *_arg)
{
- int fd = *(int *)_arg;
+ struct test *t = (struct test *)_arg;
+ int fd = t->fd;
int n;
char *a, *b;
- a = bo_create (fd);
- b = bo_create (fd);
+ a = bo_create (fd, t->tiling);
+ b = bo_create (fd, t->tiling);
for (n = 0; n < 1000; n++) {
memcpy (a, b, OBJECT_SIZE);
@@ -89,31 +103,131 @@ bo_copy (void *_arg)
return NULL;
}
-int
-main(int argc, char **argv)
+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)
{
- drm_i915_getparam_t gp;
- pthread_t threads[32];
- int n, num_fences;
- int fd, ret;
+ struct test t;
+ pthread_t *threads;
+ int n, num_fences, num_threads;
- fd = drm_open_any();
+ t.fd = drm_open_any();
+ t.tiling = tiling;
+ t.num_surfaces = surfaces_per_thread;
- gp.param = I915_PARAM_NUM_FENCES_AVAIL;
- gp.value = &num_fences;
- ret = ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
- assert (ret == 0);
+ num_fences = gem_available_fences(t.fd);
+ igt_assert(num_fences > 0);
- printf ("creating %d threads\n", num_fences);
- assert (num_fences < sizeof (threads) / sizeof (threads[0]));
+ num_threads = threads_per_fence * num_fences;
- for (n = 0; n < num_fences; n++)
- pthread_create (&threads[n], NULL, bo_copy, &fd);
+ 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);
- for (n = 0; n < num_fences; n++)
- pthread_join (threads[n], NULL);
+ if (threads_per_fence) {
+ threads = calloc(sizeof(*threads), num_threads);
+ igt_assert(threads != NULL);
- close(fd);
+ 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_fenced_exec_thrash.c b/tests/gem_fenced_exec_thrash.c
index 8281449e..42b7841d 100644
--- a/tests/gem_fenced_exec_thrash.c
+++ b/tests/gem_fenced_exec_thrash.c
@@ -31,13 +31,17 @@
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <errno.h>
+
#include <drm.h>
-#include <i915_drm.h>
+#include "ioctl_wrappers.h"
#include "drmtest.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
+#include "igt_aux.h"
#define WIDTH 1024
#define HEIGHT 1024
@@ -45,9 +49,7 @@
#define BATCH_SIZE 4096
-#define MAX_FENCES 16
-
-#define MI_BATCH_BUFFER_END (0xA<<23)
+#define MAX_FENCES 32
/*
* Testcase: execbuf fence accounting
@@ -61,6 +63,55 @@
* 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(devid, 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);
+ BLIT_RELOC_UDW(devid);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(pitch);
+ OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
+ ADVANCE_BATCH();
+
+ if (IS_GEN6(devid) || IS_GEN7(devid)) {
+ BEGIN_BATCH(3);
+ 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)
{
@@ -86,22 +137,6 @@ batch_create (int fd)
return batch_handle;
}
-static int get_num_fences(int fd)
-{
- drm_i915_getparam_t gp;
- int ret, val;
-
- gp.param = I915_PARAM_NUM_FENCES_AVAIL;
- gp.value = &val;
- ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
- assert (ret == 0);
-
- printf ("total %d fences\n", val);
- assert(val > 4);
-
- return val - 2;
-}
-
static void fill_reloc(struct drm_i915_gem_relocation_entry *reloc, uint32_t handle)
{
reloc->offset = 2 * sizeof(uint32_t);
@@ -110,23 +145,34 @@ static void fill_reloc(struct drm_i915_gem_relocation_entry *reloc, uint32_t han
reloc->write_domain = 0;
}
-int
-main(int argc, char **argv)
+#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+1];
- struct drm_i915_gem_relocation_entry reloc[2*MAX_FENCES];
+ struct drm_i915_gem_exec_object2 exec[2][2*MAX_FENCES+3];
+ struct drm_i915_gem_relocation_entry reloc[2*MAX_FENCES+2];
- int fd = drm_open_any();
- int i, n, num_fences;
+ 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));
- num_fences = get_num_fences(fd) & ~1;
- assert(num_fences <= MAX_FENCES);
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;
@@ -149,18 +195,55 @@ main(int argc, char **argv)
do {
int ret;
+ if (flags & BUSY_LOAD)
+ emit_dummy_load();
+
ret = drmIoctl(fd,
DRM_IOCTL_I915_GEM_EXECBUFFER2,
&execbuf[0]);
- assert(ret == 0);
+ igt_assert(expected_errno ?
+ ret < 0 && errno == expected_errno :
+ ret == 0);
ret = drmIoctl(fd,
DRM_IOCTL_I915_GEM_EXECBUFFER2,
&execbuf[1]);
- assert(ret == 0);
+ igt_assert(expected_errno ?
+ ret < 0 && errno == expected_errno :
+ ret == 0);
} while (--loop);
- close(fd);
+ 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);
- return 0;
+ igt_fixture
+ close(fd);
}
diff --git a/tests/gem_flink.c b/tests/gem_flink.c
index c8694808..627a6778 100644
--- a/tests/gem_flink.c
+++ b/tests/gem_flink.c
@@ -28,14 +28,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
static void
@@ -43,24 +42,24 @@ test_flink(int fd)
{
struct drm_i915_gem_create create;
struct drm_gem_flink flink;
- struct drm_gem_open gem_open;
+ struct drm_gem_open open_struct;
int ret;
- printf("Testing flink and open.\n");
+ 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);
- assert(ret == 0);
+ igt_assert(ret == 0);
flink.handle = create.handle;
ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
- assert(ret == 0);
+ igt_assert(ret == 0);
- gem_open.name = flink.name;
- ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &gem_open);
- assert(ret == 0);
- assert(gem_open.handle != 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
@@ -71,21 +70,21 @@ test_double_flink(int fd)
struct drm_gem_flink flink2;
int ret;
- printf("Testing repeated flink.\n");
+ igt_info("Testing repeated flink.\n");
memset(&create, 0, sizeof(create));
create.size = 16 * 1024;
ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
- assert(ret == 0);
+ igt_assert(ret == 0);
flink.handle = create.handle;
ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
- assert(ret == 0);
+ igt_assert(ret == 0);
flink2.handle = create.handle;
ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink2);
- assert(ret == 0);
- assert(flink2.name == flink.name);
+ igt_assert(ret == 0);
+ igt_assert(flink2.name == flink.name);
}
static void
@@ -94,37 +93,77 @@ test_bad_flink(int fd)
struct drm_gem_flink flink;
int ret;
- printf("Testing error return on bad flink ioctl.\n");
+ igt_info("Testing error return on bad flink ioctl.\n");
flink.handle = 0x10101010;
ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
- assert(ret == -1 && errno == ENOENT);
+ igt_assert(ret == -1 && errno == ENOENT);
}
static void
test_bad_open(int fd)
{
- struct drm_gem_open gem_open;
+ struct drm_gem_open open_struct;
int ret;
- printf("Testing error return on bad open ioctl.\n");
+ igt_info("Testing error return on bad open ioctl.\n");
- gem_open.name = 0x10101010;
- ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &gem_open);
+ open_struct.name = 0x10101010;
+ ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open_struct);
- assert(ret == -1 && errno == ENOENT);
+ igt_assert(ret == -1 && errno == ENOENT);
}
-int main(int argc, char **argv)
+static void
+test_flink_lifetime(int fd)
{
- 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);
- fd = drm_open_any();
+ open_struct.name = flink.name;
+ ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open_struct);
+ igt_assert(ret == 0);
+ igt_assert(open_struct.handle != 0);
- test_flink(fd);
- test_double_flink(fd);
- test_bad_flink(fd);
- test_bad_open(fd);
+ close(fd2);
+ fd2 = drm_open_any();
- return 0;
+ 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
new file mode 100644
index 00000000..eab5ef2a
--- /dev/null
+++ b/tests/gem_flink_race.c
@@ -0,0 +1,216 @@
+/*
+ * 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"
+
+/* 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 ret, scanned;
+ int device = drm_get_card();
+ char *path;
+
+ igt_drop_caches_set(DROP_RETIRE);
+
+ ret = asprintf(&path, "/sys/kernel/debug/dri/%d/i915_gem_objects", device);
+ igt_assert(ret != -1);
+
+ file = fopen(path, "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();
+ igt_assert(fd >= 0);
+
+ 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();
+ igt_assert(fd >= 0);
+
+ 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_gtt_concurrent_blit.c b/tests/gem_gtt_concurrent_blit.c
deleted file mode 100644
index c68af7b5..00000000
--- a/tests/gem_gtt_concurrent_blit.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright © 2009,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:
- * Eric Anholt <eric@anholt.net>
- * Chris Wilson <chris@chris-wilson.co.uk>
- *
- */
-
-/** @file gem_cpu_concurrent_blit.c
- *
- * This is a test of GTT mmap read/write behavior when writing to active
- * buffers.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
-#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
-
-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--)
- assert(*vaddr++ == val);
-}
-
-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", 4*width*height, 0);
- 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;
-}
-
-int
-main(int argc, char **argv)
-{
- drm_intel_bufmgr *bufmgr;
- struct intel_batchbuffer *batch;
- int num_buffers = 128, max;
- drm_intel_bo *src[128], *dst[128], *dummy;
- int width = 512, height = 512;
- int fd;
- int i;
-
- fd = drm_open_any();
-
- 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 = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd));
-
- for (i = 0; i < num_buffers; i++) {
- src[i] = create_bo(bufmgr, i, width, height);
- dst[i] = create_bo(bufmgr, ~i, width, height);
- }
- dummy = create_bo(bufmgr, 0, width, height);
-
- /* try to overwrite the source values */
- for (i = 0; i < num_buffers; i++)
- intel_copy_bo(batch, dst[i], src[i], width, height);
- for (i = num_buffers; i--; )
- set_bo(src[i], 0xdeadbeef, width, height);
- for (i = 0; i < num_buffers; i++)
- cmp_bo(dst[i], i, width, height);
-
- /* try to read the results before the copy completes */
- for (i = 0; i < num_buffers; i++)
- intel_copy_bo(batch, dst[i], src[i], width, height);
- for (i = num_buffers; i--; )
- cmp_bo(dst[i], 0xdeadbeef, width, height);
-
- /* and finally try to trick the kernel into loosing the pending write */
- for (i = num_buffers; i--; )
- set_bo(src[i], 0xabcdabcd, width, height);
- for (i = 0; i < num_buffers; i++)
- intel_copy_bo(batch, dst[i], src[i], width, height);
- for (i = num_buffers; i--; )
- intel_copy_bo(batch, dummy, dst[i], width, height);
- for (i = num_buffers; i--; )
- cmp_bo(dst[i], 0xabcdabcd, width, height);
-
- return 0;
-}
diff --git a/tests/gem_gtt_cpu_tlb.c b/tests/gem_gtt_cpu_tlb.c
index 68533709..953070c0 100644
--- a/tests/gem_gtt_cpu_tlb.c
+++ b/tests/gem_gtt_cpu_tlb.c
@@ -33,18 +33,16 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
#define OBJ_SIZE (1024*1024)
@@ -68,8 +66,7 @@ create_bo(int fd)
return handle;
}
-int
-main(int argc, char **argv)
+igt_simple_main
{
int fd;
int i;
@@ -77,6 +74,8 @@ main(int argc, char **argv)
uint32_t *ptr;
+ igt_skip_on_simulation();
+
fd = drm_open_any();
handle = gem_create(fd, OBJ_SIZE);
@@ -90,7 +89,7 @@ main(int argc, char **argv)
/* stirr up the page allocator a bit. */
ptr = malloc(OBJ_SIZE);
- assert(ptr);
+ igt_assert(ptr);
memset(ptr, 0x1, OBJ_SIZE);
handle = create_bo(fd);
@@ -100,9 +99,7 @@ main(int argc, char **argv)
*/
gem_read(fd, handle, 0, ptr, OBJ_SIZE);
for (i = 0; i < OBJ_SIZE/4; i++)
- assert(ptr[i] == i);
+ igt_assert(ptr[i] == i);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_gtt_hog.c b/tests/gem_gtt_hog.c
new file mode 100644
index 00000000..5d475400
--- /dev/null
+++ b/tests/gem_gtt_hog.c
@@ -0,0 +1,192 @@
+/*
+ * 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);
+ exit(0);
+}
+
+igt_simple_main
+{
+ struct timeval start, end;
+ pid_t children[64];
+ data_t data = {};
+ int n;
+
+ /* 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);
+ for (n = 0; n < ARRAY_SIZE(children); n++) {
+ switch ((children[n] = fork())) {
+ case -1: igt_assert(0);
+ case 0: run(&data, n); break;
+ default: break;
+ }
+ }
+
+ for (n = 0; n < ARRAY_SIZE(children); n++) {
+ int status = -1;
+ while (waitpid(children[n], &status, 0) == -1 &&
+ errno == -EINTR)
+ ;
+ igt_assert(status == 0);
+ }
+ 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
index 73a3c6dc..385eeb73 100644
--- a/tests/gem_gtt_speed.c
+++ b/tests/gem_gtt_speed.c
@@ -31,16 +31,14 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#define OBJECT_SIZE 16384
@@ -61,10 +59,14 @@ int main(int argc, char **argv)
int loop, i, tiling;
int fd;
+ igt_simple_init();
+
+ igt_skip_on_simulation();
+
if (argc > 1)
size = atoi(argv[1]);
if (size == 0) {
- fprintf(stderr, "Invalid object size specified\n");
+ igt_warn("Invalid object size specified\n");
return 1;
}
@@ -73,12 +75,12 @@ int main(int argc, char **argv)
fd = drm_open_any();
handle = gem_create(fd, size);
- assert(handle);
+ igt_assert(handle);
for (tiling = I915_TILING_NONE; tiling <= I915_TILING_Y; tiling++) {
if (tiling != I915_TILING_NONE) {
- printf("\nSetting tiling mode to %s\n",
- tiling == I915_TILING_X ? "X" : "Y");
+ igt_info("\nSetting tiling mode to %s\n",
+ tiling == I915_TILING_X ? "X" : "Y");
gem_set_tiling(fd, handle, tiling, 512);
}
@@ -116,8 +118,8 @@ int main(int argc, char **argv)
munmap(base, size);
}
gettimeofday(&end, NULL);
- printf("Time to read %dk through a CPU map: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ 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);
@@ -131,8 +133,27 @@ int main(int argc, char **argv)
munmap(base, size);
}
gettimeofday(&end, NULL);
- printf("Time to write %dk through a CPU map: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ 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, 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, 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 */
@@ -140,16 +161,16 @@ int main(int argc, char **argv)
for (loop = 0; loop < 1000; loop++)
gem_write(fd, handle, 0, buf, size);
gettimeofday(&end, NULL);
- printf("Time to pwrite %dk through the CPU: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ 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);
- printf("Time to pread %dk through the CPU: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ igt_info("Time to pread %dk through the CPU: %7.3fµs\n",
+ size/1024, elapsed(&start, &end, loop));
}
/* prefault into gtt */
@@ -182,8 +203,8 @@ int main(int argc, char **argv)
munmap(base, size);
}
gettimeofday(&end, NULL);
- printf("Time to read %dk through a GTT map: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ igt_info("Time to read %dk through a GTT map: %7.3fµs\n",
+ size/1024, elapsed(&start, &end, loop));
/* mmap write */
gettimeofday(&start, NULL);
@@ -197,8 +218,28 @@ int main(int argc, char **argv)
munmap(base, size);
}
gettimeofday(&end, NULL);
- printf("Time to write %dk through a GTT map: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ igt_info("Time to write %dk through a GTT 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));
+
+ 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));
/* mmap read */
gettimeofday(&start, NULL);
@@ -216,8 +257,8 @@ int main(int argc, char **argv)
munmap(base, size);
}
gettimeofday(&end, NULL);
- printf("Time to read %dk (again) through a GTT map: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ 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 */
@@ -225,16 +266,16 @@ int main(int argc, char **argv)
for (loop = 0; loop < 1000; loop++)
gem_write(fd, handle, 0, buf, size);
gettimeofday(&end, NULL);
- printf("Time to pwrite %dk through the GTT: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ 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);
- printf("Time to pread %dk through the GTT: %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ 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);
@@ -243,8 +284,8 @@ int main(int argc, char **argv)
gem_sync(fd, handle);
}
gettimeofday(&end, NULL);
- printf("Time to pwrite %dk through the GTT (clflush): %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ 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);
@@ -253,11 +294,11 @@ int main(int argc, char **argv)
gem_read(fd, handle, 0, buf, size);
}
gettimeofday(&end, NULL);
- printf("Time to pread %dk through the GTT (clflush): %7.3fµs\n",
- size/1024, elapsed(&start, &end, loop));
+ igt_info("Time to pread %dk through the GTT (clflush): %7.3fµs\n",
+ size/1024, elapsed(&start, &end, loop));
/* partial writes */
- printf("Now partial writes.\n");
+ igt_info("Now partial writes.\n");
size /= 4;
/* partial GTT pwrite, including clflush */
@@ -267,7 +308,7 @@ int main(int argc, char **argv)
gem_sync(fd, handle);
}
gettimeofday(&end, NULL);
- printf("Time to pwrite %dk through the GTT (clflush): %7.3fµs\n",
+ 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 */
@@ -277,7 +318,7 @@ int main(int argc, char **argv)
gem_read(fd, handle, 0, buf, size);
}
gettimeofday(&end, NULL);
- printf("Time to pread %dk through the GTT (clflush): %7.3fµs\n",
+ igt_info("Time to pread %dk through the GTT (clflush): %7.3fµs\n",
size/1024, elapsed(&start, &end, loop));
size *= 4;
diff --git a/tests/gem_hang.c b/tests/gem_hang.c
index f9db3400..8ebf6067 100644
--- a/tests/gem_hang.c
+++ b/tests/gem_hang.c
@@ -29,18 +29,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
+#include "intel_chipset.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -72,11 +72,9 @@ int main(int argc, char **argv)
{
int fd;
- if (argc != 2) {
- fprintf(stderr, "usage: %s <disabled pipe number>\n",
- argv[0]);
- exit(-1);
- }
+ igt_assert_f(argc == 2,
+ "usage: %s <disabled pipe number>\n",
+ argv[0]);
bad_pipe = atoi(argv[1]);
diff --git a/tests/gem_hangcheck_forcewake.c b/tests/gem_hangcheck_forcewake.c
index 96a30fef..cb8dd110 100644
--- a/tests/gem_hangcheck_forcewake.c
+++ b/tests/gem_hangcheck_forcewake.c
@@ -28,18 +28,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
/*
* Testcase: Provoke the hangcheck timer on an otherwise idle system
@@ -58,13 +58,15 @@ struct intel_batchbuffer *batch;
uint32_t blob[2048*2048];
#define MAX_BLT_SIZE 128
-int main(int argc, char **argv)
+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();
@@ -75,7 +77,7 @@ int main(int argc, char **argv)
batch = intel_batchbuffer_alloc(bufmgr, devid);
act_size = 2048;
- printf("filling ring\n");
+ 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);
@@ -86,21 +88,20 @@ int main(int argc, char **argv)
pitch /= 4;
for (i = 0; i < 10000; i++) {
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB |
- XY_SRC_COPY_BLT_SRC_TILED |
- XY_SRC_COPY_BLT_DST_TILED);
+ BLIT_COPY_BATCH_START(devid,
+ 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(pitch);
OUT_RELOC_FENCED(bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
if (IS_GEN6(devid) || IS_GEN7(devid)) {
@@ -112,16 +113,14 @@ int main(int argc, char **argv)
}
}
- printf("waiting\n");
+ igt_info("waiting\n");
sleep(10);
- printf("done waiting, check dmesg\n");
+ igt_info("done waiting, check dmesg\n");
drm_intel_bo_unreference(bo);
intel_batchbuffer_free(batch);
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_largeobject.c b/tests/gem_largeobject.c
index 163bf101..0f929f8f 100644
--- a/tests/gem_largeobject.c
+++ b/tests/gem_largeobject.c
@@ -28,14 +28,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
/* Should take 64 pages to store the page pointers on 64 bit */
@@ -49,7 +48,7 @@ test_large_object(int fd)
struct drm_i915_gem_create create;
struct drm_i915_gem_pin pin;
uint32_t obj_size;
- int ret;
+ char *ptr;
memset(&create, 0, sizeof(create));
memset(&pin, 0, sizeof(pin));
@@ -61,35 +60,26 @@ test_large_object(int fd)
else
obj_size = OBJ_SIZE;
create.size = obj_size;
- printf("obj size %i\n", obj_size);
+ igt_info("obj size %i\n", obj_size);
- ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
- if (ret) {
- fprintf(stderr, "object creation failed: %s\n",
- strerror(errno));
- exit(ret);
- }
+ igt_assert(ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) == 0);
- pin.handle = create.handle;
- ret = ioctl(fd, DRM_IOCTL_I915_GEM_PIN, &pin);
- if (ret) {
- fprintf(stderr, "pin failed: %s\n",
- strerror(errno));
- exit(ret);
- }
+ /* 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 */
}
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
+ igt_skip_on_simulation();
+
fd = drm_open_any();
test_large_object(fd);
-
- return 0;
}
diff --git a/tests/gem_linear_blits.c b/tests/gem_linear_blits.c
index fe15f1d1..3a2fd8dd 100644
--- a/tests/gem_linear_blits.c
+++ b/tests/gem_linear_blits.c
@@ -36,18 +36,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
+#include "intel_chipset.h"
#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "igt_aux.h"
#define WIDTH 512
#define HEIGHT 512
@@ -57,27 +58,36 @@ static uint32_t linear[WIDTH*HEIGHT];
static void
copy(int fd, uint32_t dst, uint32_t src)
{
- uint32_t batch[10];
+ 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;
+ int ret, i=0;
- batch[0] = XY_SRC_COPY_BLT_CMD |
+ batch[i++] = XY_SRC_COPY_BLT_CMD |
XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB;
- batch[1] = (3 << 24) | /* 32 bits */
+ 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[2] = 0; /* dst x1,y1 */
- batch[3] = (HEIGHT << 16) | WIDTH; /* dst x2,y2 */
- batch[4] = 0; /* dst reloc */
- batch[5] = 0; /* src x1,y1 */
- batch[6] = WIDTH*4;
- batch[7] = 0; /* src reloc */
- batch[8] = MI_BATCH_BUFFER_END;
- batch[9] = MI_NOOP;
+ 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));
@@ -92,6 +102,8 @@ copy(int fd, uint32_t dst, uint32_t src)
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;
@@ -125,7 +137,7 @@ copy(int fd, uint32_t dst, uint32_t src)
exec.buffers_ptr = (uintptr_t)obj;
exec.buffer_count = 3;
exec.batch_start_offset = 0;
- exec.batch_len = sizeof(batch);
+ exec.batch_len = i * 4;
exec.DR1 = exec.DR4 = 0;
exec.num_cliprects = 0;
exec.cliprects_ptr = 0;
@@ -138,7 +150,7 @@ copy(int fd, uint32_t dst, uint32_t src)
drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
}
- assert(ret == 0);
+ igt_assert(ret == 0);
gem_close(fd, handle);
}
@@ -166,36 +178,19 @@ check_bo(int fd, uint32_t handle, uint32_t val)
gem_read(fd, handle, 0, linear, sizeof(linear));
for (i = 0; i < WIDTH*HEIGHT; i++) {
- if (linear[i] != val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- val, linear[i], i * 4);
- abort();
- }
+ 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)
+static void run_test(int fd, int count)
{
uint32_t *handle, *start_val;
uint32_t start = 0;
- int i, fd, count;
-
- fd = drm_open_any();
-
- count = 0;
- if (argc > 1)
- count = atoi(argv[1]);
- if (count == 0)
- 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;
- printf("not enough RAM to run test, reducing buffer count\n");
- }
-
- printf("Using %d 1MiB buffers\n", count);
+ int i;
handle = malloc(sizeof(uint32_t)*count*2);
start_val = handle + count;
@@ -206,11 +201,11 @@ int main(int argc, char **argv)
start += 1024 * 1024 / 4;
}
- printf("Verifying initialisation...\n");
+ igt_info("Verifying initialisation...\n");
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Cyclic blits, forward...\n");
+ igt_info("Cyclic blits, forward...\n");
for (i = 0; i < count * 4; i++) {
int src = i % count;
int dst = (i + 1) % count;
@@ -221,7 +216,7 @@ int main(int argc, char **argv)
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Cyclic blits, backward...\n");
+ igt_info("Cyclic blits, backward...\n");
for (i = 0; i < count * 4; i++) {
int src = (i + 1) % count;
int dst = i % count;
@@ -232,7 +227,7 @@ int main(int argc, char **argv)
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Random blits...\n");
+ igt_info("Random blits...\n");
for (i = 0; i < count * 4; i++) {
int src = random() % count;
int dst = random() % count;
@@ -243,8 +238,50 @@ int main(int argc, char **argv)
copy(fd, handle[dst], handle[src]);
start_val[dst] = start_val[src];
}
- for (i = 0; i < count; i++)
+ 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, count = 0;
+
+ igt_skip_on_simulation();
+
+ igt_subtest_init(argc, argv);
+
+ igt_fixture {
+ fd = drm_open_any();
+
+ if (argc > 1)
+ count = atoi(argv[1]);
+ if (count == 0)
+ count = 3 * gem_aperture_size(fd) / (1024*1024) / 2;
+ else if (count < 2) {
+ fprintf(stderr, "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);
+ }
+
+ igt_subtest("normal")
+ run_test(fd, count);
+
+ igt_subtest("interruptible") {
+ igt_fork_signal_helper();
+ run_test(fd, count);
+ igt_stop_signal_helper();
+ }
- return 0;
+ igt_exit();
}
diff --git a/tests/gem_lut_handle.c b/tests/gem_lut_handle.c
new file mode 100644
index 00000000..d3f6f732
--- /dev/null
+++ b/tests/gem_lut_handle.c
@@ -0,0 +1,238 @@
+/*
+ * 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 theh andle 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"
+
+#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
new file mode 100644
index 00000000..04a82aa3
--- /dev/null
+++ b/tests/gem_madvise.c
@@ -0,0 +1,155 @@
+/*
+ * 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"
+
+#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;
+ 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
new file mode 100644
index 00000000..db2380b4
--- /dev/null
+++ b/tests/gem_media_fill.c
@@ -0,0 +1,142 @@
+/*
+ * 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 <getopt.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 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_media_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
index f9369f43..46ef3ece 100644
--- a/tests/gem_mmap.c
+++ b/tests/gem_mmap.c
@@ -29,68 +29,69 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#define OBJECT_SIZE 16384
+int fd;
+int handle;
-int main(int argc, char **argv)
+igt_main
{
- int fd;
struct drm_i915_gem_mmap arg;
uint8_t expected[OBJECT_SIZE];
uint8_t buf[OBJECT_SIZE];
uint8_t *addr;
int ret;
- int handle;
- fd = drm_open_any();
+ igt_fixture
+ fd = drm_open_any();
- memset(&arg, 0, sizeof(arg));
- arg.handle = 0x10101010;
- arg.offset = 0;
- arg.size = 4096;
- printf("Testing mmaping of bad object.\n");
- ret = ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, &arg);
- assert(ret == -1 && errno == ENOENT);
+ 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);
+ }
- handle = gem_create(fd, OBJECT_SIZE);
+ igt_fixture
+ handle = gem_create(fd, OBJECT_SIZE);
- printf("Testing mmaping of newly created object.\n");
- arg.handle = handle;
- arg.offset = 0;
- arg.size = OBJECT_SIZE;
- ret = ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, &arg);
- assert(ret == 0);
- addr = (uint8_t *)(uintptr_t)arg.addr_ptr;
+ igt_subtest("new-object") {
+ 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;
- printf("Testing contents of newly created object.\n");
- memset(expected, 0, sizeof(expected));
- assert(memcmp(addr, expected, sizeof(expected)) == 0);
+ igt_info("Testing contents of newly created object.\n");
+ memset(expected, 0, sizeof(expected));
+ igt_assert(memcmp(addr, expected, sizeof(expected)) == 0);
- printf("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);
- assert(memcmp(buf, addr, sizeof(buf)) == 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);
- printf("Testing that mapping stays after close\n");
- gem_close(fd, handle);
- 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);
- printf("Testing unmapping\n");
- munmap(addr, OBJECT_SIZE);
+ igt_info("Testing unmapping\n");
+ munmap(addr, OBJECT_SIZE);
+ }
- close(fd);
-
- return 0;
+ igt_fixture
+ close(fd);
}
diff --git a/tests/gem_mmap_gtt.c b/tests/gem_mmap_gtt.c
index e7a48679..7ba5e39c 100644
--- a/tests/gem_mmap_gtt.c
+++ b/tests/gem_mmap_gtt.c
@@ -25,22 +25,22 @@
*
*/
+#define _GNU_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
+#include "igt_debugfs.h"
-#define OBJECT_SIZE (16*1024*1024)
+static int OBJECT_SIZE = 16*1024*1024;
static void set_domain(int fd, uint32_t handle)
{
@@ -53,7 +53,7 @@ mmap_bo(int fd, uint32_t handle)
void *ptr;
ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
- assert(ptr != MAP_FAILED);
+ igt_assert(ptr != MAP_FAILED);
return ptr;
}
@@ -74,6 +74,43 @@ create_pointer(int fd)
}
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_copy(int fd)
{
void *src, *dst;
@@ -144,18 +181,42 @@ test_read(int fd)
munmap(dst, OBJECT_SIZE);
}
-int main(int argc, char **argv)
+static void
+run_without_prefault(int fd,
+ void (*func)(int fd))
{
- int fd;
-
- fd = drm_open_any();
-
- test_copy(fd);
- test_read(fd);
- test_write(fd);
- test_write_gtt(fd);
+ igt_disable_prefault();
+ func(fd);
+ igt_enable_prefault();
+}
- close(fd);
+int fd;
- return 0;
+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("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-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_fixture
+ close(fd);
}
diff --git a/tests/gem_mmap_offset_exhaustion.c b/tests/gem_mmap_offset_exhaustion.c
index 51ae5990..914fe6eb 100644
--- a/tests/gem_mmap_offset_exhaustion.c
+++ b/tests/gem_mmap_offset_exhaustion.c
@@ -29,15 +29,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#define OBJECT_SIZE (1024*1024)
@@ -61,11 +59,7 @@ create_and_map_bo(int fd)
handle = gem_create(fd, OBJECT_SIZE);
ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
-
- if (!ptr) {
- fprintf(stderr, "mmap failed\n");
- assert(ptr);
- }
+ igt_assert(ptr);
/* touch it to force it into the gtt */
*ptr = 0;
@@ -79,10 +73,12 @@ create_and_map_bo(int fd)
gem_madvise(fd, handle, I915_MADV_DONTNEED);
}
-int main(int argc, char **argv)
+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
@@ -91,6 +87,4 @@ int main(int argc, char **argv)
create_and_map_bo(fd);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_multi_bsd_sync_loop.c b/tests/gem_multi_bsd_sync_loop.c
new file mode 100644
index 00000000..003da42f
--- /dev/null
+++ b/tests/gem_multi_bsd_sync_loop.c
@@ -0,0 +1,164 @@
+/*
+ * 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"
+
+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);
+ 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);
+ 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
new file mode 100644
index 00000000..9acfda47
--- /dev/null
+++ b/tests/gem_non_secure_batch.c
@@ -0,0 +1,113 @@
+/*
+ * 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"
+
+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.
+ */
+
+#define MI_LOAD_REGISTER_IMM (0x22<<23)
+
+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);
+ OUT_BATCH(MI_LOAD_REGISTER_IMM | 1);
+ 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);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ 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);
+
+ return 0;
+}
diff --git a/tests/gem_partial_pwrite_pread.c b/tests/gem_partial_pwrite_pread.c
index 5c8f6f5f..7945ba79 100644
--- a/tests/gem_partial_pwrite_pread.c
+++ b/tests/gem_partial_pwrite_pread.c
@@ -28,18 +28,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
+#include "igt_aux.h"
/*
* Testcase: pwrite/pread consistency when touching partial cachelines
@@ -62,19 +63,18 @@ int fd;
static void
copy_bo(drm_intel_bo *src, drm_intel_bo *dst)
{
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(4096);
OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
@@ -96,36 +96,20 @@ blt_bo_fill(drm_intel_bo *tmp_bo, drm_intel_bo *bo, int val)
if (bo->offset < mappable_gtt_limit &&
(IS_G33(devid) || intel_gen(devid) >= 4))
- drmtest_trash_aperture();
+ igt_trash_aperture();
copy_bo(tmp_bo, bo);
}
#define MAX_BLT_SIZE 128
#define ROUNDS 1000
-int main(int argc, char **argv)
+uint8_t tmp[BO_SIZE];
+
+static void test_partial_reads(void)
{
int i, j;
- uint8_t tmp[BO_SIZE];
- uint8_t *gtt_ptr;
-
- srandom(0xdeadbeef);
- 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);
-
- drmtest_init_aperture_trashers(bufmgr);
- mappable_gtt_limit = gem_mappable_aperture_size();
-
- printf("checking partial reads\n");
+ igt_info("checking partial reads\n");
for (i = 0; i < ROUNDS; i++) {
int start, len;
int val = i % 256;
@@ -137,17 +121,22 @@ int main(int argc, char **argv)
drm_intel_bo_get_subdata(scratch_bo, start, len, tmp);
for (j = 0; j < len; j++) {
- if (tmp[j] != val) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ igt_assert_f(tmp[j] == val,
+ "mismatch at %i, got: %i, expected: %i\n",
+ j, tmp[j], val);
}
- drmtest_progress("partial reads test: ", i, ROUNDS);
+ igt_progress("partial reads test: ", i, ROUNDS);
}
- printf("checking partial writes\n");
+}
+
+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;
@@ -166,32 +155,33 @@ int main(int argc, char **argv)
gtt_ptr = staging_bo->virtual;
for (j = 0; j < start; j++) {
- if (gtt_ptr[j] != val) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ igt_assert_f(gtt_ptr[j] == val,
+ "mismatch at %i, got: %i, expected: %i\n",
+ j, tmp[j], val);
}
for (; j < start + len; j++) {
- if (gtt_ptr[j] != tmp[0]) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], i);
- exit(1);
- }
+ 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++) {
- if (gtt_ptr[j] != val) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ 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);
- drmtest_progress("partial writes test: ", i, ROUNDS);
+ igt_progress("partial writes test: ", i, ROUNDS);
}
- printf("checking partial writes after partial reads\n");
+}
+
+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;
@@ -204,11 +194,9 @@ int main(int argc, char **argv)
drm_intel_bo_get_subdata(scratch_bo, start, len, tmp);
for (j = 0; j < len; j++) {
- if (tmp[j] != val) {
- printf("mismatch in read at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ 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
@@ -229,35 +217,76 @@ int main(int argc, char **argv)
gtt_ptr = staging_bo->virtual;
for (j = 0; j < start; j++) {
- if (gtt_ptr[j] != val) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ igt_assert_f(gtt_ptr[j] == val,
+ "mismatch at %i, got: %i, expected: %i\n",
+ j, tmp[j], val);
}
for (; j < start + len; j++) {
- if (gtt_ptr[j] != tmp[0]) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], tmp[0]);
- exit(1);
- }
+ 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++) {
- if (gtt_ptr[j] != val) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ 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);
- drmtest_progress("partial read/writes test: ", i, ROUNDS);
+ 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();
}
- drmtest_cleanup_aperture_trashers();
- drm_intel_bufmgr_destroy(bufmgr);
+ do_tests(-1, "");
- close(fd);
+ /* Repeat the tests using different levels of snooping */
+ do_tests(0, "-uncached");
+ do_tests(1, "-snoop");
+ do_tests(2, "-display");
- return 0;
+ 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
new file mode 100644
index 00000000..8b5a62ef
--- /dev/null
+++ b/tests/gem_persistent_relocs.c
@@ -0,0 +1,365 @@
+/*
+ * 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"
+
+/*
+ * 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(devid, 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);
+ BLIT_RELOC_UDW(devid);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(pitch);
+ OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
+ ADVANCE_BATCH();
+
+ if (intel_gen(devid) >= 6) {
+ BEGIN_BATCH(3);
+ 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
new file mode 100644
index 00000000..91e1456a
--- /dev/null
+++ b/tests/gem_pin.c
@@ -0,0 +1,250 @@
+/*
+ * 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"
+
+#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
index e03cddd7..c95c2bdf 100644
--- a/tests/gem_pipe_control_store_loop.c
+++ b/tests/gem_pipe_control_store_loop.c
@@ -34,18 +34,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -64,25 +64,54 @@ uint32_t devid;
/* Like the store dword test, but we create new command buffers each time */
static void
-store_pipe_control_loop(void)
+store_pipe_control_loop(bool preuse_buffer)
{
int i, val = 0;
uint32_t *buf;
drm_intel_bo *target_bo;
- for (i = 0; i < 0x10000; i++) {
+ 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);
- if (!target_bo) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
+ igt_assert(target_bo);
+
+ if (preuse_buffer) {
+ COLOR_BLIT_COPY_BATCH_START(devid, 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(target_bo,
+ I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+ 0);
+ BLIT_RELOC_UDW(devid);
+ 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 (intel_gen(devid) >= 6) {
+ if (intel_gen(devid) >= 8) {
+ BEGIN_BATCH(5);
+ OUT_BATCH(GFX_OP_PIPE_CONTROL + 1);
+ OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
+ OUT_RELOC(target_bo,
+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+ PIPE_CONTROL_GLOBAL_GTT);
+ BLIT_RELOC_UDW(devid);
+ OUT_BATCH(val); /* write data */
+ ADVANCE_BATCH();
+
+ } else if (intel_gen(devid) >= 6) {
/* work-around hw issue, see intel_emit_post_sync_nonzero_flush
* in mesa sources. */
BEGIN_BATCH(4);
@@ -119,66 +148,50 @@ store_pipe_control_loop(void)
drm_intel_bo_map(target_bo, 1);
buf = target_bo->virtual;
- if (buf[0] != val) {
- fprintf(stderr,
- "value mismatch: cur 0x%08x, stored 0x%08x\n",
- buf[0], val);
- exit(-1);
- }
- buf[0] = 0; /* let batch write it again */
- drm_intel_bo_unmap(target_bo);
+ 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++;
}
-
- printf("completed %d writes successfully\n", i);
}
-int main(int argc, char **argv)
+int fd;
+
+igt_main
{
- int fd;
+ igt_fixture {
+ fd = drm_open_any();
+ devid = intel_get_drm_devid(fd);
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", argv[0]);
- exit(-1);
- }
+ bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
+ igt_assert(bufmgr);
- fd = drm_open_any();
- devid = intel_get_drm_devid(fd);
+ igt_skip_on(IS_GEN2(devid) || IS_GEN3(devid));
+ igt_skip_on(devid == PCI_CHIP_I965_G); /* has totally broken pipe control */
- bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
+ /* 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! */
- if (IS_GEN2(devid) || IS_GEN3(devid)) {
- fprintf(stderr, "no pipe_control on gen2/3\n");
- return 77;
- }
- if (devid == PCI_CHIP_I965_G) {
- fprintf(stderr, "pipe_control totally broken on i965\n");
- return 77;
- }
- /* 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);
- if (!batch) {
- fprintf(stderr, "failed to create batch buffer\n");
- exit(-1);
+ batch = intel_batchbuffer_alloc(bufmgr, devid);
+ igt_assert(batch);
}
- store_pipe_control_loop();
+ igt_subtest("fresh-buffer")
+ store_pipe_control_loop(false);
- intel_batchbuffer_free(batch);
- drm_intel_bufmgr_destroy(bufmgr);
+ igt_subtest("reused-buffer")
+ store_pipe_control_loop(true);
- close(fd);
+ igt_fixture {
+ intel_batchbuffer_free(batch);
+ drm_intel_bufmgr_destroy(bufmgr);
- return 0;
+ close(fd);
+ }
}
diff --git a/tests/gem_pread.c b/tests/gem_pread.c
new file mode 100644
index 00000000..cc83948b
--- /dev/null
+++ b/tests/gem_pread.c
@@ -0,0 +1,153 @@
+/*
+ * 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
index c9c8b02c..0b8bfa6c 100644
--- a/tests/gem_pread_after_blit.c
+++ b/tests/gem_pread_after_blit.c
@@ -37,18 +37,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
+#include "igt_aux.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -87,13 +88,10 @@ verify_large_read(drm_intel_bo *bo, uint32_t val)
drm_intel_bo_get_subdata(bo, 0, size, buf);
for (i = 0; i < size / 4; i++) {
- if (buf[i] != val) {
- fprintf(stderr,
- "Unexpected value 0x%08x instead of "
- "0x%08x at offset 0x%08x (%p)\n",
- buf[i], val, i * 4, buf);
- abort();
- }
+ 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++;
}
}
@@ -112,64 +110,126 @@ verify_small_read(drm_intel_bo *bo, uint32_t val)
drm_intel_bo_get_subdata(bo, offset, PAGE_SIZE, buf);
for (i = 0; i < PAGE_SIZE; i += 4) {
- if (buf[i / 4] != val) {
- fprintf(stderr,
- "Unexpected value 0x%08x instead of "
- "0x%08x at offset 0x%08x\n",
- buf[i / 4], val, i * 4);
- abort();
- }
+ 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++;
}
}
}
-int
-main(int argc, char **argv)
+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)
{
- int fd;
- drm_intel_bo *src1, *src2, *bo;
- uint32_t start1 = 0;
- uint32_t start2 = 1024 * 1024 / 4;
+ if (cache_level != -1) {
+ gem_set_caching(fd, tmp[0]->handle, cache_level);
+ gem_set_caching(fd, tmp[1]->handle, cache_level);
+ }
- fd = drm_open_any();
+ do {
+ /* First, do a full-buffer read after blitting */
+ intel_copy_bo(batch, tmp[0], src[0], width*height*4);
+ verify_large_read(tmp[0], start[0]);
+ intel_copy_bo(batch, tmp[0], src[1], width*height*4);
+ verify_large_read(tmp[0], start[1]);
+
+ intel_copy_bo(batch, tmp[0], src[0], width*height*4);
+ verify_small_read(tmp[0], start[0]);
+ intel_copy_bo(batch, tmp[0], src[1], width*height*4);
+ verify_small_read(tmp[0], start[1]);
+
+ intel_copy_bo(batch, tmp[0], src[0], width*height*4);
+ verify_large_read(tmp[0], start[0]);
+
+ intel_copy_bo(batch, tmp[0], src[0], width*height*4);
+ intel_copy_bo(batch, tmp[1], src[1], width*height*4);
+ verify_large_read(tmp[0], start[0]);
+ verify_large_read(tmp[1], start[1]);
+
+ intel_copy_bo(batch, tmp[0], src[0], width*height*4);
+ intel_copy_bo(batch, tmp[1], src[1], width*height*4);
+ verify_large_read(tmp[1], start[1]);
+ verify_large_read(tmp[0], start[0]);
+
+ intel_copy_bo(batch, tmp[1], src[0], width*height*4);
+ intel_copy_bo(batch, tmp[0], src[1], width*height*4);
+ verify_large_read(tmp[0], start[1]);
+ verify_large_read(tmp[1], start[0]);
+ } while (--loop);
+}
- 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_bo *src[2], *dst[2];
+int fd;
- src1 = create_bo(start1);
- src2 = create_bo(start2);
+igt_main
+{
+ const uint32_t start[2] = {0, 1024 * 1024 / 4};
- bo = drm_intel_bo_alloc(bufmgr, "dst bo", size, 4096);
+ igt_skip_on_simulation();
- /* First, do a full-buffer read after blitting */
- printf("Large read after blit 1\n");
- intel_copy_bo(batch, bo, src1, width, height);
- verify_large_read(bo, start1);
- printf("Large read after blit 2\n");
- intel_copy_bo(batch, bo, src2, width, height);
- verify_large_read(bo, start2);
+ igt_fixture {
+ fd = drm_open_any();
- printf("Small reads after blit 1\n");
- intel_copy_bo(batch, bo, src1, width, height);
- verify_small_read(bo, start1);
- printf("Small reads after blit 2\n");
- intel_copy_bo(batch, bo, src2, width, height);
- verify_small_read(bo, start2);
+ 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));
- printf("Large read after blit 3\n");
- intel_copy_bo(batch, bo, src1, width, height);
- verify_large_read(bo, start1);
+ src[0] = create_bo(start[0]);
+ src[1] = create_bo(start[1]);
- drm_intel_bo_unreference(src1);
- drm_intel_bo_unreference(src2);
- drm_intel_bo_unreference(bo);
+ dst[0] = drm_intel_bo_alloc(bufmgr, "dst bo", size, 4096);
+ dst[1] = drm_intel_bo_alloc(bufmgr, "dst bo", size, 4096);
+ }
- intel_batchbuffer_free(batch);
- drm_intel_bufmgr_destroy(bufmgr);
+ igt_subtest("normal")
+ do_test(fd, -1, src, start, dst, 1);
- close(fd);
+ igt_subtest("interruptible") {
+ igt_fork_signal_helper();
+ do_test(fd, -1, src, start, dst, 100);
+ igt_stop_signal_helper();
+ }
+
+ igt_subtest("normal-uncached")
+ do_test(fd, 0, src, start, dst, 1);
+
+ igt_subtest("interruptible-uncached") {
+ igt_fork_signal_helper();
+ do_test(fd, 0, src, start, dst, 100);
+ igt_stop_signal_helper();
+ }
+
+ igt_subtest("normal-snoop")
+ do_test(fd, 1, src, start, dst, 1);
+
+ igt_subtest("interruptible-snoop") {
+ igt_fork_signal_helper();
+ do_test(fd, 1, src, start, dst, 100);
+ igt_stop_signal_helper();
+ }
+
+ igt_subtest("normal-display")
+ do_test(fd, 2, src, start, dst, 1);
- return 0;
+ igt_subtest("interruptible-display") {
+ igt_fork_signal_helper();
+ do_test(fd, 2, src, start, dst, 100);
+ igt_stop_signal_helper();
+ }
+
+ 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
index 051ed3b5..6378b0a4 100644
--- a/tests/gem_pwrite.c
+++ b/tests/gem_pwrite.c
@@ -30,16 +30,14 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#define OBJECT_SIZE 16384
@@ -49,7 +47,6 @@
#define BLT_WRITE_RGB (1<<20)
#define BLT_SRC_TILED (1<<15)
#define BLT_DST_TILED (1<<11)
-#define MI_BATCH_BUFFER_END (0xA<<23)
static void do_gem_write(int fd, uint32_t handle, void *buf, int len, int loops)
{
@@ -84,39 +81,81 @@ static const char *bytes_per_sec(char *buf, double v)
}
+uint32_t *src, dst;
+int fd;
+
int main(int argc, char **argv)
{
int object_size = 0;
uint32_t buf[20];
- uint32_t *src, dst;
- int fd, count;
+ int count;
+ const struct {
+ int level;
+ const char *name;
+ } cache[] = {
+ { 0, "uncached" },
+ { 1, "snoop" },
+ { 2, "display" },
+ { -1 },
+ }, *c;
+
+ igt_skip_on_simulation();
- if (argc > 1)
+ 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;
- fd = drm_open_any();
-
- dst = gem_create(fd, object_size);
- src = malloc(object_size);
- 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);
- printf("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);
+ 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);
+ }
}
- free(src);
- gem_close(fd, dst);
- close(fd);
+ 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);
+ }
- return 0;
+ igt_exit();
}
diff --git a/tests/gem_pwrite_pread.c b/tests/gem_pwrite_pread.c
new file mode 100644
index 00000000..c2dc74b7
--- /dev/null
+++ b/tests/gem_pwrite_pread.c
@@ -0,0 +1,413 @@
+/*
+ * 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, OBJECT_SIZE, PROT_WRITE);
+ dst_ptr = gem_mmap__cpu(fd, dst, 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, OBJECT_SIZE, PROT_WRITE);
+ dst_ptr = gem_mmap__cpu(fd, dst, 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
index 68c3ff28..a8a7105e 100644
--- a/tests/gem_readwrite.c
+++ b/tests/gem_readwrite.c
@@ -29,14 +29,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#define OBJECT_SIZE 16384
@@ -44,91 +43,105 @@
static int
do_read(int fd, int handle, void *buf, int offset, int size)
{
- struct drm_i915_gem_pread read;
+ 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(&read, 0, sizeof(read));
- read.handle = handle;
- read.data_ptr = (uintptr_t)buf;
- read.size = size;
- read.offset = offset;
+ 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, &read);
+ 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 write;
+ struct drm_i915_gem_pwrite gem_pwrite;
- memset(&write, 0, sizeof(write));
- write.handle = handle;
- write.data_ptr = (uintptr_t)buf;
- write.size = size;
- write.offset = offset;
+ 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, &write);
+ return ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &gem_pwrite);
}
-int main(int argc, char **argv)
+int fd;
+uint32_t handle;
+
+igt_main
{
- int fd;
uint8_t expected[OBJECT_SIZE];
uint8_t buf[OBJECT_SIZE];
int ret;
- int handle;
-
- fd = drm_open_any();
-
- handle = gem_create(fd, OBJECT_SIZE);
-
- printf("Testing contents of newly created object.\n");
- ret = do_read(fd, handle, buf, 0, OBJECT_SIZE);
- assert(ret == 0);
- memset(&expected, 0, sizeof(expected));
- assert(memcmp(expected, buf, sizeof(expected)) == 0);
-
- printf("Testing read beyond end of buffer.\n");
- ret = do_read(fd, handle, buf, OBJECT_SIZE / 2, OBJECT_SIZE);
- assert(ret == -1 && errno == EINVAL);
-
- printf("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);
- assert(ret == 0);
- ret = do_read(fd, handle, buf, 0, OBJECT_SIZE);
- assert(ret == 0);
- assert(memcmp(buf, expected, sizeof(buf)) == 0);
-
- printf("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);
- assert(ret == 0);
- ret = do_read(fd, handle, buf, 0, OBJECT_SIZE);
- assert(ret == 0);
- assert(memcmp(buf, expected, sizeof(buf)) == 0);
-
- printf("Testing partial read of buffer\n");
- ret = do_read(fd, handle, buf, 512, 1024);
- assert(ret == 0);
- assert(memcmp(buf, expected + 512, 1024) == 0);
-
- printf("Testing read of bad buffer handle\n");
- ret = do_read(fd, 1234, buf, 0, 1024);
- assert(ret == -1 && errno == ENOENT);
-
- printf("Testing write of bad buffer handle\n");
- ret = do_write(fd, 1234, buf, 0, 1024);
- assert(ret == -1 && errno == ENOENT);
-
- close(fd);
-
- return 0;
+
+ 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
index 1d6db1f1..4220d69f 100644
--- a/tests/gem_reg_read.c
+++ b/tests/gem_reg_read.c
@@ -27,7 +27,9 @@
#include <stdio.h>
#include <string.h>
-#include "i915_drm.h"
+#include <errno.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
struct local_drm_i915_reg_read {
@@ -37,62 +39,41 @@ struct local_drm_i915_reg_read {
#define REG_READ_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x31, struct local_drm_i915_reg_read)
-static void handle_bad(int ret, int lerrno, int expected, const char *desc)
-{
- if (ret != 0 && lerrno != expected) {
- fprintf(stderr, "%s - errno was %d, but should have been %d\n",
- desc, lerrno, expected);
- exit(EXIT_FAILURE);
- } else if (ret == 0) {
- fprintf(stderr, "%s - Command succeeded, but should have failed\n",
- desc);
- exit(EXIT_FAILURE);
- }
-}
-
static uint64_t timer_query(int fd)
{
- struct local_drm_i915_reg_read read;
- int ret;
+ struct local_drm_i915_reg_read reg_read;
- read.offset = 0x2358;
- ret = drmIoctl(fd, REG_READ_IOCTL, &read);
- if (ret) {
+ reg_read.offset = 0x2358;
+ if (drmIoctl(fd, REG_READ_IOCTL, &reg_read)) {
perror("positive test case failed: ");
- exit(EXIT_FAILURE);
+ igt_fail(1);
}
- return read.val;
+ return reg_read.val;
}
-int main(int argc, char *argv[])
+igt_simple_main
{
- struct local_drm_i915_reg_read read;
- int ret, fd;
- uint64_t val;
+ struct local_drm_i915_reg_read reg_read;
+ int fd, ret;
fd = drm_open_any();
- read.offset = 0x2358;
- ret = drmIoctl(fd, REG_READ_IOCTL, &read);
- if (errno == EINVAL)
- exit(77);
- else if (ret)
- exit(EXIT_FAILURE);
+ reg_read.offset = 0x2358;
+ ret = drmIoctl(fd, REG_READ_IOCTL, &reg_read);
+ igt_assert(ret == 0 || errno == EINVAL);
+ igt_require(ret == 0);
- val = timer_query(fd);
+ reg_read.val = timer_query(fd);
sleep(1);
- if (timer_query(fd) == val) {
- fprintf(stderr, "Timer isn't moving, probably busted\n");
- exit(EXIT_FAILURE);
- }
+ /* Check that timer is moving and isn't busted. */
+ igt_assert(timer_query(fd) != reg_read.val);
/* bad reg */
- read.offset = 0x12345678;
- ret = drmIoctl(fd, REG_READ_IOCTL, &read);
- handle_bad(ret, errno, EINVAL, "bad register");
+ reg_read.offset = 0x12345678;
+ ret = drmIoctl(fd, REG_READ_IOCTL, &reg_read);
- close(fd);
+ igt_assert(ret != 0 && errno == EINVAL);
- exit(EXIT_SUCCESS);
+ close(fd);
}
diff --git a/tests/gem_reloc_overflow.c b/tests/gem_reloc_overflow.c
new file mode 100644
index 00000000..06a315fd
--- /dev/null
+++ b/tests/gem_reloc_overflow.c
@@ -0,0 +1,381 @@
+/*
+ * 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"
+
+/*
+ * 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
index 47681d51..271f4f67 100644
--- a/tests/gem_reloc_vs_gpu.c
+++ b/tests/gem_reloc_vs_gpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2011 Intel Corporation
+ * 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"),
@@ -25,21 +25,26 @@
*
*/
+#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
+#include <signal.h>
+#include <sys/wait.h>
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
+#include "igt_debugfs.h"
+#include "igt_aux.h"
/*
* Testcase: Kernel relocations vs. gpu races
@@ -58,17 +63,6 @@ uint32_t devid;
int special_reloc_ofs;
int special_batch_len;
-#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 */
-
static void create_special_bo(void)
{
uint32_t data[1024];
@@ -79,12 +73,22 @@ static void create_special_bo(void)
memset(data, 0, 4096);
special_bo = drm_intel_bo_alloc(bufmgr, "special batch", 4096, 4096);
- BATCH(XY_COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
+ 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
@@ -93,7 +97,7 @@ static void create_special_bo(void)
BATCH(CMD_POLY_STIPPLE_OFFSET << 16);
BATCH(0);
}
- assert(len % 2 == 0);
+ igt_assert(len % 2 == 0);
BATCH(MI_NOOP);
BATCH(MI_BATCH_BUFFER_END);
@@ -113,23 +117,21 @@ static void emit_dummy_load(int pitch)
}
for (i = 0; i < 10; i++) {
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB |
- tile_flags);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(pitch);
OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
- if (IS_GEN6(devid) || IS_GEN7(devid)) {
+ if (intel_gen(devid) >= 6) {
BEGIN_BATCH(3);
OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
OUT_BATCH(0);
@@ -140,23 +142,97 @@ static void emit_dummy_load(int pitch)
intel_batchbuffer_flush(batch);
}
-#define MAX_BLT_SIZE 128
-int main(int argc, char **argv)
+static void faulting_reloc_and_emit(int fd, drm_intel_bo *target_bo)
+{
+ 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;
+ 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;
+
+ reloc[0].offset = special_reloc_ofs;
+ reloc[0].delta = 0;
+ reloc[0].target_handle = target_bo->handle;
+ reloc[0].read_domains = I915_GEM_DOMAIN_RENDER;
+ reloc[0].write_domain = I915_GEM_DOMAIN_RENDER;
+ reloc[0].presumed_offset = 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[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);
+
+ gem_close(fd, handle_relocs);
+}
+
+static void reloc_and_emit(int fd, drm_intel_bo *target_bo)
+{
+ int ring;
+
+ if (intel_gen(devid) >= 6)
+ ring = I915_EXEC_BLT;
+ else
+ ring = 0;
+
+ drm_intel_bo_emit_reloc(special_bo, special_reloc_ofs,
+ target_bo,
+ 0,
+ I915_GEM_DOMAIN_RENDER,
+ I915_GEM_DOMAIN_RENDER);
+ drm_intel_bo_mrb_exec(special_bo, special_batch_len, NULL,
+ 0, 0, ring);
+
+}
+
+static void do_test(int fd, bool faulting_reloc)
{
uint32_t tiling_mode = I915_TILING_X;
unsigned long pitch, act_size;
- int fd, i, ring;
uint32_t test;
+ int i;
- memset(blob, 'A', sizeof(blob));
-
- 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);
+ if (faulting_reloc)
+ igt_disable_prefault();
act_size = 2048;
dummy_bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled dummy_bo", act_size, act_size,
@@ -166,41 +242,125 @@ int main(int argc, char **argv)
create_special_bo();
- if (intel_gen(devid) >= 6)
- ring = I915_EXEC_BLT;
- else
- ring = 0;
-
for (i = 0; i < NUM_TARGET_BOS; i++) {
pc_target_bo[i] = drm_intel_bo_alloc(bufmgr, "special batch", 4096, 4096);
emit_dummy_load(pitch);
- assert(pc_target_bo[i]->offset == 0);
- drm_intel_bo_emit_reloc(special_bo, special_reloc_ofs,
- pc_target_bo[i],
- 0,
- I915_GEM_DOMAIN_RENDER,
- I915_GEM_DOMAIN_RENDER);
- drm_intel_bo_mrb_exec(special_bo, special_batch_len, NULL,
- 0, 0, ring);
+ igt_assert(pc_target_bo[i]->offset == 0);
+
+ if (faulting_reloc)
+ faulting_reloc_and_emit(fd, pc_target_bo[i]);
+ else
+ reloc_and_emit(fd, pc_target_bo[i]);
}
/* 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);
- if (test != 0xdeadbeef) {
- fprintf(stderr, "mismatch in buffer %i: 0x%08x instead of 0xdeadbeef\n", i, test);
- exit(1);
- }
+ 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);
- intel_batchbuffer_free(batch);
- drm_intel_bufmgr_destroy(bufmgr);
+ 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 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;
- close(fd);
+ igt_fork_helper(&thrasher) {
+ while (1) {
+ usleep(1000);
+ igt_drop_caches_set(val);
+ }
+ }
+ }
+
+ igt_fork(i, num_threads * 4) {
+ /* 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);
+}
- return 0;
+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_subtest("faulting-reloc")
+ do_test(fd, true);
+
+ igt_fork_signal_helper();
+ igt_subtest("interruptible")
+ do_test(fd, false);
+
+ igt_subtest("faulting-reloc-interruptible")
+ do_test(fd, true);
+ 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_render_copy.c b/tests/gem_render_copy.c
new file mode 100644
index 00000000..fd26b43f
--- /dev/null
+++ b/tests/gem_render_copy.c
@@ -0,0 +1,193 @@
+/*
+ * 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 <getopt.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)
+
+#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 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);
+}
+
+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;
+ int opt_dump_png = false;
+ int opt_dump_aub = igt_aub_dump_enabled();
+
+ igt_simple_init();
+
+ while ((opt = getopt(argc, argv, "d")) != -1) {
+ switch (opt) {
+ case 'd':
+ opt_dump_png = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ 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);
+ }
+
+ 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 {
+ scratch_buf_check(&data, &dst, 10, 10, DST_COLOR);
+ scratch_buf_check(&data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR);
+ }
+
+ return 0;
+}
diff --git a/tests/gem_render_copy_redux.c b/tests/gem_render_copy_redux.c
new file mode 100644
index 00000000..73dcb722
--- /dev/null
+++ b/tests/gem_render_copy_redux.c
@@ -0,0 +1,247 @@
+/*
+ * 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 <getopt.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)
+
+#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_render();
+ 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();
+
+ return 0;
+}
diff --git a/tests/gem_render_linear_blits.c b/tests/gem_render_linear_blits.c
new file mode 100644
index 00000000..fd7c2be2
--- /dev/null
+++ b/tests/gem_render_linear_blits.c
@@ -0,0 +1,205 @@
+/*
+ * 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 <getopt.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();
+
+ 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) {
+ fprintf(stderr, "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]);
+
+ return 0;
+}
diff --git a/tests/gem_render_tiled_blits.c b/tests/gem_render_tiled_blits.c
new file mode 100644
index 00000000..8b74e2b4
--- /dev/null
+++ b/tests/gem_render_tiled_blits.c
@@ -0,0 +1,216 @@
+/*
+ * 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 <getopt.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();
+
+ 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) {
+ fprintf(stderr, "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]);
+
+ return 0;
+}
diff --git a/tests/gem_reset_stats.c b/tests/gem_reset_stats.c
new file mode 100644
index 00000000..3f5a01f8
--- /dev/null
+++ b/tests/gem_reset_stats.c
@@ -0,0 +1,1163 @@
+/*
+ * 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_debugfs.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;
+static bool hw_contexts;
+
+struct local_drm_i915_reset_stats {
+ __u32 ctx_id;
+ __u32 flags;
+ __u32 reset_count;
+ __u32 batch_active;
+ __u32 batch_pending;
+ __u32 pad;
+};
+
+struct local_drm_i915_gem_context_create {
+ __u32 ctx_id;
+ __u32 pad;
+};
+
+struct local_drm_i915_gem_context_destroy {
+ __u32 ctx_id;
+ __u32 pad;
+};
+
+#define MAX_FD 32
+
+#define CONTEXT_CREATE_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2d, struct local_drm_i915_gem_context_create)
+#define CONTEXT_DESTROY_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x2e, struct local_drm_i915_gem_context_destroy)
+#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 bool has_context(const struct target_ring *ring);
+
+static const struct target_ring {
+ uint32_t exec;
+ bool (*present)(int fd);
+ bool (*contexts)(const struct target_ring *ring);
+ const char *name;
+} rings[] = {
+ { I915_EXEC_RENDER, gem_has_render, has_context, "render" },
+ { I915_EXEC_BLT, gem_has_blt, has_context, "blt" },
+ { I915_EXEC_BSD, gem_has_bsd, has_context, "bsd" },
+ { LOCAL_I915_EXEC_VEBOX, gem_has_vebox, has_context, "vebox" },
+};
+
+static bool has_context(const struct target_ring *ring)
+{
+ if (!hw_contexts)
+ return false;
+
+ if(ring->exec == I915_EXEC_RENDER)
+ return true;
+
+ return false;
+}
+
+#define NUM_RINGS (sizeof(rings)/sizeof(struct target_ring))
+
+static const struct target_ring *current_ring;
+
+static uint32_t context_create(int fd)
+{
+ struct local_drm_i915_gem_context_create create;
+ int ret;
+
+ create.ctx_id = rand();
+ create.pad = rand();
+
+ ret = drmIoctl(fd, CONTEXT_CREATE_IOCTL, &create);
+ igt_assert(ret == 0);
+
+ return create.ctx_id;
+}
+
+static int context_destroy(int fd, uint32_t ctx_id)
+{
+ int ret;
+ struct local_drm_i915_gem_context_destroy destroy;
+
+ destroy.ctx_id = ctx_id;
+ destroy.pad = rand();
+
+ ret = drmIoctl(fd, CONTEXT_DESTROY_IOCTL, &destroy);
+ if (ret != 0)
+ return -errno;
+
+ return 0;
+}
+
+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] = 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]);
+ igt_assert(context_destroy(fd[i], ctx[i][j]) == 0);
+ }
+
+ 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();
+ igt_assert(fd_bad >= 0);
+
+ fd_good = drm_open_any();
+ igt_assert(fd_good >= 0);
+
+ 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();
+ igt_assert(fd >= 0);
+
+ assert_reset_status(fd, 0, RS_NO_ERROR);
+
+ ctx_good = context_create(fd);
+ ctx_bad = 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);
+
+ igt_assert(context_destroy(fd, ctx_good) == 0);
+ igt_assert(context_destroy(fd, ctx_bad) == 0);
+ 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 = context_create(fd1);
+ ctx_unrelated = 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);
+
+ igt_assert(context_destroy(fd1, ctx_guilty) == 0);
+ igt_assert(context_destroy(fd2, ctx_unrelated) == 0);
+
+ 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();
+ igt_assert(fd >= 0);
+ ctx = context_create(fd);
+
+ assert_reset_status(fd, ctx, RS_NO_ERROR);
+
+ h = inject_hang(fd, ctx);
+ igt_assert(h >= 0);
+ igt_assert(context_destroy(fd, ctx) == 0);
+ igt_assert(context_destroy(fd, ctx) == -ENOENT);
+
+ gem_close(fd, h);
+ close(fd);
+}
+
+static void test_close_pending(void)
+{
+ int fd, h;
+
+ fd = drm_open_any();
+ igt_assert(fd >= 0);
+
+ 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();
+ igt_assert(fd >= 0);
+
+ 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();
+ igt_assert(fd >= 0);
+
+ 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();
+ igt_assert(fd >= 0);
+ if (create_ctx)
+ ctx = 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)
+ 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();
+ igt_assert(fd >= 0);
+ ctx = context_create(fd);
+
+ _test_param(fd, ctx);
+
+ close(fd);
+}
+
+static void test_params(void)
+{
+ int fd;
+
+ fd = drm_open_any();
+ igt_assert(fd >= 0);
+
+ _test_param(fd, 0);
+
+ close(fd);
+
+}
+
+static bool gem_has_hw_contexts(int fd)
+{
+ struct local_drm_i915_gem_context_create create;
+ int ret;
+
+ memset(&create, 0, sizeof(create));
+ ret = drmIoctl(fd, CONTEXT_CREATE_IOCTL, &create);
+
+ if (ret == 0) {
+ drmIoctl(fd, CONTEXT_DESTROY_IOCTL, &create);
+ return true;
+ }
+
+ return false;
+}
+
+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 RING_HAS_CONTEXTS (current_ring->contexts(current_ring))
+#define RUN_TEST(...) do { check_gpu_ok(); __VA_ARGS__; check_gpu_ok(); } while (0)
+#define RUN_CTX_TEST(...) do { igt_skip_on(RING_HAS_CONTEXTS == false); 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);
+
+ hw_contexts = gem_has_hw_contexts(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));
+ }
+}
diff --git a/tests/gem_ring_sync_copy.c b/tests/gem_ring_sync_copy.c
new file mode 100644
index 00000000..768d02d0
--- /dev/null
+++ b/tests/gem_ring_sync_copy.c
@@ -0,0 +1,368 @@
+/*
+ * 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"
+
+#define WIDTH 512
+#define HEIGHT 512
+
+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_cmpint(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;
+
+ array_size = data->n_buffers_load * sizeof(struct igt_buf);
+ data->render.srcs = malloc(array_size);
+ data->render.dsts = malloc(array_size);
+
+ for (i = 0; i < data->n_buffers_load; 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],
+ 0, 0, /* src_x, src_y */
+ WIDTH, HEIGHT,
+ &data->render.dsts[i],
+ 0, 0 /* dst_x, dst_y */);
+ }
+}
+
+static void render_busy_fini(data_t *data)
+{
+ int i;
+
+ for (i = 0; i < data->n_buffers_load; 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;
+
+ array_size = data->n_buffers_load * sizeof(drm_intel_bo *);
+ data->blitter.srcs = malloc(array_size);
+ data->blitter.dsts = malloc(array_size);
+
+ for (i = 0; i < data->n_buffers_load; 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],
+ data->blitter.dsts[i],
+ WIDTH*HEIGHT*4);
+ }
+}
+
+static void blitter_busy_fini(data_t *data)
+{
+ int i;
+
+ for (i = 0; i < data->n_buffers_load; 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:
+ abort();
+ }
+
+ 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
index b689bcde..d4e7e2a8 100644
--- a/tests/gem_ring_sync_loop.c
+++ b/tests/gem_ring_sync_loop.c
@@ -28,19 +28,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
#include "i830_reg.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -56,14 +56,15 @@ static drm_intel_bo *target_buffer;
#define MI_DO_COMPARE (1<<21)
static void
-store_dword_loop(void)
+store_dword_loop(int fd)
{
int i;
+ int num_rings = gem_get_num_rings(fd);
srandom(0xdeadbeef);
- for (i = 0; i < 0x100000; i++) {
- int ring = random() % 3 + 1;
+ for (i = 0; i < SLOW_QUICK(0x100000, 10); i++) {
+ int ring = random() % num_rings + 1;
if (ring == I915_EXEC_RENDER) {
BEGIN_BATCH(4);
@@ -90,50 +91,31 @@ store_dword_loop(void)
drm_intel_bo_unmap(target_buffer);
}
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
int devid;
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", argv[0]);
- exit(-1);
- }
-
fd = drm_open_any();
devid = intel_get_drm_devid(fd);
- if (!HAS_BLT_RING(devid)) {
- fprintf(stderr, "inter ring check needs gen6+\n");
- return 77;
- }
+ gem_require_ring(fd, I915_EXEC_BLT);
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
+ igt_assert(bufmgr);
drm_intel_bufmgr_gem_enable_reuse(bufmgr);
batch = intel_batchbuffer_alloc(bufmgr, devid);
- if (!batch) {
- fprintf(stderr, "failed to create batch buffer\n");
- exit(-1);
- }
+ igt_assert(batch);
target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
- if (!target_buffer) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
- }
+ igt_assert(target_buffer);
- store_dword_loop();
+ store_dword_loop(fd);
drm_intel_bo_unreference(target_buffer);
intel_batchbuffer_free(batch);
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_ringfill.c b/tests/gem_ringfill.c
index 5bae8f11..5700a74d 100644
--- a/tests/gem_ringfill.c
+++ b/tests/gem_ringfill.c
@@ -35,19 +35,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
-#include "rendercopy.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;
@@ -95,8 +95,8 @@ static int check_bo(struct bo *b)
int x = i % width;
int y = i / width;
- printf("%s: copy #%d at %d,%d failed: read 0x%08x\n",
- b->ring, i, x, y, map[i]);
+ 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);
@@ -114,9 +114,9 @@ static void destroy_bo(struct bo *b)
static int check_ring(drm_intel_bufmgr *bufmgr,
struct intel_batchbuffer *batch,
const char *ring,
- render_copyfunc_t copy)
+ igt_render_copyfunc_t copy)
{
- struct scratch_buf src, tmp, dst;
+ struct igt_buf src, tmp, dst;
struct bo bo;
char output[100];
int i;
@@ -127,7 +127,6 @@ static int check_ring(drm_intel_bufmgr *bufmgr,
src.stride = 4 * width;
src.tiling = 0;
- src.data = src.cpu_mapping = NULL;
src.size = 4 * width * height;
src.num_tiles = 4 * width * height;
dst = tmp = src;
@@ -155,18 +154,18 @@ static int check_ring(drm_intel_bufmgr *bufmgr,
int x = i % width;
int y = i / width;
- drmtest_progress(output, i, width*height);
+ igt_progress(output, i, width*height);
- assert(y < height);
+ igt_assert(y < height);
/* Dummy load to fill the ring */
- copy(batch, &src, 0, 0, width, height, &tmp, 0, 0);
+ copy(batch, NULL, &src, 0, 0, width, height, &tmp, 0, 0);
/* And copy the src into dst, pixel by pixel */
- copy(batch, &src, x, y, 1, 1, &dst, x, y);
+ copy(batch, NULL, &src, x, y, 1, 1, &dst, x, y);
}
/* verify */
- printf("verifying\n");
+ igt_info("verifying\n");
i = check_bo(&bo);
destroy_bo(&bo);
@@ -174,60 +173,63 @@ static int check_ring(drm_intel_bufmgr *bufmgr,
}
static void blt_copy(struct intel_batchbuffer *batch,
- struct scratch_buf *src, unsigned src_x, unsigned src_y,
+ drm_intel_context *context,
+ struct igt_buf *src, unsigned src_x, unsigned src_y,
unsigned w, unsigned h,
- struct scratch_buf *dst, unsigned dst_x, unsigned dst_y)
+ struct igt_buf *dst, unsigned dst_x, unsigned dst_y)
{
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(batch->devid, 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(dst->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ BLIT_RELOC_UDW(batch->devid);
OUT_BATCH((src_y << 16) | src_x); /* src x1,y1 */
OUT_BATCH(src->stride);
OUT_RELOC(src->bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(batch->devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
}
-int main(int argc, char **argv)
+drm_intel_bufmgr *bufmgr;
+struct intel_batchbuffer *batch;
+int fd;
+
+igt_main
{
- drm_intel_bufmgr *bufmgr;
- struct intel_batchbuffer *batch;
- render_copyfunc_t copy;
- int fd, fails = 0;
+ igt_skip_on_simulation();
- fd = drm_open_any();
+ 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));
+ 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));
+ }
- fails += check_ring(bufmgr, batch, "blt", blt_copy);
+ igt_subtest("blitter")
+ check_ring(bufmgr, batch, "blt", blt_copy);
/* Strictly only required on architectures with a separate BLT ring,
* but lets stress everybody.
*/
- copy = NULL;
- if (IS_GEN2(batch->devid))
- copy = gen2_render_copyfunc;
- else if (IS_GEN3(batch->devid))
- copy = gen3_render_copyfunc;
- else if (IS_GEN6(batch->devid))
- copy = gen6_render_copyfunc;
- if (copy)
- fails += check_ring(bufmgr, batch, "render", copy);
-
- intel_batchbuffer_free(batch);
- drm_intel_bufmgr_destroy(bufmgr);
-
- close(fd);
-
- return fails != 0;
+ 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_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
new file mode 100644
index 00000000..fa38f1f2
--- /dev/null
+++ b/tests/gem_seqno_wrap.c
@@ -0,0 +1,645 @@
+/*
+ * 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 <wordexp.h>
+#include <getopt.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "ioctl_wrappers.h"
+#include "drmtest.h"
+#include "igt_core.h"
+#include "igt_aux.h"
+#include "intel_bufmgr.h"
+#include "intel_batchbuffer.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
+
+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;
+ char cmd[1024];
+ 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) {
+ printf("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;
+ unsigned i_tmp;
+
+ i_tmp = i_arr[i];
+ i_arr[i] = i_arr[j];
+ i_arr[j] = i_tmp;
+}
+
+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();
+ igt_assert(fd >= 0);
+
+ 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 run_cmd(char *s)
+{
+ int pid;
+ int r = -1;
+ int status = 0;
+ wordexp_t wexp;
+ int i;
+ r = wordexp(s, &wexp, 0);
+ if (r != 0) {
+ printf("can't parse %s\n", s);
+ return r;
+ }
+
+ for(i = 0; i < wexp.we_wordc; i++)
+ printf("argv[%d] = %s\n", i, wexp.we_wordv[i]);
+
+ pid = fork();
+
+ if (pid == 0) {
+ char path[PATH_MAX];
+ char full_path[PATH_MAX];
+
+ if (getcwd(path, PATH_MAX) == NULL)
+ perror("getcwd");
+
+ igt_assert(snprintf(full_path, PATH_MAX, "%s/%s", path, wexp.we_wordv[0]) > 0);
+
+ r = execv(full_path, wexp.we_wordv);
+ if (r == -1)
+ perror("execv failed");
+ } else {
+ int waitcount = options.timeout;
+
+ while(waitcount-- > 0) {
+ r = waitpid(pid, &status, WNOHANG);
+ if (r == pid) {
+ if(WIFEXITED(status)) {
+ if (WEXITSTATUS(status))
+ fprintf(stderr,
+ "child returned with %d\n",
+ WEXITSTATUS(status));
+ return WEXITSTATUS(status);
+ }
+ } else if (r != 0) {
+ perror("waitpid");
+ return -errno;
+ }
+
+ sleep(3);
+ }
+
+ kill(pid, SIGKILL);
+ return -ETIMEDOUT;
+ }
+
+ return r;
+}
+
+static const char *dfs_base = "/sys/kernel/debug/dri";
+static const char *dfs_entry = "i915_next_seqno";
+
+static int dfs_open(int mode)
+{
+ char fname[FILENAME_MAX];
+ int fh;
+
+ snprintf(fname, FILENAME_MAX, "%s/%i/%s",
+ dfs_base, card_index, dfs_entry);
+
+ fh = open(fname, mode);
+ igt_require(fh >= 0);
+
+ return fh;
+}
+
+static int __read_seqno(uint32_t *seqno)
+{
+ int fh;
+ char buf[32];
+ int r;
+ char *p;
+ unsigned long int tmp;
+
+ fh = dfs_open(O_RDONLY);
+
+ r = read(fh, buf, sizeof(buf) - 1);
+ close(fh);
+ if (r < 0) {
+ perror("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) {
+ perror("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;
+
+ if (options.dontwrap)
+ return 0;
+
+ fh = dfs_open(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) {
+ printf("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)
+{
+ if (strnlen(options.cmd, sizeof(options.cmd)) > 0)
+ igt_assert(run_cmd(options.cmd) == 0);
+ else
+ 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 void print_usage(const char *s)
+{
+ printf("%s: [OPTION]...\n", s);
+ printf(" where options are:\n");
+ printf(" -b --background run in background inducing wraps\n");
+ printf(" -c --cmd=cmdstring use cmdstring to cross wrap\n");
+ printf(" -n --rounds=num run num times across wrap boundary, 0 == forever\n");
+ printf(" -t --timeout=sec set timeout to wait for testrun to sec seconds\n");
+ printf(" -d --dontwrap don't wrap just run the test\n");
+ printf(" -p --prewrap=n set seqno to WRAP - n for each testrun\n");
+ printf(" -r --norandom dont randomize prewrap space\n");
+ printf(" -i --buffers number of buffers to copy\n");
+ igt_fail(-1);
+}
+
+static void parse_options(int argc, char **argv)
+{
+ int c;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"cmd", required_argument, 0, 'c'},
+ {"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'},
+ };
+
+ strcpy(options.cmd, "");
+ 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;
+
+ while((c = getopt_long(argc, argv, "c:n:bvt:dp:ri:",
+ long_options, &option_index)) != -1) {
+ switch(c) {
+ case 'b':
+ options.background = 1;
+ printf("running in background inducing wraps\n");
+ break;
+ case 'd':
+ options.dontwrap = 1;
+ printf("won't wrap after testruns\n");
+ break;
+ case 'n':
+ options.rounds = atoi(optarg);
+ printf("running %d rounds\n", options.rounds);
+ break;
+ case 'c':
+ strncpy(options.cmd, optarg, sizeof(options.cmd) - 1);
+ options.cmd[sizeof(options.cmd) - 1] = 0;
+ printf("cmd set to %s\n", options.cmd);
+ break;
+ case 'i':
+ options.buffers = atoi(optarg);
+ printf("buffers %d\n", options.buffers);
+ break;
+ case 't':
+ options.timeout = atoi(optarg);
+ if (options.timeout == 0)
+ options.timeout = 10;
+ printf("setting timeout to %d seconds\n",
+ options.timeout);
+ break;
+ case 'r':
+ options.random = 0;
+ break;
+ case 'p':
+ options.prewrap_space = atoi(optarg);
+ printf("prewrap set to %d (0x%x)\n",
+ options.prewrap_space, UINT32_MAX -
+ options.prewrap_space);
+ break;
+ default:
+ printf("unkown command options\n");
+ print_usage(argv[0]);
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ printf("unkown command options\n");
+ print_usage(argv[0]);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int wcount = 0;
+ int r = -1;
+
+ igt_simple_init();
+
+ parse_options(argc, argv);
+
+ 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);
+ }
+
+ if (options.rounds == wcount) {
+ igt_debug("done %d wraps successfully\n", wcount);
+ return 0;
+ }
+
+ return r;
+}
diff --git a/tests/gem_set_tiling_vs_blt.c b/tests/gem_set_tiling_vs_blt.c
index 5fa90d49..d9751552 100644
--- a/tests/gem_set_tiling_vs_blt.c
+++ b/tests/gem_set_tiling_vs_blt.c
@@ -47,7 +47,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
@@ -55,11 +54,12 @@
#include <sys/time.h>
#include <stdbool.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -82,23 +82,22 @@ static void do_test(uint32_t tiling, unsigned stride,
uint32_t blt_stride, blt_bits;
bool tiling_changed = false;
- printf("filling ring .. ");
+ igt_info("filling ring .. ");
busy_bo = drm_intel_bo_alloc(bufmgr, "busy bo bo", 16*1024*1024, 4096);
for (i = 0; i < 250; i++) {
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(2*1024*4);
OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
if (IS_GEN6(devid) || IS_GEN7(devid)) {
@@ -111,7 +110,7 @@ static void do_test(uint32_t tiling, unsigned stride,
}
intel_batchbuffer_flush(batch);
- printf("playing tricks .. ");
+ 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);
@@ -121,7 +120,7 @@ static void do_test(uint32_t tiling, unsigned stride,
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);
- assert(ret == 0);
+ igt_assert(ret == 0);
drm_intel_gem_bo_map_gtt(test_bo);
ptr = test_bo->virtual;
*ptr = 0;
@@ -135,12 +134,13 @@ static void do_test(uint32_t tiling, unsigned stride,
/* 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);
- if (test_bo_handle != test_bo->handle)
- fprintf(stderr, "libdrm reuse trick failed\n");
+ /* 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);
- assert(ret == 0);
+ igt_assert(ret == 0);
if (tiling == I915_TILING_NONE) {
drm_intel_bo_subdata(test_bo, 0, TEST_SIZE, data);
@@ -159,58 +159,55 @@ static void do_test(uint32_t tiling, unsigned stride,
blt_bits = XY_SRC_COPY_BLT_SRC_TILED;
}
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- blt_bits |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(blt_stride);
OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
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);
- if (test_bo_handle != test_bo->handle)
- fprintf(stderr, "libdrm reuse trick failed\n");
+ /* 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);
- assert(ret == 0);
+ 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.
*/
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(stride_after);
OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
/* Now try to trick the kernel the kernel into changing up the fencing
* too early. */
- printf("checking .. ");
+ 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++)
- assert(data[i] == i);
+ igt_assert(data[i] == i);
/* check whether tiling on the test_bo actually changed. */
drm_intel_gem_bo_map_gtt(test_bo);
@@ -220,50 +217,56 @@ static void do_test(uint32_t tiling, unsigned stride,
tiling_changed = true;
ptr = NULL;
drm_intel_gem_bo_unmap_gtt(test_bo);
- assert(tiling_changed);
+ igt_assert(tiling_changed);
drm_intel_bo_unreference(test_bo);
drm_intel_bo_unreference(target_bo);
drm_intel_bo_unreference(busy_bo);
- printf("done\n");
+ igt_info("done\n");
}
-int main(int argc, char **argv)
+int fd;
+
+igt_main
{
- int i, fd;
+ int i;
uint32_t tiling, tiling_after;
- for (i = 0; i < 1024*256; i++)
- data[i] = i;
+ igt_skip_on_simulation();
- fd = drm_open_any();
+ igt_fixture {
+ for (i = 0; i < 1024*256; i++)
+ data[i] = i;
- 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);
+ 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);
+ }
- printf("testing untiled->tiled transisition:\n");
- tiling = I915_TILING_NONE;
- tiling_after = I915_TILING_X;
- do_test(tiling, TEST_STRIDE, tiling_after, TEST_STRIDE);
- assert(tiling == I915_TILING_NONE);
- assert(tiling_after == I915_TILING_X);
-
- printf("testing tiled->untiled transisition:\n");
- tiling = I915_TILING_X;
- tiling_after = I915_TILING_NONE;
- do_test(tiling, TEST_STRIDE, tiling_after, TEST_STRIDE);
- assert(tiling == I915_TILING_X);
- assert(tiling_after == I915_TILING_NONE);
+ 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);
+ }
- printf("testing tiled->tiled transisition:\n");
- tiling = I915_TILING_X;
- tiling_after = I915_TILING_X;
- do_test(tiling, TEST_STRIDE/2, tiling_after, TEST_STRIDE);
- assert(tiling == I915_TILING_X);
- 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);
+ }
- return 0;
+ 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
index 1241b54d..e0ef2b7b 100644
--- a/tests/gem_set_tiling_vs_gtt.c
+++ b/tests/gem_set_tiling_vs_gtt.c
@@ -29,17 +29,16 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
#define OBJECT_SIZE (1024*1024)
#define TEST_STRIDE (1024*4)
@@ -48,7 +47,7 @@
* Testcase: Check set_tiling vs gtt mmap coherency
*/
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
uint32_t *ptr;
@@ -58,6 +57,8 @@ int main(int argc, char **argv)
bool tiling_changed;
int tile_height;
+ igt_skip_on_simulation();
+
fd = drm_open_any();
if (IS_GEN2(intel_get_drm_devid(fd)))
@@ -67,7 +68,7 @@ int main(int argc, char **argv)
handle = gem_create(fd, OBJECT_SIZE);
ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
- assert(ptr);
+ 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);
@@ -76,7 +77,7 @@ int main(int argc, char **argv)
gem_set_tiling(fd, handle, I915_TILING_X, TEST_STRIDE);
- printf("testing untiled->tiled\n");
+ 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
@@ -84,7 +85,7 @@ int main(int argc, char **argv)
for (i = 0; i < OBJECT_SIZE/4; i++)
if (ptr[i] != data[i])
tiling_changed = true;
- assert(tiling_changed);
+ 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++)
@@ -92,7 +93,7 @@ int main(int argc, char **argv)
gem_set_tiling(fd, handle, I915_TILING_X, TEST_STRIDE*2);
- printf("testing tiled->tiled\n");
+ 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);
@@ -104,13 +105,11 @@ int main(int argc, char **argv)
+ half*tile_height + ofs;
uint32_t val = data[data_i];
- if (ptr[i] != val) {
- printf("mismatch at %i, row=%i, half=%i, ofs=%i\n",
- i, row, half, ofs);
- printf("read: 0x%08x, expected: 0x%08x\n",
- ptr[i], val);
- assert(0);
- }
+ 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);
}
@@ -119,7 +118,7 @@ int main(int argc, char **argv)
ptr[i] = data[i] = i;
gem_set_tiling(fd, handle, I915_TILING_NONE, 0);
- printf("testing tiled->untiled\n");
+ 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
@@ -127,11 +126,9 @@ int main(int argc, char **argv)
for (i = 0; i < OBJECT_SIZE/4; i++)
if (ptr[i] != data[i])
tiling_changed = true;
- assert(tiling_changed);
+ igt_assert(tiling_changed);
munmap(ptr, OBJECT_SIZE);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_set_tiling_vs_pwrite.c b/tests/gem_set_tiling_vs_pwrite.c
index 35ec5cdc..cf5aaeb0 100644
--- a/tests/gem_set_tiling_vs_pwrite.c
+++ b/tests/gem_set_tiling_vs_pwrite.c
@@ -29,17 +29,15 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
#define OBJECT_SIZE (1024*1024)
#define TEST_STRIDE (1024*4)
@@ -48,7 +46,7 @@
* Testcase: Check set_tiling vs pwrite coherency
*/
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
uint32_t *ptr;
@@ -56,6 +54,8 @@ int main(int argc, char **argv)
int i;
uint32_t handle;
+ igt_skip_on_simulation();
+
fd = drm_open_any();
for (i = 0; i < OBJECT_SIZE/4; i++)
@@ -63,7 +63,7 @@ int main(int argc, char **argv)
handle = gem_create(fd, OBJECT_SIZE);
ptr = gem_mmap(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
- assert(ptr);
+ igt_assert(ptr);
gem_set_tiling(fd, handle, I915_TILING_X, TEST_STRIDE);
@@ -71,12 +71,12 @@ int main(int argc, char **argv)
gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
*ptr = 0xdeadbeef;
- printf("testing pwrite on tiled buffer\n");
+ 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++)
- assert(i == data[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);
@@ -84,16 +84,14 @@ int main(int argc, char **argv)
gem_set_tiling(fd, handle, I915_TILING_NONE, 0);
- printf("testing pwrite on untiled, but still fenced buffer\n");
+ 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++)
- assert(i == data[i]);
+ igt_assert(i == data[i]);
munmap(ptr, OBJECT_SIZE);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_storedw_batches_loop.c b/tests/gem_storedw_batches_loop.c
index 8cf5f719..fef3718f 100644
--- a/tests/gem_storedw_batches_loop.c
+++ b/tests/gem_storedw_batches_loop.c
@@ -29,145 +29,150 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
+#include "intel_chipset.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.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(void)
+store_dword_loop(int divider, unsigned flags)
{
- int cmd, i, val = 0, ret;
+ 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 < 0x80000; i++) {
+ 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);
- if (!cmd_bo) {
- fprintf(stderr, "failed to alloc cmd bo\n");
- exit(-1);
- }
+ 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[0] = cmd;
- buf[1] = 0;
- buf[2] = target_bo->offset;
- buf[3] = 0x42000000 + val;
-
- ret = drm_intel_bo_references(cmd_bo, target_bo);
- if (ret) {
- fprintf(stderr, "failed to link cmd & target bos\n");
- exit(-1);
+ 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;
- ret = drm_intel_bo_emit_reloc(cmd_bo, 8, target_bo, 0,
- I915_GEM_DOMAIN_INSTRUCTION,
- I915_GEM_DOMAIN_INSTRUCTION);
- if (ret) {
- fprintf(stderr, "failed to emit reloc\n");
- exit(-1);
- }
+ igt_assert(drm_intel_bo_references(cmd_bo, target_bo) == 0);
- buf[4] = MI_BATCH_BUFFER_END;
- buf[5] = MI_BATCH_BUFFER_END;
+ 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);
- ret = drm_intel_bo_references(cmd_bo, target_bo);
- if (ret != 1) {
- fprintf(stderr, "bad bo reference count: %d\n", ret);
- exit(-1);
- }
+ igt_assert(drm_intel_bo_references(cmd_bo, target_bo) == 1);
- ret = drm_intel_bo_exec(cmd_bo, 6 * 4, NULL, 0, 0);
- if (ret) {
- fprintf(stderr, "bo exec failed: %d\n", ret);
- exit(-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;
- if (buf[0] != (0x42000000 | val)) {
- fprintf(stderr,
- "value mismatch: cur 0x%08x, stored 0x%08x\n",
- buf[0], 0x42000000 | val);
- exit(-1);
- }
+ 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++;
}
- printf("completed %d writes successfully\n", i);
+ igt_info("completed %d writes successfully\n", i);
}
-int main(int argc, char **argv)
+int fd;
+int devid;
+
+igt_main
{
- int fd;
- int devid;
+ igt_skip_on_simulation();
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", argv[0]);
- exit(-1);
- }
+ igt_fixture {
+ fd = drm_open_any();
+ devid = intel_get_drm_devid(fd);
- fd = drm_open_any();
- devid = intel_get_drm_devid(fd);
+ has_ppgtt = gem_uses_aliasing_ppgtt(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);
- if (IS_GEN2(devid) || IS_GEN3(devid) || IS_GEN4(devid) || IS_GEN5(devid)) {
+ bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
+ igt_assert(bufmgr);
- fprintf(stderr, "MI_STORE_DATA can only use GTT address on gen4+/g33 and"
- "needs snoopable mem on pre-gen6\n");
- return 77;
- }
+ // drm_intel_bufmgr_gem_enable_reuse(bufmgr);
-
- bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
+ target_bo = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
+ igt_assert(target_bo);
}
-// drm_intel_bufmgr_gem_enable_reuse(bufmgr);
- target_bo = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
- if (!target_bo) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
+ igt_subtest("normal") {
+ store_dword_loop(1, 0);
+ store_dword_loop(2, 0);
+ store_dword_loop(3, 0);
+ store_dword_loop(5, 0);
}
- store_dword_loop();
-
- drm_intel_bo_unreference(target_bo);
- drm_intel_bufmgr_destroy(bufmgr);
+ 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);
+ }
- close(fd);
+ igt_fixture {
+ drm_intel_bo_unreference(target_bo);
+ drm_intel_bufmgr_destroy(bufmgr);
- return 0;
+ close(fd);
+ }
}
diff --git a/tests/gem_storedw_loop_blt.c b/tests/gem_storedw_loop_blt.c
index dda9b835..8c4157d5 100644
--- a/tests/gem_storedw_loop_blt.c
+++ b/tests/gem_storedw_loop_blt.c
@@ -29,18 +29,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -52,103 +52,105 @@ static int has_ppgtt = 0;
*/
static void
-store_dword_loop(void)
+emit_store_dword_imm(int devid, drm_intel_bo *dest, uint32_t val)
{
- int cmd, i, val = 0;
- uint32_t *buf;
-
+ int cmd;
cmd = MI_STORE_DWORD_IMM;
if (!has_ppgtt)
cmd |= MI_MEM_VIRTUAL;
- for (i = 0; i < 0x100000; i++) {
+ if (intel_gen(devid) >= 8) {
+ BEGIN_BATCH(4);
+ OUT_BATCH(cmd);
+ OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION,
+ I915_GEM_DOMAIN_INSTRUCTION, 0);
+ OUT_BATCH(0);
+ OUT_BATCH(val);
+ ADVANCE_BATCH();
+ } else {
BEGIN_BATCH(4);
OUT_BATCH(cmd);
OUT_BATCH(0); /* reserved */
- OUT_RELOC(target_buffer, I915_GEM_DOMAIN_INSTRUCTION,
+ 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;
- if (buf[0] != val) {
- fprintf(stderr,
- "value mismatch: cur 0x%08x, stored 0x%08x\n",
- buf[0], val);
- exit(-1);
- }
+ 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;
- printf("completed %d writes successfully, current value: 0x%08x\n", i,
+ igt_info("completed %d writes successfully, current value: 0x%08x\n", i,
buf[0]);
drm_intel_bo_unmap(target_buffer);
}
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
int devid;
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", argv[0]);
- exit(-1);
- }
-
fd = drm_open_any();
devid = intel_get_drm_devid(fd);
has_ppgtt = gem_uses_aliasing_ppgtt(fd);
- if (IS_GEN2(devid) || IS_GEN3(devid) || IS_GEN4(devid) || IS_GEN5(devid)) {
-
- fprintf(stderr, "MI_STORE_DATA can only use GTT address on gen4+/g33 and "
- "needs snoopable mem on pre-gen6\n");
- return 77;
- }
+ 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 */
- if (!has_ppgtt) {
- fprintf(stderr, "no ppgtt detected, which is required\n");
- return 77;
- }
+ igt_require(has_ppgtt);
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
+ igt_assert(bufmgr);
drm_intel_bufmgr_gem_enable_reuse(bufmgr);
batch = intel_batchbuffer_alloc(bufmgr, devid);
- if (!batch) {
- fprintf(stderr, "failed to create batch buffer\n");
- exit(-1);
- }
+ igt_assert(batch);
target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
- if (!target_buffer) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
- }
+ igt_assert(target_buffer);
- store_dword_loop();
+ 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);
-
- return 0;
}
diff --git a/tests/gem_storedw_loop_bsd.c b/tests/gem_storedw_loop_bsd.c
index d7c61047..f89d522e 100644
--- a/tests/gem_storedw_loop_bsd.c
+++ b/tests/gem_storedw_loop_bsd.c
@@ -29,18 +29,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -52,109 +52,108 @@ static int has_ppgtt = 0;
*/
static void
-store_dword_loop(void)
+emit_store_dword_imm(int devid, drm_intel_bo *dest, uint32_t val)
{
- int cmd, i, val = 0;
- uint32_t *buf;
-
+ int cmd;
cmd = MI_STORE_DWORD_IMM;
if (!has_ppgtt)
cmd |= MI_MEM_VIRTUAL;
- for (i = 0; i < 0x100000; i++) {
+ if (intel_gen(devid) >= 8) {
+ BEGIN_BATCH(4);
+ OUT_BATCH(cmd);
+ OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION,
+ I915_GEM_DOMAIN_INSTRUCTION, 0);
+ OUT_BATCH(0);
+ OUT_BATCH(val);
+ ADVANCE_BATCH();
+ } else {
BEGIN_BATCH(4);
OUT_BATCH(cmd);
OUT_BATCH(0); /* reserved */
- OUT_RELOC(target_buffer, I915_GEM_DOMAIN_INSTRUCTION,
+ 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;
- if (buf[0] != val) {
- fprintf(stderr,
- "value mismatch: cur 0x%08x, stored 0x%08x\n",
- buf[0], val);
- exit(-1);
- }
+ 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;
- printf("completed %d writes successfully, current value: 0x%08x\n", i,
+ igt_info("completed %d writes successfully, current value: 0x%08x\n", i,
buf[0]);
drm_intel_bo_unmap(target_buffer);
}
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
int devid;
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", argv[0]);
- exit(-1);
- }
-
fd = drm_open_any();
devid = intel_get_drm_devid(fd);
has_ppgtt = gem_uses_aliasing_ppgtt(fd);
- if (IS_GEN2(devid) || IS_GEN3(devid) || IS_GEN4(devid) || IS_GEN5(devid)) {
+ 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");
- fprintf(stderr, "MI_STORE_DATA can only use GTT address on gen4+/g33 and "
- "needs snoopable mem on pre-gen6\n");
- return 77;
- }
-
- if (IS_GEN6(devid)) {
-
- fprintf(stderr, "MI_STORE_DATA broken on gen6 bsd\n");
- return 77;
- }
+ igt_skip_on_f(intel_gen(devid) == 6,
+ "MI_STORE_DATA broken on gen6 bsd\n");
/* This only works with ppgtt */
- if (!has_ppgtt) {
- fprintf(stderr, "no ppgtt detected, which is required\n");
- return 77;
- }
+ igt_require(has_ppgtt);
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
+ igt_assert(bufmgr);
drm_intel_bufmgr_gem_enable_reuse(bufmgr);
batch = intel_batchbuffer_alloc(bufmgr, devid);
- if (!batch) {
- fprintf(stderr, "failed to create batch buffer\n");
- exit(-1);
- }
+ igt_assert(batch);
target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
- if (!target_buffer) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
- }
+ igt_assert(target_buffer);
- store_dword_loop();
+ 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);
-
- return 0;
}
diff --git a/tests/gem_storedw_loop_render.c b/tests/gem_storedw_loop_render.c
index 19a41b65..9defc6d6 100644
--- a/tests/gem_storedw_loop_render.c
+++ b/tests/gem_storedw_loop_render.c
@@ -29,18 +29,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -52,97 +52,102 @@ static int has_ppgtt = 0;
*/
static void
-store_dword_loop(void)
+emit_store_dword_imm(int devid, drm_intel_bo *dest, uint32_t val)
{
- int cmd, i, val = 0;
- uint32_t *buf;
-
+ int cmd;
cmd = MI_STORE_DWORD_IMM;
if (!has_ppgtt)
cmd |= MI_MEM_VIRTUAL;
- for (i = 0; i < 0x100000; i++) {
+ if (intel_gen(devid) >= 8) {
+ BEGIN_BATCH(4);
+ OUT_BATCH(cmd);
+ OUT_RELOC(dest, I915_GEM_DOMAIN_INSTRUCTION,
+ I915_GEM_DOMAIN_INSTRUCTION, 0);
+ OUT_BATCH(0);
+ OUT_BATCH(val);
+ ADVANCE_BATCH();
+ } else {
BEGIN_BATCH(4);
OUT_BATCH(cmd);
OUT_BATCH(0); /* reserved */
- OUT_RELOC(target_buffer, I915_GEM_DOMAIN_INSTRUCTION,
+ 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;
- if (buf[0] != val) {
- fprintf(stderr,
- "value mismatch: cur 0x%08x, stored 0x%08x\n",
- buf[0], val);
- exit(-1);
- }
+ 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;
- printf("completed %d writes successfully, current value: 0x%08x\n", i,
+ igt_info("completed %d writes successfully, current value: 0x%08x\n", i,
buf[0]);
drm_intel_bo_unmap(target_buffer);
}
-int main(int argc, char **argv)
+igt_simple_main
{
int fd;
int devid;
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", argv[0]);
- exit(-1);
- }
-
fd = drm_open_any();
devid = intel_get_drm_devid(fd);
has_ppgtt = gem_uses_aliasing_ppgtt(fd);
- if (IS_GEN2(devid) || IS_GEN3(devid) || IS_GEN4(devid) || IS_GEN5(devid)) {
-
- fprintf(stderr, "MI_STORE_DATA can only use GTT address on gen4+/g33 and "
- "needs snoopable mem on pre-gen6\n");
- return 77;
- }
+ 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);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
+ igt_assert(bufmgr);
drm_intel_bufmgr_gem_enable_reuse(bufmgr);
batch = intel_batchbuffer_alloc(bufmgr, devid);
- if (!batch) {
- fprintf(stderr, "failed to create batch buffer\n");
- exit(-1);
- }
+ igt_assert(batch);
target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
- if (!target_buffer) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
- }
+ igt_assert(target_buffer);
- store_dword_loop();
+ 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);
-
- return 0;
}
diff --git a/tests/gem_storedw_loop_vebox.c b/tests/gem_storedw_loop_vebox.c
new file mode 100644
index 00000000..c94a6770
--- /dev/null
+++ b/tests/gem_storedw_loop_vebox.c
@@ -0,0 +1,130 @@
+/*
+ * 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"
+
+#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);
+ OUT_BATCH(cmd);
+ if (intel_gen(batch->devid) < 8)
+ OUT_BATCH(0); /* reserved */
+ OUT_RELOC(target_buffer, I915_GEM_DOMAIN_INSTRUCTION,
+ I915_GEM_DOMAIN_INSTRUCTION, 0);
+ BLIT_RELOC_UDW(batch->devid);
+ 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_cmpint (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
index 69239ac1..e6a6ce69 100644
--- a/tests/gem_stress.c
+++ b/tests/gem_stress.c
@@ -49,7 +49,26 @@
* In short: designed for maximum evilness.
*/
-#include "rendercopy.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 <getopt.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 CMD_POLY_STIPPLE_OFFSET 0x7906
@@ -100,7 +119,7 @@ struct option_struct options;
#define BUSY_BUF_SIZE (256*4096)
#define TILE_BYTES(size) ((size)*(size)*sizeof(uint32_t))
-static struct scratch_buf buffers[2][MAX_BUFS];
+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;
@@ -116,9 +135,9 @@ struct {
unsigned max_failed_reads;
} stats;
-static void tile2xy(struct scratch_buf *buf, unsigned tile, unsigned *x, unsigned *y)
+static void tile2xy(struct igt_buf *buf, unsigned tile, unsigned *x, unsigned *y)
{
- assert(tile < buf->num_tiles);
+ 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;
}
@@ -141,20 +160,18 @@ static void emit_blt(drm_intel_bo *src_bo, uint32_t src_tiling, unsigned src_pit
}
/* copy lower half to upper half */
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB |
- cmd_bits);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(src_y << 16 | src_x);
OUT_BATCH(src_pitch);
OUT_RELOC_FENCED(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
if (IS_GEN6(devid) || IS_GEN7(devid)) {
@@ -173,21 +190,21 @@ static void keep_gpu_busy(void)
int tmp;
tmp = 1 << gpu_busy_load;
- assert(tmp <= 1024);
+ 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 scratch_buf *buf, int writing)
+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 scratch_buf *src, unsigned src_x, unsigned src_y,
- struct scratch_buf *dst, unsigned dst_x, unsigned dst_y,
+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! */
@@ -209,7 +226,7 @@ static void cpucpy2d(uint32_t *src, unsigned src_stride, unsigned src_x, unsigne
printf("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);
if (options.trace_tile >= 0 && options.fail)
- exit(1);
+ igt_fail(1);
failed++;
}
/* when not aborting, correct any errors */
@@ -217,7 +234,7 @@ static void cpucpy2d(uint32_t *src, unsigned src_stride, unsigned src_x, unsigne
}
}
if (failed && options.fail)
- exit(1);
+ igt_fail(1);
if (failed > stats.max_failed_reads)
stats.max_failed_reads = failed;
@@ -225,11 +242,11 @@ static void cpucpy2d(uint32_t *src, unsigned src_stride, unsigned src_x, unsigne
stats.num_failed++;
}
-static void cpu_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned src_y,
- struct scratch_buf *dst, unsigned dst_x, unsigned dst_y,
+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)
{
- assert(batch->ptr == batch->buffer);
+ igt_assert(batch->ptr == batch->buffer);
if (options.ducttape)
drm_intel_bo_wait_rendering(dst->bo);
@@ -244,14 +261,14 @@ static void cpu_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned src_y
logical_tile_no);
}
-static void prw_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned src_y,
- struct scratch_buf *dst, unsigned dst_x, unsigned dst_y,
+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;
- assert(batch->ptr == batch->buffer);
+ igt_assert(batch->ptr == batch->buffer);
if (options.ducttape)
drm_intel_bo_wait_rendering(dst->bo);
@@ -288,8 +305,8 @@ static void prw_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned src_y
}
}
-static void blitter_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned src_y,
- struct scratch_buf *dst, unsigned dst_x, unsigned dst_y,
+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;
@@ -318,37 +335,27 @@ static void blitter_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned s
}
}
-static void render_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned src_y,
- struct scratch_buf *dst, unsigned dst_x, unsigned dst_y,
+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 (IS_GEN2(devid))
- gen2_render_copyfunc(batch,
- src, src_x, src_y,
- options.tile_size, options.tile_size,
- dst, dst_x, dst_y);
- else if (IS_GEN3(devid))
- gen3_render_copyfunc(batch,
- src, src_x, src_y,
- options.tile_size, options.tile_size,
- dst, dst_x, dst_y);
- else if (IS_GEN6(devid))
- gen6_render_copyfunc(batch,
- src, src_x, src_y,
- options.tile_size, options.tile_size,
- dst, dst_x, dst_y);
- else if (IS_GEN7(devid))
- gen7_render_copyfunc(batch,
- src, src_x, src_y,
- options.tile_size, options.tile_size,
- dst, dst_x, dst_y);
- else
+ 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);
@@ -453,32 +460,32 @@ static void fan_in_and_check(void)
}
}
-static void sanitize_stride(struct scratch_buf *buf)
+static void sanitize_stride(struct igt_buf *buf)
{
- if (buf_height(buf) > options.max_dimension)
+ if (igt_buf_height(buf) > options.max_dimension)
buf->stride = buf->size / options.max_dimension;
- if (buf_height(buf) < options.tile_size)
+ if (igt_buf_height(buf) < options.tile_size)
buf->stride = buf->size / options.tile_size;
- if (buf_width(buf) < options.tile_size)
+ if (igt_buf_width(buf) < options.tile_size)
buf->stride = options.tile_size * sizeof(uint32_t);
- assert(buf->stride <= 8192);
- assert(buf_width(buf) <= options.max_dimension);
- assert(buf_height(buf) <= options.max_dimension);
+ igt_assert(buf->stride <= 8192);
+ igt_assert(igt_buf_width(buf) <= options.max_dimension);
+ igt_assert(igt_buf_height(buf) <= options.max_dimension);
- assert(buf_width(buf) >= options.tile_size);
- assert(buf_height(buf) >= options.tile_size);
+ igt_assert(igt_buf_width(buf) >= options.tile_size);
+ igt_assert(igt_buf_height(buf) >= options.tile_size);
}
-static void init_buffer(struct scratch_buf *buf, unsigned 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;
- assert(buf->bo);
+ igt_assert(buf->bo);
buf->tiling = I915_TILING_NONE;
buf->stride = 4096;
@@ -499,12 +506,12 @@ static void init_buffer(struct scratch_buf *buf, unsigned size)
static void exchange_buf(void *array, unsigned i, unsigned j)
{
- struct scratch_buf *buf_arr, tmp;
+ struct igt_buf *buf_arr, tmp;
buf_arr = array;
- memcpy(&tmp, &buf_arr[i], sizeof(struct scratch_buf));
- memcpy(&buf_arr[i], &buf_arr[j], sizeof(struct scratch_buf));
- memcpy(&buf_arr[j], &tmp, sizeof(struct scratch_buf));
+ 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));
}
@@ -513,7 +520,7 @@ static void init_set(unsigned set)
long int r;
int i;
- drmtest_permute_array(buffers[set], num_buffers, exchange_buf);
+ igt_permute_array(buffers[set], num_buffers, exchange_buf);
if (current_set == 1 && options.gpu_busy_load == 0) {
gpu_busy_load++;
@@ -576,7 +583,7 @@ 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 scratch_buf *src_buf, *dst_buf;
+ 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
@@ -618,22 +625,6 @@ static void copy_tiles(unsigned *permutation)
intel_batchbuffer_flush(batch);
}
-static int get_num_fences(void)
-{
- drm_i915_getparam_t gp;
- int ret, val;
-
- gp.param = I915_PARAM_NUM_FENCES_AVAIL;
- gp.value = &val;
- ret = drmIoctl(drm_fd, DRM_IOCTL_I915_GETPARAM, &gp);
- assert (ret == 0);
-
- printf ("total %d fences\n", val);
- assert(val > 4);
-
- return val - 2;
-}
-
static void sanitize_tiles_per_buf(void)
{
if (options.tiles_per_buf > options.scratch_buf_size / TILE_BYTES(options.tile_size))
@@ -665,6 +656,7 @@ static void parse_options(int argc, char **argv)
{"tile-size", 1, 0, TILESZ},
#define CHCK_RENDER 0xdead0003
{"check-render-cpyfn", 0, 0, CHCK_RENDER},
+ {NULL, 0, 0, 0},
};
options.scratch_buf_size = 256*4096;
@@ -813,7 +805,8 @@ static void init(void)
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 = get_num_fences();
+ 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);
@@ -834,7 +827,7 @@ static void init(void)
static void check_render_copyfunc(void)
{
- struct scratch_buf src, dst;
+ struct igt_buf src, dst;
uint32_t *ptr;
int i, j, pass;
@@ -845,10 +838,10 @@ static void check_render_copyfunc(void)
init_buffer(&dst, options.scratch_buf_size);
for (pass = 0; pass < 16; pass++) {
- int sx = random() % (buf_width(&src)-options.tile_size);
- int sy = random() % (buf_height(&src)-options.tile_size);
- int dx = random() % (buf_width(&dst)-options.tile_size);
- int dy = random() % (buf_height(&dst)-options.tile_size);
+ 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);
@@ -889,7 +882,7 @@ int main(int argc, char **argv)
/* start our little helper early before too may allocations occur */
if (options.use_signal_helper)
- drmtest_fork_signal_helper();
+ igt_fork_signal_helper();
init();
@@ -898,9 +891,9 @@ int main(int argc, char **argv)
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));
- assert(tile_permutation);
- assert(current_permutation);
- assert(tmp_permutation);
+ igt_assert(tile_permutation);
+ igt_assert(current_permutation);
+ igt_assert(tmp_permutation);
fan_out();
@@ -916,7 +909,7 @@ int main(int argc, char **argv)
for (j = 0; j < num_total_tiles; j++)
current_permutation[j] = j;
- drmtest_permute_array(current_permutation, num_total_tiles, exchange_uint);
+ igt_permute_array(current_permutation, num_total_tiles, exchange_uint);
copy_tiles(current_permutation);
@@ -939,7 +932,7 @@ int main(int argc, char **argv)
close(drm_fd);
- drmtest_stop_signal_helper();
+ igt_stop_signal_helper();
return 0;
}
diff --git a/tests/gem_threaded_access_tiled.c b/tests/gem_threaded_access_tiled.c
new file mode 100644
index 00000000..3752a1f6
--- /dev/null
+++ b/tests/gem_threaded_access_tiled.c
@@ -0,0 +1,122 @@
+/*
+ * 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"
+
+/* 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
index 86c9a886..cb135ce4 100644
--- a/tests/gem_tiled_blits.c
+++ b/tests/gem_tiled_blits.c
@@ -44,18 +44,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
+#include "igt_aux.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -67,23 +68,22 @@ create_bo(uint32_t start_val)
drm_intel_bo *bo, *linear_bo;
uint32_t *linear;
uint32_t tiling = I915_TILING_X;
- int ret, i;
+ int i;
bo = drm_intel_bo_alloc(bufmgr, "tiled bo", 1024 * 1024, 4096);
- ret = drm_intel_bo_set_tiling(bo, &tiling, width * 4);
- assert(ret == 0);
- assert(tiling == I915_TILING_X);
+ 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 */
- drm_intel_bo_map(linear_bo, 1);
+ 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);
+ intel_copy_bo (batch, bo, linear_bo, width*height*4);
drm_intel_bo_unreference(linear_bo);
@@ -99,18 +99,16 @@ check_bo(drm_intel_bo *bo, uint32_t start_val)
linear_bo = drm_intel_bo_alloc(bufmgr, "linear dst", 1024 * 1024, 4096);
- intel_copy_bo(batch, linear_bo, bo, width, height);
+ intel_copy_bo(batch, linear_bo, bo, width*height*4);
- drm_intel_bo_map(linear_bo, 0);
+ do_or_die(drm_intel_bo_map(linear_bo, 0));
linear = linear_bo->virtual;
for (i = 0; i < 1024 * 1024 / 4; i++) {
- if (linear[i] != start_val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- start_val, linear[i], i * 4);
- abort();
- }
+ 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);
@@ -118,47 +116,26 @@ check_bo(drm_intel_bo *bo, uint32_t start_val)
drm_intel_bo_unreference(linear_bo);
}
-int main(int argc, char **argv)
+static void run_test(int count)
{
drm_intel_bo **bo;
uint32_t *bo_start_val;
uint32_t start = 0;
- int i, fd, count;
-
- fd = drm_open_any();
-
- count = 0;
- if (argc > 1)
- count = atoi(argv[1]);
- if (count == 0) {
- count = 3 * gem_aperture_size(fd) / (1024*1024) / 2;
- count += (count & 1) == 0;
- }
-
- if (count > intel_get_total_ram_mb() * 9 / 10) {
- count = intel_get_total_ram_mb() * 9 / 10;
- printf("not enough RAM to run test, reducing buffer count\n");
- }
-
- printf("Using %d 1MiB buffers\n", count);
+ int i;
bo = malloc(sizeof(drm_intel_bo *)*count);
bo_start_val = malloc(sizeof(uint32_t)*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(start);
bo_start_val[i] = start;
start += 1024 * 1024 / 4;
}
- printf("Verifying initialisation...\n");
+ igt_info("Verifying initialisation...\n");
for (i = 0; i < count; i++)
check_bo(bo[i], bo_start_val[i]);
- printf("Cyclic blits, forward...\n");
+ igt_info("Cyclic blits, forward...\n");
for (i = 0; i < count * 4; i++) {
int src = i % count;
int dst = (i+1) % count;
@@ -166,13 +143,21 @@ int main(int argc, char **argv)
if (src == dst)
continue;
- intel_copy_bo(batch, bo[dst], bo[src], width, height);
+ 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]);
- printf("Cyclic blits, backward...\n");
+ 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;
@@ -180,13 +165,13 @@ int main(int argc, char **argv)
if (src == dst)
continue;
- intel_copy_bo(batch, bo[dst], bo[src], width, height);
+ 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]);
- printf("Random blits...\n");
+ igt_info("Random blits...\n");
for (i = 0; i < count * 4; i++) {
int src = random() % count;
int dst = random() % count;
@@ -194,21 +179,69 @@ int main(int argc, char **argv)
if (src == dst)
continue;
- intel_copy_bo(batch, bo[dst], bo[src], width, height);
+ 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]);
-
for (i = 0; i < count; i++) {
+ check_bo(bo[i], bo_start_val[i]);
drm_intel_bo_unreference(bo[i]);
- bo[i] = NULL;
}
- intel_batchbuffer_free(batch);
- drm_intel_bufmgr_destroy(bufmgr);
+ free(bo_start_val);
+ free(bo);
+}
+
+int fd;
+
+int main(int argc, char **argv)
+{
+ int count = 0;
+
+ igt_subtest_init(argc, argv);
+
+ igt_fixture {
+ fd = drm_open_any();
+
+ if (igt_run_in_simulation())
+ count = 2;
+ if (argc > 1)
+ count = atoi(argv[1]);
+ if (count == 0) {
+ count = 3 * gem_aperture_size(fd) / (1024*1024) / 2;
+ count += (count & 1) == 0;
+ } else if (count < 2) {
+ fprintf(stderr, "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");
+ }
- close(fd);
+ igt_info("Using %d 1MiB buffers\n", count);
+
+ 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("normal")
+ run_test(count);
+
+ igt_subtest("interruptible") {
+ igt_fork_signal_helper();
+ run_test(count);
+ igt_stop_signal_helper();
+ }
+
+ igt_fixture {
+ intel_batchbuffer_free(batch);
+ drm_intel_bufmgr_destroy(bufmgr);
+
+ close(fd);
+ }
- return 0;
+ igt_exit();
}
diff --git a/tests/gem_tiled_fence_blits.c b/tests/gem_tiled_fence_blits.c
index dc654793..e3f322e3 100644
--- a/tests/gem_tiled_fence_blits.c
+++ b/tests/gem_tiled_fence_blits.c
@@ -44,18 +44,21 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
+#include "igt_aux.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -71,8 +74,8 @@ create_bo(int fd, uint32_t start_val)
bo = drm_intel_bo_alloc(bufmgr, "tiled bo", 1024 * 1024, 4096);
ret = drm_intel_bo_set_tiling(bo, &tiling, width * 4);
- assert(ret == 0);
- assert(tiling == I915_TILING_X);
+ 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++)
@@ -91,31 +94,31 @@ check_bo(int fd, drm_intel_bo *bo, uint32_t start_val)
gem_read(fd, bo->handle, 0, linear, sizeof(linear));
for (i = 0; i < 1024 * 1024 / 4; i++) {
- if (linear[i] != start_val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- start_val, linear[i], i * 4);
- abort();
- }
+ 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++;
}
}
-int main(int argc, char **argv)
+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;
- printf("not enough RAM to run test, reducing buffer count\n");
+ igt_info("not enough RAM to run test, reducing buffer count\n");
}
count |= 1;
- printf("Using %d 1MiB buffers\n", count);
+ igt_info("Using %d 1MiB buffers\n", count);
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
drm_intel_bufmgr_gem_enable_reuse(bufmgr);
@@ -126,7 +129,7 @@ int main(int argc, char **argv)
bo_start_val[i] = start;
/*
- printf("Creating bo %d\n", i);
+ igt_info("Creating bo %d\n", i);
check_bo(bo[i], bo_start_val[i]);
*/
@@ -135,7 +138,7 @@ int main(int argc, char **argv)
for (i = 0; i < count; i++) {
int src = count - i - 1;
- intel_copy_bo(batch, bo[i], bo[src], width, height);
+ intel_copy_bo(batch, bo[i], bo[src], width*height*4);
bo_start_val[i] = bo_start_val[src];
}
@@ -146,18 +149,18 @@ int main(int argc, char **argv)
if (src == dst)
continue;
- intel_copy_bo(batch, bo[dst], bo[src], width, height);
+ 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]);
- printf("%d: copy bo %d to %d\n", i, src, dst);
+ igt_info("%d: copy bo %d to %d\n", i, src, dst);
*/
}
for (i = 0; i < count; i++) {
/*
- printf("check %d\n", i);
+ igt_info("check %d\n", i);
*/
check_bo(fd, bo[i], bo_start_val[i]);
@@ -169,6 +172,4 @@ int main(int argc, char **argv)
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_tiled_partial_pwrite_pread.c b/tests/gem_tiled_partial_pwrite_pread.c
index bd0d4e09..f22e834b 100644
--- a/tests/gem_tiled_partial_pwrite_pread.c
+++ b/tests/gem_tiled_partial_pwrite_pread.c
@@ -28,18 +28,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_chipset.h"
+#include "intel_io.h"
+#include "igt_aux.h"
/*
* Testcase: pwrite/pread consistency when touching partial cachelines
@@ -83,20 +84,18 @@ copy_bo(drm_intel_bo *src, int src_tiled,
cmd_bits |= XY_SRC_COPY_BLT_SRC_TILED;
}
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB |
- cmd_bits);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(src_pitch);
OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
@@ -118,45 +117,20 @@ blt_bo_fill(drm_intel_bo *tmp_bo, drm_intel_bo *bo, int val)
if (bo->offset < mappable_gtt_limit &&
(IS_G33(devid) || intel_gen(devid) >= 4))
- drmtest_trash_aperture();
+ igt_trash_aperture();
copy_bo(tmp_bo, 0, bo, 1);
}
#define MAX_BLT_SIZE 128
#define ROUNDS 200
-int main(int argc, char **argv)
+uint8_t tmp[BO_SIZE];
+uint8_t compare_tmp[BO_SIZE];
+
+static void test_partial_reads(void)
{
int i, j;
- uint8_t tmp[BO_SIZE];
- uint8_t compare_tmp[BO_SIZE];
- uint32_t tiling_mode = I915_TILING_X;
- srandom(0xdeadbeef);
-
- 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);
- assert(tiling_mode == I915_TILING_X);
- 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);
-
- drmtest_init_aperture_trashers(bufmgr);
- mappable_gtt_limit = gem_mappable_aperture_size();
-
- printf("checking partial reads\n");
for (i = 0; i < ROUNDS; i++) {
int start, len;
int val = i % 256;
@@ -168,17 +142,19 @@ int main(int argc, char **argv)
drm_intel_bo_get_subdata(scratch_bo, start, len, tmp);
for (j = 0; j < len; j++) {
- if (tmp[j] != val) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- start + j, tmp[j], val);
- exit(1);
- }
+ igt_assert_f(tmp[j] == val,
+ "mismatch at %i, got: %i, expected: %i\n",
+ start + j, tmp[j], val);
}
- drmtest_progress("partial reads test: ", i, ROUNDS);
+ igt_progress("partial reads test: ", i, ROUNDS);
}
+}
+
+static void test_partial_writes(void)
+{
+ int i, j;
- printf("checking partial writes\n");
for (i = 0; i < ROUNDS; i++) {
int start, len;
int val = i % 256;
@@ -197,32 +173,30 @@ int main(int argc, char **argv)
compare_tmp);
for (j = 0; j < start; j++) {
- if (compare_tmp[j] != val) {
- printf("amismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ igt_assert_f(compare_tmp[j] == val,
+ "mismatch at %i, got: %i, expected: %i\n",
+ j, tmp[j], val);
}
for (; j < start + len; j++) {
- if (compare_tmp[j] != tmp[0]) {
- printf("bmismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], i);
- exit(1);
- }
+ 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++) {
- if (compare_tmp[j] != val) {
- printf("cmismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ 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);
- drmtest_progress("partial writes test: ", i, ROUNDS);
+ igt_progress("partial writes test: ", i, ROUNDS);
}
+}
+
+static void test_partial_read_writes(void)
+{
+ int i, j;
- printf("checking partial writes after partial reads\n");
for (i = 0; i < ROUNDS; i++) {
int start, len;
int val = i % 256;
@@ -235,11 +209,9 @@ int main(int argc, char **argv)
drm_intel_bo_get_subdata(scratch_bo, start, len, tmp);
for (j = 0; j < len; j++) {
- if (tmp[j] != val) {
- printf("mismatch in read at %i, got: %i, expected: %i\n",
- start + j, tmp[j], val);
- exit(1);
- }
+ 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
@@ -260,35 +232,71 @@ int main(int argc, char **argv)
compare_tmp);
for (j = 0; j < start; j++) {
- if (compare_tmp[j] != val) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ igt_assert_f(compare_tmp[j] == val,
+ "mismatch at %i, got: %i, expected: %i\n",
+ j, tmp[j], val);
}
for (; j < start + len; j++) {
- if (compare_tmp[j] != tmp[0]) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], tmp[0]);
- exit(1);
- }
+ 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++) {
- if (compare_tmp[j] != val) {
- printf("mismatch at %i, got: %i, expected: %i\n",
- j, tmp[j], val);
- exit(1);
- }
+ 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);
- drmtest_progress("partial read/writes test: ", i, ROUNDS);
+ igt_progress("partial read/writes test: ", i, ROUNDS);
}
+}
- drmtest_cleanup_aperture_trashers();
- drm_intel_bufmgr_destroy(bufmgr);
+igt_main
+{
+ uint32_t tiling_mode = I915_TILING_X;
- close(fd);
+ igt_skip_on_simulation();
- return 0;
+ 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
index 189affce..4815b724 100644
--- a/tests/gem_tiled_pread.c
+++ b/tests/gem_tiled_pread.c
@@ -38,18 +38,17 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
#define WIDTH 512
#define HEIGHT 512
@@ -71,7 +70,7 @@ gem_get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle)
get_tiling.handle = handle;
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING, &get_tiling);
- assert(ret == 0);
+ igt_assert(ret == 0);
*tiling = get_tiling.tiling_mode;
*swizzle = get_tiling.swizzle_mode;
@@ -121,12 +120,11 @@ calculate_expected(int offset)
int tile_y = tile_off / tile_width;
int tile_x = (tile_off % tile_width) / 4;
- /* printf("%3d, %3d, %3d,%3d\n", base_x, base_y, tile_x, tile_y); */
+ 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;
}
-int
-main(int argc, char **argv)
+igt_simple_main
{
int fd;
int i, iter = 100;
@@ -213,25 +211,19 @@ main(int argc, char **argv)
swizzle_str = "bit9^10^11";
break;
default:
- fprintf(stderr, "Bad swizzle bits; %d\n",
- swizzle);
- abort();
+ igt_assert_f(0, "Bad swizzle bits; %d\n",
+ swizzle);
}
expected_val = calculate_expected(swizzled_offset);
found_val = linear[(j - offset) / 4];
- if (expected_val != found_val) {
- fprintf(stderr,
- "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);
- abort();
- }
+ 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);
-
- return 0;
}
diff --git a/tests/gem_tiled_pread_pwrite.c b/tests/gem_tiled_pread_pwrite.c
index e2225c5e..b6d9d627 100644
--- a/tests/gem_tiled_pread_pwrite.c
+++ b/tests/gem_tiled_pread_pwrite.c
@@ -47,18 +47,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include "drm.h"
-#include "i915_drm.h"
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "igt_aux.h"
#define WIDTH 512
#define HEIGHT 512
@@ -77,7 +78,7 @@ gem_get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle)
get_tiling.handle = handle;
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING, &get_tiling);
- assert(ret == 0);
+ igt_assert(ret == 0);
*tiling = get_tiling.tiling_mode;
*swizzle = get_tiling.swizzle_mode;
@@ -113,8 +114,7 @@ create_bo(int fd)
return handle;
}
-int
-main(int argc, char **argv)
+igt_simple_main
{
int fd;
uint32_t *data;
@@ -123,9 +123,8 @@ main(int argc, char **argv)
uint32_t handle, handle_target;
int count;
-
fd = drm_open_any();
- count = intel_get_total_ram_mb() * 9 / 10;
+ count = SLOW_QUICK(intel_get_total_ram_mb() * 9 / 10, 8) ;
for (i = 0; i < count/2; i++) {
current_tiling_mode = I915_TILING_X;
@@ -141,19 +140,17 @@ main(int argc, char **argv)
/* 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++)
- if (data[j] != j) {
- fprintf(stderr, "mismatch at %i: %i\n",
- j, data[j]);
- exit(1);
- }
+ 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);
- drmtest_progress("gem_tiled_pread_pwrite: ", i, count/2);
+ igt_progress("gem_tiled_pread_pwrite: ", i, count/2);
}
close(fd);
-
- return 0;
}
diff --git a/tests/gem_tiled_swapping.c b/tests/gem_tiled_swapping.c
index d1484f0e..86c79f2d 100644
--- a/tests/gem_tiled_swapping.c
+++ b/tests/gem_tiled_swapping.c
@@ -47,22 +47,24 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include "drm.h"
-#include "i915_drm.h"
+#include <pthread.h>
+
+#include <drm.h>
+
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "igt_aux.h"
#define WIDTH 512
#define HEIGHT 512
-static uint32_t linear[WIDTH * HEIGHT];
+#define LINEAR_DWORDS (4 * WIDTH * HEIGHT)
static uint32_t current_tiling_mode;
#define PAGE_SIZE 4096
@@ -74,72 +76,124 @@ create_bo_and_fill(int fd)
uint32_t *data;
int i;
- handle = gem_create(fd, sizeof(linear));
+ handle = gem_create(fd, LINEAR_DWORDS);
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);
+ data = gem_mmap(fd, handle, LINEAR_DWORDS, PROT_READ | PROT_WRITE);
+ if (data == NULL && errno == ENOSPC)
+ return 0;
+
for (i = 0; i < WIDTH*HEIGHT; i++)
data[i] = i;
- munmap(data, sizeof(linear));
+ munmap(data, LINEAR_DWORDS);
return handle;
}
uint32_t *bo_handles;
-int *idx_arr;
-int
-main(int argc, char **argv)
+struct thread {
+ pthread_t thread;
+ int *idx_arr;
+ int fd, count;
+};
+
+static void
+check_bo(int fd, uint32_t handle)
{
- int fd;
uint32_t *data;
- int i, j;
- int count;
- current_tiling_mode = I915_TILING_X;
+ int j;
+
+ /* Check the target bo's contents. */
+ data = gem_mmap(fd, handle, LINEAR_DWORDS, 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, LINEAR_DWORDS);
+}
- fd = drm_open_any();
- /* need slightly more than total ram */
- count = intel_get_total_ram_mb() * 11 / 10;
- bo_handles = calloc(count, sizeof(uint32_t));
- assert(bo_handles);
+static void *thread_run(void *data)
+{
+ struct thread *t = data;
+ int i;
- idx_arr = calloc(count, sizeof(int));
- assert(idx_arr);
+ for (i = 0; i < t->count; i++)
+ check_bo(t->fd, bo_handles[t->idx_arr[i]]);
- if (intel_get_total_swap_mb() == 0) {
- printf("no swap detected\n");
- return 77;
- }
+ return NULL;
+}
- if (intel_get_total_ram_mb() / 4 > intel_get_total_swap_mb()) {
- printf("not enough swap detected\n");
- return 77;
- }
+static void thread_init(struct thread *t, int fd, int count)
+{
+ int i;
- for (i = 0; i < count; i++)
- bo_handles[i] = create_bo_and_fill(fd);
+ t->fd = fd;
+ t->count = count;
+ t->idx_arr = calloc(count, sizeof(int));
+ igt_assert(t->idx_arr);
for (i = 0; i < count; i++)
- idx_arr[i] = i;
-
- drmtest_permute_array(idx_arr, count,
- drmtest_exchange_int);
-
- for (i = 0; i < count/2; i++) {
- /* Check the target bo's contents. */
- data = gem_mmap(fd, bo_handles[idx_arr[i]],
- sizeof(linear), PROT_READ | PROT_WRITE);
- for (j = 0; j < WIDTH*HEIGHT; j++)
- if (data[j] != j) {
- fprintf(stderr, "mismatch at %i: %i\n",
- j, data[j]);
- exit(1);
- }
- munmap(data, sizeof(linear));
+ 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);
+}
+
+igt_simple_main
+{
+ struct thread *threads;
+ int fd, n, count, num_threads;
+
+ current_tiling_mode = I915_TILING_X;
+
+ igt_skip_on_simulation();
+ intel_purge_vm_caches();
+
+ fd = drm_open_any();
+ /* need slightly more than available memory */
+ count = intel_get_total_ram_mb() + intel_get_total_swap_mb() / 4;
+ 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_log(IGT_LOG_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());
+ igt_require(intel_check_memory(count, 1024*1024, CHECK_RAM | CHECK_SWAP));
+
+ for (n = 0; n < count; n++) {
+ bo_handles[n] = create_bo_and_fill(fd);
+ /* Not enough mmap address space possible. */
+ igt_require(bo_handles[n]);
}
- close(fd);
+ thread_init(&threads[0], fd, count);
+ thread_run(&threads[0]);
+ thread_fini(&threads[0]);
+
+ /* Once more with threads */
+ igt_subtest("threaded") {
+ for (n = 0; n < num_threads; n++) {
+ thread_init(&threads[n], fd, count);
+ pthread_create(&threads[n].thread, NULL, thread_run, &threads[n]);
+ }
+ for (n = 0; n < num_threads; n++) {
+ pthread_join(threads[n].thread, NULL);
+ thread_fini(&threads[n]);
+ }
+ }
- return 0;
+ close(fd);
}
diff --git a/tests/gem_tiling_max_stride.c b/tests/gem_tiling_max_stride.c
new file mode 100644
index 00000000..4d0553d4
--- /dev/null
+++ b/tests/gem_tiling_max_stride.c
@@ -0,0 +1,139 @@
+/*
+ * 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"
+
+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
index bffc62ea..aa0e01e1 100644
--- a/tests/gem_unfence_active_buffers.c
+++ b/tests/gem_unfence_active_buffers.c
@@ -41,7 +41,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
@@ -49,11 +48,12 @@
#include <sys/time.h>
#include <stdbool.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -64,12 +64,14 @@ uint32_t devid;
uint32_t data[TEST_SIZE/4];
-int main(int argc, char **argv)
+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;
@@ -80,23 +82,22 @@ int main(int argc, char **argv)
devid = intel_get_drm_devid(fd);
batch = intel_batchbuffer_alloc(bufmgr, devid);
- printf("filling ring\n");
+ 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++) {
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(2*1024*4);
OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
if (IS_GEN6(devid) || IS_GEN7(devid)) {
@@ -110,51 +111,49 @@ int main(int argc, char **argv)
intel_batchbuffer_flush(batch);
num_fences = gem_available_fences(fd);
- printf("creating havoc on %i fences\n", num_fences);
+ 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);
- assert(ret == 0);
+ igt_assert(ret == 0);
drm_intel_bo_disable_reuse(test_bo);
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(TEST_STRIDE);
OUT_RELOC_FENCED(test_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
- printf("test bo offset: %#lx\n", test_bo->offset);
+ 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++) {
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(devid, 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);
+ BLIT_RELOC_UDW(devid);
OUT_BATCH(0 << 16 | 0);
OUT_BATCH(2*1024*4);
OUT_RELOC_FENCED(busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
ADVANCE_BATCH();
if (IS_GEN6(devid) || IS_GEN7(devid)) {
@@ -166,6 +165,4 @@ int main(int argc, char **argv)
}
}
intel_batchbuffer_flush(batch);
-
- return 0;
}
diff --git a/tests/gem_unref_active_buffers.c b/tests/gem_unref_active_buffers.c
index aa29c1de..cdc30990 100644
--- a/tests/gem_unref_active_buffers.c
+++ b/tests/gem_unref_active_buffers.c
@@ -35,62 +35,57 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "intel_bufmgr.h"
#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
static drm_intel_bo *load_bo;
-int main(int argc, char **argv)
+igt_simple_main
{
int fd, i;
+ igt_skip_on_simulation();
+
fd = drm_open_any();
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
- if (!bufmgr) {
- fprintf(stderr, "failed to init libdrm\n");
- exit(-1);
- }
+ 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));
- assert(batch);
+ 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);
- if (!load_bo) {
- fprintf(stderr, "failed to alloc target buffer\n");
- exit(-1);
- }
+ igt_assert(load_bo);
- BEGIN_BATCH(8);
- OUT_BATCH(XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ BLIT_COPY_BATCH_START(batch->devid, 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);
+ BLIT_RELOC_UDW(batch->devid);
OUT_BATCH((0 << 16) | 512); /* src x1, y1 */
OUT_BATCH(4096);
OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(batch->devid);
ADVANCE_BATCH();
intel_batchbuffer_flush(batch);
@@ -102,6 +97,4 @@ int main(int argc, char **argv)
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c
new file mode 100644
index 00000000..14efddae
--- /dev/null
+++ b/tests/gem_userptr_blits.c
@@ -0,0 +1,1249 @@
+/*
+ * 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 <assert.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <signal.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;
+
+ 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;
+
+ 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);
+ 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 int num_handle_ptr_map;
+
+static void add_handle_ptr(uint32_t handle, void *ptr)
+{
+ if (handle >= num_handle_ptr_map) {
+ handle_ptr_map = realloc(handle_ptr_map,
+ (handle + 1000) * sizeof(void*));
+ num_handle_ptr_map = handle + 1000;
+ }
+
+ handle_ptr_map[handle] = ptr;
+}
+
+static void *get_handle_ptr(uint32_t handle)
+{
+ return handle_ptr_map[handle];
+}
+
+static void free_handle_ptr(uint32_t handle)
+{
+ igt_assert(handle < num_handle_ptr_map);
+ igt_assert(handle_ptr_map[handle]);
+
+ free(handle_ptr_map[handle]);
+ handle_ptr_map[handle] = NULL;
+}
+
+static uint32_t create_userptr_bo(int fd, int size)
+{
+ void *ptr;
+ uint32_t handle;
+ int ret;
+
+ ret = posix_memalign(&ptr, PAGE_SIZE, size);
+ igt_assert(ret == 0);
+
+ ret = gem_userptr(fd, (uint32_t *)ptr, size, 0, &handle);
+ igt_assert(ret == 0);
+ add_handle_ptr(handle, ptr);
+
+ return 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;
+
+ 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. */
+ 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. */
+ 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. */
+ 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_mapping(int fd)
+{
+ int ret;
+ uint32_t handle, handle2;
+ void *ptr;
+
+ /* 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);
+
+ /* GTT mapping */
+ handle = create_bo(fd, 0);
+ ptr = gem_mmap__gtt(fd, handle, sizeof(linear), PROT_READ | PROT_WRITE);
+ if (ptr == NULL)
+ gem_close(fd, handle);
+ assert(ptr != NULL);
+ assert(((unsigned long)ptr & (PAGE_SIZE - 1)) == 0);
+ assert((sizeof(linear) & (PAGE_SIZE - 1)) == 0);
+ ret = gem_userptr(fd, ptr, sizeof(linear), 0, &handle2);
+ igt_assert(ret == 0);
+ copy(fd, handle, handle, ~0); /* QQQ Precise errno? */
+ gem_close(fd, handle2);
+ munmap(ptr, sizeof(linear));
+ gem_close(fd, handle);
+
+ return 0;
+}
+
+static int test_forbidden_ops(int fd)
+{
+ void *ptr;
+ int ret;
+ uint32_t handle;
+ char buf[PAGE_SIZE];
+ struct drm_i915_gem_pread gem_pread;
+ struct drm_i915_gem_pwrite gem_pwrite;
+
+ assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
+
+ ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle);
+ igt_assert(ret == 0);
+
+ 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);
+ if (ret == 0) {
+ gem_close(fd, handle);
+ free(ptr);
+ }
+ igt_assert(ret != 0);
+
+ 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);
+ if (ret == 0) {
+ gem_close(fd, handle);
+ free(ptr);
+ }
+ igt_assert(ret != 0);
+
+ gem_close(fd, handle);
+ free(ptr);
+
+ return 0;
+}
+
+static char counter;
+
+static void (*orig_sigbus)(int sig, siginfo_t *info, void *param);
+static unsigned long sigbus_start;
+static long sigbus_cnt = -1;
+
+static void
+check_bo(int fd1, uint32_t handle1, int is_userptr, int fd2, uint32_t handle2)
+{
+ char *ptr1, *ptr2;
+ int i;
+ unsigned long size = sizeof(linear);
+
+ if (is_userptr)
+ ptr1 = get_handle_ptr(handle1);
+ else
+ ptr1 = gem_mmap(fd1, handle1, sizeof(linear), PROT_READ | PROT_WRITE);
+
+ ptr2 = gem_mmap(fd2, handle2, sizeof(linear), PROT_READ | PROT_WRITE);
+
+ igt_assert(ptr1);
+ igt_assert(ptr2);
+
+ sigbus_start = (unsigned long)ptr2;
+
+ if (sigbus_cnt == 0)
+ size = 1;
+
+ /* check whether it's still our old object first. */
+ for (i = 0; i < size; i++) {
+ igt_assert(ptr1[i] == counter);
+ igt_assert(ptr2[i] == counter);
+ }
+
+ counter++;
+
+ if (size > 1) {
+ memset(ptr1, counter, size);
+ igt_assert(memcmp(ptr1, ptr2, size) == 0);
+ }
+
+ 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))) {
+ sigbus_cnt++;
+ addr = mmap((void *)ptr, sizeof(linear), PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
+ if ((unsigned long)addr == ptr) {
+ memset(addr, counter, sizeof(linear));
+ return;
+ }
+ }
+
+ if (orig_sigbus)
+ orig_sigbus(sig, info, param);
+ assert(0);
+}
+
+static int test_dmabuf(void)
+{
+ int fd1, fd2;
+ uint32_t handle, handle_import1, handle_import2, handle_selfimport;
+ int dma_buf_fd = -1;
+ int ret;
+ struct sigaction sigact, orig_sigact;
+
+ fd1 = drm_open_any();
+ fd2 = drm_open_any();
+
+ handle = create_userptr_bo(fd1, 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);
+
+ return 0;
+ } else {
+ igt_assert(ret == 0);
+ igt_assert(dma_buf_fd >= 0);
+ }
+ handle_import1 = prime_fd_to_handle(fd2, dma_buf_fd);
+ check_bo(fd1, handle, 1, 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, 1, fd2, handle_import1);
+
+ /* destroy userptr object and expect SIGBUS */
+ free_userptr_bo(fd1, handle);
+ sigact.sa_sigaction = sigbus;
+ sigact.sa_flags = SA_SIGINFO;
+ ret = sigaction(SIGBUS, &sigact, &orig_sigact);
+ assert(ret == 0);
+ orig_sigbus = orig_sigact.sa_sigaction;
+ sigbus_cnt = 0;
+ check_bo(fd2, handle_import1, 0, fd2, handle_import1);
+ assert(sigbus_cnt > 0);
+ sigact.sa_sigaction = orig_sigbus;
+ sigact.sa_flags = SA_SIGINFO;
+ ret = sigaction(SIGBUS, &sigact, &orig_sigact);
+ assert(ret == 0);
+
+ gem_close(fd2, handle_import1);
+ close(fd1);
+ close(fd2);
+
+ return 0;
+}
+
+static int test_usage_restrictions(int fd)
+{
+ void *ptr;
+ int ret;
+ uint32_t handle;
+
+ 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)
+{
+ void *ptr;
+ int ret;
+ uint32_t handle;
+
+ igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
+
+ ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle);
+ igt_assert(ret == 0);
+
+ gem_close(fd, handle);
+ free(ptr);
+
+ 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;
+
+ 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,
+ .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;
+}
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+static int 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);
+
+ ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle2);
+ igt_assert(ret == 0);
+ gem_close(fd, handle2);
+
+ ret = gem_userptr(fd, ptr + PAGE_SIZE * 2, PAGE_SIZE, 0, &handle2);
+ igt_assert(ret == 0);
+ gem_close(fd, handle2);
+
+ ret = gem_userptr(fd, ptr, PAGE_SIZE * 2, 0, &handle2);
+ igt_assert(ret == expected);
+ if (ret == 0)
+ gem_close(fd, handle2);
+
+ ret = gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE * 2, 0, &handle2);
+ igt_assert(ret == expected);
+ if (ret == 0)
+ gem_close(fd, handle2);
+
+ ret = gem_userptr(fd, ptr, PAGE_SIZE * 3, 0, &handle2);
+ igt_assert(ret == expected);
+ if (ret == 0)
+ gem_close(fd, handle2);
+
+ gem_close(fd, handle);
+ free(ptr);
+
+ return 0;
+}
+
+static int 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);
+ 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);
+ 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]);
+
+ return 0;
+}
+
+static int 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);
+ 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);
+ assert(ret == 0);
+
+ return 0;
+}
+
+static int test_unmap_cycles(int fd, int expected)
+{
+ int i;
+
+ for (i = 0; i < 1000; i++)
+ test_unmap(fd, expected);
+
+ return 0;
+}
+
+unsigned int total_ram;
+uint64_t aperture_size;
+int fd, count;
+
+
+int main(int argc, char **argv)
+{
+ int size = sizeof(linear);
+
+ igt_skip_on_simulation();
+
+ 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-mapping")
+ test_invalid_mapping(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);
+
+ 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("create-destroy-sync")
+ test_create_destroy(fd);
+
+ 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("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();
+
+ return 0;
+}
diff --git a/tests/gem_vmap_blits.c b/tests/gem_vmap_blits.c
deleted file mode 100644
index b8868214..00000000
--- a/tests/gem_vmap_blits.c
+++ /dev/null
@@ -1,355 +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>
- * Chris Wilson <chris@chris-wilson.co.uk>
- *
- */
-
-/** @file gem_vmap_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 <assert.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include "drm.h"
-#include "i915_drm.h"
-#include "drmtest.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-#include "intel_gpu_tools.h"
-
-#if !defined(I915_PARAM_HAS_VMAP)
-#warning No vmap support in drm, skipping
-int main(int argc, char **argv)
-{
- fprintf(stderr, "No vmap support in drm.\n");
- return 77;
-}
-#else
-
-#define WIDTH 512
-#define HEIGHT 512
-
-static uint32_t linear[WIDTH*HEIGHT];
-
-static uint32_t gem_vmap(int fd, void *ptr, int size, int read_only)
-{
- struct drm_i915_gem_vmap vmap;
-
- vmap.user_ptr = (uintptr_t)ptr;
- vmap.user_size = size;
- vmap.flags = 0;
- if (read_only)
- vmap.flags |= I915_VMAP_READ_ONLY;
-
- if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VMAP, &vmap))
- return 0;
-
- return vmap.handle;
-}
-
-
-static void gem_vmap_sync(int fd, uint32_t handle)
-{
- gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
-}
-
-static void
-gem_read(int fd, uint32_t handle, int offset, int size, void *buf)
-{
- struct drm_i915_gem_pread pread;
- int ret;
-
- pread.handle = handle;
- pread.offset = offset;
- pread.size = size;
- pread.data_ptr = (uintptr_t)buf;
- ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_PREAD, &pread);
- assert(ret == 0);
-}
-
-static void
-copy(int fd, uint32_t dst, uint32_t src)
-{
- uint32_t batch[10];
- 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;
-
- batch[0] = XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB;
- batch[1] = (3 << 24) | /* 32 bits */
- (0xcc << 16) | /* copy ROP */
- WIDTH*4;
- batch[2] = 0; /* dst x1,y1 */
- batch[3] = (HEIGHT << 16) | WIDTH; /* dst x2,y2 */
- batch[4] = 0; /* dst reloc */
- batch[5] = 0; /* src x1,y1 */
- batch[6] = WIDTH*4;
- batch[7] = 0; /* src reloc */
- batch[8] = MI_BATCH_BUFFER_END;
- batch[9] = 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[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 = sizeof(batch);
- 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;
- exec.rsvd1 = 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);
- }
- assert(ret == 0);
-
- gem_close(fd, handle);
-}
-
-static uint32_t
-create_vmap(int fd, uint32_t val, uint32_t *ptr)
-{
- uint32_t handle;
- int i;
-
- handle = gem_vmap(fd, ptr, sizeof(linear), 0);
-
- /* Fill the BO with dwords starting at val */
- for (i = 0; i < WIDTH*HEIGHT; i++)
- ptr[i] = val++;
-
- return 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++) {
- if (ptr[i] != val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- val, ptr[i], i * 4);
- abort();
- }
- 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_vmap(int fd)
-{
- drm_i915_getparam_t gp;
- int i;
-
- gp.param = I915_PARAM_HAS_VMAP;
- gp.value = &i;
-
- return drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0 && i > 0;
-}
-
-int main(int argc, char **argv)
-{
- uint32_t *memory;
- uint32_t *cpu, *cpu_val;
- uint32_t *gpu, *gpu_val;
- uint32_t start = 0;
- int i, fd, count;
-
- fd = drm_open_any();
-
- if (!has_vmap(fd)) {
- fprintf(stderr, "No vmap support, ignoring.\n");
- return 77;
- }
-
- count = 0;
- if (argc > 1)
- count = atoi(argv[1]);
- if (count == 0)
- count = 3 * gem_aperture_size(fd) / (1024*1024) / 4;
- printf("Using 2x%d 1MiB buffers\n", count);
-
- memory = malloc(count*sizeof(linear));
- if (memory == NULL) {
- fprintf(stderr, "Unable to allocate %lld bytes\n",
- (long long)count*sizeof(linear));
- return 1;
- }
-
- 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_vmap(fd, start, memory+i*WIDTH*HEIGHT);
- cpu_val[i] = start;
- start += WIDTH*HEIGHT;;
- }
-
- printf("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]);
- }
-
- printf("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]);
- gpu_val[dst] = cpu_val[src];
- }
- for (i = 0; i < count; i++)
- check_gpu(fd, gpu[i], gpu_val[i]);
-
- printf("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]);
- cpu_val[dst] = gpu_val[src];
- }
- for (i = 0; i < count; i++) {
- gem_vmap_sync(fd, cpu[i]);
- check_cpu(memory+i*WIDTH*HEIGHT, cpu_val[i]);
- }
-
- printf("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]);
- gpu_val[dst] = cpu_val[src];
- } else {
- copy(fd, cpu[dst], gpu[src]);
- cpu_val[dst] = gpu_val[src];
- }
- }
- for (i = 0; i < count; i++) {
- check_gpu(fd, gpu[i], gpu_val[i]);
- gem_vmap_sync(fd, cpu[i]);
- check_cpu(memory+i*WIDTH*HEIGHT, cpu_val[i]);
- }
-
- return 0;
-}
-
-#endif
diff --git a/tests/gem_wait_render_timeout.c b/tests/gem_wait_render_timeout.c
index c321d36c..a34c006c 100644
--- a/tests/gem_wait_render_timeout.c
+++ b/tests/gem_wait_render_timeout.c
@@ -27,8 +27,26 @@
#include <stdio.h>
#include <time.h>
-#include "drm.h"
-#include "rendercopy.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 <getopt.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
@@ -69,7 +87,7 @@ gem_bo_wait_timeout(int fd, uint32_t handle, uint64_t *timeout_ns)
struct local_drm_i915_gem_wait wait;
int ret;
- assert(timeout_ns);
+ igt_assert(timeout_ns);
wait.bo_handle = handle;
wait.timeout_ns = *timeout_ns;
@@ -80,38 +98,37 @@ gem_bo_wait_timeout(int fd, uint32_t handle, uint64_t *timeout_ns)
return ret ? -errno : 0;
}
-static bool
-gem_bo_busy(int fd, uint32_t handle)
-{
- struct drm_i915_gem_busy busy;
-
- busy.handle = handle;
- do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_BUSY, &busy));
-
- return !!busy.busy;
-}
-
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;
- BEGIN_BATCH(5);
- OUT_BATCH(COLOR_BLT_CMD |
- COLOR_BLT_WRITE_ALPHA |
- COLOR_BLT_WRITE_RGB);
+
+ if (intel_gen(batch->devid) >= 8) {
+ BEGIN_BATCH(8);
+ OUT_BATCH(MI_NOOP);
+ OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | 5 |
+ COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
+ } else {
+ BEGIN_BATCH(6);
+ OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | 4 |
+ COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
+ }
OUT_BATCH((3 << 24) | /* 32 Bit Color */
- 0xF0 | /* Raster OP copy background register */
+ (0xF0 << 16) | /* Raster OP copy background register */
0); /* Dest pitch is 0 */
+ OUT_BATCH(0);
OUT_BATCH(width << 16 |
height);
OUT_RELOC(buf, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ if (intel_gen(batch->devid) >= 8)
+ OUT_BATCH(0);
OUT_BATCH(rand()); /* random pattern */
ADVANCE_BATCH();
}
-int main(int argc, char **argv)
+igt_simple_main
{
drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch;
@@ -122,6 +139,8 @@ int main(int argc, char **argv)
bool done = false;
int i, iter = 1;
+ igt_skip_on_simulation();
+
fd = drm_open_any();
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
@@ -131,10 +150,8 @@ int main(int argc, char **argv)
dst = drm_intel_bo_alloc(bufmgr, "dst", BUF_SIZE, 4096);
dst2 = drm_intel_bo_alloc(bufmgr, "dst2", BUF_SIZE, 4096);
- if (gem_bo_wait_timeout(fd, dst->handle, &timeout) == -EINVAL) {
- printf("kernel doesn't support wait_timeout, skipping test\n");
- return -77;
- }
+ 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
@@ -148,15 +165,15 @@ int main(int argc, char **argv)
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
#endif
- assert(clock_gettime(CLOCK_MONOTONIC_RAW, &start) == 0);
+ 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);
- assert(clock_gettime(CLOCK_MONOTONIC_RAW, &end) == 0);
+ igt_assert(clock_gettime(CLOCK_MONOTONIC_RAW, &end) == 0);
diff = do_time_diff(&end, &start);
- assert(diff >= 0);
+ igt_assert(diff >= 0);
if ((diff / MSEC_PER_SEC) > ENOUGH_WORK_IN_SECONDS)
done = true;
@@ -164,12 +181,12 @@ int main(int argc, char **argv)
iter <<= 1;
} while (!done && iter < 1000000);
- assert(iter < 1000000);
+ igt_assert_cmpint(iter, <, 1000000);
- printf("%d iters is enough work\n", iter);
+ igt_info("%d iters is enough work\n", iter);
gem_quiescent_gpu(fd);
if (do_signals)
- drmtest_fork_signal_helper();
+ 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
@@ -178,25 +195,21 @@ int main(int argc, char **argv)
blt_color_fill(batch, dst2, BUF_PAGES);
intel_batchbuffer_flush(batch);
- assert(gem_bo_busy(fd, dst2->handle) == true);
+ igt_assert(gem_bo_busy(fd, dst2->handle) == true);
- ret = gem_bo_wait_timeout(fd, dst2->handle, &timeout);
- if (ret) {
- fprintf(stderr, "Timed wait failed %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
- assert(gem_bo_busy(fd, dst2->handle) == false);
- assert(timeout != 0);
+ igt_assert(gem_bo_wait_timeout(fd, dst2->handle, &timeout) == 0);
+ igt_assert(gem_bo_busy(fd, dst2->handle) == false);
+ igt_assert_cmpint(timeout, !=, 0);
if (timeout == (ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC))
- printf("Buffer was already done!\n");
+ igt_info("Buffer was already done!\n");
else {
- printf("Finished with %lu time remaining\n", timeout);
+ igt_info("Finished with %lu time remaining\n", timeout);
}
/* check that polling with timeout=0 works. */
timeout = 0;
- assert(gem_bo_wait_timeout(fd, dst2->handle, &timeout) == 0);
- assert(timeout == 0);
+ igt_assert(gem_bo_wait_timeout(fd, dst2->handle, &timeout) == 0);
+ igt_assert(timeout == 0);
/* Now check that we correctly time out, twice the auto-tune load should
* be good enough. */
@@ -207,24 +220,22 @@ int main(int argc, char **argv)
intel_batchbuffer_flush(batch);
ret = gem_bo_wait_timeout(fd, dst2->handle, &timeout);
- assert(ret == -ETIME);
- assert(timeout == 0);
- assert(gem_bo_busy(fd, dst2->handle) == true);
+ igt_assert(ret == -ETIME);
+ igt_assert(timeout == 0);
+ igt_assert(gem_bo_busy(fd, dst2->handle) == true);
/* check that polling with timeout=0 works. */
timeout = 0;
- assert(gem_bo_wait_timeout(fd, dst2->handle, &timeout) == -ETIME);
- assert(timeout == 0);
+ igt_assert(gem_bo_wait_timeout(fd, dst2->handle, &timeout) == -ETIME);
+ igt_assert(timeout == 0);
if (do_signals)
- drmtest_stop_signal_helper();
+ igt_stop_signal_helper();
drm_intel_bo_unreference(dst2);
drm_intel_bo_unreference(dst);
intel_batchbuffer_free(batch);
drm_intel_bufmgr_destroy(bufmgr);
close(fd);
-
- return 0;
}
diff --git a/tests/gem_write_read_ring_switch.c b/tests/gem_write_read_ring_switch.c
new file mode 100644
index 00000000..76e1c2af
--- /dev/null
+++ b/tests/gem_write_read_ring_switch.c
@@ -0,0 +1,197 @@
+/*
+ * 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"
+
+#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(batch->devid, 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);
+ BLIT_RELOC_UDW(batch->devid);
+ OUT_BATCH((0 << 16) | 512); /* src x1, y1 */
+ OUT_BATCH(4096);
+ OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(batch->devid);
+ ADVANCE_BATCH();
+ }
+
+ COLOR_BLIT_COPY_BATCH_START(batch->devid, 0);
+ OUT_BATCH((3 << 24) | /* 32 bits */
+ (0xff << 16) |
+ 128);
+ OUT_BATCH(0); /* dst x1,y1 */
+ OUT_BATCH((1 << 16) | 1);
+ OUT_RELOC(target_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ BLIT_RELOC_UDW(batch->devid);
+ 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);
+ 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);
+ 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);
+ 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
index 5bb6d868..75d61a58 100644
--- a/tests/gen3_mixed_blits.c
+++ b/tests/gen3_mixed_blits.c
@@ -36,18 +36,17 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include <sys/mman.h>
#include <sys/ioctl.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
#include "i915_reg.h"
#include "i915_3d.h"
@@ -268,11 +267,11 @@ render_copy(int fd,
if ((b - batch) & 1)
*b++ = 0;
- assert(b - batch <= 1024);
+ igt_assert(b - batch <= 1024);
handle = gem_create(fd, 4096);
gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0]));
- assert(r-reloc == 2);
+ igt_assert(r-reloc == 2);
tiling_bits = 0;
if (use_fence)
@@ -320,7 +319,7 @@ render_copy(int fd,
drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
}
- assert(ret == 0);
+ igt_assert(ret == 0);
gem_close(fd, handle);
}
@@ -336,7 +335,7 @@ static void blt_copy(int fd, uint32_t dst, uint32_t src)
*b++ = (XY_SRC_COPY_BLT_CMD |
XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ XY_SRC_COPY_BLT_WRITE_RGB | 6);
*b++ = 3 << 24 | 0xcc << 16 | WIDTH * 4;
*b++ = 0;
*b++ = HEIGHT << 16 | WIDTH;
@@ -350,11 +349,11 @@ static void blt_copy(int fd, uint32_t dst, uint32_t src)
if ((b - batch) & 1)
*b++ = 0;
- assert(b - batch <= 1024);
+ igt_assert(b - batch <= 1024);
handle = gem_create(fd, 4096);
gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0]));
- assert(r-reloc == 2);
+ igt_assert(r-reloc == 2);
obj[0].handle = dst;
obj[0].relocation_count = 0;
@@ -398,7 +397,7 @@ static void blt_copy(int fd, uint32_t dst, uint32_t src)
drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
}
- assert(ret == 0);
+ igt_assert(ret == 0);
gem_close(fd, handle);
}
@@ -432,7 +431,7 @@ create_bo(int fd, uint32_t val, int tiling)
/* Fill the BO with dwords starting at val */
v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ | PROT_WRITE);
- assert(v);
+ igt_assert(v);
for (i = 0; i < WIDTH*HEIGHT; i++)
v[i] = val++;
munmap(v, WIDTH*HEIGHT*4);
@@ -447,14 +446,12 @@ check_bo(int fd, uint32_t handle, uint32_t val)
int i;
v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ);
- assert(v);
+ igt_assert(v);
for (i = 0; i < WIDTH*HEIGHT; i++) {
- if (v[i] != val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- val, v[i], i * 4);
- abort();
- }
+ 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);
@@ -466,19 +463,18 @@ int main(int argc, char **argv)
uint32_t start = 0;
int i, fd, count;
+ igt_simple_init();
+
fd = drm_open_any();
- if (!IS_GEN3(intel_get_drm_devid(fd))) {
- printf("gen3-only test, doing nothing\n");
- return 77;
- }
+ 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;
- printf("Using %d 1MiB buffers\n", count);
+ igt_info("Using %d 1MiB buffers\n", count);
handle = malloc(sizeof(uint32_t)*count*3);
tiling = handle + count;
@@ -490,12 +486,12 @@ int main(int argc, char **argv)
start += 1024 * 1024 / 4;
}
- printf("Verifying initialisation..."); fflush(stdout);
+ igt_info("Verifying initialisation..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Cyclic blits, forward..."); fflush(stdout);
+ igt_info("Cyclic blits, forward..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = i % count;
int dst = (i + 1) % count;
@@ -503,12 +499,12 @@ int main(int argc, char **argv)
copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Cyclic blits, backward..."); fflush(stdout);
+ igt_info("Cyclic blits, backward..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = (i + 1) % count;
int dst = i % count;
@@ -516,12 +512,12 @@ int main(int argc, char **argv)
copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Random blits..."); fflush(stdout);
+ igt_info("Random blits..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = random() % count;
int dst = random() % count;
@@ -532,10 +528,10 @@ int main(int argc, char **argv)
copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
return 0;
}
diff --git a/tests/gen3_render_linear_blits.c b/tests/gen3_render_linear_blits.c
index 529e23ff..7fe368d6 100644
--- a/tests/gen3_render_linear_blits.c
+++ b/tests/gen3_render_linear_blits.c
@@ -36,16 +36,16 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
#include "i915_reg.h"
#include "i915_3d.h"
@@ -241,11 +241,11 @@ copy(int fd, uint32_t dst, uint32_t src)
if ((b - batch) & 1)
*b++ = 0;
- assert(b - batch <= 1024);
+ igt_assert(b - batch <= 1024);
handle = gem_create(fd, 4096);
gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0]));
- assert(r-reloc == 2);
+ igt_assert(r-reloc == 2);
obj[0].handle = dst;
obj[0].relocation_count = 0;
@@ -289,7 +289,7 @@ copy(int fd, uint32_t dst, uint32_t src)
drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
}
- assert(ret == 0);
+ igt_assert(ret == 0);
gem_close(fd, handle);
}
@@ -317,12 +317,10 @@ check_bo(int fd, uint32_t handle, uint32_t val)
gem_read(fd, handle, 0, linear, sizeof(linear));
for (i = 0; i < WIDTH*HEIGHT; i++) {
- if (linear[i] != val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- val, linear[i], i * 4);
- abort();
- }
+ igt_assert_f(linear[i] == val,
+ "Expected 0x%08x, found 0x%08x "
+ "at offset 0x%08x\n",
+ val, linear[i], i * 4);
val++;
}
}
@@ -333,19 +331,18 @@ int main(int argc, char **argv)
uint32_t start = 0;
int i, fd, count;
+ igt_simple_init();
+
fd = drm_open_any();
- if (!IS_GEN3(intel_get_drm_devid(fd))) {
- printf("gen3-only test, doing nothing\n");
- return 77;
- }
+ 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;
- printf("Using %d 1MiB buffers\n", count);
+ igt_info("Using %d 1MiB buffers\n", count);
handle = malloc(sizeof(uint32_t)*count*2);
start_val = handle + count;
@@ -356,11 +353,11 @@ int main(int argc, char **argv)
start += 1024 * 1024 / 4;
}
- printf("Verifying initialisation...\n");
+ igt_info("Verifying initialisation...\n");
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Cyclic blits, forward...\n");
+ igt_info("Cyclic blits, forward...\n");
for (i = 0; i < count * 4; i++) {
int src = i % count;
int dst = (i + 1) % count;
@@ -371,7 +368,7 @@ int main(int argc, char **argv)
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Cyclic blits, backward...\n");
+ igt_info("Cyclic blits, backward...\n");
for (i = 0; i < count * 4; i++) {
int src = (i + 1) % count;
int dst = i % count;
@@ -382,7 +379,7 @@ int main(int argc, char **argv)
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Random blits...\n");
+ igt_info("Random blits...\n");
for (i = 0; i < count * 4; i++) {
int src = random() % count;
int dst = random() % count;
diff --git a/tests/gen3_render_mixed_blits.c b/tests/gen3_render_mixed_blits.c
index 1353b9d7..77ac0e2f 100644
--- a/tests/gen3_render_mixed_blits.c
+++ b/tests/gen3_render_mixed_blits.c
@@ -36,18 +36,17 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include <sys/mman.h>
#include <sys/ioctl.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
#include "i915_reg.h"
#include "i915_3d.h"
@@ -255,11 +254,11 @@ copy(int fd,
if ((b - batch) & 1)
*b++ = 0;
- assert(b - batch <= 1024);
+ igt_assert(b - batch <= 1024);
handle = gem_create(fd, 4096);
gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0]));
- assert(r-reloc == 2);
+ igt_assert(r-reloc == 2);
obj[0].handle = dst;
obj[0].relocation_count = 0;
@@ -303,7 +302,7 @@ copy(int fd,
drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
}
- assert(ret == 0);
+ igt_assert(ret == 0);
gem_close(fd, handle);
}
@@ -320,7 +319,7 @@ create_bo(int fd, uint32_t val, int tiling)
/* Fill the BO with dwords starting at val */
v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ | PROT_WRITE);
- assert(v);
+ igt_assert(v);
for (i = 0; i < WIDTH*HEIGHT; i++)
v[i] = val++;
munmap(v, WIDTH*HEIGHT*4);
@@ -335,14 +334,12 @@ check_bo(int fd, uint32_t handle, uint32_t val)
int i;
v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ);
- assert(v);
+ igt_assert(v);
for (i = 0; i < WIDTH*HEIGHT; i++) {
- if (v[i] != val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- val, v[i], i * 4);
- abort();
- }
+ 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);
@@ -354,19 +351,18 @@ int main(int argc, char **argv)
uint32_t start = 0;
int i, fd, count;
+ igt_simple_init();
+
fd = drm_open_any();
- if (!IS_GEN3(intel_get_drm_devid(fd))) {
- printf("gen3-only test, doing nothing\n");
- return 77;
- }
+ 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;
- printf("Using %d 1MiB buffers\n", count);
+ igt_info("Using %d 1MiB buffers\n", count);
handle = malloc(sizeof(uint32_t)*count*3);
tiling = handle + count;
@@ -378,12 +374,12 @@ int main(int argc, char **argv)
start += 1024 * 1024 / 4;
}
- printf("Verifying initialisation..."); fflush(stdout);
+ igt_info("Verifying initialisation..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Cyclic blits, forward..."); fflush(stdout);
+ igt_info("Cyclic blits, forward..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = i % count;
int dst = (i + 1) % count;
@@ -391,12 +387,12 @@ int main(int argc, char **argv)
copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Cyclic blits, backward..."); fflush(stdout);
+ igt_info("Cyclic blits, backward..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = (i + 1) % count;
int dst = i % count;
@@ -404,12 +400,12 @@ int main(int argc, char **argv)
copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Random blits..."); fflush(stdout);
+ igt_info("Random blits..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = random() % count;
int dst = random() % count;
@@ -420,10 +416,10 @@ int main(int argc, char **argv)
copy(fd, handle[dst], tiling[dst], handle[src], tiling[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
return 0;
}
diff --git a/tests/gen3_render_tiledx_blits.c b/tests/gen3_render_tiledx_blits.c
index 0e96e797..95c0c96b 100644
--- a/tests/gen3_render_tiledx_blits.c
+++ b/tests/gen3_render_tiledx_blits.c
@@ -36,18 +36,17 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include <sys/mman.h>
#include <sys/ioctl.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
#include "i915_reg.h"
#include "i915_3d.h"
@@ -242,11 +241,11 @@ copy(int fd, uint32_t dst, uint32_t src)
if ((b - batch) & 1)
*b++ = 0;
- assert(b - batch <= 1024);
+ igt_assert(b - batch <= 1024);
handle = gem_create(fd, 4096);
gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0]));
- assert(r-reloc == 2);
+ igt_assert(r-reloc == 2);
obj[0].handle = dst;
obj[0].relocation_count = 0;
@@ -290,7 +289,7 @@ copy(int fd, uint32_t dst, uint32_t src)
drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
}
- assert(ret == 0);
+ igt_assert(ret == 0);
gem_close(fd, handle);
}
@@ -307,7 +306,7 @@ create_bo(int fd, uint32_t val)
/* Fill the BO with dwords starting at val */
v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ | PROT_WRITE);
- assert(v);
+ igt_assert(v);
for (i = 0; i < WIDTH*HEIGHT; i++)
v[i] = val++;
munmap(v, WIDTH*HEIGHT*4);
@@ -322,14 +321,12 @@ check_bo(int fd, uint32_t handle, uint32_t val)
int i;
v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ);
- assert(v);
+ igt_assert(v);
for (i = 0; i < WIDTH*HEIGHT; i++) {
- if (v[i] != val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- val, v[i], i * 4);
- abort();
- }
+ 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);
@@ -341,19 +338,18 @@ int main(int argc, char **argv)
uint32_t start = 0;
int i, fd, count;
+ igt_simple_init();
+
fd = drm_open_any();
- if (!IS_GEN3(intel_get_drm_devid(fd))) {
- printf("gen3-only test, doing nothing\n");
- return 77;
- }
+ 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;
- printf("Using %d 1MiB buffers\n", count);
+ igt_info("Using %d 1MiB buffers\n", count);
handle = malloc(sizeof(uint32_t)*count*2);
start_val = handle + count;
@@ -364,11 +360,11 @@ int main(int argc, char **argv)
start += 1024 * 1024 / 4;
}
- printf("Verifying initialisation...\n");
+ igt_info("Verifying initialisation...\n");
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Cyclic blits, forward...\n");
+ igt_info("Cyclic blits, forward...\n");
for (i = 0; i < count * 4; i++) {
int src = i % count;
int dst = (i + 1) % count;
@@ -379,7 +375,7 @@ int main(int argc, char **argv)
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Cyclic blits, backward...\n");
+ igt_info("Cyclic blits, backward...\n");
for (i = 0; i < count * 4; i++) {
int src = (i + 1) % count;
int dst = i % count;
@@ -390,7 +386,7 @@ int main(int argc, char **argv)
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("Random blits...\n");
+ igt_info("Random blits...\n");
for (i = 0; i < count * 4; i++) {
int src = random() % count;
int dst = random() % count;
diff --git a/tests/gen3_render_tiledy_blits.c b/tests/gen3_render_tiledy_blits.c
index 90fc7eb9..1b9a4196 100644
--- a/tests/gen3_render_tiledy_blits.c
+++ b/tests/gen3_render_tiledy_blits.c
@@ -36,18 +36,17 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include <sys/mman.h>
#include <sys/ioctl.h>
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
#include "i915_reg.h"
#include "i915_3d.h"
@@ -242,11 +241,11 @@ copy(int fd, uint32_t dst, uint32_t src)
if ((b - batch) & 1)
*b++ = 0;
- assert(b - batch <= 1024);
+ igt_assert(b - batch <= 1024);
handle = gem_create(fd, 4096);
gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0]));
- assert(r-reloc == 2);
+ igt_assert(r-reloc == 2);
obj[0].handle = dst;
obj[0].relocation_count = 0;
@@ -290,7 +289,7 @@ copy(int fd, uint32_t dst, uint32_t src)
drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
}
- assert(ret == 0);
+ igt_assert(ret == 0);
gem_close(fd, handle);
}
@@ -307,7 +306,7 @@ create_bo(int fd, uint32_t val)
/* Fill the BO with dwords starting at val */
v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ | PROT_WRITE);
- assert(v);
+ igt_assert(v);
for (i = 0; i < WIDTH*HEIGHT; i++)
v[i] = val++;
munmap(v, WIDTH*HEIGHT*4);
@@ -322,14 +321,12 @@ check_bo(int fd, uint32_t handle, uint32_t val)
int i;
v = gem_mmap(fd, handle, WIDTH*HEIGHT*4, PROT_READ);
- assert(v);
+ igt_assert(v);
for (i = 0; i < WIDTH*HEIGHT; i++) {
- if (v[i] != val) {
- fprintf(stderr, "Expected 0x%08x, found 0x%08x "
- "at offset 0x%08x\n",
- val, v[i], i * 4);
- abort();
- }
+ 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);
@@ -341,19 +338,18 @@ int main(int argc, char **argv)
uint32_t start = 0;
int i, fd, count;
+ igt_simple_init();
+
fd = drm_open_any();
- if (!IS_GEN3(intel_get_drm_devid(fd))) {
- printf("gen3-only test, doing nothing\n");
- return 77;
- }
+ 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;
- printf("Using %d 1MiB buffers\n", count);
+ igt_info("Using %d 1MiB buffers\n", count);
handle = malloc(sizeof(uint32_t)*count*2);
start_val = handle + count;
@@ -364,12 +360,12 @@ int main(int argc, char **argv)
start += 1024 * 1024 / 4;
}
- printf("Verifying initialisation..."); fflush(stdout);
+ igt_info("Verifying initialisation..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Cyclic blits, forward..."); fflush(stdout);
+ igt_info("Cyclic blits, forward..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = i % count;
int dst = (i + 1) % count;
@@ -377,12 +373,12 @@ int main(int argc, char **argv)
copy(fd, handle[dst], handle[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Cyclic blits, backward..."); fflush(stdout);
+ igt_info("Cyclic blits, backward..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = (i + 1) % count;
int dst = i % count;
@@ -390,12 +386,12 @@ int main(int argc, char **argv)
copy(fd, handle[dst], handle[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
- printf("Random blits..."); fflush(stdout);
+ igt_info("Random blits..."); fflush(stdout);
for (i = 0; i < count * 32; i++) {
int src = random() % count;
int dst = random() % count;
@@ -406,10 +402,10 @@ int main(int argc, char **argv)
copy(fd, handle[dst], handle[src]);
start_val[dst] = start_val[src];
}
- printf("verifying..."); fflush(stdout);
+ igt_info("verifying..."); fflush(stdout);
for (i = 0; i < count; i++)
check_bo(fd, handle[i], start_val[i]);
- printf("done\n");
+ igt_info("done\n");
return 0;
}
diff --git a/tests/gen7_forcewake_mt.c b/tests/gen7_forcewake_mt.c
new file mode 100644
index 00000000..0ea7d094
--- /dev/null
+++ b/tests/gen7_forcewake_mt.c
@@ -0,0 +1,206 @@
+/*
+ * 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"
+
+#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_LOAD_REGISTER_IMM (0x22<<23)
+#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 | 1,
+ FORCEWAKE_MT,
+ 2 << 16 | 2,
+ MI_STORE_REGISTER_MEM | 1,
+ FORCEWAKE_MT,
+ 0, // to be patched
+ MI_LOAD_REGISTER_IMM | 1,
+ 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/igt_fork_helper.c b/tests/igt_fork_helper.c
new file mode 100644
index 00000000..b4cf27eb
--- /dev/null
+++ b/tests/igt_fork_helper.c
@@ -0,0 +1,37 @@
+/*
+ * 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 "drmtest.h"
+#include "igt_aux.h"
+
+int main(int argc, char **argv)
+{
+ for (int i = 0; i < 1000; i++) {
+ igt_fork_signal_helper();
+ igt_stop_signal_helper();
+ }
+}
diff --git a/tests/igt_list_only.c b/tests/igt_list_only.c
new file mode 100644
index 00000000..d3ea8c27
--- /dev/null
+++ b/tests/igt_list_only.c
@@ -0,0 +1,42 @@
+/*
+ * 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 "drmtest.h"
+
+int main(int argc, char **argv)
+{
+ char prog[] = "igt_list_only";
+ char arg[] = "--list-subtests";
+ char *fake_argv[] = {prog, arg};
+
+ igt_subtest_init(2, fake_argv);
+
+ igt_subtest("A")
+ ;
+
+ igt_exit();
+}
diff --git a/tests/igt_no_exit.c b/tests/igt_no_exit.c
new file mode 100644
index 00000000..ba3fae0a
--- /dev/null
+++ b/tests/igt_no_exit.c
@@ -0,0 +1,39 @@
+/*
+ * 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 "drmtest.h"
+
+int main(int argc, char **argv)
+{
+ char prog[] = "igt_no_exit";
+ char *fake_argv[] = {prog};
+
+ igt_subtest_init(1, fake_argv);
+
+ igt_subtest("A")
+ ;
+}
diff --git a/tests/igt_no_exit_list_only.c b/tests/igt_no_exit_list_only.c
new file mode 100644
index 00000000..3b232be7
--- /dev/null
+++ b/tests/igt_no_exit_list_only.c
@@ -0,0 +1,40 @@
+/*
+ * 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 "drmtest.h"
+
+int main(int argc, char **argv)
+{
+ char prog[] = "igt_list_only";
+ char arg[] = "--list-subtests";
+ char *fake_argv[] = {prog, arg};
+
+ igt_subtest_init(2, fake_argv);
+
+ igt_subtest("A")
+ ;
+}
diff --git a/tests/igt_no_subtest.c b/tests/igt_no_subtest.c
new file mode 100644
index 00000000..47f15fce
--- /dev/null
+++ b/tests/igt_no_subtest.c
@@ -0,0 +1,38 @@
+/*
+ * 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 "drmtest.h"
+
+int main(int argc, char **argv)
+{
+ char prog[] = "igt_no_exit";
+ char *fake_argv[] = {prog};
+
+ igt_subtest_init(1, fake_argv);
+
+ igt_exit();
+}
diff --git a/tests/igt_simulation.c b/tests/igt_simulation.c
new file mode 100644
index 00000000..15cbe642
--- /dev/null
+++ b/tests/igt_simulation.c
@@ -0,0 +1,156 @@
+/*
+ * 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 <stdlib.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "drmtest.h"
+#include "igt_core.h"
+
+bool simple;
+bool list_subtests;
+bool in_fixture;
+bool in_subtest;
+
+char test[] = "test";
+char list[] = "--list-subtests";
+char *argv_list[] = { test, list };
+char *argv_run[] = { test };
+
+static int do_fork(void)
+{
+ int pid, status;
+
+ switch (pid = fork()) {
+ case -1:
+ assert(0);
+ case 0:
+ if (simple) {
+ igt_simple_init();
+
+ igt_skip_on_simulation();
+
+ exit(0);
+ } else {
+ if (list_subtests)
+ igt_subtest_init(2, argv_list);
+ else
+ igt_subtest_init(1, argv_run);
+
+ if (in_fixture) {
+ igt_fixture
+ igt_skip_on_simulation();
+ } if (in_subtest) {
+ igt_subtest("sim")
+ igt_skip_on_simulation();
+ } else
+ igt_skip_on_simulation();
+
+ if (!in_subtest)
+ igt_subtest("foo")
+ ;
+
+ igt_exit();
+ }
+ default:
+ while (waitpid(pid, &status, 0) == -1 &&
+ errno == EINTR)
+ ;
+
+ assert(WIFEXITED(status));
+
+ return WEXITSTATUS(status);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ /* simple tests */
+ simple = true;
+ assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SKIP);
+
+ assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ /* subtests, list mode */
+ simple = false;
+ list_subtests = true;
+
+ in_fixture = false;
+ assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ in_fixture = true;
+ assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ in_fixture = false;
+ in_subtest = true;
+ assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ /* subtest, run mode */
+ simple = false;
+ list_subtests = false;
+
+ in_fixture = false;
+ assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SKIP);
+
+ assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ in_fixture = true;
+ assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SKIP);
+
+ assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ in_fixture = false;
+ in_subtest = true;
+ assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SKIP);
+
+ assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
+ assert(do_fork() == IGT_EXIT_SUCCESS);
+
+ return 0;
+}
diff --git a/tests/kms_addfb.c b/tests/kms_addfb.c
new file mode 100644
index 00000000..349e7fb9
--- /dev/null
+++ b/tests/kms_addfb.c
@@ -0,0 +1,229 @@
+/*
+ * 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();
+
+ pitch_tests(fd);
+
+ size_tests(fd);
+
+ igt_fixture
+ close(fd);
+}
diff --git a/tests/kms_cursor_crc.c b/tests/kms_cursor_crc.c
new file mode 100644
index 00000000..1b8da268
--- /dev/null
+++ b/tests/kms_cursor_crc.c
@@ -0,0 +1,470 @@
+/*
+ * 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"
+
+#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;
+} data_t;
+
+typedef struct {
+ data_t *data;
+ 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_size;
+ igt_pipe_crc_t *pipe_crc;
+} test_data_t;
+
+static void draw_cursor(cairo_t *cr, int x, int y, int w)
+{
+ w /= 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, w, w, 1.0, 0.0, 0.0, 1.0);
+ igt_paint_color_alpha(cr, x + w, y, w, w, 0.0, 1.0, 0.0, 1.0);
+ igt_paint_color_alpha(cr, x, y + w, w, w, 0.0, 0.0, 1.0, 1.0);
+ igt_paint_color_alpha(cr, x + w, y + w, w, w, 0.5, 0.5, 0.5, 1.0);
+}
+
+static void cursor_enable(test_data_t *test_data)
+{
+ data_t *data = test_data->data;
+ igt_display_t *display = &data->display;
+ igt_output_t *output = test_data->output;
+ igt_plane_t *cursor;
+
+ cursor = igt_output_get_plane(output, IGT_PLANE_CURSOR);
+ igt_plane_set_fb(cursor, &data->fb);
+ igt_display_commit(display);
+}
+
+static void cursor_disable(test_data_t *test_data)
+{
+ data_t *data = test_data->data;
+ igt_display_t *display = &data->display;
+ igt_output_t *output = test_data->output;
+ igt_plane_t *cursor;
+
+ cursor = igt_output_get_plane(output, IGT_PLANE_CURSOR);
+ igt_plane_set_fb(cursor, NULL);
+ igt_display_commit(display);
+}
+
+
+static void do_single_test(test_data_t *test_data, int x, int y)
+{
+ data_t *data = test_data->data;
+ igt_display_t *display = &data->display;
+ igt_pipe_crc_t *pipe_crc = test_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_info("."); fflush(stdout);
+
+ /* Hardware test */
+ igt_paint_test_pattern(cr, test_data->screenw, test_data->screenh);
+ cursor_enable(test_data);
+ cursor = igt_output_get_plane(test_data->output, IGT_PLANE_CURSOR);
+ igt_plane_set_position(cursor, x, y);
+ igt_display_commit(display);
+ igt_wait_for_vblank(data->drm_fd, test_data->pipe);
+ igt_pipe_crc_collect_crc(pipe_crc, &crc);
+ cursor_disable(test_data);
+
+ /* Now render the same in software and collect crc */
+ draw_cursor(cr, x, y, test_data->curw);
+ igt_display_commit(display);
+ igt_wait_for_vblank(data->drm_fd, test_data->pipe);
+ igt_pipe_crc_collect_crc(pipe_crc, &ref_crc);
+ /* Clear screen afterwards */
+ igt_paint_color(cr, 0, 0, test_data->screenw, test_data->screenh,
+ 0.0, 0.0, 0.0);
+
+ igt_assert(igt_crc_equal(&crc, &ref_crc));
+}
+
+static void do_test(test_data_t *test_data,
+ int left, int right, int top, int bottom)
+{
+ do_single_test(test_data, left, top);
+ do_single_test(test_data, right, top);
+ do_single_test(test_data, right, bottom);
+ do_single_test(test_data, left, bottom);
+}
+
+static void test_crc_onscreen(test_data_t *test_data)
+{
+ int left = test_data->left;
+ int right = test_data->right;
+ int top = test_data->top;
+ int bottom = test_data->bottom;
+ int cursor_w = test_data->curw;
+ int cursor_h = test_data->curh;
+
+ /* fully inside */
+ do_test(test_data, left, right, top, bottom);
+
+ /* 2 pixels inside */
+ do_test(test_data, left - (cursor_w-2), right + (cursor_w-2), top , bottom );
+ do_test(test_data, left , right , top - (cursor_h-2), bottom + (cursor_h-2));
+ do_test(test_data, left - (cursor_w-2), right + (cursor_w-2), top - (cursor_h-2), bottom + (cursor_h-2));
+
+ /* 1 pixel inside */
+ do_test(test_data, left - (cursor_w-1), right + (cursor_w-1), top , bottom );
+ do_test(test_data, left , right , top - (cursor_h-1), bottom + (cursor_h-1));
+ do_test(test_data, left - (cursor_w-1), right + (cursor_w-1), top - (cursor_h-1), bottom + (cursor_h-1));
+}
+
+static void test_crc_offscreen(test_data_t *test_data)
+{
+ int left = test_data->left;
+ int right = test_data->right;
+ int top = test_data->top;
+ int bottom = test_data->bottom;
+ int cursor_w = test_data->curw;
+ int cursor_h = test_data->curh;
+
+ /* fully outside */
+ do_test(test_data, left - (cursor_w), right + (cursor_w), top , bottom );
+ do_test(test_data, left , right , top - (cursor_h), bottom + (cursor_h));
+ do_test(test_data, left - (cursor_w), right + (cursor_w), top - (cursor_h), bottom + (cursor_h));
+
+ /* fully outside by 1 extra pixels */
+ do_test(test_data, left - (cursor_w+1), right + (cursor_w+1), top , bottom );
+ do_test(test_data, left , right , top - (cursor_h+1), bottom + (cursor_h+1));
+ do_test(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(test_data, left - (cursor_w+2), right + (cursor_w+2), top , bottom );
+ do_test(test_data, left , right , top - (cursor_h+2), bottom + (cursor_h+2));
+ do_test(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(test_data, left - (cursor_w+512), right + (cursor_w+512), top , bottom );
+ do_test(test_data, left , right , top - (cursor_h+512), bottom + (cursor_h+512));
+ do_test(test_data, left - (cursor_w+512), right + (cursor_w+512), top - (cursor_h+512), bottom + (cursor_h+512));
+
+ /* go nuts */
+ do_test(test_data, INT_MIN, INT_MAX, INT_MIN, INT_MAX);
+}
+
+static void test_crc_sliding(test_data_t *test_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(test_data, i, 0);
+ do_single_test(test_data, 0, i);
+ do_single_test(test_data, i, i);
+ }
+}
+
+static void test_crc_random(test_data_t *test_data)
+{
+ int i;
+
+ /* Random cursor placement */
+ for (i = 0; i < 50; i++) {
+ int x = rand() % (test_data->screenw + test_data->curw * 2) - test_data->curw;
+ int y = rand() % (test_data->screenh + test_data->curh * 2) - test_data->curh;
+ do_single_test(test_data, x, y);
+ }
+}
+
+static bool prepare_crtc(test_data_t *test_data, igt_output_t *output,
+ int cursor_w, int cursor_h)
+{
+ drmModeModeInfo *mode;
+ data_t *data = test_data->data;
+ igt_display_t *display = &data->display;
+ igt_plane_t *primary;
+
+ /* select the pipe we want to use */
+ igt_output_set_pipe(output, test_data->pipe);
+ 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,
+ false, /* tiled */
+ 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 (test_data->pipe_crc)
+ igt_pipe_crc_free(test_data->pipe_crc);
+
+ test_data->pipe_crc = igt_pipe_crc_new(test_data->pipe,
+ INTEL_PIPE_CRC_SOURCE_AUTO);
+ if (!test_data->pipe_crc) {
+ igt_info("auto crc not supported on this connector with pipe %i\n",
+ test_data->pipe);
+ return false;
+ }
+
+ /* x/y position where the cursor is still fully visible */
+ test_data->left = 0;
+ test_data->right = mode->hdisplay - cursor_w;
+ test_data->top = 0;
+ test_data->bottom = mode->vdisplay - cursor_h;
+ test_data->screenw = mode->hdisplay;
+ test_data->screenh = mode->vdisplay;
+ test_data->curw = cursor_w;
+ test_data->curh = cursor_h;
+ test_data->cursor_max_size = cursor_w;
+
+ /* make sure cursor is disabled */
+ cursor_disable(test_data);
+ igt_wait_for_vblank(data->drm_fd, test_data->pipe);
+
+ /* get reference crc w/o cursor */
+ igt_pipe_crc_collect_crc(test_data->pipe_crc, &test_data->ref_crc);
+
+ return true;
+}
+
+static void cleanup_crtc(test_data_t *test_data, igt_output_t *output)
+{
+ data_t *data = test_data->data;
+ igt_display_t *display = &data->display;
+ igt_plane_t *primary;
+
+ igt_pipe_crc_free(test_data->pipe_crc);
+ test_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)(test_data_t *), int cursor_w, int cursor_h)
+{
+ igt_display_t *display = &data->display;
+ igt_output_t *output;
+ enum pipe p;
+ test_data_t test_data = {
+ .data = data,
+ };
+ int valid_tests = 0;
+
+ for_each_connected_output(display, output) {
+ test_data.output = output;
+ for (p = 0; p < igt_display_get_n_pipes(display); p++) {
+ test_data.pipe = p;
+
+ if (!prepare_crtc(&test_data, output, cursor_w, cursor_h))
+ continue;
+
+ valid_tests++;
+
+ igt_info("Beginning %s on pipe %c, connector %s\n",
+ igt_subtest_name(), pipe_name(test_data.pipe),
+ igt_output_name(output));
+
+ testfunc(&test_data);
+
+ igt_info("\n%s on pipe %c, connector %s: PASSED\n\n",
+ igt_subtest_name(), pipe_name(test_data.pipe),
+ igt_output_name(output));
+
+ /* cleanup what prepare_crtc() has done */
+ cleanup_crtc(&test_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;
+
+ fb_id = igt_create_fb(data->drm_fd, cur_w, cur_h,
+ DRM_FORMAT_ARGB8888, false,
+ &data->fb);
+ igt_assert(fb_id);
+
+ cr = igt_get_cairo_ctx(data->drm_fd, &data->fb);
+ draw_cursor(cr, 0, 0, cur_w);
+ igt_assert(cairo_status(cr) == 0);
+}
+
+static void test_cursor_size(test_data_t *test_data)
+{
+ data_t *data = test_data->data;
+ igt_display_t *display = &data->display;
+ igt_pipe_crc_t *pipe_crc = test_data->pipe_crc;
+ igt_crc_t crc[10], ref_crc;
+ igt_plane_t *cursor;
+ cairo_t *cr;
+ uint32_t fb_id;
+ int i, size, cursor_max_size = test_data->cursor_max_size;
+
+ /* 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, false, &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(test_data);
+ cursor = igt_output_get_plane(test_data->output, IGT_PLANE_CURSOR);
+ igt_plane_set_position(cursor, 0, 0);
+ for (i = 0, size = cursor_max_size; size >= 64; size /= 2, i++) {
+ /* Change size in flight: */
+ int ret = drmModeSetCursor(data->drm_fd, test_data->output->config.crtc->crtc_id,
+ data->fb.gem_handle, size, size);
+ igt_assert(ret == 0);
+ igt_wait_for_vblank(data->drm_fd, test_data->pipe);
+ igt_pipe_crc_collect_crc(pipe_crc, &crc[i]);
+ }
+ cursor_disable(test_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, test_data->pipe);
+ igt_pipe_crc_collect_crc(pipe_crc, &ref_crc);
+ /* Clear screen afterwards */
+ igt_paint_color(cr, 0, 0, test_data->screenw, test_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_max_size)
+{
+ int cursor_size;
+ for (cursor_size = 64; cursor_size <= 256; cursor_size *= 2)
+ {
+ igt_fixture
+ igt_require(cursor_max_size >= cursor_size);
+
+ igt_fixture
+ create_cursor_fb(data, cursor_size, cursor_size);
+
+ /* Using created cursor FBs to test cursor support */
+ igt_subtest_f("cursor-%d-onscreen", cursor_size)
+ run_test(data, test_crc_onscreen, cursor_size, cursor_size);
+ igt_subtest_f("cursor-%d-offscreen", cursor_size)
+ run_test(data, test_crc_offscreen, cursor_size, cursor_size);
+ igt_subtest_f("cursor-%d-sliding", cursor_size)
+ run_test(data, test_crc_sliding, cursor_size, cursor_size);
+ igt_subtest_f("cursor-%d-random", cursor_size)
+ run_test(data, test_crc_random, cursor_size, cursor_size);
+
+ igt_fixture
+ igt_remove_fb(data->drm_fd, &data->fb);
+ }
+}
+
+igt_main
+{
+ uint64_t cursor_width = 64, cursor_height = 64;
+ data_t data = {};
+ int ret;
+
+ igt_skip_on_simulation();
+
+ igt_fixture {
+ data.drm_fd = drm_open_any();
+
+ 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_cmpint(cursor_width, ==, cursor_height);
+
+ igt_set_vt_graphics_mode();
+
+ igt_require_pipe_crc();
+
+ igt_display_init(&data.display, data.drm_fd);
+ }
+
+ igt_subtest_f("cursor-size-change")
+ run_test(&data, test_cursor_size, cursor_width, cursor_height);
+
+ run_test_generic(&data, cursor_width);
+
+ igt_fixture {
+ igt_display_fini(&data.display);
+ }
+}
diff --git a/tests/kms_fbc_crc.c b/tests/kms_fbc_crc.c
new file mode 100644
index 00000000..810f6f34
--- /dev/null
+++ b/tests/kms_fbc_crc.c
@@ -0,0 +1,531 @@
+/*
+ * 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"
+
+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, 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);
+
+ BEGIN_BATCH(5);
+ OUT_BATCH(COLOR_BLT_CMD);
+ OUT_BATCH((1 << 24) | (0xf0 << 16) | 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 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);
+ 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, 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, 0xff);
+ 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,
+ true, /* tiled */
+ 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,
+ true, /* tiled */
+ 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);
+ if (!pipe_crc) {
+ igt_info("auto crc not supported on this connector with crtc %i\n",
+ data->pipe);
+
+ 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;
+ }
+
+ 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 (data->pipe = 0; data->pipe < igt_display_get_n_pipes(display); data->pipe++) {
+ if (!prepare_crtc(data))
+ continue;
+
+ igt_info("Beginning %s on pipe %c, connector %s\n",
+ igt_subtest_name(), pipe_name(data->pipe),
+ igt_output_name(data->output));
+
+ if (!prepare_test(data, mode)) {
+ igt_info("%s on pipe %c, connector %s: SKIPPED\n",
+ igt_subtest_name(), pipe_name(data->pipe),
+ igt_output_name(data->output));
+ continue;
+ }
+
+ valid_tests++;
+
+ test_crc(data, mode);
+
+ igt_info("%s on pipe %c, connector %s: PASSED\n",
+ igt_subtest_name(), 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();
+ igt_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
new file mode 100644
index 00000000..d3ca132f
--- /dev/null
+++ b/tests/kms_fence_pin_leak.c
@@ -0,0 +1,239 @@
+/*
+ * 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"
+
+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);
+ 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,
+ true, /* 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,
+ true, /* 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);
+
+ printf(".");
+ fflush(stdout);
+ }
+
+ 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]);
+
+ printf("\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 (p = 0; p < igt_display_get_n_pipes(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();
+
+ data.devid = intel_get_drm_devid(data.drm_fd);
+
+ igt_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
new file mode 100644
index 00000000..46ce2ed1
--- /dev/null
+++ b/tests/kms_flip.c
@@ -0,0 +1,1651 @@
+/*
+ * 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>
+#include <linux/kd.h>
+#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_debugfs.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 max(a, b) ((a) > (b) ? (a) : (b))
+
+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 void emit_dummy_load__bcs(struct test_output *o)
+{
+ int i, limit;
+ drm_intel_bo *dummy_bo, *target_bo, *tmp_bo;
+ struct igt_fb *fb_info = &o->fb_info[o->current_fb_id];
+ unsigned pitch = fb_info->stride;
+
+ limit = intel_gen(devid) < 6 ? 500 : 5000;
+
+ dummy_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", fb_info->size, 4096);
+ igt_assert(dummy_bo);
+ target_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle);
+ igt_assert(target_bo);
+
+ for (i = 0; i < limit; i++) {
+ BLIT_COPY_BATCH_START(devid, 0);
+ OUT_BATCH((3 << 24) | /* 32 bits */
+ (0xcc << 16) | /* copy ROP */
+ pitch);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(o->fb_height << 16 | o->fb_width);
+ OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ BLIT_RELOC_UDW(devid);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(pitch);
+ OUT_RELOC_FENCED(target_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(devid);
+ ADVANCE_BATCH();
+
+ if (IS_GEN6(devid) || IS_GEN7(devid)) {
+ BEGIN_BATCH(3);
+ OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ }
+
+ tmp_bo = dummy_bo;
+ dummy_bo = target_bo;
+ target_bo = tmp_bo;
+ }
+ intel_batchbuffer_flush(batch);
+
+ drm_intel_bo_unreference(dummy_bo);
+ drm_intel_bo_unreference(target_bo);
+}
+
+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,
+ "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 void emit_dummy_load__rcs(struct test_output *o)
+{
+ const struct igt_fb *fb_info = &o->fb_info[o->current_fb_id];
+ igt_render_copyfunc_t copyfunc;
+ struct igt_buf sb[2], *src, *dst;
+ int i, limit;
+
+ copyfunc = igt_get_render_copyfunc(devid);
+ if (copyfunc == NULL)
+ return emit_dummy_load__bcs(o);
+
+ limit = intel_gen(devid) < 6 ? 500 : 5000;
+
+ sb[0].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", fb_info->size, 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 * o->fb_width;
+
+ sb[1].bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle);
+ igt_assert(sb[1].bo);
+ sb[1].size = sb[1].bo->size;
+ sb[1].tiling = fb_info->tiling;
+ sb[1].data = NULL;
+ sb[1].num_tiles = sb[1].bo->size;
+ sb[1].stride = fb_info->stride;
+
+ src = &sb[0];
+ dst = &sb[1];
+
+ for (i = 0; i < limit; i++) {
+ struct igt_buf *tmp;
+
+ copyfunc(batch, NULL,
+ src, 0, 0,
+ o->fb_width, o->fb_height,
+ dst, 0, 0);
+
+ tmp = src;
+ src = dst;
+ dst = tmp;
+ }
+ intel_batchbuffer_flush(batch);
+
+ drm_intel_bo_unreference(sb[0].bo);
+ drm_intel_bo_unreference(sb[1].bo);
+}
+
+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_base[] = "/sys/kernel/debug/dri";
+ static const char dfs_entry_error[] = "i915_error_state";
+ static const char data[] = "";
+ char fname[FILENAME_MAX];
+ int card_index = drm_get_card();
+ int fd;
+
+ igt_assert(card_index != -1);
+
+ /* clear the error state */
+ snprintf(fname, FILENAME_MAX, "%s/%i/%s",
+ dfs_base, card_index, dfs_entry_error);
+
+ fd = open(fname, 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_WITH_DUMMY_BCS)
+ emit_dummy_load__bcs(o);
+
+ if (o->flags & TEST_WITH_DUMMY_RCS)
+ emit_dummy_load__rcs(o);
+
+ if (!(o->flags & TEST_SINGLE_BUFFER))
+ o->current_fb_id = !o->current_fb_id;
+
+ 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, 1, 0, &reply) == 0);
+ end = gettime_us();
+ igt_assert(end - start > 1 * frame_time(o) / 2 &&
+ end - start < 3 * frame_time(o) / 2);
+ join_vblank_wait_thread();
+ }
+
+ igt_info("."); fflush(stdout);
+
+ 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 = count * 10 > o->fb_width - o->kmode[0].hdisplay ? o->fb_width - o->kmode[0].hdisplay : count * 10;
+
+ /* 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) < 0) {
+ 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]) < 0)
+ return;
+
+ if (kmstest_get_connector_config(drm_fd, o->_connector[1],
+ 1 << crtc_idx1, &config[1]) < 0) {
+ 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;
+ bool tiled;
+ 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;
+
+ tiled = false;
+ if (o->flags & TEST_FENCE_STRESS)
+ tiled = true;
+
+ /* 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),
+ tiled, &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),
+ tiled, &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),
+ true, &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_assert(modes);
+ duration = duration * 1000 / modes;
+ duration = duration < 500 ? 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(modes);
+ duration = duration * 1000 / modes;
+ duration = duration < 500 ? 500 : duration;
+
+ /* 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);
+ }
+}
+
+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,
+ "bcs-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,
+ "bcs-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, "bcs-flip-vs-dpms" },
+ { 60, TEST_FLIP | TEST_DPMS | TEST_WITH_DUMMY_RCS, "rcs-flip-vs-dpms" },
+ { 30, TEST_FLIP | TEST_PAN, "flip-vs-panning" },
+ { 60, TEST_FLIP | TEST_PAN | TEST_WITH_DUMMY_BCS, "bcs-flip-vs-panning" },
+ { 60, TEST_FLIP | TEST_PAN | TEST_WITH_DUMMY_RCS, "rcs-flip-vs-panning" },
+ { 60, TEST_FLIP | TEST_MODESET | TEST_EINVAL, "flip-vs-modeset" },
+ { 60, TEST_FLIP | TEST_MODESET | TEST_WITH_DUMMY_BCS, "bcs-flip-vs-modeset" },
+ { 60, TEST_FLIP | TEST_MODESET | TEST_WITH_DUMMY_RCS, "rcs-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();
+
+ igt_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);
+ }
+
+ 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_tiling.c b/tests/kms_flip_tiling.c
new file mode 100644
index 00000000..ca20ad96
--- /dev/null
+++ b/tests/kms_flip_tiling.c
@@ -0,0 +1,145 @@
+/*
+ * 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"
+
+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 = 0;
+ pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+ igt_output_set_pipe(output, 0);
+
+ 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, false, &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, true, 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();
+
+ igt_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_mmio_vs_cs_flip.c b/tests/kms_mmio_vs_cs_flip.c
new file mode 100644
index 00000000..314a31d8
--- /dev/null
+++ b/tests/kms_mmio_vs_cs_flip.c
@@ -0,0 +1,580 @@
+/*
+ * 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);
+ 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(data->devid, 0);
+ OUT_BATCH((3 << 24) | /* 32 bits */
+ (0xcc << 16) | /* copy ROP */
+ pitch);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(h << 16 | w);
+ OUT_RELOC(data->busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ BLIT_RELOC_UDW(data->devid);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(pitch);
+ OUT_RELOC(data->busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ BLIT_RELOC_UDW(data->devid);
+ 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,
+ false, /* tiled */
+ 1.0, 0.0, 0.0,
+ &red_fb);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 1.0, 0.0,
+ &green_fb);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 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);
+ if (!data->pipe_crc) {
+ igt_info("auto crc not supported on this connector with crtc %i\n",
+ pipe);
+
+ igt_plane_set_fb(primary, NULL);
+ igt_plane_set_fb(sprite, NULL);
+ igt_output_set_pipe(output, PIPE_ANY);
+ 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);
+
+ return false;
+ }
+
+ /* 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,
+ false, /* tiled */
+ 1.0, 0.0, 0.0,
+ &red_fb);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 0.0, 0.0, 1.0,
+ &blue_fb);
+ igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1,
+ DRM_FORMAT_XRGB8888,
+ false, /* tiled */
+ 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);
+ if (!data->pipe_crc) {
+ igt_info("auto crc not supported on this connector with crtc %i\n",
+ pipe);
+
+ igt_plane_set_fb(primary, NULL);
+ igt_output_set_pipe(output, PIPE_ANY);
+ 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);
+
+ return false;
+ }
+
+ /* 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_for_pipe(data_t *data, enum pipe pipe)
+{
+ igt_output_t *output;
+ enum igt_plane plane = 1; /* testing with one sprite is enough */
+ int valid_tests = 0;
+
+ igt_require(data->display.pipes[pipe].n_planes > 2);
+
+ for_each_connected_output(&data->display, output) {
+ 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_for_pipe(data_t *data, enum pipe pipe)
+{
+ igt_output_t *output;
+ int valid_tests = 0;
+
+ for_each_connected_output(&data->display, output) {
+ 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
+{
+ int pipe;
+
+ igt_skip_on_simulation();
+
+ igt_fixture {
+ data.drm_fd = drm_open_any();
+
+ igt_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") {
+ for (pipe = 0; pipe < data.display.n_pipes; pipe++)
+ run_plane_test_for_pipe(&data, pipe);
+ }
+
+ igt_subtest_f("setcrtc_vs_cs_flip") {
+ for (pipe = 0; pipe < data.display.n_pipes; pipe++)
+ run_crtc_test_for_pipe(&data, pipe);
+ }
+
+ 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
new file mode 100644
index 00000000..9eec4e6f
--- /dev/null
+++ b/tests/kms_pipe_crc_basic.c
@@ -0,0 +1,231 @@
+/*
+ * 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 "igt_aux.h"
+#include "ioctl_wrappers.h"
+
+typedef struct {
+ int drm_fd;
+ igt_display_t display;
+ struct igt_fb fb;
+} data_t;
+
+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_cmpint(written, ==, (strlen(cmd)));
+ igt_assert(ferror(ctl));
+ igt_assert_cmpint(errno, ==, EINVAL);
+
+ fclose(ctl);
+}
+
+#define TEST_SEQUENCE (1<<0)
+
+static void test_read_crc(data_t *data, int pipe, unsigned flags)
+{
+ igt_display_t *display = &data->display;
+ igt_pipe_crc_t *pipe_crc;
+ igt_crc_t *crcs = NULL;
+ int valid_connectors = 0;
+ igt_output_t *output;
+
+ igt_skip_on(pipe >= data->display.n_pipes);
+
+ for_each_connected_output(display, output) {
+ igt_plane_t *primary;
+ drmModeModeInfo *mode;
+
+ igt_output_set_pipe(output, pipe);
+
+ igt_info("%s: Testing connector %s using pipe %c\n",
+ igt_subtest_name(), igt_output_name(output),
+ pipe_name(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, 1.0, 0.0,
+ &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);
+
+ if (!pipe_crc)
+ continue;
+ valid_connectors++;
+
+ igt_pipe_crc_start(pipe_crc);
+
+ /* wait for 3 vblanks and the corresponding 3 CRCs */
+ igt_pipe_crc_get_crcs(pipe_crc, 3, &crcs);
+
+ igt_pipe_crc_stop(pipe_crc);
+
+ /* ensure the CRCs are not all 0s */
+ igt_assert(!igt_crc_is_null(&crcs[0]));
+ igt_assert(!igt_crc_is_null(&crcs[1]));
+ igt_assert(!igt_crc_is_null(&crcs[2]));
+
+ /* and ensure that they'are all equal, we haven't changed the fb */
+ igt_assert(igt_crc_equal(&crcs[0], &crcs[1]));
+ igt_assert(igt_crc_equal(&crcs[1], &crcs[2]));
+
+ if (flags & TEST_SEQUENCE) {
+ igt_assert(crcs[0].frame + 1 == crcs[1].frame);
+ igt_assert(crcs[1].frame + 1 == crcs[2].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);
+ }
+
+ 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();
+
+ igt_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
new file mode 100644
index 00000000..5db09473
--- /dev/null
+++ b/tests/kms_plane.c
@@ -0,0 +1,242 @@
+/*
+ * 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"
+
+typedef struct {
+ int drm_fd;
+ igt_display_t display;
+} data_t;
+
+/*
+ * 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_pipe_crc_t *pipe_crc;
+ 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,
+ false /* tiling */,
+ 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);
+}
+
+static void
+test_position_init(test_position_t *test, igt_output_t *output, enum pipe pipe)
+{
+ data_t *data = test->data;
+ struct igt_fb green_fb;
+ drmModeModeInfo *mode;
+ igt_plane_t *primary;
+
+ test->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+
+ 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,
+ false, /* tiled */
+ 0.0, 1.0, 0.0,
+ &green_fb);
+ igt_plane_set_fb(primary, &green_fb);
+
+ igt_display_commit(&data->display);
+
+ igt_pipe_crc_collect_crc(test->pipe_crc, &test->reference_crc);
+
+ igt_plane_set_fb(primary, NULL);
+ igt_display_commit(&data->display);
+
+ igt_remove_fb(data->drm_fd, &green_fb);
+}
+
+static void
+test_position_fini(test_position_t *test, igt_output_t *output)
+{
+ igt_pipe_crc_free(test->pipe_crc);
+
+ igt_output_set_pipe(output, PIPE_ANY);
+ igt_display_commit(&test->data->display);
+}
+
+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 %c plane %d\n",
+ igt_output_name(output), pipe_name(pipe), plane);
+
+ test_position_init(&test, 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,
+ false, /* tiled */
+ 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(test.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);
+
+ test_position_fini(&test, output);
+}
+
+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);
+}
+
+static void
+run_tests_for_pipe_plane(data_t *data, enum pipe pipe, enum igt_plane plane)
+{
+ igt_subtest_f("plane-position-covered-pipe-%c-plane-%d",
+ pipe_name(pipe), plane)
+ test_plane_position(data, pipe, plane,
+ TEST_POSITION_FULLY_COVERED);
+
+ igt_subtest_f("plane-position-hole-pipe-%c-plane-%d",
+ pipe_name(pipe), plane)
+ test_plane_position(data, pipe, plane, 0);
+}
+
+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();
+
+ igt_set_vt_graphics_mode();
+
+ igt_require_pipe_crc();
+ igt_display_init(&data.display, data.drm_fd);
+ }
+
+ for (int pipe = 0; pipe < 3; pipe++)
+ run_tests_for_pipe(&data, pipe);
+
+ igt_fixture {
+ igt_display_fini(&data.display);
+ }
+}
diff --git a/tests/kms_render.c b/tests/kms_render.c
new file mode 100644
index 00000000..6c742e23
--- /dev/null
+++ b/tests/kms_render.c
@@ -0,0 +1,249 @@
+/*
+ * 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_str(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, false, &fb[0]))
+ goto err1;
+
+ if (!igt_create_fb(drm_fd, width, height, format, false, &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++)
+ test_format(test_name,
+ cconf, &cconf->connector->modes[i],
+ 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;
+ int ret;
+
+ ret = kmstest_get_connector_config(drm_fd, connector_id,
+ 1 << j, &cconf);
+ if (ret < 0)
+ 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();
+
+ bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
+ devid = intel_get_drm_devid(drm_fd);
+ batch = intel_batchbuffer_alloc(bufmgr, devid);
+
+ igt_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_setmode.c b/tests/kms_setmode.c
new file mode 100644
index 00000000..0b765a9c
--- /dev/null
+++ b/tests/kms_setmode.c
@@ -0,0 +1,742 @@
+/*
+ * 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 <getopt.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;
+ bool enable_tiling;
+ int fb_id;
+
+ bpp = 32;
+ depth = 24;
+ enable_tiling = false;
+ fb_id = igt_create_fb(drm_fd, crtc->mode.hdisplay,
+ crtc->mode.vdisplay,
+ igt_bpp_depth_to_drm_format(bpp, depth),
+ enable_tiling, 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_str(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) < 0)
+ 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();
+ if (!dry_run)
+ igt_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
new file mode 100644
index 00000000..087b79db
--- /dev/null
+++ b/tests/kms_sink_crc_basic.c
@@ -0,0 +1,191 @@
+/*
+ * 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"
+
+enum color {
+ WHITE,
+ BLACK,
+ NUM_COLORS,
+};
+
+typedef struct {
+ struct kmstest_connector_config config;
+ struct igt_fb fb;
+} connector_t;
+
+typedef struct {
+ int drm_fd;
+ drmModeRes *resources;
+} data_t;
+
+static void get_crc(char *crc) {
+ int ret;
+ FILE *file = fopen("/sys/kernel/debug/dri/0/i915_sink_crc_eDP1", "r");
+ igt_require(file);
+
+ ret = fscanf(file, "%s\n", crc);
+ igt_require(ret > 0);
+
+ fclose(file);
+}
+
+static uint32_t create_fb(data_t *data,
+ int w, int h,
+ double r, double g, double b,
+ struct igt_fb *fb)
+{
+ cairo_t *cr;
+ uint32_t fb_id;
+
+ fb_id = igt_create_fb(data->drm_fd, w, h,
+ DRM_FORMAT_XRGB8888, false, fb);
+ igt_assert(fb_id);
+
+ cr = igt_get_cairo_ctx(data->drm_fd, fb);
+ igt_paint_color(cr, 0, 0, w, h, r, g, b);
+ igt_assert(cairo_status(cr) == 0);
+
+ return fb_id;
+}
+
+static bool
+connector_set_mode(data_t *data, connector_t *connector, drmModeModeInfo *mode,
+ enum color crtc_color)
+{
+ struct kmstest_connector_config *config = &connector->config;
+ unsigned int fb_id;
+ int ret;
+
+ if (crtc_color == WHITE)
+ fb_id = create_fb(data, mode->hdisplay, mode->vdisplay,
+ 1.0, 1.0, 1.0, &connector->fb);
+ else
+ fb_id = create_fb(data, mode->hdisplay, mode->vdisplay,
+ 0.0, 0.0, 0.0, &connector->fb);
+ igt_assert(fb_id);
+
+ ret = drmModeSetCrtc(data->drm_fd,
+ config->crtc->crtc_id,
+ connector->fb.fb_id,
+ 0, 0, /* x, y */
+ &config->connector->connector_id,
+ 1,
+ mode);
+ igt_assert(ret == 0);
+
+ return 0;
+}
+
+static void basic_sink_crc_check(data_t *data, uint32_t connector_id)
+{
+ connector_t connector;
+ int ret;
+ char ref_crc_white[12];
+ char ref_crc_black[12];
+ char crc_check[12];
+
+ ret = kmstest_get_connector_config(data->drm_fd,
+ connector_id,
+ 1 << 0,
+ &connector.config);
+ igt_require(ret == 0);
+
+ /*Go White*/
+ connector_set_mode(data, &connector, &connector.config.default_mode, WHITE);
+
+ /* get reference crc for white color */
+ get_crc(ref_crc_white);
+
+ /* Go Black */
+ connector_set_mode(data, &connector, &connector.config.default_mode, BLACK);
+
+ /* get reference crc for black color */
+ get_crc(ref_crc_black);
+
+ igt_assert(strcmp(ref_crc_black, ref_crc_white) != 0);
+
+ /*Go White again*/
+ connector_set_mode(data, &connector, &connector.config.default_mode, WHITE);
+
+ get_crc(crc_check);
+ igt_assert(strcmp(crc_check, ref_crc_white) == 0);
+
+ /* Go Black again */
+ connector_set_mode(data, &connector, &connector.config.default_mode, BLACK);
+
+ get_crc(crc_check);
+ igt_assert(strcmp(crc_check, ref_crc_black) == 0);
+
+ kmstest_free_connector_config(&connector.config);
+}
+
+static void run_test(data_t *data)
+{
+ int i;
+ drmModeConnectorPtr c;
+ uint32_t connector_id = 0;
+
+ for (i = 0; i < data->resources->count_connectors; i++) {
+ connector_id = data->resources->connectors[i];
+ c = drmModeGetConnector(data->drm_fd, connector_id);
+
+ if (c->connector_type != DRM_MODE_CONNECTOR_eDP ||
+ c->connection != DRM_MODE_CONNECTED)
+ continue;
+
+ basic_sink_crc_check(data, connector_id);
+ 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();
+
+ igt_set_vt_graphics_mode();
+
+ data.resources = drmModeGetResources(data.drm_fd);
+ igt_assert(data.resources);
+
+ run_test(&data);
+
+ drmModeFreeResources(data.resources);
+}
diff --git a/tests/sysfs_edid_timing b/tests/kms_sysfs_edid_timing
index 3a8c6c0e..ec704f67 100755
--- a/tests/sysfs_edid_timing
+++ b/tests/kms_sysfs_edid_timing
@@ -1,10 +1,15 @@
-#!/bin/sh
+#!/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)
diff --git a/tests/pm_lpsp.c b/tests/pm_lpsp.c
new file mode 100644
index 00000000..9d3884c0
--- /dev/null
+++ b/tests/pm_lpsp.c
@@ -0,0 +1,280 @@
+/*
+ * 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);
+}
+
+static void disable_all_screens(int drm_fd, drmModeResPtr drm_resources)
+{
+ int i, rc;
+
+ for (i = 0; i < drm_resources->count_crtcs; i++) {
+ rc = drmModeSetCrtc(drm_fd, drm_resources->crtcs[i], -1, 0, 0,
+ NULL, 0, NULL);
+ igt_assert(rc == 0);
+ }
+}
+
+/* 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)
+{
+ disable_all_screens(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,
+ false, &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",
+ };
+
+ disable_all_screens(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;
+
+ disable_all_screens(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();
+ 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);
+
+ igt_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_psr.c b/tests/pm_psr.c
new file mode 100644
index 00000000..3ab7e7a0
--- /dev/null
+++ b/tests/pm_psr.c
@@ -0,0 +1,86 @@
+/*
+ * 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:
+ * Rodrigo Vivi <rodrigo.vivi@intel.com>
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "drmtest.h"
+
+#define SLEEP_DURATION 5000 // in milliseconds
+
+static int get_perf(const char *path)
+{
+ int ret, perf;
+ FILE *file;
+ char str[4];
+
+ file = fopen(path, "r");
+ igt_assert(file);
+
+ ret = fscanf(file, "Sink_Support: %s\n", str);
+ igt_skip_on_f(ret == 0,
+ "i915_edp_psr_status format not supported by this test case\n");
+ igt_require(strcmp(str, "yes") == 0);
+ ret = fscanf(file, "Source_OK: %s\n", str);
+ igt_assert(ret != 0);
+
+ igt_require(strcmp(str, "yes") == 0);
+
+ ret = fscanf(file, "Enabled: %s\n", str);
+ igt_assert(ret != 0);
+ igt_assert(strcmp(str, "yes") == 0);
+
+ ret = fscanf(file, "Performance_Counter: %i", &perf);
+ igt_assert(ret != 0);
+
+ igt_assert(perf);
+
+ fclose(file);
+ return perf;
+}
+
+igt_simple_main
+{
+ int ret, perf1, perf2;
+ int device = drm_get_card();
+ char *path;
+
+ igt_skip_on_simulation();
+
+ ret = asprintf(&path, "/sys/kernel/debug/dri/%d/i915_edp_psr_status", device);
+ igt_assert(ret != -1);
+
+ perf1 = get_perf(path);
+ sleep(SLEEP_DURATION / 1000);
+ perf2 = get_perf(path);
+
+ igt_assert_f(perf1 != perf2,
+ "Unable to enter PSR state again\n");
+}
diff --git a/tests/pm_rc6_residency.c b/tests/pm_rc6_residency.c
new file mode 100644
index 00000000..550e3adf
--- /dev/null
+++ b/tests/pm_rc6_residency.c
@@ -0,0 +1,169 @@
+/*
+ * 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"
+
+#define NUMBER_OF_RC6_RESIDENCY 3
+#define SLEEP_DURATION 3000 // in milliseconds
+#define RC6_FUDGE 900 // in milliseconds
+
+
+static unsigned int readit(const char *path)
+{
+ unsigned int ret;
+ int scanned;
+
+ FILE *file;
+ file = fopen(path, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Couldn't open %s (%d)\n", path, errno);
+ abort();
+ }
+ 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[])
+{
+ 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");//open
+ igt_require(file);
+
+ /* claim success if no rc6 enabled. */
+ if (readit(path) == 0)
+ igt_success();
+
+ for(unsigned int i = 0; i < 6; i++)
+ {
+ if(i == 3)
+ sleep(SLEEP_DURATION / 1000);
+ ret = asprintf(&path, "/sys/class/drm/card%d/power/%s_residency_ms",device,name_of_rc6_residency[i % 3] );
+ igt_assert(ret != -1);
+ value[i] = readit(path);
+ }
+ free(path);
+}
+
+static void rc6_residency_counter(int value[],const char * name_of_rc6_residency[])
+{
+ unsigned int flag_counter,flag_support;
+ double counter_result = 0;
+ flag_counter = 0;
+ flag_support = 0;
+
+ for(int flag = NUMBER_OF_RC6_RESIDENCY-1; flag >= 0 ; flag --)
+ {
+ unsigned int tmp_counter, tmp_support;
+ double counter;
+ counter = ((double)value[flag + 3] - (double)value[flag]) /(double) SLEEP_DURATION;
+
+ if( counter > 0.9 ){
+ counter_result = counter;
+ tmp_counter = 1;
+ }
+ else
+ tmp_counter = 0;
+
+ if( value [flag + 3] == 0){
+ tmp_support = 0;
+ printf("This machine doesn't support %s\n",name_of_rc6_residency[flag]);
+ }
+ 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;
+ }
+
+ printf("The residency counter : %f \n", counter_result);
+
+ igt_assert_f(flag_counter != 0 , "The RC6 residency counter is not good.\n");
+ igt_assert_f(flag_support != 0 , "This machine doesn't support any RC6 state!\n");
+ igt_assert_f(counter_result <=1 , "Debug files must be wrong \n");
+
+ printf("This machine entry %s state.\n", name_of_rc6_residency[(flag_counter / 2) - 1]);
+}
+
+static void rc6_residency_check(int value[])
+{
+ unsigned int diff;
+ diff = (value[3] - value[0]) +
+ (value[4] - value[1]) +
+ (value[5] - value[2]);
+
+ 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");
+}
+
+igt_main
+{
+ int value[6];
+ int fd;
+ const char * name_of_rc6_residency[3]={"rc6","rc6p","rc6pp"};
+
+ igt_skip_on_simulation();
+
+ /* Use drm_open_any to verify device existence */
+ fd = drm_open_any();
+ close(fd);
+
+ read_rc6_residency(value, name_of_rc6_residency);
+
+ igt_subtest("rc6-residency-check")
+ rc6_residency_check(value);
+
+ igt_subtest("rc6-residency-counter")
+ rc6_residency_counter(value, name_of_rc6_residency);
+
+}
diff --git a/tests/pm_rpm.c b/tests/pm_rpm.c
new file mode 100644
index 00000000..323e0729
--- /dev/null
+++ b/tests/pm_rpm.c
@@ -0,0 +1,1497 @@
+/*
+ * 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_debugfs.h"
+
+#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,
+};
+
+/* 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;
+struct scanout_fb *fbs = NULL;
+
+/* 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];
+};
+
+/* During the stress tests we want to be as fast as possible, so use pre-created
+ * FBs instead of creating them again and again. */
+struct scanout_fb {
+ uint32_t handle;
+ int width;
+ int height;
+ struct scanout_fb *next;
+};
+
+/* 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)
+{
+ int i, rc;
+
+ for (i = 0; i < data->res->count_crtcs; i++) {
+ rc = drmModeSetCrtc(drm_fd, data->res->crtcs[i], -1, 0, 0,
+ NULL, 0, NULL);
+ igt_assert(rc == 0);
+ }
+}
+
+static struct scanout_fb *create_fb(struct mode_set_data *data, int width,
+ int height)
+{
+ struct scanout_fb *fb_info;
+ struct igt_fb fb;
+ cairo_t *cr;
+
+ fb_info = malloc(sizeof(struct scanout_fb));
+ igt_assert(fb_info);
+
+ fb_info->handle = igt_create_fb(drm_fd, width, height,
+ DRM_FORMAT_XRGB8888,
+ false, &fb);
+ fb_info->width = width;
+ fb_info->height = height;
+ fb_info->next = NULL;
+
+ cr = igt_get_cairo_ctx(drm_fd, &fb);
+ igt_paint_test_pattern(cr, width, height);
+ cairo_destroy(cr);
+
+ return fb_info;
+}
+
+static uint32_t get_fb(struct mode_set_data *data, int width, int height)
+{
+ struct scanout_fb *fb;
+
+ if (!fbs) {
+ fbs = create_fb(data, width, height);
+ return fbs->handle;
+ }
+
+ for (fb = fbs; fb != NULL; fb = fb->next) {
+ if (fb->width == width && fb->height == height)
+ return fb->handle;
+
+ if (!fb->next) {
+ fb->next = create_fb(data, width, height);
+ return fb->next->handle;
+ }
+ }
+ igt_assert(false);
+}
+
+static bool enable_one_screen_with_type(struct mode_set_data *data,
+ enum screen_type type)
+{
+ uint32_t crtc_id = 0, buffer_id = 0, connector_id = 0;
+ drmModeModeInfoPtr mode = NULL;
+ int i, rc;
+
+ 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 == 0)
+ return false;
+
+ crtc_id = data->res->crtcs[0];
+ buffer_id = get_fb(data, 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);
+
+ return true;
+}
+
+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));
+}
+
+static drmModePropertyBlobPtr get_connector_edid(drmModeConnectorPtr connector,
+ int index)
+{
+ unsigned int i;
+ drmModeObjectPropertiesPtr props;
+ drmModePropertyBlobPtr ret = NULL;
+
+ props = drmModeObjectGetProperties(drm_fd, connector->connector_id,
+ DRM_MODE_OBJECT_CONNECTOR);
+
+ for (i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr prop = drmModeGetProperty(drm_fd,
+ props->props[i]);
+
+ if (strcmp(prop->name, "EDID") == 0) {
+ igt_assert(prop->flags & DRM_MODE_PROP_BLOB);
+ igt_assert(prop->count_blobs == 0);
+ ret = drmModeGetPropertyBlob(drm_fd,
+ props->prop_values[i]);
+ }
+
+ drmModeFreeProperty(prop);
+ }
+
+ drmModeFreeObjectProperties(props);
+ return ret;
+}
+
+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);
+
+ igt_set_vt_graphics_mode();
+}
+
+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(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 void test_i2c(struct mode_set_data *data)
+{
+ int i2c_edids = count_i2c_valid_edids();
+ int drm_edids = count_drm_valid_edids(data);
+
+ igt_assert_cmpint(i2c_edids, ==, drm_edids);
+}
+
+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 = open("/sys/kernel/debug/dri/0/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;
+
+ write(fd, "min_power\n", 10);
+ close(fd);
+ }
+ free(file_name);
+
+ /* Audio runtime PM policies. */
+ 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);
+ }
+}
+
+static void setup_environment(void)
+{
+ drm_fd = drm_open_any();
+ igt_assert(drm_fd >= 0);
+
+ igt_require_f(drmSetMaster(drm_fd) == 0, "Can't become DRM master, "
+ "please check if no other DRM client is running.\n");
+
+ 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)
+{
+ struct scanout_fb *fb, *fb_next;
+
+ fb = fbs;
+ while (fb) {
+ fb_next = fb->next;
+ free(fb);
+ fb = fb_next;
+ }
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ enable_one_screen(&ms_data);
+ igt_assert(wait_for_active());
+}
+
+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);
+
+ 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(&ms_data);
+ igt_assert(wait_for_active());
+ get_drm_info(&pre_suspend);
+ igt_assert(wait_for_active());
+
+ disable_all_screens(&ms_data);
+ igt_assert(wait_for_suspended());
+ get_drm_info(&during_suspend);
+ igt_assert(wait_for_suspended());
+
+ enable_one_screen(&ms_data);
+ igt_assert(wait_for_active());
+ 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(&ms_data);
+ igt_assert(wait_for_active());
+
+ disable_all_screens(&ms_data);
+ igt_assert(wait_for_suspended());
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_active());
+
+ 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, 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_active());
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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, 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(&ms_data);
+ igt_assert(wait_for_active());
+ 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(&ms_data);
+ igt_assert(wait_for_active());
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_active());
+
+ 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(&ms_data);
+ igt_assert(wait_for_active());
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_active());
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ sleep(5);
+
+ gem_quiescent_gpu(drm_fd);
+}
+
+/* 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ 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(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ igt_assert(device_in_pci_d3());
+
+ enable_one_screen(&ms_data);
+ igt_assert(wait_for_active());
+
+ igt_assert(!device_in_pci_d3());
+}
+
+static void stay_subtest(void)
+{
+ disable_all_screens(&ms_data);
+ igt_assert(wait_for_suspended());
+
+ while (1)
+ sleep(600);
+}
+
+static void system_suspend_subtest(void)
+{
+ disable_all_screens(&ms_data);
+ igt_assert(wait_for_suspended());
+ igt_system_suspend_autoresume();
+ igt_assert(wait_for_suspended());
+}
+
+int main(int argc, char *argv[])
+{
+ int rounds = 50;
+ bool stay = false;
+
+ igt_subtest_init(argc, argv);
+
+ /* The --quick option makes the stress tests not so stressful. Useful
+ * when you're developing and just want to make a quick test to make
+ * sure you didn't break everything. */
+ if (argc > 1 && strcmp(argv[1], "--quick") == 0)
+ rounds = 10;
+
+ /* The --stay option enables a mode where we disable all the screens,
+ * then stay like that, runtime suspended. This mode is useful for
+ * running manual tests while debugging. */
+ if (argc > 1 && strcmp(argv[1], "--stay") == 0)
+ stay = true;
+
+ /* 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();
+
+ /* 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();
+
+ /* 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();
+
+ /* 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
new file mode 100644
index 00000000..c1156a5f
--- /dev/null
+++ b/tests/pm_rps.c
@@ -0,0 +1,595 @@
+/*
+ * 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 <getopt.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "drmtest.h"
+#include "intel_io.h"
+#include "intel_bufmgr.h"
+#include "intel_batchbuffer.h"
+#include "intel_chipset.h"
+#include "igt_debugfs.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 int do_writeval(FILE *filp, int val, int lerrno)
+{
+ int ret, orig;
+
+ orig = readval(filp);
+ rewind(filp);
+ ret = fprintf(filp, "%d", val);
+
+ if (lerrno) {
+ /* Expecting specific error */
+ igt_assert(ret == EOF && errno == lerrno);
+ igt_assert(readval(filp) == orig);
+ } else {
+ /* Expecting no error */
+ igt_assert(ret != EOF);
+ igt_assert(readval(filp) == val);
+ }
+
+ return ret;
+}
+#define writeval(filp, val) do_writeval(filp, val, 0)
+#define writeval_inval(filp, val) do_writeval(filp, val, EINVAL)
+
+static void checkit(const int *freqs)
+{
+ igt_assert_cmpint(freqs[MIN], <=, freqs[MAX]);
+ igt_assert_cmpint(freqs[CUR], <=, freqs[MAX]);
+ igt_assert_cmpint(freqs[MIN], <=, freqs[CUR]);
+ igt_assert_cmpint(freqs[RPn], <=, freqs[MIN]);
+ igt_assert_cmpint(freqs[MAX], <=, freqs[RP0]);
+ igt_assert_cmpint(freqs[RP1], <=, freqs[RP0]);
+ igt_assert_cmpint(freqs[RPn], <=, freqs[RP1]);
+ igt_assert(freqs[RP0] != 0);
+ igt_assert(freqs[RP1] != 0);
+}
+
+static void matchit(const int *freqs1, const int *freqs2)
+{
+ igt_assert_cmpint(freqs1[CUR], ==, freqs2[CUR]);
+ igt_assert_cmpint(freqs1[MIN], ==, freqs2[MIN]);
+ igt_assert_cmpint(freqs1[MAX], ==, freqs2[MAX]);
+ igt_assert_cmpint(freqs1[RP0], ==, freqs2[RP0]);
+ igt_assert_cmpint(freqs1[RP1], ==, freqs2[RP1]);
+ igt_assert_cmpint(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;
+
+ if (intel_gen(lh.devid) >= 8) {
+ BEGIN_BATCH(4);
+ OUT_BATCH(cmd);
+ OUT_RELOC(lh.target_buffer, I915_GEM_DOMAIN_INSTRUCTION,
+ I915_GEM_DOMAIN_INSTRUCTION, 0);
+ OUT_BATCH(0);
+ OUT_BATCH(val);
+ ADVANCE_BATCH();
+ } else {
+ BEGIN_BATCH(4);
+ OUT_BATCH(cmd);
+ 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_wait_helper(&lh.igt_proc);
+}
+
+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 min_max_config(void (*check)(void))
+{
+ int fmid = (origfreqs[RPn] + origfreqs[RP0]) / 2;
+
+ /* hw (and so kernel) currently rounds to 50 MHz ... */
+ fmid = fmid / 50 * 50;
+
+ igt_debug("\nCheck original min and max...\n");
+ check();
+
+ igt_debug("\nSet min=RPn and max=RP0...\n");
+ writeval(stuff[MIN].filp, origfreqs[RPn]);
+ writeval(stuff[MAX].filp, origfreqs[RP0]);
+ 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);
+ check();
+
+ igt_debug("\nDecrease min to RPn...\n");
+ writeval(stuff[MIN].filp, origfreqs[RPn]);
+ 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_cmpint(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_cmpint(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);
+
+ igt_subtest("min-max-config-idle")
+ min_max_config(idle_check);
+
+ igt_subtest("min-max-config-loaded") {
+ load_helper_run(HIGH);
+ min_max_config(loaded_check);
+ 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
index 962e903d..99d5cf29 100644
--- a/tests/prime_nv_api.c
+++ b/tests/prime_nv_api.c
@@ -16,8 +16,10 @@
#include "intel_bufmgr.h"
#include "nouveau.h"
-#include "intel_gpu_tools.h"
+#include "intel_io.h"
#include "intel_batchbuffer.h"
+#include "drmtest.h"
+#include "intel_chipset.h"
#define BO_SIZE (256*1024)
@@ -29,7 +31,7 @@ struct nouveau_client *nclient, *nclient2;
uint32_t devid;
struct intel_batchbuffer *intel_batch;
-static int find_and_open_devices(void)
+static void find_and_open_devices(void)
{
int i;
char path[80];
@@ -38,6 +40,8 @@ static int find_and_open_devices(void)
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;
@@ -46,166 +50,234 @@ static int find_and_open_devices(void)
if (!fl)
break;
- fgets(vendor_id, 8, fl);
+ 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;
+ igt_assert(intel_fd);
intel_fd2 = open(path, O_RDWR);
- if (!intel_fd2)
- return -1;
+ igt_assert(intel_fd2);
} else if (venid == 0x10de) {
nouveau_fd = open(path, O_RDWR);
- if (!nouveau_fd)
- return -1;
+ igt_assert(nouveau_fd);
nouveau_fd2 = open(path, O_RDWR);
- if (!nouveau_fd2)
- return -1;
+ igt_assert(nouveau_fd2);
}
}
- return 0;
}
-static int test1(void)
+static void test_i915_nv_import_twice(void)
{
- int ret;
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);
- ret = drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- if (ret)
- goto out;
+ igt_assert(drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd) == 0);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo);
- if (ret < 0) {
- close(prime_fd);
- goto out;
- }
- ret = nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2);
+ 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);
- if (ret < 0)
- goto out;
- if (nvbo->handle != nvbo2->handle)
- ret = -1;
-out:
nouveau_bo_ref(NULL, &nvbo2);
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
+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);
-static int test2(void)
+ 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)
{
- int ret;
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);
- ret = drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- if (ret < 0)
- goto out;
+ 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);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo);
+ /* create a new dma-buf */
close(prime_fd);
- if (ret < 0)
- goto out;
- ret = nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2);
- if (ret == 0)
- ret = -1;
- else
- ret = 0;
-
-out:
+ 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);
- return ret;
}
+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 int test3(void)
+static void test_i915_nv_double_import(void)
{
- int ret;
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);
- ret = drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- if (ret < 0)
- goto out;
+ igt_assert(drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd) == 0);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo);
- if (ret < 0) {
- close(prime_fd);
- goto out;
- }
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo2);
+ 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);
- if (ret < 0)
- goto out;
- if (nvbo->handle != nvbo2->handle)
- ret = -1;
+ igt_assert(nvbo->handle == nvbo2->handle);
-out:
nouveau_bo_ref(NULL, &nvbo2);
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
/* export handle twice from one driver - import twice
see if we get same object */
-static int test4(void)
+static void test_i915_nv_double_export(void)
{
- int ret;
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);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0);
close(prime_fd);
- if (ret >= 0)
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd2, &nvbo2);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd2, &nvbo2) == 0);
close(prime_fd2);
- if (ret < 0)
- goto out;
- if (nvbo->handle != nvbo2->handle)
- ret = -1;
+ igt_assert(nvbo->handle == nvbo2->handle);
-out:
nouveau_bo_ref(NULL, &nvbo2);
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
/* export handle from intel driver - reimport to intel driver
see if you get same object */
-static int test5(void)
+static void test_i915_self_import(void)
{
- int ret;
drm_intel_bo *test_intel_bo, *test_intel_bo2;
int prime_fd;
@@ -215,52 +287,35 @@ static int test5(void)
test_intel_bo2 = drm_intel_bo_gem_create_from_prime(bufmgr, prime_fd, BO_SIZE);
close(prime_fd);
- if (!test_intel_bo2) {
- ret = -1;
- goto out;
- }
+ igt_assert(test_intel_bo2);
- ret = 0;
- if (test_intel_bo->handle != test_intel_bo2->handle)
- ret = -1;
+ igt_assert(test_intel_bo->handle == test_intel_bo2->handle);
-out:
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
/* nouveau export reimport test */
-static int test6(void)
+static void test_nv_self_import(void)
{
- int ret;
int prime_fd;
struct nouveau_bo *nvbo, *nvbo2;
- ret = nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
- 0, BO_SIZE, NULL, &nvbo);
- if (ret < 0)
- return ret;
- ret = nouveau_bo_set_prime(nvbo, &prime_fd);
- if (ret < 0)
- return ret;
+ 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);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo2);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo2) == 0);
close(prime_fd);
- if (ret < 0)
- return ret;
- if (nvbo->handle != nvbo2->handle)
- fprintf(stderr,"mismatch handles %d %d\n", nvbo->handle, nvbo2->handle);
+ igt_assert(nvbo->handle == nvbo2->handle);
nouveau_bo_ref(NULL, &nvbo);
nouveau_bo_ref(NULL, &nvbo2);
- return 0;
}
/* export handle from intel driver - reimport to another intel driver bufmgr
see if you get same object */
-static int test7(void)
+static void test_i915_self_import_to_different_fd(void)
{
- int ret;
drm_intel_bo *test_intel_bo, *test_intel_bo2;
int prime_fd;
@@ -270,139 +325,89 @@ static int test7(void)
test_intel_bo2 = drm_intel_bo_gem_create_from_prime(bufmgr2, prime_fd, BO_SIZE);
close(prime_fd);
- if (!test_intel_bo2) {
- ret = -1;
- goto out;
- }
+ igt_assert(test_intel_bo2);
- ret = 0;
- /* not sure what to test for, just that we don't explode */
-out:
drm_intel_bo_unreference(test_intel_bo2);
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
/* nouveau export reimport to other driver test */
-static int test8(void)
+static void test_nv_self_import_to_different_fd(void)
{
- int ret;
int prime_fd;
struct nouveau_bo *nvbo, *nvbo2;
- ret = nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
- 0, BO_SIZE, NULL, &nvbo);
- if (ret < 0)
- return ret;
- ret = nouveau_bo_set_prime(nvbo, &prime_fd);
- if (ret < 0)
- return ret;
+ 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);
- ret = nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev2, prime_fd, &nvbo2) == 0);
close(prime_fd);
- if (ret < 0)
- return ret;
/* not sure what to test for, just make sure we don't explode */
nouveau_bo_ref(NULL, &nvbo);
nouveau_bo_ref(NULL, &nvbo2);
- return 0;
}
-int main(int argc, char **argv)
+igt_main
{
- int ret;
+ igt_fixture {
+ find_and_open_devices();
- ret = find_and_open_devices();
- if (ret < 0)
- return ret;
+ igt_require(nouveau_fd != -1);
+ igt_require(nouveau_fd2 != -1);
+ igt_require(intel_fd != -1);
+ igt_require(intel_fd2 != -1);
- if (nouveau_fd == -1 || intel_fd == -1 || nouveau_fd2 == -1 || intel_fd2 == -1) {
- fprintf(stderr,"failed to find intel and nouveau GPU\n");
- return 77;
- }
-
- /* set up intel bufmgr */
- bufmgr = drm_intel_bufmgr_gem_init(intel_fd, 4096);
- if (!bufmgr)
- return -1;
- /* 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);
- if (!bufmgr2)
- return -1;
- drm_intel_bufmgr_gem_enable_reuse(bufmgr2);
-
- /* set up nouveau bufmgr */
- ret = nouveau_device_wrap(nouveau_fd, 0, &ndev);
- if (ret < 0) {
- fprintf(stderr,"failed to wrap nouveau device\n");
- return 77;
- }
+ /* 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);
- ret = nouveau_client_new(ndev, &nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to setup nouveau client\n");
- return -1;
- }
-
- /* set up nouveau bufmgr */
- ret = nouveau_device_wrap(nouveau_fd2, 0, &ndev2);
- if (ret < 0) {
- fprintf(stderr,"failed to wrap nouveau device\n");
- return 77;
- }
-
- ret = nouveau_client_new(ndev2, &nclient2);
- if (ret < 0) {
- fprintf(stderr,"failed to setup nouveau client\n");
- return -1;
- }
+ bufmgr2 = drm_intel_bufmgr_gem_init(intel_fd2, 4096);
+ igt_assert(bufmgr2);
+ drm_intel_bufmgr_gem_enable_reuse(bufmgr2);
- /* set up an intel batch buffer */
- devid = intel_get_drm_devid(intel_fd);
- intel_batch = intel_batchbuffer_alloc(bufmgr, devid);
+ /* set up nouveau bufmgr */
+ igt_assert(nouveau_device_wrap(nouveau_fd, 0, &ndev) >= 0);
+ igt_assert(nouveau_client_new(ndev, &nclient) >= 0);
- ret = test1();
- if (ret)
- fprintf(stderr,"prime_test: failed test 1\n");
+ /* set up nouveau bufmgr */
+ igt_assert(nouveau_device_wrap(nouveau_fd2, 0, &ndev2) >= 0);
- ret = test2();
- if (ret)
- fprintf(stderr,"prime_test: failed test 2\n");
+ igt_assert(nouveau_client_new(ndev2, &nclient2) >= 0);;
- ret = test3();
- if (ret)
- fprintf(stderr,"prime_test: failed test 3\n");
-
- ret = test4();
- if (ret)
- fprintf(stderr,"prime_test: failed test 4\n");
-
- ret = test5();
- if (ret)
- fprintf(stderr,"prime_test: failed test 5\n");
-
- ret = test6();
- if (ret)
- fprintf(stderr,"prime_test: failed test 6\n");
-
- ret = test7();
- if (ret)
- fprintf(stderr,"prime_test: failed test 7\n");
-
- ret = test8();
- if (ret)
- fprintf(stderr,"prime_test: failed test 8\n");
-
- intel_batchbuffer_free(intel_batch);
-
- nouveau_device_del(&ndev);
- drm_intel_bufmgr_destroy(bufmgr);
-
- close(intel_fd);
- close(nouveau_fd);
+ /* set up an intel batch buffer */
+ devid = intel_get_drm_devid(intel_fd);
+ intel_batch = intel_batchbuffer_alloc(bufmgr, devid);
+ igt_assert(intel_batch);
+ }
- return ret;
+#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
index 21dccf38..fb0f62ff 100644
--- a/tests/prime_nv_pcopy.c
+++ b/tests/prime_nv_pcopy.c
@@ -23,11 +23,13 @@
#include <sys/ioctl.h>
#include <errno.h>
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "intel_bufmgr.h"
#include "nouveau.h"
-#include "intel_gpu_tools.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;
@@ -49,24 +51,17 @@ static uint32_t memtype_intel, tile_intel_y, tile_intel_x;
#define NV01_SUBC(subc, mthd) SUBC_##subc((NV01_SUBCHAN_##mthd))
-#if 0
-#define dbg(fmt...) fprintf(stderr, fmt);
-#else
-#define dbg(...) do { } while (0)
-#endif
-
typedef struct {
uint32_t w, h;
uint32_t pitch, lines;
} rect;
-static int nv_bo_alloc(struct nouveau_bo **bo, rect *r,
- uint32_t w, uint32_t h, uint32_t tile_mode,
- int handle, uint32_t dom)
+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;
- int ret;
*bo = NULL;
if (tile_mode) {
@@ -92,7 +87,7 @@ static int nv_bo_alloc(struct nouveau_bo **bo, rect *r,
dx = 1 << tile_x;
dy = 1 << tile_y;
- dbg("Tiling requirements: x y %u %u\n", dx, dy);
+ igt_debug("Tiling requirements: x y %u %u\n", dx, dy);
}
r->w = w;
@@ -108,43 +103,31 @@ static int nv_bo_alloc(struct nouveau_bo **bo, rect *r,
cfg.nv50.tile_mode = tile_mode;
if (dom == NOUVEAU_BO_GART)
dom |= NOUVEAU_BO_MAP;
- ret = nouveau_bo_new(ndev, dom, 4096, size, &cfg, bo);
- if (!ret)
- ret = nouveau_bo_map(*bo, NOUVEAU_BO_RDWR, nclient);
- if (ret) {
- fprintf(stderr, "creating bo failed with %i %s\n",
- ret, strerror(-ret));
- nouveau_bo_ref(NULL, bo);
- return ret;
- }
+ igt_assert(nouveau_bo_new(ndev, dom, 4096, size, &cfg, bo) == 0);
+ igt_assert(nouveau_bo_map(*bo, NOUVEAU_BO_RDWR, nclient) == 0);
- dbg("new flags %08x memtype %08x tile %08x\n", (*bo)->flags, (*bo)->config.nv50.memtype, (*bo)->config.nv50.tile_mode);
+ 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) {
- dbg("tile mode was: %02x, now: %02x\n", (*bo)->config.nv50.tile_mode, tile_mode);
+ 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 {
- ret = nouveau_bo_prime_handle_ref(ndev, handle, bo);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, handle, bo) == 0);
close(handle);
- if (ret < 0) {
- fprintf(stderr, "receiving bo failed with %i %s\n",
- ret, strerror(-ret));
- return ret;
- }
- if ((*bo)->size < size) {
- fprintf(stderr, "expected bo size to be at least %u,"
- "but received %"PRIu64"\n", size, (*bo)->size);
- nouveau_bo_ref(NULL, bo);
- return -1;
- }
- dbg("prime flags %08x memtype %08x tile %08x\n", (*bo)->flags, (*bo)->config.nv50.memtype, (*bo)->config.nv50.tile_mode);
+ 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;
}
- dbg("size: %"PRIu64"\n", (*bo)->size);
-
- return ret;
+ igt_debug("size: %"PRIu64"\n", (*bo)->size);
}
static inline void
@@ -193,7 +176,7 @@ noop_intel(drm_intel_bo *bo)
intel_batchbuffer_flush(batch);
}
-static int find_and_open_devices(void)
+static void find_and_open_devices(void)
{
int i;
char path[80], *unused;
@@ -218,57 +201,37 @@ static int find_and_open_devices(void)
sprintf(path, "/dev/dri/card%d", i);
if (venid == 0x8086) {
intel_fd = open(path, O_RDWR);
- if (!intel_fd)
- return -1;
+ igt_assert(intel_fd);
} else if (venid == 0x10de) {
nouveau_fd = open(path, O_RDWR);
- if (!nouveau_fd)
- return -1;
+ igt_assert(nouveau_fd);
}
}
- return 0;
}
-static int init_nouveau(void)
+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, ret;
+ int size;
uint32_t class;
void *data;
- ret = nouveau_device_wrap(nouveau_fd, 0, &ndev);
- if (ret < 0) {
- fprintf(stderr,"failed to wrap nouveau device\n");
- return ret;
- }
+ igt_assert(nouveau_device_wrap(nouveau_fd, 0, &ndev) == 0);
- ret = nouveau_client_new(ndev, &nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to setup nouveau client\n");
- return ret;
- }
+ igt_assert(nouveau_client_new(ndev, &nclient) == 0);
- if (ndev->chipset < 0xa3 || ndev->chipset == 0xaa || ndev->chipset == 0xac) {
- fprintf(stderr, "Your card doesn't support PCOPY\n");
- return -1;
- }
+ 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
- if (ndev->chipset >= 0xe0) {
- fprintf(stderr, "Unsure how kepler works!\n");
- return -1;
- }
- ret = nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
- 4096, 4096, NULL, &query_bo);
- if (!ret)
- ret = nouveau_bo_map(query_bo, NOUVEAU_BO_RDWR, nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to setup query counter\n");
- return ret;
- }
+ 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;
@@ -282,45 +245,22 @@ static int init_nouveau(void)
size = sizeof(nvc0_data);
}
- ret = nouveau_object_new(&ndev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
- data, size, &nchannel);
- if (ret) {
- fprintf(stderr, "Error creating GPU channel: %d\n", ret);
- if (ret == -ENODEV) {
- fprintf(stderr, "Make sure nouveau_accel is active\n");
- fprintf(stderr, "nvd9 is likely broken regardless\n");
- }
- return ret;
- }
+ igt_assert(nouveau_object_new(&ndev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
+ data, size, &nchannel) == 0);
fifo = nchannel->data;
- ret = nouveau_pushbuf_new(nclient, nchannel, 4, 32 * 1024,
- true, &npush);
- if (ret) {
- fprintf(stderr, "Error allocating DMA push buffer: %d\n", ret);
- return ret;
- }
+ igt_assert(nouveau_pushbuf_new(nclient, nchannel, 4, 32 * 1024,
+ true, &npush) == 0);
- ret = nouveau_bufctx_new(nclient, 1, &nbufctx);
- if (ret) {
- fprintf(stderr, "Error allocating buffer context: %d\n", ret);
- return ret;
- }
+ igt_assert(nouveau_bufctx_new(nclient, 1, &nbufctx) == 0);
npush->user_priv = nbufctx;
/* Hope this is enough init for PCOPY */
- ret = nouveau_object_new(nchannel, class, class & 0xffff, NULL, 0, &pcopy);
- if (ret) {
- fprintf(stderr, "Failed to allocate pcopy: %d\n", ret);
- return ret;
- }
- ret = nouveau_pushbuf_space(npush, 512, 0, 0);
- if (ret) {
- fprintf(stderr, "No space in pushbuf: %d\n", ret);
- return ret;
- }
+ 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;
@@ -339,7 +279,6 @@ static int init_nouveau(void)
PUSH_DATA(npush, pcopy->handle);
}
nouveau_pushbuf_kick(npush, npush->channel);
- return ret;
}
static void fill16(void *ptr, uint32_t val)
@@ -351,12 +290,12 @@ static void fill16(void *ptr, uint32_t val)
#define TILE_SIZE 4096
-static int swtile_y(uint8_t *out, const uint8_t *in, int w, int h)
+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;
- assert(!(w % 128));
- assert(!(h % 32));
+ 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) {
@@ -364,8 +303,8 @@ static int swtile_y(uint8_t *out, const uint8_t *in, int w, int h)
for (dy = 0; dy < 32; ++dy) {
uint32_t out_ofs = (dx * 32 + dy) * 16;
uint32_t in_ofs = (y + dy) * w + (x + 16 * dx);
- assert(out_ofs < TILE_SIZE);
- assert(in_ofs < w*h);
+ 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);
@@ -374,158 +313,36 @@ static int swtile_y(uint8_t *out, const uint8_t *in, int w, int h)
}
}
}
- assert(out == endptr);
- return 0;
+ igt_assert(out == endptr);
}
-static int swtile_x(uint8_t *out, const uint8_t *in, int w, int h)
+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;
- assert(!(w % 512));
- assert(!(h % 8));
+ 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;
- assert(out_ofs < TILE_SIZE);
- assert(in_ofs < w*h);
+ igt_assert(out_ofs < TILE_SIZE);
+ igt_assert(in_ofs < w*h);
memcpy(&out[out_ofs], &in[in_ofs], 512);
}
}
}
- assert(out == endptr);
- return 0;
-}
-
-#if 0
-/* X tiling is approximately linear, except tiled in 512x8 blocks, so lets abuse that
- *
- * How? Whole contiguous tiles can be copied safely as if linear
- */
-
-static int perform_copy_hack(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 exec = 0x00000000;
- uint32_t src_off = 0, dst_off = 0;
- struct nouveau_pushbuf *push = npush;
- uint32_t dw, tiles, tile_src = nvbi->config.nv50.tile_mode, tile_dst = nvbo->config.nv50.tile_mode;
-
- if (tile_src == tile_intel_x)
- dw = 512 - (src_x & 512);
- else
- dw = 512 - (dst_x % 512);
-
- if (!nvbi->config.nv50.memtype)
- exec |= 0x00000010;
- if (!tile_src)
- src_off = src_y * src->pitch + src_x;
-
- if (!nvbo->config.nv50.memtype)
- exec |= 0x00000100;
- if (!tile_dst)
- dst_off = dst_y * dst->pitch + dst_x;
-
- if (dw > w)
- dw = w;
- tiles = 1 + ((w - dw + 511)/512);
-
- if (nouveau_pushbuf_space(push, 8 + tiles * 32, 0, 0) ||
- nouveau_pushbuf_refn(push, refs, 3))
- return -1;
-
- for (; w; w -= dw, src_x += dw, dst_x += dw, dw = w > 512 ? 512 : w) {
- if (tile_src == tile_intel_x) {
- /* Find the correct tiled offset */
- src_off = 8 * dst->pitch * (src_y / 8);
- src_off += src_x / 512 * 4096;
- src_off += (src_x % 512) + 512 * (src_y % 8);
-
- if (!tile_dst)
- dst_off = dst_y * dst->pitch + dst_x;
- } else {
- if (!tile_src)
- src_off = src_y * src->pitch + src_x;
-
- dst_off = 8 * dst->pitch * (dst_y / 8);
- dst_off += dst_x / 512 * 4096;
- dst_off += (dst_x % 512) + 512 * (dst_y % 8);
- }
-
- fprintf(stderr, "Copying from %u to %u for %u bytes\n", src_x, dst_x, dw);
- fprintf(stderr, "src ofs: %u, dst ofs: %u\n", src_off, dst_off);
- BEGIN_NVXX(push, SUBC_COPY(0x0200), 7);
- PUSH_DATA (push, tile_src == tile_intel_x ? 0 : nvbi->config.nv50.tile_mode);
- PUSH_DATA (push, src->pitch);
- PUSH_DATA (push, src->h);
- PUSH_DATA (push, 1);
- PUSH_DATA (push, 0);
- PUSH_DATA (push, src_x);
- PUSH_DATA (push, src_y);
-
- BEGIN_NVXX(push, SUBC_COPY(0x0220), 7);
- PUSH_DATA (push, tile_dst == tile_intel_x ? 0 : nvbo->config.nv50.tile_mode);
- PUSH_DATA (push, dst->pitch);
- PUSH_DATA (push, dst->h);
- PUSH_DATA (push, 1);
- PUSH_DATA (push, 0);
- PUSH_DATA (push, dst_x);
- PUSH_DATA (push, dst_y);
-
- BEGIN_NVXX(push, SUBC_COPY(0x030c), 8);
- 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, dw);
- PUSH_DATA (push, h);
-
- if (w == dw) {
- exec |= 0x3000; /* QUERY|QUERY_SHORT */
- 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);
- }
- nouveau_pushbuf_kick(push, push->channel);
- while (*query < query_counter) { }
- return 0;
+ igt_assert(out == endptr);
}
-#endif
-static int 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)
+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)
{
-#if 0
- /* Too much effort */
- if (nvbi->config.nv50.tile_mode == tile_intel_x &&
- nvbo->config.nv50.tile_mode == tile_intel_x)
- return -1;
- else if (nvbi->config.nv50.tile_mode == tile_intel_x ||
- nvbo->config.nv50.tile_mode == tile_intel_x)
- return perform_copy_hack(nvbo, dst, dst_x, dst_y,
- nvbi, src, src_x, src_y, w, h);
-#endif
struct nouveau_pushbuf_refn refs[] = {
{ nvbi, (nvbi->flags & NOUVEAU_BO_APER) | NOUVEAU_BO_RD },
{ nvbo, (nvbo->flags & NOUVEAU_BO_APER) | NOUVEAU_BO_WR },
@@ -534,15 +351,15 @@ static int perform_copy(struct nouveau_bo *nvbo, const rect *dst,
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)
- dbg("src is y-tiled\n");
+ igt_debug("src is y-tiled\n");
if (nvbo->config.nv50.tile_mode == tile_intel_y)
- dbg("dst is y-tiled\n");
+ igt_debug("dst is y-tiled\n");
- if (nouveau_pushbuf_space(push, 64, 0, 0) ||
- nouveau_pushbuf_refn(push, refs, 3))
- return -1;
+ 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;
@@ -591,73 +408,62 @@ static int perform_copy(struct nouveau_bo *nvbo, const rect *dst,
BEGIN_NVXX(push, SUBC_COPY(0x0300), 1);
PUSH_DATA (push, exec);
- nouveau_pushbuf_kick(push, push->channel);
- while (*query < query_counter) { usleep(1000); }
- return 0;
+ ret = nouveau_pushbuf_kick(push, push->channel);
+ while (!ret && *query < query_counter) { usleep(1000); }
+
+ igt_assert(ret == 0);
}
-static int check1_macro(uint32_t *p, uint32_t w, uint32_t h)
+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);
- if (p[0] != val || p[1] != val || p[2] != val || p[3] != val) {
- fprintf(stderr, "Retile check failed in first tile!\n");
- fprintf(stderr, "%08x %08x %08x %08x instead of %08x\n",
- p[0], p[1], p[2], p[3], val);
- return -1;
- }
+ 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) {
- if (p[0] != val || p[1] != val || p[2] != val || p[3] != val) {
- fprintf(stderr, "Retile check failed in second tile!\n");
- fprintf(stderr, "%08x %08x %08x %08x instead of %08x\n",
- p[0], p[1], p[2], p[3], val);
- return -1;
- }
+ 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) {
- if (p[0] != val || p[1] != val || p[2] != val || p[3] != val) {
- fprintf(stderr, "Retile check failed in third tile!\n");
- fprintf(stderr, "%08x %08x %08x %08x instead of %08x\n",
- p[0], p[1], p[2], p[3], val);
- return -1;
- }
+ 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) {
- if (p[0] != val || p[1] != val || p[2] != val || p[3] != val) {
- fprintf(stderr, "Retile check failed in fourth tile!\n");
- fprintf(stderr, "%08x %08x %08x %08x instead of %08x\n",
- p[0], p[1], p[2], p[3], val);
- return -1;
- }
+ 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);
}
}
- return 0;
}
/* test 1, see if we can copy from linear to intel Y format safely */
-static int test1_macro(void)
+static void test1_macro(void)
{
- int ret, prime_fd = -1;
+ 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;
- ret = nv_bo_alloc(&nvbi, &src, w, h, 0, -1, NOUVEAU_BO_GART);
- if (ret >= 0)
- ret = nv_bo_alloc(&nvbo, &dst, w, h, tile_intel_y, -1, NOUVEAU_BO_GART);
- if (ret < 0)
- goto out;
+ 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);
@@ -691,34 +497,30 @@ static int test1_macro(void)
memset(nvbo->map, 0xfc, w * h);
if (pcopy)
- ret = perform_copy(nvbo, &dst, 0, 0, nvbi, &src, 0, 0, w, h);
+ perform_copy(nvbo, &dst, 0, 0, nvbi, &src, 0, 0, w, h);
else
- ret = swtile_y(nvbo->map, nvbi->map, w, h);
- if (!ret)
- ret = check1_macro(nvbo->map, w/128, h/32);
+ swtile_y(nvbo->map, nvbi->map, w, h);
+ check1_macro(nvbo->map, w/128, h/32);
-out:
nouveau_bo_ref(NULL, &nvbo);
nouveau_bo_ref(NULL, &nvbi);
close(prime_fd);
- return ret;
}
-static int dump_line(uint8_t *map)
+static void dump_line(uint8_t *map)
{
uint32_t dx, dy;
- fprintf(stderr, "Dumping sub-tile:\n");
+ igt_debug("Dumping sub-tile:\n");
for (dy = 0; dy < 32; ++dy) {
for (dx = 0; dx < 15; ++dx, ++map) {
- fprintf(stderr, "%02x ", *map);
+ igt_debug("%02x ", *map);
}
- fprintf(stderr, "%02x\n", *(map++));
+ igt_debug("%02x\n", *(map++));
}
- return -1;
}
-static int check1_micro(void *map, uint32_t pitch, uint32_t lines,
- uint32_t dst_x, uint32_t dst_y, uint32_t w, uint32_t h)
+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;
@@ -727,23 +529,22 @@ static int check1_micro(void *map, uint32_t pitch, uint32_t lines,
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]) {
- fprintf(stderr, "failed check at x=%u y=%u, expected %02x got %02x\n",
- x, y, expected, m[x]);
- return dump_line(m);
- }
+
+ 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]);
}
}
-
- return 0;
}
/* test 1, but check micro format, should be unaffected by bit9 swizzling */
-static int test1_micro(void)
+static void test1_micro(void)
{
struct nouveau_bo *bo_intel = NULL, *bo_nvidia = NULL, *bo_linear = NULL;
rect intel, nvidia, linear;
- int ret = -1;
uint32_t tiling = I915_TILING_Y;
uint32_t src_x = 0, src_y = 0;
@@ -754,31 +555,18 @@ static int test1_micro(void)
int prime_fd;
test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", w * h, 4096);
- if (!test_intel_bo)
- return -1;
+ igt_assert(test_intel_bo);
drm_intel_bo_set_tiling(test_intel_bo, &tiling, w);
- if (tiling != I915_TILING_Y) {
- fprintf(stderr, "Couldn't set y tiling\n");
- goto out;
- }
- ret = drm_intel_gem_bo_map_gtt(test_intel_bo);
- if (ret)
- goto out;
+ 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);
- if (prime_fd < 0) {
- drm_intel_bo_unreference(test_intel_bo);
- goto out;
- }
+ igt_assert(prime_fd >= 0);
noop_intel(test_intel_bo);
- ret = nv_bo_alloc(&bo_intel, &intel, w, h, tile_intel_y, prime_fd, 0);
- if (!ret)
- ret = nv_bo_alloc(&bo_nvidia, &nvidia, w, h, 0x10, -1, NOUVEAU_BO_VRAM);
- if (!ret)
- ret = nv_bo_alloc(&bo_linear, &linear, w, h, 0, -1, NOUVEAU_BO_GART);
- if (ret)
- goto out;
+ 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;
@@ -793,162 +581,21 @@ static int test1_micro(void)
}
}
- ret = perform_copy(bo_nvidia, &nvidia, 0, 0, bo_linear, &linear, 0, 0, nvidia.pitch, nvidia.h);
- if (ret)
- goto out;
+ perform_copy(bo_nvidia, &nvidia, 0, 0, bo_linear, &linear, 0, 0, nvidia.pitch, nvidia.h);
/* Perform the actual sub rectangle copy */
if (pcopy)
- ret = perform_copy(bo_intel, &intel, dst_x, dst_y, bo_nvidia, &nvidia, src_x, src_y, w, h);
+ perform_copy(bo_intel, &intel, dst_x, dst_y, bo_nvidia, &nvidia, src_x, src_y, w, h);
else
- ret = swtile_y(test_intel_bo->virtual, bo_linear->map, w, h);
- if (ret)
- goto out;
+ swtile_y(test_intel_bo->virtual, bo_linear->map, w, h);
noop_intel(test_intel_bo);
- ret = check1_micro(test_intel_bo->virtual, intel.pitch, intel.h, dst_x, dst_y, w, h);
+ check1_micro(test_intel_bo->virtual, intel.pitch, intel.h, dst_x, dst_y, w, h);
-out:
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);
- return ret;
-}
-
-static int check1_swizzle(uint32_t *p, uint32_t pitch, uint32_t lines,
- uint32_t dst_x, uint32_t dst_y, uint32_t w, uint32_t h)
-{
- uint32_t i, val, j;
-
- for (j = 0; j < 32; ++j, p += (pitch - w)/4) {
- for (i = 0; i < 8; ++i, p += 4) {
- val = (i * 32) + j;
- val = (val) | (val << 8) | (val << 16) | (val << 24);
- if (p[0] != val || p[1] != val || p[2] != val || p[3] != val) {
- fprintf(stderr, "Retile check failed in first tile!\n");
- fprintf(stderr, "%08x %08x %08x %08x instead of %08x\n",
- p[0], p[1], p[2], p[3], val);
- return -1;
- }
- }
-
- val = 0x3e3e3e3e;
- for (; i < w/16; ++i, p += 4) {
- if (p[0] != val || p[1] != val || p[2] != val || p[3] != val) {
- fprintf(stderr, "Retile check failed in second tile!\n");
- fprintf(stderr, "%08x %08x %08x %08x instead of %08x\n",
- p[0], p[1], p[2], p[3], val);
- return -1;
- }
- }
- }
-
- for (j = 32; j < h; ++j, p += (pitch - w)/4) {
- val = 0x7e7e7e7e;
- for (i = 0; i < 8; ++i, p += 4) {
- if (p[0] != val || p[1] != val || p[2] != val || p[3] != val) {
- fprintf(stderr, "Retile check failed in third tile!\n");
- fprintf(stderr, "%08x %08x %08x %08x instead of %08x\n",
- p[0], p[1], p[2], p[3], val);
- return -1;
- }
- }
-
- val = 0xcececece;
- for (; i < w/16; ++i, p += 4) {
- if (p[0] != val || p[1] != val || p[2] != val || p[3] != val) {
- fprintf(stderr, "Retile check failed in fourth tile!\n");
- fprintf(stderr, "%08x %08x %08x %08x instead of %08x\n",
- p[0], p[1], p[2], p[3], val);
- return -1;
- }
- }
- }
- return 0;
-}
-
-/* Create a new bo, set tiling to y, and see if macro swizzling is done correctl */
-static int test1_swizzle(void)
-{
- struct nouveau_bo *bo_intel = NULL, *bo_nvidia = NULL, *bo_linear = NULL;
- rect intel, nvidia, linear;
- int ret = -1;
- 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;
- uint8_t *ptr;
-
- drm_intel_bo *test_intel_bo;
- int prime_fd;
-
- test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", w * h, 4096);
- if (!test_intel_bo)
- return -1;
- drm_intel_bo_set_tiling(test_intel_bo, &tiling, w);
- if (tiling != I915_TILING_Y) {
- fprintf(stderr, "Couldn't set y tiling\n");
- goto out;
- }
- ret = drm_intel_gem_bo_map_gtt(test_intel_bo);
- if (ret)
- goto out;
-
- drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- if (prime_fd < 0) {
- drm_intel_bo_unreference(test_intel_bo);
- goto out;
- }
-
- ret = nv_bo_alloc(&bo_intel, &intel, w, h, tile_intel_y, prime_fd, 0);
- if (!ret)
- ret = nv_bo_alloc(&bo_nvidia, &nvidia, w, h, 0x10, -1, NOUVEAU_BO_VRAM);
- if (!ret)
- ret = nv_bo_alloc(&bo_linear, &linear, w, h, 0, -1, NOUVEAU_BO_GART);
- if (ret)
- goto out;
-
- noop_intel(test_intel_bo);
- ptr = bo_linear->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);
-
- ret = perform_copy(bo_nvidia, &nvidia, 0, 0, bo_linear, &linear, 0, 0, nvidia.pitch, nvidia.h);
- if (ret)
- goto out;
-
- /* Perform the actual sub rectangle copy */
- ret = perform_copy(bo_intel, &intel, dst_x, dst_y, bo_nvidia, &nvidia, src_x, src_y, w, h);
- if (ret)
- goto out;
- noop_intel(test_intel_bo);
-
- ret = check1_swizzle(test_intel_bo->virtual, intel.pitch, intel.h, dst_x, dst_y, w, h);
-
-out:
- 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);
- return ret;
}
/* test 2, see if we can copy from linear to intel X format safely
@@ -956,19 +603,15 @@ out:
* as a reference for potential future tests. Software tiling is
* used for now
*/
-static int test2(void)
+static void test2(void)
{
- int ret;
struct nouveau_bo *nvbo = NULL, *nvbi = NULL;
rect dst, src;
uint8_t *ptr;
uint32_t w = 1024, h = 16, x, y;
- ret = nv_bo_alloc(&nvbi, &src, w, h, 0, -1, NOUVEAU_BO_GART);
- if (ret >= 0)
- ret = nv_bo_alloc(&nvbo, &dst, w, h, tile_intel_x, -1, NOUVEAU_BO_GART);
- if (ret < 0)
- goto out;
+ 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
@@ -998,31 +641,26 @@ static int test2(void)
/* do this in software, there is no X major tiling in PCOPY (yet?) */
if (0 && pcopy)
- ret = perform_copy(nvbo, &dst, 0, 0, nvbi, &src, 0, 0, w, h);
+ perform_copy(nvbo, &dst, 0, 0, nvbi, &src, 0, 0, w, h);
else
- ret = swtile_x(nvbo->map, nvbi->map, w, h);
- if (!ret)
- ret = check1_macro(nvbo->map, w/512, h/8);
+ swtile_x(nvbo->map, nvbi->map, w, h);
+ check1_macro(nvbo->map, w/512, h/8);
-out:
nouveau_bo_ref(NULL, &nvbo);
nouveau_bo_ref(NULL, &nvbi);
- return ret;
}
-static int 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)
+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;
- if (p[pitch * lines / 4 - 1] == 0x03030303) {
- fprintf(stderr, "copy failed: Not all lines have been copied back!\n");
- return -1;
- }
+ 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) {
@@ -1032,21 +670,18 @@ static int check3(const uint32_t *p, uint32_t pitch, uint32_t lines,
expected = 0x80808080;
else
expected = 0x04040404;
- if (*p != expected) {
- fprintf(stderr, "%u,%u should be %08x, but is %08x\n", x, y, expected, *p);
- return -1;
- }
+ igt_assert_f(*p == expected,
+ "%u,%u should be %08x, but is %08x\n",
+ x, y, expected, *p);
}
}
- return 0;
}
/* copy from nvidia bo to intel bo and copy to a linear bo to check if tiling went succesful */
-static int test3_base(int tile_src, int tile_dst)
+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;
- int ret;
uint32_t cpp = 4;
uint32_t src_x = 1 * cpp, src_y = 1;
@@ -1057,87 +692,69 @@ static int test3_base(int tile_src, int tile_dst)
int prime_fd;
test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", 2048 * cpp * 768, 4096);
- if (!test_intel_bo)
- return -1;
+ igt_assert(test_intel_bo);
drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- if (prime_fd < 0) {
- drm_intel_bo_unreference(test_intel_bo);
- return -1;
- }
+ igt_assert(prime_fd >= 0);
- ret = nv_bo_alloc(&bo_intel, &intel, 2048 * cpp, 768, tile_dst, prime_fd, 0);
- if (!ret)
- ret = nv_bo_alloc(&bo_nvidia, &nvidia, 300 * cpp, 300, tile_src, -1, NOUVEAU_BO_VRAM);
- if (!ret)
- ret = nv_bo_alloc(&bo_linear, &linear, 2048 * cpp, 768, 0, -1, NOUVEAU_BO_GART);
- if (ret)
- goto out;
+ 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);
- ret = perform_copy(bo_intel, &intel, 0, 0, bo_linear, &linear, 0, 0, linear.pitch, linear.h);
- if (ret)
- goto out;
+ 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);
- ret = perform_copy(bo_nvidia, &nvidia, 0, 0, bo_linear, &linear, 0, 0, nvidia.pitch, nvidia.h);
- if (ret)
- goto out;
+ 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);
- ret = perform_copy(bo_intel, &intel, dst_x, dst_y, bo_nvidia, &nvidia, src_x, src_y, w, h);
- if (ret)
- goto out;
+ 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);
- ret = perform_copy(bo_linear, &linear, 0, 0, bo_intel, &intel, 0, 0, intel.pitch, intel.h);
- if (ret)
- goto out;
+ perform_copy(bo_linear, &linear, 0, 0, bo_intel, &intel, 0, 0, intel.pitch, intel.h);
noop_intel(test_intel_bo);
- ret = check3(bo_linear->map, linear.pitch, linear.h, dst_x, dst_y, w, h);
+ check3(bo_linear->map, linear.pitch, linear.h, dst_x, dst_y, w, h);
-out:
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);
- return ret;
}
-static int test3_1(void)
+static void test3_1(void)
{
/* nvidia tiling to intel */
- return test3_base(0x40, tile_intel_y);
+ test3_base(0x40, tile_intel_y);
}
-static int test3_2(void)
+static void test3_2(void)
{
/* intel tiling to nvidia */
- return test3_base(tile_intel_y, 0x40);
+ test3_base(tile_intel_y, 0x40);
}
-static int test3_3(void)
+static void test3_3(void)
{
/* intel tiling to linear */
- return test3_base(tile_intel_y, 0);
+ test3_base(tile_intel_y, 0);
}
-static int test3_4(void)
+static void test3_4(void)
{
/* linear tiling to intel */
- return test3_base(0, tile_intel_y);
+ test3_base(0, tile_intel_y);
}
-static int test3_5(void)
+static void test3_5(void)
{
/* linear to linear */
- return test3_base(0, 0);
+ test3_base(0, 0);
}
/* Acquire when == SEQUENCE */
@@ -1151,44 +768,33 @@ static int test3_5(void)
#define SEMA_ACQUIRE_GEQUAL 4
/* Test only new style semaphores, old ones are AWFUL */
-static int test_semaphore(void)
+static void test_semaphore(void)
{
drm_intel_bo *test_intel_bo = NULL;
struct nouveau_bo *sema_bo = NULL;
- int ret = -1, prime_fd;
+ int prime_fd;
uint32_t *sema;
struct nouveau_pushbuf *push = npush;
- if (ndev->chipset < 0x84)
- return -1;
+ igt_skip_on(ndev->chipset < 0x84);
/* Should probably be kept in sysmem */
test_intel_bo = drm_intel_bo_alloc(bufmgr, "semaphore bo", 4096, 4096);
- if (!test_intel_bo)
- goto out;
+ igt_assert(test_intel_bo);
drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- if (prime_fd < 0)
- goto out;
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &sema_bo);
+ igt_assert(prime_fd >= 0);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &sema_bo) == 0);
close(prime_fd);
- if (ret < 0)
- goto out;
- ret = drm_intel_gem_bo_map_gtt(test_intel_bo);
- if (ret != 0) {
- fprintf(stderr,"failed to map bo\n");
- goto out;
- }
+ igt_assert(drm_intel_gem_bo_map_gtt(test_intel_bo) == 0);
sema = test_intel_bo->virtual;
sema++;
*sema = 0;
- ret = -1;
- if (nouveau_pushbuf_space(push, 64, 0, 0) ||
- nouveau_pushbuf_refn(push, &(struct nouveau_pushbuf_refn)
- { sema_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR }, 1))
- goto out;
+ 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;
@@ -1227,80 +833,54 @@ static int test_semaphore(void)
nouveau_pushbuf_kick(push, push->channel);
usleep(1000);
- if (*sema != 2) {
- fprintf(stderr, "new sema should be 2 is %u\n", *sema);
- goto out;
- }
+ igt_assert(*sema == 2);
*sema = 3;
usleep(1000);
- if (*sema != 4) {
- fprintf(stderr, "new sema should be 4 is %u\n", *sema);
- goto out;
- }
+ igt_assert(*sema == 4);
*sema = 5;
usleep(1000);
- if (*sema != 6) {
- fprintf(stderr, "new sema should be 6 is %u\n", *sema);
- goto out;
- }
+ igt_assert(*sema == 6);
*sema = 8;
usleep(1000);
- if (*sema != 9) {
- fprintf(stderr, "new sema should be 9 is %u\n", *sema);
- goto out;
- }
- ret = 0;
+ igt_assert(*sema == 9);
-out:
nouveau_bo_ref(NULL, &sema_bo);
- if (test_intel_bo)
- drm_intel_bo_unreference(test_intel_bo);
- return ret;
+ drm_intel_bo_unreference(test_intel_bo);
}
-int main(int argc, char **argv)
+igt_main
{
- int ret, failed = 0, run = 0;
+ igt_fixture {
+ find_and_open_devices();
- ret = find_and_open_devices();
- if (ret < 0)
- return ret;
+ igt_require(nouveau_fd != -1);
+ igt_require(intel_fd != -1);
- if (nouveau_fd == -1 || intel_fd == -1) {
- fprintf(stderr,"failed to find intel and nouveau GPU\n");
- return 77;
+ /* 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);
}
- /* set up intel bufmgr */
- bufmgr = drm_intel_bufmgr_gem_init(intel_fd, 4096);
- if (!bufmgr)
- return -1;
- /* Do not enable reuse, we share (almost) all buffers. */
- //drm_intel_bufmgr_gem_enable_reuse(bufmgr);
-
- /* set up nouveau bufmgr */
- ret = init_nouveau();
- if (ret < 0)
- return 77;
-
- /* set up an intel batch buffer */
- devid = intel_get_drm_devid(intel_fd);
- batch = intel_batchbuffer_alloc(bufmgr, devid);
-
-#define xtest(x, args...) do { \
- ret = ((x)(args)); \
- ++run; \
- if (ret) { \
- ++failed; \
- fprintf(stderr, "prime_pcopy: failed " #x "\n"); } \
- } while (0)
+#define xtest(x, args...) \
+ igt_subtest( #x ) \
+ (x)(args);
xtest(test1_macro);
xtest(test1_micro);
- xtest(test1_swizzle);
+ //xtest(test1_swizzle);
xtest(test2);
xtest(test3_1);
xtest(test3_2);
@@ -1309,21 +889,20 @@ int main(int argc, char **argv)
xtest(test3_5);
xtest(test_semaphore);
- nouveau_bo_ref(NULL, &query_bo);
- nouveau_object_del(&pcopy);
- nouveau_bufctx_del(&nbufctx);
- nouveau_pushbuf_del(&npush);
- nouveau_object_del(&nchannel);
+ 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);
+ intel_batchbuffer_free(batch);
- nouveau_client_del(&nclient);
- nouveau_device_del(&ndev);
- drm_intel_bufmgr_destroy(bufmgr);
+ nouveau_client_del(&nclient);
+ nouveau_device_del(&ndev);
+ drm_intel_bufmgr_destroy(bufmgr);
- close(intel_fd);
- close(nouveau_fd);
-
- printf("Tests: %u run, %u failed\n", run, failed);
- return failed;
+ close(intel_fd);
+ close(nouveau_fd);
+ }
}
diff --git a/tests/prime_nv_test.c b/tests/prime_nv_test.c
index 2269f84f..8211cd6f 100644
--- a/tests/prime_nv_test.c
+++ b/tests/prime_nv_test.c
@@ -22,11 +22,13 @@
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "intel_bufmgr.h"
#include "nouveau.h"
-#include "intel_gpu_tools.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;
@@ -46,6 +48,8 @@ static int find_and_open_devices(void)
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;
@@ -54,7 +58,8 @@ static int find_and_open_devices(void)
if (!fl)
break;
- fgets(vendor_id, 8, fl);
+ ret = fgets(vendor_id, 8, fl);
+ igt_assert(ret);
fclose(fl);
venid = strtoul(vendor_id, NULL, 16);
@@ -80,25 +85,22 @@ static int find_and_open_devices(void)
* close prime_fd,
* unref buffers
*/
-static int test1(void)
+static void test_i915_nv_sharing(void)
{
- int ret;
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);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0);
close(prime_fd);
- if (ret < 0)
- return ret;
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return 0;
}
/*
@@ -109,38 +111,30 @@ static int test1(void)
* close prime_fd,
* unref buffers
*/
-static int test2(void)
+static void test_nv_i915_sharing(void)
{
- int ret;
drm_intel_bo *test_intel_bo;
int prime_fd;
struct nouveau_bo *nvbo;
- ret = nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
- 0, BO_SIZE, NULL, &nvbo);
- if (ret < 0)
- return ret;
- ret = nouveau_bo_set_prime(nvbo, &prime_fd);
- if (ret < 0)
- return ret;
+ 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);
- if (!test_intel_bo)
- return -1;
+ igt_assert(test_intel_bo);
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return 0;
}
/*
* allocate intel, give to nouveau, map on nouveau
* write 0xdeadbeef, non-gtt map on intel, read
*/
-static int test3(void)
+static void test_nv_write_i915_cpu_mmap_read(void)
{
- int ret;
drm_intel_bo *test_intel_bo;
int prime_fd;
struct nouveau_bo *nvbo = NULL;
@@ -150,46 +144,28 @@ static int test3(void)
drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo);
- if (ret < 0) {
- fprintf(stderr,"failed to ref prime buffer %d\n", ret);
- close(prime_fd);
- goto free_intel;
- }
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0);
close(prime_fd);
- goto free_intel;
-
- ret = nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to map nouveau bo\n");
- goto out;
- }
+ 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);
- if (*ptr != 0xdeadbeef) {
- fprintf(stderr,"mapped value doesn't match\n");
- ret = -1;
- }
-out:
+ igt_assert(*ptr == 0xdeadbeef);
nouveau_bo_ref(NULL, &nvbo);
-free_intel:
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
/*
* allocate intel, give to nouveau, map on nouveau
* write 0xdeadbeef, gtt map on intel, read
*/
-static int test4(void)
+static void test_nv_write_i915_gtt_mmap_read(void)
{
- int ret;
drm_intel_bo *test_intel_bo;
int prime_fd;
struct nouveau_bo *nvbo = NULL;
@@ -199,227 +175,118 @@ static int test4(void)
drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0);
close(prime_fd);
- if (ret < 0) {
- fprintf(stderr,"failed to ref prime buffer\n");
- return ret;
- }
-
- ret = nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to map nouveau bo\n");
- goto out;
- }
-
-
+ 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);
- if (*ptr != 0xdeadbeef) {
- fprintf(stderr,"mapped value doesn't match\n");
- ret = -1;
- }
-out:
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
/* 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 int test5(void)
+static void test_i915_import_cpu_mmap(void)
{
- int ret;
drm_intel_bo *test_intel_bo;
int prime_fd;
struct nouveau_bo *nvbo;
uint32_t *ptr;
- ret = nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
- 0, BO_SIZE, NULL, &nvbo);
- if (ret < 0)
- return ret;
- ret = nouveau_bo_set_prime(nvbo, &prime_fd);
- if (ret < 0)
- return ret;
-
+ 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);
- if (!test_intel_bo)
- return -1;
+ igt_assert(test_intel_bo);
- ret = nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to map nouveau bo\n");
- goto out;
- }
+ igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0);
ptr = nvbo->map;
*ptr = 0xdeadbeef;
- ret = drm_intel_bo_map(test_intel_bo, 0);
- if (ret != 0) {
- /* failed to map the bo is expected */
- ret = 0;
- goto out;
- }
- if (!test_intel_bo->virtual) {
- ret = 0;
- goto out;
- }
+ igt_assert(drm_intel_bo_map(test_intel_bo, 0) == 0);
+ igt_assert(test_intel_bo->virtual);
ptr = test_intel_bo->virtual;
- if (*ptr != 0xdeadbeef) {
- fprintf(stderr,"mapped value doesn't match %08x\n", *ptr);
- ret = -1;
- }
- out:
+ igt_assert(*ptr == 0xdeadbeef);
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
/* test drm_intel_bo_map_gtt works properly,
this tries to map the backing shmem fd, which doesn't exist
for these objects */
-static int test6(void)
+static void test_i915_import_gtt_mmap(void)
{
- int ret;
drm_intel_bo *test_intel_bo;
int prime_fd;
struct nouveau_bo *nvbo;
uint32_t *ptr;
- ret = nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
- 0, BO_SIZE, NULL, &nvbo);
- if (ret < 0)
- return ret;
- ret = nouveau_bo_set_prime(nvbo, &prime_fd);
- if (ret < 0)
- return ret;
+ 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);
- if (!test_intel_bo)
- return -1;
+ igt_assert(test_intel_bo);
- ret = nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to map nouveau bo\n");
- goto out;
- }
+ igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0);
ptr = nvbo->map;
*ptr = 0xdeadbeef;
*(ptr + 1) = 0xa55a55;
- ret = drm_intel_gem_bo_map_gtt(test_intel_bo);
- if (ret != 0) {
- fprintf(stderr,"failed to map bo\n");
- goto out;
- }
- if (!test_intel_bo->virtual) {
- ret = -1;
- fprintf(stderr,"failed to map bo\n");
- goto out;
- }
+ igt_assert(drm_intel_gem_bo_map_gtt(test_intel_bo) == 0);
+ igt_assert(test_intel_bo->virtual);
ptr = test_intel_bo->virtual;
- if (*ptr != 0xdeadbeef) {
- fprintf(stderr,"mapped value doesn't match %08x %08x\n", *ptr, *(ptr + 1));
- ret = -1;
- }
- out:
+ igt_assert(*ptr == 0xdeadbeef);
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return ret;
-}
-
-static int do_read(int fd, int handle, void *buf, int offset, int size)
-{
- struct drm_i915_gem_pread intel_pread;
-
- /* Ensure that we don't have any convenient data in buf in case
- * we fail.
- */
- memset(buf, 0xd0, size);
-
- memset(&intel_pread, 0, sizeof(intel_pread));
- intel_pread.handle = handle;
- intel_pread.data_ptr = (uintptr_t)buf;
- intel_pread.size = size;
- intel_pread.offset = offset;
-
- return ioctl(fd, DRM_IOCTL_I915_GEM_PREAD, &intel_pread);
-}
-
-static int do_write(int fd, int handle, void *buf, int offset, int size)
-{
- struct drm_i915_gem_pwrite intel_pwrite;
-
- memset(&intel_pwrite, 0, sizeof(intel_pwrite));
- intel_pwrite.handle = handle;
- intel_pwrite.data_ptr = (uintptr_t)buf;
- intel_pwrite.size = size;
- intel_pwrite.offset = offset;
-
- return ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &intel_pwrite);
}
/* test 7 - import from nouveau into intel, test pread/pwrite fail */
-static int test7(void)
+static void test_i915_import_pread_pwrite(void)
{
- int ret;
drm_intel_bo *test_intel_bo;
int prime_fd;
struct nouveau_bo *nvbo;
uint32_t *ptr;
uint32_t buf[64];
- ret = nouveau_bo_new(ndev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
- 0, BO_SIZE, NULL, &nvbo);
- if (ret < 0)
- return ret;
- ret = nouveau_bo_set_prime(nvbo, &prime_fd);
- if (ret < 0)
- return ret;
+ 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);
- if (!test_intel_bo)
- return -1;
+ igt_assert(test_intel_bo);
- ret = nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to map nouveau bo\n");
- goto out;
- }
+ igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0);
ptr = nvbo->map;
*ptr = 0xdeadbeef;
- ret = do_read(intel_fd, test_intel_bo->handle, buf, 0, 256);
- if (ret != -1) {
- fprintf(stderr,"pread succeedded %d\n", ret);
- goto out;
- }
+ gem_read(intel_fd, test_intel_bo->handle, 0, buf, 256);
+ igt_assert(buf[0] == 0xdeadbeef);
buf[0] = 0xabcdef55;
- ret = do_write(intel_fd, test_intel_bo->handle, buf, 0, 4);
- if (ret != -1) {
- fprintf(stderr,"pwrite succeedded\n");
- goto out;
- }
- ret = 0;
- out:
+ 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);
- return ret;
}
static void
@@ -440,7 +307,7 @@ 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);
- assert(bo);
+ 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
@@ -454,9 +321,8 @@ create_bo(drm_intel_bufmgr *ibufmgr, uint32_t val, int width, int height)
/* use intel hw to fill the BO with a blit from another BO,
then readback from the nouveau bo, check value is correct */
-static int test8(void)
+static void test_i915_blt_fill_nv_read(void)
{
- int ret;
drm_intel_bo *test_intel_bo, *src_bo;
int prime_fd;
struct nouveau_bo *nvbo = NULL;
@@ -468,115 +334,68 @@ static int test8(void)
drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);
- ret = nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo);
+ igt_assert(nouveau_bo_prime_handle_ref(ndev, prime_fd, &nvbo) == 0);
close(prime_fd);
- if (ret < 0) {
- fprintf(stderr,"failed to ref prime buffer\n");
- return ret;
- }
- intel_copy_bo(intel_batch, test_intel_bo, src_bo, 256, 1);
+ intel_copy_bo(intel_batch, test_intel_bo, src_bo, BO_SIZE);
- ret = nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to map nouveau bo\n");
- goto out;
- }
+ igt_assert(nouveau_bo_map(nvbo, NOUVEAU_BO_RDWR, nclient) == 0);
drm_intel_bo_map(test_intel_bo, 0);
ptr = nvbo->map;
- if (*ptr != 0xaa55aa55) {
- fprintf(stderr,"mapped value doesn't match\n");
- ret = -1;
- }
-out:
+ igt_assert(*ptr == 0xaa55aa55);
nouveau_bo_ref(NULL, &nvbo);
drm_intel_bo_unreference(test_intel_bo);
- return ret;
}
/* test 8 use nouveau to do blit */
/* test 9 nouveau copy engine?? */
-int main(int argc, char **argv)
+igt_main
{
- int ret;
+ igt_fixture {
+ igt_assert(find_and_open_devices() == 0);
- ret = find_and_open_devices();
- if (ret < 0)
- return ret;
+ igt_require(nouveau_fd != -1);
+ igt_require(intel_fd != -1);
- if (nouveau_fd == -1 || intel_fd == -1) {
- fprintf(stderr,"failed to find intel and nouveau GPU\n");
- return 77;
- }
+ /* 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 intel bufmgr */
- bufmgr = drm_intel_bufmgr_gem_init(intel_fd, 4096);
- if (!bufmgr)
- return -1;
- /* Do not enable reuse, we share (almost) all buffers. */
- //drm_intel_bufmgr_gem_enable_reuse(bufmgr);
-
- /* set up nouveau bufmgr */
- ret = nouveau_device_wrap(nouveau_fd, 0, &ndev);
- if (ret < 0) {
- fprintf(stderr,"failed to wrap nouveau device\n");
- return 77;
- }
+ /* set up nouveau bufmgr */
+ igt_assert(nouveau_device_wrap(nouveau_fd, 0, &ndev) == 0);
+ igt_assert(nouveau_client_new(ndev, &nclient) == 0);
- ret = nouveau_client_new(ndev, &nclient);
- if (ret < 0) {
- fprintf(stderr,"failed to setup nouveau client\n");
- return -1;
+ /* set up an intel batch buffer */
+ devid = intel_get_drm_devid(intel_fd);
+ intel_batch = intel_batchbuffer_alloc(bufmgr, devid);
}
- /* 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 */
- ret = test1();
- if (ret)
- fprintf(stderr,"prime_test: failed test 1\n");
-
- ret = test2();
- if (ret)
- fprintf(stderr,"prime_test: failed test 2\n");
-
- ret = test3();
- if (ret)
- fprintf(stderr,"prime_test: failed test 3\n");
+#define xtest(name) \
+ igt_subtest(#name) \
+ test_##name();
- ret = test4();
- if (ret)
- fprintf(stderr,"prime_test: failed test 4\n");
+ 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);
- ret = test5();
- if (ret)
- fprintf(stderr,"prime_test: failed test 5\n");
+ igt_fixture {
+ intel_batchbuffer_free(intel_batch);
- ret = test6();
- if (ret)
- fprintf(stderr,"prime_test: failed test 6\n");
+ nouveau_device_del(&ndev);
+ drm_intel_bufmgr_destroy(bufmgr);
- ret = test7();
- if (ret)
- fprintf(stderr,"prime_test: failed test 7\n");
-
- ret = test8();
- if (ret)
- fprintf(stderr,"prime_test: failed test 8\n");
-
- intel_batchbuffer_free(intel_batch);
-
- nouveau_device_del(&ndev);
- drm_intel_bufmgr_destroy(bufmgr);
-
- close(intel_fd);
- close(nouveau_fd);
-
- return ret;
+ close(intel_fd);
+ close(nouveau_fd);
+ }
}
diff --git a/tests/prime_self_import.c b/tests/prime_self_import.c
index 111ed4da..67fd5217 100644
--- a/tests/prime_self_import.c
+++ b/tests/prime_self_import.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2012 Intel Corporation
+ * 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"),
@@ -31,51 +31,143 @@
* ... 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 <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
-#include <sys/mman.h>
#include <sys/ioctl.h>
+#include <pthread.h>
+
#include "drm.h"
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
+#include "igt_debugfs.h"
#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;
- static char counter = 0;
int i;
ptr1 = gem_mmap(fd1, handle1, BO_SIZE, PROT_READ | PROT_WRITE);
ptr2 = gem_mmap(fd2, handle2, BO_SIZE, PROT_READ | PROT_WRITE);
- assert(ptr1);
+ igt_assert(ptr1);
/* check whether it's still our old object first. */
for (i = 0; i < BO_SIZE; i++) {
- assert(ptr1[i] == counter);
- assert(ptr2[i] == counter);
+ igt_assert(ptr1[i] == counter);
+ igt_assert(ptr2[i] == counter);
}
counter++;
memset(ptr1, counter, BO_SIZE);
- assert(memcmp(ptr1, ptr2, BO_SIZE) == 0);
+ igt_assert(memcmp(ptr1, ptr2, BO_SIZE) == 0);
munmap(ptr1, BO_SIZE);
munmap(ptr2, BO_SIZE);
}
-int main(int argc, char **argv)
+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;
@@ -94,11 +186,11 @@ int main(int argc, char **argv)
/* 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);
- assert(handle_import1 == handle_import2);
+ igt_assert(handle_import1 == handle_import2);
/* Same for re-importing on the exporting fd. */
handle_selfimport = prime_fd_to_handle(fd1, dma_buf_fd);
- assert(handle == handle_selfimport);
+ igt_assert(handle == handle_selfimport);
/* close dma_buf, check whether nothing disappears. */
close(dma_buf_fd);
@@ -118,6 +210,250 @@ int main(int argc, char **argv)
/* 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;
+ int device = drm_get_card();
+ char *path;
+
+ igt_drop_caches_set(DROP_RETIRE);
+
+ ret = asprintf(&path, "/sys/kernel/debug/dri/%d/i915_gem_objects", device);
+ igt_assert(ret != -1);
+
+ file = fopen(path, "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();
+ igt_assert(fds[0] >= 0);
- return 0;
+ 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(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;
+
+ obj_count = get_object_count();
+
+ num_threads = sysconf(_SC_NPROCESSORS_ONLN);
+
+ threads = calloc(num_threads, sizeof(pthread_t));
+
+ fd = drm_open_any();
+ igt_assert(fd >= 0);
+
+ 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);
+ igt_assert(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
new file mode 100644
index 00000000..62b381a3
--- /dev/null
+++ b/tests/prime_udl.c
@@ -0,0 +1,180 @@
+/* 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
index 6f814a13..e9d44110 100755
--- a/tests/sysfs_l3_parity
+++ b/tests/sysfs_l3_parity
@@ -8,20 +8,20 @@ fi
SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )"
. $SOURCE_DIR/drm_lib.sh
-$SOURCE_DIR/../tools/intel_l3_parity -c
+$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 0,0,0
-disabled=`$SOURCE_DIR/../tools/intel_l3_parity | grep -c 'Row 0, Bank 0, Subbank 0 is disabled'`
+$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 -c
+$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 | wc -c` != "0" ] ; then
- echo "Fail"
+if [ `$SOURCE_DIR/../tools/intel_l3_parity -l | wc -l` != 1 ] ; then
+ echo "Fail 2"
exit 1
fi
diff --git a/tests/sysfs_rc6_residency.c b/tests/sysfs_rc6_residency.c
deleted file mode 100644
index 2f33697a..00000000
--- a/tests/sysfs_rc6_residency.c
+++ /dev/null
@@ -1,119 +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 "drmtest.h"
-
-#define SLEEP_DURATION 3000 // in milliseconds
-#define RC6_FUDGE 900 // in milliseconds
-
-static unsigned int readit(const char *path)
-{
- unsigned int ret;
-
- FILE *file;
- file = fopen(path, "r");
- if (file == NULL) {
- fprintf(stderr, "Couldn't open %s (%d)\n", path, errno);
- abort();
- }
- fscanf(file, "%u", &ret);
- fclose(file);
-
- return ret;
-}
-
-int main(int argc, char *argv[])
-{
- const int device = drm_get_card(0);
- char *path, *pathp, *pathpp;
- int fd, ret;
- unsigned int value1, value1p, value1pp, value2, value2p, value2pp;
- FILE *file;
- int diff;
-
- /* Use drm_open_any to verify device existence */
- fd = drm_open_any();
- close(fd);
-
- ret = asprintf(&path, "/sys/class/drm/card%d/power/rc6_enable", device);
- assert(ret != -1);
-
- /* 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);
-
- file = fopen(path, "r");
- if (!file) {
- printf("kernel too old or rc6 not supported on this platform.\n");
- exit(77);
- }
-
- /* claim success if no rc6 enabled. */
- if (readit(path) == 0)
- exit(EXIT_SUCCESS);
-
- ret = asprintf(&path, "/sys/class/drm/card%d/power/rc6_residency_ms", device);
- assert(ret != -1);
- ret = asprintf(&pathp, "/sys/class/drm/card%d/power/rc6p_residency_ms", device);
- assert(ret != -1);
- ret = asprintf(&pathpp, "/sys/class/drm/card%d/power/rc6pp_residency_ms", device);
- assert(ret != -1);
-
- value1 = readit(path);
- value1p = readit(pathp);
- value1pp = readit(pathpp);
- sleep(SLEEP_DURATION / 1000);
- value2 = readit(path);
- value2p = readit(pathp);
- value2pp = readit(pathpp);
-
- free(pathpp);
- free(pathp);
- free(path);
-
- diff = (value2pp - value1pp) +
- (value2p - value1p) +
- (value2 - value1);
-
- if (diff > (SLEEP_DURATION + RC6_FUDGE)) {
- fprintf(stderr, "Diff was too high. That is unpossible\n");
- exit(EXIT_FAILURE);
- }
- if (diff < (SLEEP_DURATION - RC6_FUDGE)) {
- fprintf(stderr, "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");
- exit(EXIT_FAILURE);
- }
-
- exit(EXIT_SUCCESS);
-}
diff --git a/tests/template.c b/tests/template.c
new file mode 100644
index 00000000..24fd8506
--- /dev/null
+++ b/tests/template.c
@@ -0,0 +1,80 @@
+/*
+ * 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:
+ *
+ */
+
+#include "drmtest.h"
+
+/*
+ * Note that test function (and code called by them) should generally not return
+ * a variable indicating success/failure. Instead use the igt_require/igt_assert
+ * macros to skip out of the entire subtest.
+ *
+ * Also, helper functions should only return a status code if the callers have a
+ * real need to differentiate. If the only thing they do is call igt_assert or a
+ * similar macro then it'll result in simpler code when the check is moved
+ * completely into the helper.
+ */
+static void test_A(int fd)
+{
+}
+
+static void test_B(int fd)
+{
+}
+
+/*
+ * Variables which are written to in igt_fixtures/subtest blocks need to be
+ * allocated outside of the relevant function scope, otherwise gcc will wreak
+ * havoc (since these magic blocks use setjmp/longjmp internally).
+ *
+ * Common practice is to put variables used in the main test function into
+ * global scope, but only right above the main function itself (to avoid leaking
+ * it into other functions).
+ */
+
+int drm_fd;
+
+igt_main
+{
+ igt_fixture {
+ drm_fd = drm_open_any();
+ igt_require(drm_fd >= 0);
+
+ /* Set up other interesting stuff shared by all tests. */
+ }
+
+ igt_subtest("A")
+ test_A(drm_fd);
+ igt_subtest("B")
+ test_B(drm_fd);
+ /*
+ * Note that subtest names can be programatically generated. See the
+ * various uses of igt_subtest_f for a few neat ideas.
+ */
+
+ igt_fixture {
+ close(drm_fd);
+ }
+}
diff --git a/tests/test_rte_check b/tests/test_rte_check
new file mode 100755
index 00000000..6389592d
--- /dev/null
+++ b/tests/test_rte_check
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+whoami | grep root || ( echo ERROR: not running as root; exit 1 )
+
+SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )"
+. $SOURCE_DIR/drm_lib.sh
+
+exit 0
diff --git a/tests/testdisplay.c b/tests/testdisplay.c
index 14d7da39..125e7d2f 100644
--- a/tests/testdisplay.c
+++ b/tests/testdisplay.c
@@ -45,33 +45,44 @@
* - DP commands (e.g. poweroff)
* - verify outputs against VBT/physical connectors
*/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
-#include <assert.h>
#include <cairo.h>
#include <errno.h>
#include <math.h>
#include <stdint.h>
+#include <stdbool.h>
+#include <strings.h>
#include <unistd.h>
+#include <termios.h>
#include <sys/poll.h>
#include <sys/time.h>
-#include <sys/mman.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
-#include "i915_drm.h"
+#include "ioctl_wrappers.h"
#include "drmtest.h"
#include "testdisplay.h"
+#include "igt_kms.h"
#include <stdlib.h>
#include <signal.h>
+static int tio_fd;
+struct termios saved_tio;
+
drmModeRes *resources;
int drm_fd, modes;
-int dump_info = 0, test_all_modes =0, test_preferred_mode = 0, force_mode = 0,
- test_plane, enable_tiling;
+int test_all_modes = 0, test_preferred_mode = 0, force_mode = 0, test_plane,
+ test_stereo_modes, enable_tiling;
int sleep_between_modes = 5;
+int do_dpms = 0; /* This aliases to DPMS_ON */
uint32_t depth = 24, stride, bpp;
int qr_code = 0;
+int specified_mode_num = -1, specified_disp_id = -1;
drmModeModeInfo force_timing;
@@ -81,62 +92,6 @@ unsigned int plane_crtc_id;
unsigned int plane_id;
int plane_width, plane_height;
static const uint32_t SPRITE_COLOR_KEY = 0x00aaaaaa;
-uint32_t *fb_ptr;
-
-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-
-struct type_name {
- int type;
- const char *name;
-};
-
-#define type_name_fn(res) \
-static const char * res##_str(int type) { \
- unsigned int i; \
- for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
- if (res##_names[i].type == type) \
- return res##_names[i].name; \
- } \
- return "(invalid)"; \
-}
-
-struct type_name encoder_type_names[] = {
- { DRM_MODE_ENCODER_NONE, "none" },
- { DRM_MODE_ENCODER_DAC, "DAC" },
- { DRM_MODE_ENCODER_TMDS, "TMDS" },
- { DRM_MODE_ENCODER_LVDS, "LVDS" },
- { DRM_MODE_ENCODER_TVDAC, "TVDAC" },
-};
-
-type_name_fn(encoder_type)
-
-struct type_name connector_status_names[] = {
- { DRM_MODE_CONNECTED, "connected" },
- { DRM_MODE_DISCONNECTED, "disconnected" },
- { DRM_MODE_UNKNOWNCONNECTION, "unknown" },
-};
-
-type_name_fn(connector_status)
-
-struct type_name connector_type_names[] = {
- { DRM_MODE_CONNECTOR_Unknown, "unknown" },
- { DRM_MODE_CONNECTOR_VGA, "VGA" },
- { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
- { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
- { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
- { DRM_MODE_CONNECTOR_Composite, "composite" },
- { DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
- { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
- { DRM_MODE_CONNECTOR_Component, "component" },
- { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
- { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort" },
- { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
- { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
- { DRM_MODE_CONNECTOR_TV, "TV" },
- { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort" },
-};
-
-type_name_fn(connector_type)
/*
* Mode setting with the kernel interfaces is a bit of a chore.
@@ -152,6 +107,7 @@ struct connector {
drmModeEncoder *encoder;
drmModeConnector *connector;
int crtc;
+ int crtc_idx;
int pipe;
};
@@ -182,8 +138,8 @@ static void dump_connectors_fd(int drmfd)
printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n",
connector->connector_id,
connector->encoder_id,
- connector_status_str(connector->connection),
- connector_type_str(connector->connector_type),
+ kmstest_connector_status_str(connector->connection),
+ kmstest_connector_type_str(connector->connector_type),
connector->mmWidth, connector->mmHeight,
connector->count_modes);
@@ -193,8 +149,10 @@ static void dump_connectors_fd(int drmfd)
printf(" modes:\n");
printf(" name refresh (Hz) hdisp hss hse htot vdisp "
"vss vse vtot flags type clock\n");
- for (j = 0; j < connector->count_modes; j++)
+ for (j = 0; j < connector->count_modes; j++){
+ fprintf(stdout, "[%d]", j );
kmstest_dump_mode(&connector->modes[j]);
+ }
drmModeFreeConnector(connector);
}
@@ -233,109 +191,58 @@ static void dump_crtcs_fd(int drmfd)
drmModeFreeResources(mode_resources);
}
-static void connector_find_preferred_mode(struct connector *c)
+static void dump_info(void)
{
- drmModeConnector *connector;
- drmModeEncoder *encoder = NULL;
- int i, j;
-
- /* First, find the connector & mode */
- c->mode_valid = 0;
- connector = drmModeGetConnector(drm_fd, c->id);
- if (!connector) {
- fprintf(stderr, "could not get connector %d: %s\n",
- c->id, strerror(errno));
- drmModeFreeConnector(connector);
- return;
- }
-
- if (connector->connection != DRM_MODE_CONNECTED) {
- drmModeFreeConnector(connector);
- return;
- }
-
- if (!connector->count_modes) {
- fprintf(stderr, "connector %d has no modes\n", c->id);
- drmModeFreeConnector(connector);
- return;
- }
-
- if (connector->connector_id != c->id) {
- fprintf(stderr, "connector id doesn't match (%d != %d)\n",
- connector->connector_id, c->id);
- drmModeFreeConnector(connector);
- return;
- }
-
- for (j = 0; j < connector->count_modes; j++) {
- c->mode = connector->modes[j];
- if (c->mode.type & DRM_MODE_TYPE_PREFERRED) {
- c->mode_valid = 1;
- break;
- }
- }
-
- if (!c->mode_valid) {
- if (connector->count_modes > 0) {
- /* use the first mode as test mode */
- c->mode = connector->modes[0];
- c->mode_valid = 1;
- }
- else {
- fprintf(stderr, "failed to find any modes on connector %d\n",
- c->id);
- return;
- }
- }
-
- /* Now get the encoder */
- for (i = 0; i < connector->count_encoders; i++) {
- encoder = drmModeGetEncoder(drm_fd, connector->encoders[i]);
-
- if (!encoder) {
- fprintf(stderr, "could not get encoder %i: %s\n",
- resources->encoders[i], strerror(errno));
- drmModeFreeEncoder(encoder);
- continue;
- }
-
- break;
- }
+ dump_connectors_fd(drm_fd);
+ dump_crtcs_fd(drm_fd);
+}
- c->encoder = encoder;
+static void connector_find_preferred_mode(uint32_t connector_id,
+ unsigned long crtc_idx_mask,
+ int mode_num, struct connector *c)
+{
+ struct kmstest_connector_config config;
- if (i == resources->count_encoders) {
- fprintf(stderr, "failed to find encoder\n");
+ if (kmstest_get_connector_config(drm_fd, connector_id, crtc_idx_mask,
+ &config) < 0) {
c->mode_valid = 0;
return;
}
- /* Find first CRTC not in use */
- for (i = 0; i < resources->count_crtcs; i++) {
- if (resources->crtcs[i] && (c->encoder->possible_crtcs & (1<<i)))
- break;
+ c->connector = config.connector;
+ c->encoder = config.encoder;
+ c->crtc = config.crtc->crtc_id;
+ c->crtc_idx = config.crtc_idx;
+ c->pipe = config.pipe;
+
+ if (mode_num != -1) {
+ igt_assert(mode_num < config.connector->count_modes);
+ c->mode = config.connector->modes[mode_num];
+ } else {
+ c->mode = config.default_mode;
}
- c->crtc = resources->crtcs[i];
- c->pipe = i;
-
- if(test_preferred_mode || force_mode)
- resources->crtcs[i] = 0;
-
- c->connector = connector;
+ c->mode_valid = 1;
}
static void
-paint_color_key(void)
+paint_color_key(struct igt_fb *fb_info)
{
int i, j;
+ uint32_t *fb_ptr;
+
+ fb_ptr = gem_mmap(drm_fd, fb_info->gem_handle,
+ fb_info->size, PROT_READ | PROT_WRITE);
+ igt_assert(fb_ptr);
for (i = crtc_y; i < crtc_y + crtc_h; i++)
for (j = crtc_x; j < crtc_x + crtc_w; j++) {
uint32_t offset;
- offset = (i * width) + j;
+ offset = (i * fb_info->stride / 4) + j;
fb_ptr[offset] = SPRITE_COLOR_KEY;
}
+
+ munmap(fb_ptr, fb_info->size);
}
static void paint_image(cairo_t *cr, const char *file)
@@ -369,94 +276,58 @@ static void paint_image(cairo_t *cr, const char *file)
cairo_surface_destroy(image);
}
-static void
-paint_output_info(cairo_t *cr, int l_width, int l_height, void *priv)
+static void paint_output_info(struct connector *c, struct igt_fb *fb)
{
- struct connector *c = priv;
- cairo_text_extents_t name_extents, mode_extents;
- char name_buf[128], mode_buf[128];
- int i, x, y, modes_x, modes_y;
-
- /* Get text extents for each string */
- snprintf(name_buf, sizeof name_buf, "%s",
- connector_type_str(c->connector->connector_type));
- cairo_set_font_size(cr, 48);
- cairo_select_font_face(cr, "Helvetica",
- CAIRO_FONT_SLANT_NORMAL,
- CAIRO_FONT_WEIGHT_NORMAL);
- cairo_text_extents(cr, name_buf, &name_extents);
-
- snprintf(mode_buf, sizeof mode_buf, "%s @ %dHz on %s encoder",
- c->mode.name, c->mode.vrefresh,
- encoder_type_str(c->encoder->encoder_type));
- cairo_set_font_size(cr, 36);
- cairo_text_extents(cr, mode_buf, &mode_extents);
+ cairo_t *cr = igt_get_cairo_ctx(drm_fd, fb);
+ int l_width = fb->width;
+ int l_height = fb->height;
+ double str_width;
+ double x, y, top_y;
+ double max_width;
+ int i;
+
+ igt_paint_test_pattern(cr, l_width, l_height);
- /* Paint output name */
- x = l_width / 2;
- x -= name_extents.width / 2;
- y = l_height / 2;
- y -= (name_extents.height / 2) - (mode_extents.height / 2) - 10;
+ cairo_move_to(cr, l_width / 2, l_height / 2);
+
+ /* Print connector and mode name */
cairo_set_font_size(cr, 48);
- cairo_move_to(cr, x, y);
- cairo_text_path(cr, name_buf);
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_stroke_preserve(cr);
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_fill(cr);
-
- /* Paint mode name */
- x = l_width / 2;
- x -= mode_extents.width / 2;
- modes_x = x;
- y = l_height / 2;
- y += (mode_extents.height / 2) + (name_extents.height / 2) + 10;
+ igt_cairo_printf_line(cr, align_hcenter, 10, "%s",
+ kmstest_connector_type_str(c->connector->connector_type));
+
cairo_set_font_size(cr, 36);
- cairo_move_to(cr, x, y);
- cairo_text_path(cr, mode_buf);
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_stroke_preserve(cr);
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_fill(cr);
+ str_width = igt_cairo_printf_line(cr, align_hcenter, 10,
+ "%s @ %dHz on %s encoder", c->mode.name, c->mode.vrefresh,
+ kmstest_encoder_type_str(c->encoder->encoder_type));
+
+ cairo_rel_move_to(cr, -str_width / 2, 0);
/* List available modes */
- snprintf(mode_buf, sizeof mode_buf, "Available modes:");
cairo_set_font_size(cr, 18);
- cairo_text_extents(cr, mode_buf, &mode_extents);
- x = modes_x;
- modes_x = x + mode_extents.width;
- y += mode_extents.height + 10;
- modes_y = y;
- cairo_move_to(cr, x, y);
- cairo_text_path(cr, mode_buf);
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_stroke_preserve(cr);
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_fill(cr);
+ str_width = igt_cairo_printf_line(cr, align_left, 10,
+ "Available modes:");
+ cairo_rel_move_to(cr, str_width, 0);
+ cairo_get_current_point(cr, &x, &top_y);
+ max_width = 0;
for (i = 0; i < c->connector->count_modes; i++) {
- snprintf(mode_buf, sizeof mode_buf, "%s @ %dHz",
- c->connector->modes[i].name,
- c->connector->modes[i].vrefresh);
- cairo_set_font_size(cr, 18);
- cairo_text_extents(cr, mode_buf, &mode_extents);
- x = modes_x - mode_extents.width; /* right justify modes */
- y += mode_extents.height + 10;
- if (y + mode_extents.height >= height) {
- y = modes_y + mode_extents.height + 10;
- modes_x += mode_extents.width + 10;
- x = modes_x - mode_extents.width;
+ cairo_get_current_point(cr, &x, &y);
+ if (y >= l_height) {
+ x += max_width + 10;
+ max_width = 0;
+ cairo_move_to(cr, x, top_y);
}
- cairo_move_to(cr, x, y);
- cairo_text_path(cr, mode_buf);
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_stroke_preserve(cr);
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_fill(cr);
+ str_width = igt_cairo_printf_line(cr, align_right, 10,
+ "%s @ %dHz", c->connector->modes[i].name,
+ c->connector->modes[i].vrefresh);
+ if (str_width > max_width)
+ max_width = str_width;
}
if (qr_code)
- paint_image(cr, "./pass.png");
+ paint_image(cr, IGT_DATADIR"/pass.png");
+
+ igt_assert(!cairo_status(cr));
}
static void sighandler(int signo)
@@ -480,18 +351,8 @@ static void
set_mode(struct connector *c)
{
unsigned int fb_id = 0;
- int j, test_mode_num;
-
- if (depth <= 8)
- bpp = 8;
- else if (depth > 8 && depth <= 16)
- bpp = 16;
- else if (depth > 16 && depth <= 32)
- bpp = 32;
-
- connector_find_preferred_mode(c);
- if (!c->mode_valid)
- return;
+ struct igt_fb fb_info[2] = { };
+ int j, test_mode_num, current_fb = 0, old_fb = -1;
test_mode_num = 1;
if (force_mode){
@@ -503,29 +364,27 @@ set_mode(struct connector *c)
test_mode_num = c->connector->count_modes;
for (j = 0; j < test_mode_num; j++) {
- struct kmstest_fb fb_info;
if (test_all_modes)
c->mode = c->connector->modes[j];
+ /* set_mode() only tests 2D modes */
+ if (c->mode.flags & DRM_MODE_FLAG_3D_MASK)
+ continue;
+
if (!c->mode_valid)
continue;
width = c->mode.hdisplay;
height = c->mode.vdisplay;
- fb_id = kmstest_create_fb(drm_fd, width, height, bpp, depth,
- enable_tiling, &fb_info,
- paint_output_info, c);
-
- fb_ptr = gem_mmap(drm_fd, fb_info.gem_handle,
- fb_info.size, PROT_READ | PROT_WRITE);
- assert(fb_ptr);
- paint_color_key();
-
- gem_close(drm_fd, fb_info.gem_handle);
+ fb_id = igt_create_fb(drm_fd, width, height,
+ igt_bpp_depth_to_drm_format(bpp, depth),
+ enable_tiling, &fb_info[current_fb]);
+ paint_output_info(c, &fb_info[current_fb]);
+ paint_color_key(&fb_info[current_fb]);
- fprintf(stdout, "CRTS(%u):",c->crtc);
+ fprintf(stdout, "CRTC(%u):[%d]",c->crtc, j);
kmstest_dump_mode(&c->mode);
if (drmModeSetCrtc(drm_fd, c->crtc, fb_id, 0, 0,
&c->id, 1, &c->mode)) {
@@ -535,19 +394,197 @@ set_mode(struct connector *c)
continue;
}
+ if (old_fb != -1)
+ igt_remove_fb(drm_fd, &fb_info[old_fb]);
+ old_fb = current_fb;
+ current_fb = 1 - current_fb;
+
if (sleep_between_modes && test_all_modes && !qr_code)
sleep(sleep_between_modes);
+ if (do_dpms) {
+ kmstest_set_connector_dpms(drm_fd, c->connector, do_dpms);
+ sleep(sleep_between_modes);
+ kmstest_set_connector_dpms(drm_fd, c->connector, DRM_MODE_DPMS_ON);
+ }
+
if (qr_code){
set_single();
pause();
}
+ }
+ if (test_all_modes)
+ igt_remove_fb(drm_fd, &fb_info[old_fb]);
+
+ drmModeFreeEncoder(c->encoder);
+ drmModeFreeConnector(c->connector);
+}
+
+struct box {
+ int x, y, width, height;
+};
+
+struct stereo_fb_layout {
+ int fb_width, fb_height;
+ struct box left, right;
+};
+
+static void box_init(struct box *box, int x, int y, int bwidth, int bheight)
+{
+ box->x = x;
+ box->y = y;
+ box->width = bwidth;
+ box->height = bheight;
+}
+
+static void stereo_fb_layout_from_mode(struct stereo_fb_layout *layout,
+ drmModeModeInfo *mode)
+{
+ unsigned int format = mode->flags & DRM_MODE_FLAG_3D_MASK;
+ const int hdisplay = mode->hdisplay, vdisplay = mode->vdisplay;
+ int middle;
+
+ switch (format) {
+ case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
+ layout->fb_width = hdisplay;
+ layout->fb_height = vdisplay;
+
+ middle = vdisplay / 2;
+ box_init(&layout->left, 0, 0, hdisplay, middle);
+ box_init(&layout->right,
+ 0, middle, hdisplay, vdisplay - middle);
+ break;
+ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
+ layout->fb_width = hdisplay;
+ layout->fb_height = vdisplay;
+
+ middle = hdisplay / 2;
+ box_init(&layout->left, 0, 0, middle, vdisplay);
+ box_init(&layout->right,
+ middle, 0, hdisplay - middle, vdisplay);
+ break;
+ case DRM_MODE_FLAG_3D_FRAME_PACKING:
+ {
+ int vactive_space = mode->vtotal - vdisplay;
+
+ layout->fb_width = hdisplay;
+ layout->fb_height = 2 * vdisplay + vactive_space;
+
+ box_init(&layout->left,
+ 0, 0, hdisplay, vdisplay);
+ box_init(&layout->right,
+ 0, vdisplay + vactive_space, hdisplay, vdisplay);
+ break;
+ }
+ default:
+ igt_assert(0);
}
+}
- if(test_all_modes){
- drmModeRmFB(drm_fd,fb_id);
- drmModeSetCrtc(drm_fd, c->crtc, fb_id, 0, 0, &c->id, 1, 0);
+static const char *stereo_mode_str(drmModeModeInfo *mode)
+{
+ unsigned int layout = mode->flags & DRM_MODE_FLAG_3D_MASK;
+
+ switch (layout) {
+ case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
+ return "TB";
+ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
+ return "SbSH";
+ case DRM_MODE_FLAG_3D_FRAME_PACKING:
+ return "FP";
+ default:
+ igt_assert(0);
+ }
+}
+
+static uint32_t create_stereo_fb(drmModeModeInfo *mode, struct igt_fb *fb)
+{
+ struct stereo_fb_layout layout;
+ cairo_t *cr;
+ uint32_t fb_id;
+
+ stereo_fb_layout_from_mode(&layout, mode);
+ fb_id = igt_create_fb(drm_fd, layout.fb_width, layout.fb_height,
+ igt_bpp_depth_to_drm_format(bpp, depth),
+ enable_tiling, fb);
+ cr = igt_get_cairo_ctx(drm_fd, fb);
+
+ igt_paint_image(cr, IGT_DATADIR"/1080p-left.png",
+ layout.left.x, layout.left.y,
+ layout.left.width, layout.left.height);
+ igt_paint_image(cr, IGT_DATADIR"/1080p-right.png",
+ layout.right.x, layout.right.y,
+ layout.right.width, layout.right.height);
+
+ cairo_destroy(cr);
+
+ {
+ char buffer[64];
+
+ snprintf(buffer, sizeof(buffer), "%dx%d@%dHz-%s.png",
+ mode->hdisplay,
+ mode->vdisplay,
+ mode->vrefresh,
+ stereo_mode_str(mode));
+
+ igt_write_fb_to_png(drm_fd, fb, buffer);
+ }
+
+ return fb_id;
+}
+
+static void do_set_stereo_mode(struct connector *c)
+{
+ uint32_t fb_id;
+ struct igt_fb fb_info;
+
+ fb_id = create_stereo_fb(&c->mode, &fb_info);
+
+ if (drmModeSetCrtc(drm_fd, c->crtc, fb_id, 0, 0,
+ &c->id, 1, &c->mode)) {
+ fprintf(stderr, "failed to set mode (%dx%d@%dHz): %s\n",
+ width, height, c->mode.vrefresh,
+ strerror(errno));
+ }
+}
+
+static void
+set_stereo_mode(struct connector *c)
+{
+ int i, n;
+
+
+ if (specified_mode_num != -1)
+ n = 1;
+ else
+ n = c->connector->count_modes;
+
+ for (i = 0; i < n; i++) {
+ if (specified_mode_num == -1)
+ c->mode = c->connector->modes[i];
+
+ if (!c->mode_valid)
+ continue;
+
+ if (!(c->mode.flags & DRM_MODE_FLAG_3D_MASK))
+ continue;
+
+ fprintf(stdout, "CRTC(%u): [%d]", c->crtc, i);
+ kmstest_dump_mode(&c->mode);
+ do_set_stereo_mode(c);
+
+ if (qr_code) {
+ set_single();
+ pause();
+ } else if (sleep_between_modes)
+ sleep(sleep_between_modes);
+
+ if (do_dpms) {
+ kmstest_set_connector_dpms(drm_fd, c->connector, DRM_MODE_DPMS_OFF);
+ sleep(sleep_between_modes);
+ kmstest_set_connector_dpms(drm_fd, c->connector, DRM_MODE_DPMS_ON);
+ }
}
drmModeFreeEncoder(c->encoder);
@@ -580,25 +617,63 @@ int update_display(void)
if (!connectors)
return 0;
- if (dump_info) {
- dump_connectors_fd(drm_fd);
- dump_crtcs_fd(drm_fd);
- }
+ if (test_preferred_mode || test_all_modes ||
+ force_mode || specified_disp_id != -1) {
+ unsigned long crtc_idx_mask = -1UL;
- if (test_preferred_mode || test_all_modes || force_mode) {
/* Find any connected displays */
for (c = 0; c < resources->count_connectors; c++) {
- connectors[c].id = resources->connectors[c];
- set_mode(&connectors[c]);
+ struct connector *connector = &connectors[c];
+
+ connector->id = resources->connectors[c];
+ if (specified_disp_id != -1 &&
+ connector->id != specified_disp_id)
+ continue;
+
+ connector_find_preferred_mode(connector->id,
+ crtc_idx_mask,
+ specified_mode_num,
+ connector);
+ if (!connector->mode_valid)
+ continue;
+
+ set_mode(connector);
+
+ if (test_preferred_mode || force_mode ||
+ specified_mode_num != -1)
+ crtc_idx_mask &= ~(1 << connector->crtc_idx);
+
+ }
+ }
+
+ if (test_stereo_modes) {
+ for (c = 0; c < resources->count_connectors; c++) {
+ struct connector *connector = &connectors[c];
+
+ connector->id = resources->connectors[c];
+ if (specified_disp_id != -1 &&
+ connector->id != specified_disp_id)
+ continue;
+
+ connector_find_preferred_mode(connector->id,
+ -1UL,
+ specified_mode_num,
+ connector);
+ if (!connector->mode_valid)
+ continue;
+
+ set_stereo_mode(connector);
}
}
+
+ free(connectors);
drmModeFreeResources(resources);
return 1;
}
-static char optstr[] = "hiaf:s:d:p:mrt";
+static char optstr[] = "3hiaf:s:d:p:mrto:j:";
-static void usage(char *name)
+static void __attribute__((noreturn)) usage(char *name)
{
fprintf(stderr, "usage: %s [-hiasdpmtf]\n", name);
fprintf(stderr, "\t-i\tdump info\n");
@@ -607,8 +682,11 @@ static void usage(char *name)
fprintf(stderr, "\t-d\t<depth>\tbit depth of scanout buffer\n");
fprintf(stderr, "\t-p\t<planew,h>,<crtcx,y>,<crtcw,h> test overlay plane\n");
fprintf(stderr, "\t-m\ttest the preferred mode\n");
+ fprintf(stderr, "\t-3\ttest all 3D modes\n");
fprintf(stderr, "\t-t\tuse a tiled framebuffer\n");
+ fprintf(stderr, "\t-j\tdo dpms off, optional arg to select dpms leve (1-3)\n");
fprintf(stderr, "\t-r\tprint a QR code on the screen whose content is \"pass\" for the automatic test\n");
+ fprintf(stderr, "\t-o\t<id of the display>,<number of the mode>\tonly test specified mode on the specified display\n");
fprintf(stderr, "\t-f\t<clock MHz>,<hdisp>,<hsync-start>,<hsync-end>,<htotal>,\n");
fprintf(stderr, "\t\t<vdisp>,<vsync-start>,<vsync-end>,<vtotal>\n");
fprintf(stderr, "\t\ttest force mode\n");
@@ -618,6 +696,12 @@ static void usage(char *name)
#define dump_resource(res) if (res) dump_##res()
+static void cleanup_and_exit(int ret)
+{
+ close(drm_fd);
+ exit(ret);
+}
+
static gboolean input_event(GIOChannel *source, GIOCondition condition,
gpointer data)
{
@@ -626,7 +710,7 @@ static gboolean input_event(GIOChannel *source, GIOCondition condition,
count = read(g_io_channel_unix_get_fd(source), buf, sizeof(buf));
if (buf[0] == 'q' && (count == 1 || buf[1] == '\n')) {
- exit(0);
+ cleanup_and_exit(0);
}
return TRUE;
@@ -637,6 +721,7 @@ static void enter_exec_path( char **argv )
char *exec_path = NULL;
char *pos = NULL;
short len_path = 0;
+ int ret;
len_path = strlen( argv[0] );
exec_path = (char*) malloc(len_path);
@@ -646,10 +731,29 @@ static void enter_exec_path( char **argv )
if (pos != NULL)
*(pos+1) = '\0';
- chdir(exec_path);
+ ret = chdir(exec_path);
+ igt_assert(ret == 0);
free(exec_path);
}
+static void restore_termio_mode(int sig)
+{
+ tcsetattr(tio_fd, TCSANOW, &saved_tio);
+ close(tio_fd);
+}
+
+static void set_termio_mode(void)
+{
+ struct termios tio;
+
+ tio_fd = dup(STDIN_FILENO);
+ tcgetattr(tio_fd, &saved_tio);
+ igt_install_exit_handler(restore_termio_mode);
+ tio = saved_tio;
+ tio.c_lflag &= ~(ICANON | ECHO);
+ tcsetattr(tio_fd, TCSANOW, &tio);
+}
+
int main(int argc, char **argv)
{
int c;
@@ -657,14 +761,19 @@ int main(int argc, char **argv)
GIOChannel *stdinchannel;
GMainLoop *mainloop;
float force_clock;
+ bool opt_dump_info = false;
+
+ igt_skip_on_simulation();
enter_exec_path( argv );
- opterr = 0;
while ((c = getopt(argc, argv, optstr)) != -1) {
switch (c) {
+ case '3':
+ test_stereo_modes = 1;
+ break;
case 'i':
- dump_info = 1;
+ opt_dump_info = true;
break;
case 'a':
test_all_modes = 1;
@@ -681,6 +790,11 @@ int main(int argc, char **argv)
case 's':
sleep_between_modes = atoi(optarg);
break;
+ case 'j':
+ do_dpms = atoi(optarg);
+ if (do_dpms == 0)
+ do_dpms = DRM_MODE_DPMS_OFF;
+ break;
case 'd':
depth = atoi(optarg);
fprintf(stderr, "using depth %d\n", depth);
@@ -701,20 +815,45 @@ int main(int argc, char **argv)
case 'r':
qr_code = 1;
break;
+ case 'o':
+ sscanf(optarg, "%d,%d", &specified_disp_id, &specified_mode_num);
+ break;
default:
- fprintf(stderr, "unknown option %c\n", c);
/* fall through */
case 'h':
usage(argv[0]);
break;
}
}
- if (!test_all_modes && !force_mode && !dump_info &&
- !test_preferred_mode)
+
+ set_termio_mode();
+
+ if (depth <= 8)
+ bpp = 8;
+ else if (depth <= 16)
+ bpp = 16;
+ else if (depth <= 32)
+ bpp = 32;
+
+ if (!test_all_modes && !force_mode && !test_preferred_mode &&
+ specified_mode_num == -1 && !test_stereo_modes)
test_all_modes = 1;
drm_fd = drm_open_any();
+ if (test_stereo_modes &&
+ drmSetClientCap(drm_fd, DRM_CLIENT_CAP_STEREO_3D, 1) < 0) {
+ fprintf(stderr, "DRM_CLIENT_CAP_STEREO_3D failed\n");
+ goto out_close;
+ }
+
+ if (opt_dump_info) {
+ dump_info();
+ goto out_close;
+ }
+
+ igt_set_vt_graphics_mode();
+
mainloop = g_main_loop_new(NULL, FALSE);
if (!mainloop) {
fprintf(stderr, "failed to create glib mainloop\n");
@@ -747,7 +886,7 @@ int main(int argc, char **argv)
goto out_stdio;
}
- if (dump_info || test_all_modes)
+ if (test_all_modes)
goto out_stdio;
g_main_loop_run(mainloop);
diff --git a/tests/tools_test b/tests/tools_test
new file mode 100755
index 00000000..4c5577a7
--- /dev/null
+++ b/tests/tools_test
@@ -0,0 +1,18 @@
+#!/bin/bash
+# Test some of the most critical tools we have accidentally broken before.
+# TODO: Possibly make tests parse output
+
+whoami | grep -q root || ( echo ERROR: not running as root; exit 1 )
+
+SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )"
+. $SOURCE_DIR/drm_lib.sh
+
+# ARB_MODE has existed for many gens
+do_or_die "$SOURCE_DIR/../tools/intel_reg_read 0x4030"
+
+do_or_die "$SOURCE_DIR/../tools/intel_reg_dumper"
+
+# TODO: Add more tests
+
+exit 0
+