summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/Makefile.sources1
-rw-r--r--tests/kms_mmio_vs_cs_flip.c523
-rw-r--r--tests/meson.build1
3 files changed, 0 insertions, 525 deletions
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 791e4f83..8066fb1a 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -194,7 +194,6 @@ TESTS_progs = \
kms_invalid_dotclock \
kms_legacy_colorkey \
kms_mmap_write_crc \
- kms_mmio_vs_cs_flip \
kms_panel_fitting \
kms_pipe_b_c_ivb \
kms_pipe_crc_basic \
diff --git a/tests/kms_mmio_vs_cs_flip.c b/tests/kms_mmio_vs_cs_flip.c
deleted file mode 100644
index fa947d9c..00000000
--- a/tests/kms_mmio_vs_cs_flip.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright © 2014 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "igt.h"
-#include <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-
-typedef struct {
- int drm_fd;
- igt_display_t display;
- igt_pipe_crc_t *pipe_crc;
- drm_intel_bufmgr *bufmgr;
- drm_intel_bo *busy_bo;
- uint32_t devid;
- bool flip_done;
-} data_t;
-
-static void exec_nop(data_t *data, uint32_t handle, unsigned int ring)
-{
- struct intel_batchbuffer *batch;
- drm_intel_bo *bo;
-
- batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
- igt_assert(batch);
-
- bo = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle);
- igt_assert(bo);
-
- /* add relocs to make sure the kernel will think we write to dst */
- BEGIN_BATCH(4, 1);
- OUT_BATCH(MI_BATCH_BUFFER_END);
- OUT_BATCH(MI_NOOP);
- OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
- OUT_BATCH(MI_NOOP);
- ADVANCE_BATCH();
-
- intel_batchbuffer_flush_on_ring(batch, ring);
- intel_batchbuffer_free(batch);
-
- drm_intel_bo_unreference(bo);
-}
-
-static void exec_blt(data_t *data)
-{
- struct intel_batchbuffer *batch;
- int w, h, pitch, i;
-
- batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
- igt_assert(batch);
-
- w = 8192;
- h = data->busy_bo->size / (8192 * 4);
- pitch = w * 4;
-
- for (i = 0; i < 40; i++) {
- BLIT_COPY_BATCH_START(0);
- OUT_BATCH((3 << 24) | /* 32 bits */
- (0xcc << 16) | /* copy ROP */
- pitch);
- OUT_BATCH(0 << 16 | 0);
- OUT_BATCH(h << 16 | w);
- OUT_RELOC_FENCED(data->busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
- OUT_BATCH(0 << 16 | 0);
- OUT_BATCH(pitch);
- OUT_RELOC_FENCED(data->busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
- ADVANCE_BATCH();
- }
-
- intel_batchbuffer_flush(batch);
- intel_batchbuffer_free(batch);
-}
-
-static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
- unsigned int usec, void *_data)
-{
- data_t *data = _data;
-
- data->flip_done = true;
-}
-
-static void wait_for_flip(data_t *data, uint32_t flip_handle)
-{
- struct timeval timeout = {
- .tv_sec = 3,
- .tv_usec = 0,
- };
- drmEventContext evctx = {
- .version = 2,
- .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_lte(0, ret);
-
- 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 void
-test_plane(data_t *data, igt_output_t *output, enum pipe pipe, int 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);
-
- primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
- 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,
- LOCAL_DRM_FORMAT_MOD_NONE,
- 1.0, 0.0, 0.0,
- &red_fb);
- igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
- DRM_FORMAT_XRGB8888,
- LOCAL_DRM_FORMAT_MOD_NONE,
- 0.0, 1.0, 0.0,
- &green_fb);
- igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
- DRM_FORMAT_XRGB8888,
- LOCAL_DRM_FORMAT_MOD_NONE,
- 0.0, 0.0, 1.0,
- &blue_fb);
-
- /*
- * Make sure these buffers are suited for display use
- * because most of the modeset operations must be fast
- * later on.
- */
- igt_plane_set_fb(primary, &blue_fb);
- igt_display_commit(&data->display);
- igt_plane_set_fb(sprite, &green_fb);
- igt_display_commit(&data->display);
- igt_plane_set_fb(sprite, NULL);
- igt_display_commit(&data->display);
-
- if (data->pipe_crc)
- igt_pipe_crc_free(data->pipe_crc);
- data->pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
-
- /* set red fb and grab reference crc */
- igt_plane_set_fb(primary, &red_fb);
- igt_display_commit(&data->display);
- igt_pipe_crc_collect_crc(data->pipe_crc, &ref_crc);
-
- ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id,
- blue_fb.fb_id, 0, 0, &output->id, 1,
- mode);
- igt_assert_eq(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_eq(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_eq(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_eq(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_eq(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_crc_equal(&ref_crc, &crc);
-}
-
-/*
- * 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 void
-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);
-
- 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,
- LOCAL_DRM_FORMAT_MOD_NONE,
- 1.0, 0.0, 0.0,
- &red_fb);
- igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1,
- DRM_FORMAT_XRGB8888,
- LOCAL_DRM_FORMAT_MOD_NONE,
- 0.0, 0.0, 1.0,
- &blue_fb);
- igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1,
- DRM_FORMAT_XRGB8888,
- LOCAL_DRM_FORMAT_MOD_NONE,
- 0.0, 1.0, 0.0,
- &green_fb);
-
- /*
- * Make sure these buffers are suited for display use
- * because most of the modeset operations must be fast
- * later on.
- */
- igt_plane_set_fb(primary, &green_fb);
- igt_display_commit(&data->display);
- igt_plane_set_fb(primary, &blue_fb);
- igt_display_commit(&data->display);
-
- if (data->pipe_crc)
- igt_pipe_crc_free(data->pipe_crc);
- data->pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
-
- /* set red fb and grab reference crc */
- igt_plane_set_fb(primary, &red_fb);
- igt_display_commit(&data->display);
- igt_pipe_crc_collect_crc(data->pipe_crc, &ref_crc);
-
- /*
- * Further down we need to issue an mmio flip w/o the kernel
- * waiting for vblank. The easiest way is to just pan within
- * the same FB. So pan away a bit here, and later we undo this
- * with another pan which will result in the desired mmio flip.
- */
- ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id,
- green_fb.fb_id, 0, 1, &output->id, 1,
- mode);
- igt_assert_eq(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_eq(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_eq(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_eq(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_crc_equal(&ref_crc, &crc);
-}
-
-static void
-run_plane_test(data_t *data)
-{
- igt_output_t *output;
- int plane = 1; /* testing with one sprite is enough */
- int valid_tests = 0;
- enum pipe pipe;
-
- for_each_pipe_with_valid_output(&data->display, pipe, output) {
- igt_require(data->display.pipes[pipe].n_planes > 2);
-
- test_plane(data, output, pipe, plane);
- valid_tests++;
- }
-
- igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
-}
-
-static void
-run_crtc_test(data_t *data)
-{
- igt_output_t *output;
- int valid_tests = 0;
- enum pipe pipe;
-
- for_each_pipe_with_valid_output(&data->display, pipe, output) {
- test_crtc(data, output, pipe);
- valid_tests++;
- }
-
- igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
-}
-
-static data_t data;
-
-igt_main
-{
- igt_skip_on_simulation();
-
- igt_fixture {
- data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
-
- kmstest_set_vt_graphics_mode();
-
- data.devid = intel_get_drm_devid(data.drm_fd);
-
- igt_require_pipe_crc(data.drm_fd);
- igt_display_init(&data.display, data.drm_fd);
-
- data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096);
- igt_assert(data.bufmgr);
- drm_intel_bufmgr_gem_enable_reuse(data.bufmgr);
-
- data.busy_bo = drm_intel_bo_alloc(data.bufmgr, "bo",
- 64*1024*1024, 4096);
- gem_set_tiling(data.drm_fd, data.busy_bo->handle, 0, 4096);
- }
-
- igt_subtest_f("setplane_vs_cs_flip")
- run_plane_test(&data);
-
- igt_subtest_f("setcrtc_vs_cs_flip")
- run_crtc_test(&data);
-
- igt_fixture {
- drm_intel_bo_unreference(data.busy_bo);
- drm_intel_bufmgr_destroy(data.bufmgr);
- igt_display_fini(&data.display);
- }
-}
diff --git a/tests/meson.build b/tests/meson.build
index 015afa47..1f00fc4f 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -170,7 +170,6 @@ test_progs = [
'kms_invalid_dotclock',
'kms_legacy_colorkey',
'kms_mmap_write_crc',
- 'kms_mmio_vs_cs_flip',
'kms_panel_fitting',
'kms_pipe_b_c_ivb',
'kms_pipe_crc_basic',