summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/kms_flip_tiling.c230
1 files changed, 184 insertions, 46 deletions
diff --git a/tests/kms_flip_tiling.c b/tests/kms_flip_tiling.c
index 83455058..c7fd4de2 100644
--- a/tests/kms_flip_tiling.c
+++ b/tests/kms_flip_tiling.c
@@ -35,8 +35,7 @@
#include "ioctl_wrappers.h"
#include "intel_chipset.h"
-IGT_TEST_DESCRIPTION("Test that a page flip from a tiled buffer to a linear"
- " one works correctly.");
+IGT_TEST_DESCRIPTION("Test page flips and tiling scenarios");
typedef struct {
int drm_fd;
@@ -44,16 +43,8 @@ typedef struct {
int gen;
} 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)
+fill_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode)
{
cairo_t *cr;
@@ -62,67 +53,124 @@ fill_linear_fb(struct igt_fb *fb, data_t *data, drmModeModeInfo *mode)
cairo_destroy(cr);
}
+static igt_pipe_crc_t *_pipe_crc;
+
+static igt_pipe_crc_t *pipe_crc_new(int pipe)
+{
+ if (_pipe_crc) {
+ igt_pipe_crc_free(_pipe_crc);
+ _pipe_crc = NULL;
+ }
+
+ _pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+ igt_assert(_pipe_crc);
+
+ return _pipe_crc;
+}
+
+static void pipe_crc_free(void)
+{
+ if (_pipe_crc) {
+ igt_pipe_crc_free(_pipe_crc);
+ _pipe_crc = NULL;
+ }
+}
+
+static void wait_for_pageflip(int fd)
+{
+ drmEventContext evctx = { .version = DRM_EVENT_CONTEXT_VERSION };
+ struct timeval timeout = { .tv_sec = 0, .tv_usec = 32000 };
+ fd_set fds;
+ int ret;
+
+ /* Wait for pageflip completion, then consume event on fd */
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ do {
+ ret = select(fd + 1, &fds, NULL, NULL, &timeout);
+ } while (ret < 0 && errno == EINTR);
+ igt_assert_eq(ret, 1);
+ igt_assert(drmHandleEvent(fd, &evctx) == 0);
+}
+
static void
-test_flip_changes_tiling(data_t *data, igt_output_t *output, uint64_t tiling)
+test_flip_tiling(data_t *data, igt_output_t *output, uint64_t tiling[2])
{
- struct igt_fb linear, tiled;
drmModeModeInfo *mode;
igt_plane_t *primary;
+ struct igt_fb fb[2];
igt_pipe_crc_t *pipe_crc;
igt_crc_t reference_crc, crc;
int fb_id, pipe, ret, width;
pipe = output->config.pipe;
- pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+ pipe_crc = pipe_crc_new(pipe);
igt_output_set_pipe(output, pipe);
mode = igt_output_get_mode(output);
primary = igt_output_get_plane(output, 0);
- /* Allocate a linear buffer. Since a page flip to a buffer with
- * different stride doesn't work, choose width so that the stride of
- * both buffers is the same. */
- width = 512;
- while (width < mode->hdisplay)
- width *= 2;
+ width = mode->hdisplay;
+
+ if (tiling[0] != tiling[1] &&
+ (tiling[0] != LOCAL_DRM_FORMAT_MOD_NONE ||
+ tiling[1] != LOCAL_DRM_FORMAT_MOD_NONE)) {
+ /*
+ * 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, LOCAL_DRM_FORMAT_MOD_NONE,
- &linear);
+ DRM_FORMAT_XRGB8888, tiling[0],
+ &fb[0]);
+ igt_assert(fb_id);
+
+ /* Second fb has different background so CRC does not match. */
+ fb_id = igt_create_color_fb(data->drm_fd, width, mode->vdisplay,
+ DRM_FORMAT_XRGB8888, tiling[1],
+ 0.5, 0.5, 0.5, &fb[1]);
+ igt_assert(fb_id);
- /* fill it with a pattern that will look wrong if tiling is wrong */
- fill_linear_fb(&linear, data, mode);
+ fill_fb(&fb[0], data, mode);
+ fill_fb(&fb[1], data, mode);
- /* set the crtc and generate a reference crc */
- igt_plane_set_fb(primary, &linear);
+ /* Set the crtc and generate a reference CRC. */
+ igt_plane_set_fb(primary, &fb[1]);
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, tiling,
- 0.0, 0.0, 0.0, &tiled);
- igt_plane_set_fb(primary, &tiled);
+ /* Commit the first fb. */
+ igt_plane_set_fb(primary, &fb[0]);
igt_display_commit(&data->display);
- /* flip to the linear buffer */
+ /* Flip to the second fb. */
ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id,
- fb_id, 0, NULL);
- igt_assert_eq(ret, 0);
+ fb[1].fb_id, DRM_MODE_PAGE_FLIP_EVENT, NULL);
+ /*
+ * Page flip should work but some transitions may be temporarily
+ * on some kernels.
+ */
+ igt_require(ret == 0);
- igt_wait_for_vblank(data->drm_fd, pipe);
+ wait_for_pageflip(data->drm_fd);
- /* get a crc and compare with the reference */
+ /* Get a crc and compare with the reference. */
igt_pipe_crc_collect_crc(pipe_crc, &crc);
igt_assert_crc_equal(&reference_crc, &crc);
- /* clean up */
+ /* Clean up. */
igt_plane_set_fb(primary, NULL);
- igt_pipe_crc_free(pipe_crc);
+ pipe_crc_free();
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);
+ igt_remove_fb(data->drm_fd, &fb[0]);
+ igt_remove_fb(data->drm_fd, &fb[1]);
}
static data_t data;
@@ -142,28 +190,118 @@ igt_main
igt_display_init(&data.display, data.drm_fd);
}
+ /*
+ * 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
+ * generates 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 reference one.
+ */
+
igt_subtest_f("flip-changes-tiling") {
+ uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_X_TILED,
+ LOCAL_DRM_FORMAT_MOD_NONE };
+
for_each_connected_output(&data.display, output)
- test_flip_changes_tiling(&data, output,
- LOCAL_I915_FORMAT_MOD_X_TILED);
+ test_flip_tiling(&data, output, tiling);
}
igt_subtest_f("flip-changes-tiling-Y") {
+ uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Y_TILED,
+ LOCAL_DRM_FORMAT_MOD_NONE };
+
igt_require_fb_modifiers(data.drm_fd);
igt_require(data.gen >= 9);
for_each_connected_output(&data.display, output)
- test_flip_changes_tiling(&data, output,
- LOCAL_I915_FORMAT_MOD_Y_TILED);
+ test_flip_tiling(&data, output, tiling);
}
igt_subtest_f("flip-changes-tiling-Yf") {
+ uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Yf_TILED,
+ LOCAL_DRM_FORMAT_MOD_NONE };
+
+ igt_require_fb_modifiers(data.drm_fd);
+ igt_require(data.gen >= 9);
+
+ for_each_connected_output(&data.display, output)
+ test_flip_tiling(&data, output, tiling);
+ }
+
+ /*
+ * Test that a page flip from a tiled buffer to another tiled one works
+ * correctly. First, it sets the crtc with the tiled buffer and
+ * generates a reference crc for the pipe. Then a page flip to second
+ * tiled buffer is issued. A new crc is generated and compared to the
+ * reference one.
+ */
+
+ igt_subtest_f("flip-X-tiled") {
+ uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_X_TILED,
+ LOCAL_I915_FORMAT_MOD_X_TILED };
+
+ for_each_connected_output(&data.display, output)
+ test_flip_tiling(&data, output, tiling);
+ }
+
+ igt_subtest_f("flip-Y-tiled") {
+ uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Y_TILED,
+ LOCAL_I915_FORMAT_MOD_Y_TILED };
+
+ igt_require_fb_modifiers(data.drm_fd);
+ igt_require(data.gen >= 9);
+
+ for_each_connected_output(&data.display, output)
+ test_flip_tiling(&data, output, tiling);
+ }
+
+ igt_subtest_f("flip-Yf-tiled") {
+ uint64_t tiling[2] = { LOCAL_I915_FORMAT_MOD_Yf_TILED,
+ LOCAL_I915_FORMAT_MOD_Yf_TILED };
+
+ igt_require_fb_modifiers(data.drm_fd);
+ igt_require(data.gen >= 9);
+
+ for_each_connected_output(&data.display, output)
+ test_flip_tiling(&data, output, tiling);
+ }
+
+ /*
+ * Test that a page flip from a linear buffer to a tiled one works
+ * correctly. First, it sets the crtc with the linear buffer and
+ * generates a reference crc for the pipe. Then a page flip to a tiled
+ * buffer is issued. A new crc is generated and compared to the
+ * reference one.
+ */
+
+ igt_subtest_f("flip-to-X-tiled") {
+ uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE,
+ LOCAL_I915_FORMAT_MOD_X_TILED };
+
+ for_each_connected_output(&data.display, output)
+ test_flip_tiling(&data, output, tiling);
+ }
+
+ igt_subtest_f("flip-to-Y-tiled") {
+ uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE,
+ LOCAL_I915_FORMAT_MOD_Y_TILED };
+
+ igt_require_fb_modifiers(data.drm_fd);
+ igt_require(data.gen >= 9);
+
+ for_each_connected_output(&data.display, output)
+ test_flip_tiling(&data, output, tiling);
+ }
+
+ igt_subtest_f("flip-to-Yf-tiled") {
+ uint64_t tiling[2] = { LOCAL_DRM_FORMAT_MOD_NONE,
+ LOCAL_I915_FORMAT_MOD_Yf_TILED };
+
igt_require_fb_modifiers(data.drm_fd);
igt_require(data.gen >= 9);
for_each_connected_output(&data.display, output)
- test_flip_changes_tiling(&data, output,
- LOCAL_I915_FORMAT_MOD_Yf_TILED);
+ test_flip_tiling(&data, output, tiling);
}
igt_fixture {