summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>2021-12-06 17:01:59 +0800
committerRodrigo Siqueira <Rodrigo.Siqueira@amd.com>2021-12-07 10:20:49 -0500
commit8f5c265e388555b5a0d84f545d31440a0a8db62b (patch)
tree7820c9602d666a18ff5917f560cf4a3bccefd4fc
parent90fa64c8267ac4db4c7cdd8955da0bb14d818152 (diff)
tests/amdgpu: Add MPO swizzle mode toggle test
Sequence captured on ChromeOS - we experience underflow when toggling between swizzle modes on the primary plane with MPO enabled. Add a new subtest replicating that sequence, "mpo-swizzle-toggle". Converts the existing framework over to the new multi-display framework since that's the configuration where this was found. Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
-rw-r--r--tests/amdgpu/amd_plane.c260
1 files changed, 217 insertions, 43 deletions
diff --git a/tests/amdgpu/amd_plane.c b/tests/amdgpu/amd_plane.c
index 64273330f..09fd3b085 100644
--- a/tests/amdgpu/amd_plane.c
+++ b/tests/amdgpu/amd_plane.c
@@ -21,56 +21,153 @@
*/
#include "igt.h"
+#include "libdrm/amdgpu.h"
+#include "libdrm/amdgpu_drm.h"
+
+/* Maximum pipes on any AMD ASIC. */
+#define MAX_PIPES 6
/* Common test data. */
typedef struct data {
- igt_display_t display;
- igt_plane_t *primary;
- igt_plane_t *overlay;
- igt_output_t *output;
- igt_pipe_t *pipe;
- igt_pipe_crc_t *pipe_crc;
- drmModeModeInfo *mode;
- enum pipe pipe_id;
- int fd;
- int w;
- int h;
+ igt_display_t display;
+ igt_plane_t *primary[MAX_PIPES];
+ igt_plane_t *cursor[MAX_PIPES];
+ igt_plane_t *overlay[MAX_PIPES];
+ igt_output_t *output[MAX_PIPES];
+ igt_pipe_t *pipe[MAX_PIPES];
+ igt_pipe_crc_t *pipe_crc[MAX_PIPES];
+ drmModeModeInfo mode[MAX_PIPES];
+ enum pipe pipe_id[MAX_PIPES];
+ int w[MAX_PIPES];
+ int h[MAX_PIPES];
+ int fd;
} data_t;
+static const drmModeModeInfo test_mode_1 = {
+ .name = "1920x1080 Test",
+ .vrefresh = 60,
+ .clock = 148500,
+ .hdisplay = 1920,
+ .hsync_start = 2008,
+ .hsync_end = 2052,
+ .htotal = 2200,
+ .vdisplay = 1080,
+ .vsync_start = 1084,
+ .vsync_end = 1089,
+ .vtotal = 1125,
+ .type = 0x40,
+ .flags = DRM_MODE_FLAG_NHSYNC,
+ .hskew = 0,
+ .vscan = 0,
+};
+
+static const drmModeModeInfo test_mode_2 = {
+ .name = "1280x1024 Test",
+ .vrefresh = 60,
+ .clock = 148500,
+ .hdisplay = 1280,
+ .hsync_start = 2008,
+ .hsync_end = 2052,
+ .htotal = 2200,
+ .vdisplay = 1024,
+ .vsync_start = 1084,
+ .vsync_end = 1089,
+ .vtotal = 1125,
+ .type = DRM_MODE_TYPE_DRIVER,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .hskew = 0,
+ .vscan = 0,
+};
+
static void test_init(data_t *data)
{
igt_display_t *display = &data->display;
+ int i, n, max_pipes = display->n_pipes;
+
+ for (i = 0; i < max_pipes; ++i) {
+ data->pipe_id[i] = PIPE_A + i;
+ data->pipe[i] = &data->display.pipes[data->pipe_id[i]];
+ data->primary[i] = igt_pipe_get_plane_type(
+ data->pipe[i], DRM_PLANE_TYPE_PRIMARY);
+ data->overlay[i] = igt_pipe_get_plane_type_index(
+ data->pipe[i], DRM_PLANE_TYPE_OVERLAY, 0);
+ data->cursor[i] = igt_pipe_get_plane_type(
+ data->pipe[i], DRM_PLANE_TYPE_CURSOR);
+ data->pipe_crc[i] =
+ igt_pipe_crc_new(data->fd, data->pipe_id[i], "auto");
+ }
+
+ for (i = 0, n = 0; i < display->n_outputs && n < max_pipes; ++i) {
+ igt_output_t *output = &display->outputs[i];
+
+ data->output[n] = output;
+
+ /* Only allow physically connected displays for the tests. */
+ if (!igt_output_is_connected(output))
+ continue;
- /* It doesn't matter which pipe we choose on amdpgu. */
- data->pipe_id = PIPE_A;
- data->pipe = &data->display.pipes[data->pipe_id];
+ igt_assert(kmstest_get_connector_default_mode(
+ data->fd, output->config.connector, &data->mode[n]));
+ data->w[n] = data->mode[n].hdisplay;
+ data->h[n] = data->mode[n].vdisplay;
+
+ n += 1;
+ }
+
+ igt_require(data->output[0]);
igt_display_reset(display);
+}
- data->output = igt_get_single_output_for_pipe(display, data->pipe_id);
- igt_require(data->output);
+static void test_fini(data_t *data)
+{
+ igt_display_t *display = &data->display;
+ int i, max_pipes = display->n_pipes;
- data->mode = igt_output_get_mode(data->output);
- igt_assert(data->mode);
+ for (i = 0; i < max_pipes; ++i) {
+ igt_pipe_crc_free(data->pipe_crc[i]);
+ }
- data->primary =
- igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_PRIMARY);
- data->overlay =
- igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_OVERLAY);
+ igt_display_reset(display);
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
+}
- data->pipe_crc = igt_pipe_crc_new(data->fd, data->pipe_id,
- INTEL_PIPE_CRC_SOURCE_AUTO);
+/* Forces a mode for a connector. */
+static void force_output_mode(data_t *data, igt_output_t *output,
+ drmModeModeInfo const *mode)
+{
+ /* This allows us to create a virtual sink. */
+ if (!igt_output_is_connected(output)) {
+ kmstest_force_edid(data->fd, output->config.connector,
+ igt_kms_get_4k_edid());
- igt_output_set_pipe(data->output, data->pipe_id);
+ kmstest_force_connector(data->fd, output->config.connector,
+ FORCE_CONNECTOR_DIGITAL);
+ }
- data->w = data->mode->hdisplay;
- data->h = data->mode->vdisplay;
+ igt_output_override_mode(output, mode);
}
-static void test_fini(data_t *data)
+
+static int set_metadata(data_t *data, igt_fb_t *fb, struct amdgpu_bo_metadata *info)
{
- igt_pipe_crc_free(data->pipe_crc);
- igt_display_reset(&data->display);
+ struct drm_amdgpu_gem_metadata args = {};
+
+ args.handle = fb->gem_handle;
+ args.op = AMDGPU_GEM_METADATA_OP_SET_METADATA;
+ args.data.flags = info->flags;
+ args.data.tiling_info = info->tiling_info;
+
+ if (info->size_metadata > sizeof(args.data.data))
+ return -EINVAL;
+
+ if (info->size_metadata) {
+ args.data.data_size_bytes = info->size_metadata;
+ memcpy(args.data.data, info->umd_metadata, info->size_metadata);
+ }
+
+ return drmCommandWriteRead(data->fd, DRM_AMDGPU_GEM_METADATA, &args,
+ sizeof(args));
}
static void draw_color_alpha(igt_fb_t *fb, int x, int y, int w, int h,
@@ -91,36 +188,38 @@ static void test_mpo_4k(data_t *data)
igt_crc_t ref_crc, new_crc;
igt_display_t *display = &data->display;
int cutout_x, cutout_y, cutout_w, cutout_h;
+ int w, h;
test_init(data);
/* Skip if not 4K resolution. */
- igt_skip_on(!(data->mode->hdisplay == 3840 &&
- data->mode->vdisplay == 2160));
+ igt_skip_on(!(data->mode[0].hdisplay == 3840
+ && data->mode[0].vdisplay == 2160));
+ w = data->w[0];
+ h = data->h[0];
cutout_x = cutout_w = 1280;
cutout_y = cutout_h = 720;
- igt_create_color_fb(data->fd, data->w, data->h, DRM_FORMAT_XRGB8888,
- 0, 1.00, 1.00, 1.00, &r_fb);
- igt_create_color_fb(data->fd, data->w, data->h, DRM_FORMAT_XRGB8888,
- 0, 1.00, 1.00, 1.00, &p_fb);
- igt_create_fb(data->fd, data->w, data->h, DRM_FORMAT_ARGB8888,
- 0, &o_fb);
+ igt_create_color_fb(data->fd, w, h, DRM_FORMAT_XRGB8888, 0, 1.00, 1.00,
+ 1.00, &r_fb);
+ igt_create_color_fb(data->fd, w, h, DRM_FORMAT_XRGB8888, 0, 1.00, 1.00,
+ 1.00, &p_fb);
+ igt_create_fb(data->fd, w, h, DRM_FORMAT_ARGB8888, 0, &o_fb);
draw_color_alpha(&o_fb, 0, 0, o_fb.width, o_fb.height, 1.00, 1.00, 1.00, 1.00);
draw_color_alpha(&o_fb, cutout_x, cutout_y, cutout_w, cutout_h,
0.00, 0.00, 0.00, 0.00);
- igt_plane_set_fb(data->primary, &r_fb);
+ igt_plane_set_fb(data->primary[0], &r_fb);
igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
- igt_pipe_crc_collect_crc(data->pipe_crc, &ref_crc);
+ igt_pipe_crc_collect_crc(data->pipe_crc[0], &ref_crc);
- igt_plane_set_fb(data->primary, &p_fb);
- igt_plane_set_fb(data->overlay, &o_fb);
+ igt_plane_set_fb(data->primary[0], &p_fb);
+ igt_plane_set_fb(data->overlay[0], &o_fb);
igt_display_commit_atomic(display, 0, NULL);
- igt_pipe_crc_collect_crc(data->pipe_crc, &new_crc);
+ igt_pipe_crc_collect_crc(data->pipe_crc[0], &new_crc);
igt_assert_crc_equal(&ref_crc, &new_crc);
@@ -130,6 +229,80 @@ static void test_mpo_4k(data_t *data)
igt_remove_fb(data->fd, &r_fb);
}
+static void test_mpo_swizzle_toggle(data_t *data)
+{
+ struct amdgpu_bo_metadata meta = {};
+ igt_display_t *display = &data->display;
+ igt_fb_t fb_1280_xr24_tiled, fb_1280_ar24_tiled, fb_1920_xb24_tiled,
+ fb_1920_xb24_linear, fb_1920_xr24_tiled;
+ int w, h;
+
+ w = 2400;
+ h = 1350;
+
+ igt_create_pattern_fb(data->fd, 1280, 1024, DRM_FORMAT_XRGB8888, 0,
+ &fb_1280_xr24_tiled);
+ igt_create_pattern_fb(data->fd, 1280, 1024, DRM_FORMAT_ARGB8888, 0,
+ &fb_1280_ar24_tiled);
+ igt_create_pattern_fb(data->fd, 1920, 1080, DRM_FORMAT_XBGR8888, 0,
+ &fb_1920_xb24_tiled);
+ igt_create_pattern_fb(data->fd, 1920, 1080, DRM_FORMAT_XBGR8888, 0,
+ &fb_1920_xb24_linear);
+ igt_create_pattern_fb(data->fd, 1920, 1080, DRM_FORMAT_XRGB8888, 0,
+ &fb_1920_xr24_tiled);
+
+ meta.tiling_info = AMDGPU_TILING_SET(SWIZZLE_MODE, 0x19);
+ set_metadata(data, &fb_1280_xr24_tiled, &meta);
+
+ meta.tiling_info = AMDGPU_TILING_SET(SWIZZLE_MODE, 0x19);
+ set_metadata(data, &fb_1280_ar24_tiled, &meta);
+
+ meta.tiling_info = AMDGPU_TILING_SET(SWIZZLE_MODE, 0x19);
+ set_metadata(data, &fb_1920_xb24_tiled, &meta);
+
+ meta.tiling_info = AMDGPU_TILING_SET(SWIZZLE_MODE, 0x19);
+ set_metadata(data, &fb_1920_xr24_tiled, &meta);
+
+ test_init(data);
+
+ /* Initial modeset */
+ igt_output_set_pipe(data->output[0], data->pipe_id[0]);
+ igt_output_set_pipe(data->output[1], data->pipe_id[1]);
+ force_output_mode(data, data->output[0], &test_mode_1);
+ force_output_mode(data, data->output[1], &test_mode_2);
+
+ igt_plane_set_fb(data->primary[0], &fb_1920_xr24_tiled);
+ igt_plane_set_fb(data->primary[1], &fb_1920_xb24_linear);
+ igt_plane_set_size(data->primary[1], w, h);
+
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
+
+ /* Enable overlay plane. */
+ igt_plane_set_fb(data->overlay[1], &fb_1280_ar24_tiled);
+ igt_plane_set_fb(data->primary[1], &fb_1920_xb24_linear);
+ igt_plane_set_size(data->primary[1], w, h);
+ igt_display_commit_atomic(display, 0, 0);
+
+ /* Switch to tiled. */
+ igt_plane_set_fb(data->overlay[1], &fb_1280_ar24_tiled);
+ igt_plane_set_fb(data->primary[1], &fb_1920_xb24_tiled);
+ igt_plane_set_size(data->primary[1], w, h);
+ igt_display_commit_atomic(display, 0, 0);
+
+ /* Switch to linear. */
+ igt_plane_set_fb(data->overlay[1], &fb_1280_ar24_tiled);
+ igt_plane_set_fb(data->primary[1], &fb_1920_xb24_linear);
+ igt_plane_set_size(data->primary[1], w, h);
+ igt_display_commit_atomic(display, 0, 0);
+
+ test_fini(data);
+ igt_remove_fb(data->fd, &fb_1280_xr24_tiled);
+ igt_remove_fb(data->fd, &fb_1280_ar24_tiled);
+ igt_remove_fb(data->fd, &fb_1920_xb24_tiled);
+ igt_remove_fb(data->fd, &fb_1920_xb24_linear);
+ igt_remove_fb(data->fd, &fb_1920_xr24_tiled);
+}
+
igt_main
{
data_t data;
@@ -150,6 +323,7 @@ igt_main
}
igt_subtest("test-mpo-4k") test_mpo_4k(&data);
+ igt_subtest("mpo-swizzle-toggle") test_mpo_swizzle_toggle(&data);
igt_fixture
{