[PATCH i-g-t v3] tests/amdgpu: Add test for native cursor fallback to overlay
Leo Li
sunpeng.li at amd.com
Thu Aug 21 18:28:19 UTC 2025
On 2025-07-23 13:27, IVAN.LIPSKI at amd.com wrote:
> From: Ivan Lipski <ivan.lipski at amd.com>
>
> [Why & How]
> The AMD display hardware does not use dedicated cursor planes.
> Instead, the cursor is rendered either using the primary plane
> or an available overlay plane. This test verifies that the
> cursor correctly falls back from native to overlay mode
> when the underneath primary plane is incompatible. It also tests
The last sentence seems like a typo?
>
> It has 5 subtests:
>
> rgb-to-yuv
> Switches the primary plane to a NV12 format FB and verifies that
> the cursor falls back from native to overlay.
>
> non-full
> Switches the primary planeto a FB that does not fill the entire CRTC
> (currently sized at a quarter of the CRTC).
>
> scaling-[50,75,125,150,175,200]
> Switches the primary plane to a FB with a chosen scaling (50%-200%), which
> is then filled in the CRTC.
>
> max-planes
> Enables 2 overlay planes, a primary plane and a cursor. Then
> switches the primary plane to YUV to cause the cursor to fall back to
> overlay. Verifies that the cursor can still fallback to overlay when 4
> planes are enabled.
>
> no-available-planes
> Enables 3 available overlay planes, a primary plane and a cursor. Then
> switches the primary plane to YUV to cause the cursor to fall back to
> overlay. Verifies that the atomic commit fails due to no available overlay
> planes.
>
> Signed-off-by: Ivan Lipski <ivan.lipski at amd.com>
> ---
> tests/amdgpu/amd_cursor_overlay.c | 484 ++++++++++++++++++++++++++++++
> tests/amdgpu/meson.build | 1 +
> 2 files changed, 485 insertions(+)
> create mode 100644 tests/amdgpu/amd_cursor_overlay.c
>
> diff --git a/tests/amdgpu/amd_cursor_overlay.c b/tests/amdgpu/amd_cursor_overlay.c
> new file mode 100644
> index 000000000..cf5ea83a0
> --- /dev/null
> +++ b/tests/amdgpu/amd_cursor_overlay.c
> @@ -0,0 +1,484 @@
> +// SPDX-License-Identifier: MIT
> +// Copyright 2025 Advanced Micro Devices, Inc.
> +
> +#include "igt.h"
> +#include "igt_kms.h"
> +
> +/**
> + * TEST: amd_cursor_overlay
> + * Category: Display
> + * Description: Tests cursor fall back from native to overlay
> + * Driver requirement: amdgpu
> + */
> +
> +/**
> + * SUBTEST: rgb-to-yuv
> + * Description: Tests native cursor fall back to overlay cursor when a top plane
> + * switches from RGB to YUV.
> + * SUBTEST: non-full
> + * Description: Tests native cursor fall back to overlay cursor when a top plane
> + * does not fill the crtc.
> + * SUBTEST: scaling-%d
> + * Description: Tests native cursor fall back to overlay cursor when a top plane
> + * is scaled.
> + *
> + * arg[1].values: 50, 75, 125, 150, 175, 200
> + *
> + * SUBTEST: max-planes
> + * Description: Tests native cursor fall back to overlay cursor when a top plane
> + * is YUV and there are two overlay planes used.
> + *
> + * SUBTEST: no-available-planes
> + * Description: Tests native cursor attempt to fall back to overlay cursor required,
> + * but fails atomic commit due to no available overlay planes.
> + */
> +
> +enum {
> + TEST_YUV = 1,
> + TEST_QUARTER_FB = 1 << 1,
> + TEST_SCALING = 1 << 2,
> + TEST_MAX_PLANES = 1 << 3,
> + TEST_NO_PLANES = 1 << 4,
nit: to avoid confusion, s/NO_PLANES/NO_AVAILABLE_PLANES
> +};
> +
> +typedef struct {
> + int x;
> + int y;
> +} pos_t;
> +
> +/* Common test data. */
> +typedef struct data {
> + igt_display_t display;
> + igt_plane_t *primary;
> + igt_plane_t *cursor;
> + igt_plane_t *overlay1;
> + igt_plane_t *overlay2;
> + igt_plane_t *overlay3;
> + igt_output_t *output;
> + igt_pipe_t *pipe;
> + igt_pipe_crc_t *pipe_crc;
> + drmModeModeInfo *mode;
> + igt_fb_t rgb_fb;
> + igt_fb_t yuv_fb;
> + igt_fb_t rgb_fb_o1;
> + igt_fb_t rgb_fb_o2;
> + igt_fb_t rgb_fb_o3;
> + igt_fb_t quarter_fb;
> + igt_fb_t scale_fb;
> + igt_fb_t cfb;
> + enum pipe pipe_id;
> + int drm_fd;
> + uint64_t max_curw;
> + uint64_t max_curh;
> +} data_t;
> +
> +/* Retuns the number of available overlay planes */
> +static int get_overlay_planes_count(igt_display_t *display, enum pipe pipe)
> +{
> + int count = 0;
> + igt_plane_t *plane;
> +
> + for_each_plane_on_pipe(display, pipe, plane)
> + if (plane->type == DRM_PLANE_TYPE_OVERLAY)
> + count++;
> +
> + return count;
> +}
> +
> +/* Common test setup. */
> +static void test_init(data_t *data, enum pipe pipe_id, igt_output_t *output,
> + unsigned int flags)
> +{
> + data->pipe_id = pipe_id;
> + data->pipe = &data->display.pipes[data->pipe_id];
> + data->output = output;
> + data->mode = igt_output_get_mode(data->output);
> + data->primary = igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_PRIMARY);
> + data->cursor = igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_CURSOR);
> +
> + if (flags & TEST_NO_PLANES || flags & TEST_MAX_PLANES) {
> + data->overlay1 = igt_pipe_get_plane_type_index(data->pipe, DRM_PLANE_TYPE_OVERLAY, 0);
> + data->overlay2 = igt_pipe_get_plane_type_index(data->pipe, DRM_PLANE_TYPE_OVERLAY, 1);
> + }
> + if (flags & TEST_NO_PLANES)
> + data->overlay3 = igt_pipe_get_plane_type_index(data->pipe, DRM_PLANE_TYPE_OVERLAY, 2);
> +
> + igt_info("Using (pipe %s + %s) to run the subtest.\n",
> + kmstest_pipe_name(data->pipe_id), igt_output_name(data->output));
> +
> + igt_require_pipe_crc(data->drm_fd);
> + data->pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe_id,
> + IGT_PIPE_CRC_SOURCE_AUTO);
> +}
> +
> +/* Common test finish. */
> +static void test_fini(data_t *data)
> +{
> + igt_pipe_crc_free(data->pipe_crc);
> + igt_display_reset(&data->display);
> + igt_plane_set_fb(data->primary, NULL);
> + igt_plane_set_fb(data->cursor, NULL);
> + if (data->overlay1)
> + igt_plane_set_fb(data->overlay1, NULL);
> + if (data->overlay2)
> + igt_plane_set_fb(data->overlay2, NULL);
> + if (data->overlay3)
> + igt_plane_set_fb(data->overlay3, NULL);
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +}
> +
> +/* Common test cleanup. */
> +static void test_cleanup(data_t *data)
> +{
> + igt_remove_fb(data->drm_fd, &data->cfb);
> + igt_remove_fb(data->drm_fd, &data->rgb_fb);
> + igt_remove_fb(data->drm_fd, &data->yuv_fb);
> + if (data->overlay1)
> + igt_remove_fb(data->drm_fd, &data->rgb_fb_o1);
> + if (data->overlay2)
> + igt_remove_fb(data->drm_fd, &data->rgb_fb_o2);
> + if (data->overlay3)
> + igt_remove_fb(data->drm_fd, &data->rgb_fb_o3);
> + igt_remove_fb(data->drm_fd, &data->quarter_fb);
> + igt_remove_fb(data->drm_fd, &data->scale_fb);
> +}
> +
> +
> +static void test_cursor_pos(data_t *data, int x, int y, unsigned int flags, unsigned int scaling_factor)
> +{
> + igt_crc_t ref_crc, test_crc;
> + cairo_t *cr;
> + igt_fb_t *rgb_fb = &data->rgb_fb;
> + igt_fb_t *yuv_fb = &data->yuv_fb;
> + igt_fb_t *quarter_fb = &data->quarter_fb;
> + igt_fb_t *rgb_fb_o1 = &data->rgb_fb_o1;
> + igt_fb_t *rgb_fb_o2 = &data->rgb_fb_o2;
> + igt_fb_t *rgb_fb_o3 = &data->rgb_fb_o3;
> + igt_fb_t *cfb = &data->cfb;
> + int cw = cfb->width;
> + int ch = cfb->height;
> + int ret;
> +
> +
> + cr = igt_get_cairo_ctx(rgb_fb->fd, rgb_fb);
> +
> + igt_plane_set_fb(data->primary, rgb_fb);
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> + igt_paint_color(cr, 0, 0, rgb_fb->width, rgb_fb->height, 0.0, 0.0, 0.0);
> +
> + /* Draw a magenta square where the cursor should be. */
> + igt_paint_color(cr, x, y, cw, ch, 1.0, 0.0, 1.0);
> + igt_put_cairo_ctx(cr);
> +
> + if (flags & TEST_MAX_PLANES) {
> + /* Display the overlay planes. */
> + igt_plane_set_fb(data->overlay1, rgb_fb_o1);
> + igt_plane_set_position(data->overlay1, 0, 0);
> + igt_plane_set_fb(data->overlay2, rgb_fb_o2);
> + igt_plane_set_position(data->overlay2, data->rgb_fb_o1.width, data->rgb_fb_o1.height);
> + igt_display_commit_atomic(&data->display, 0, NULL);
> +
> + /* Display the cursor. */
> + igt_plane_set_fb(data->cursor, cfb);
> + igt_plane_set_position(data->cursor, x, y);
> + igt_display_commit_atomic(&data->display, 0, NULL);
> +
> + /* Trigger cursor fall back due to a YUV plane;
> + * expect the atomic commit to fail due to no
> + * available overlay planes.
> + */
> + igt_plane_set_fb(data->primary, &data->yuv_fb);
> + ret = igt_display_try_commit_atomic(&data->display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
> +
> + /* Remove the overlay planes. */
> + igt_plane_set_fb(data->overlay1, NULL);
> + igt_plane_set_fb(data->overlay2, NULL);
> + igt_plane_set_fb(data->cursor, NULL);
> + igt_display_commit_atomic(&data->display, 0, NULL);
> +
> + /* Expected atomic commit to fail due to no available overlay planes. */
> + igt_assert_f(ret == 0, "Expected atomic commit to succeed.\n");
> + return;
> + }
> + if (flags & TEST_NO_PLANES) {
> +
> + /* Display the overlay planes. */
> + igt_plane_set_fb(data->overlay1, rgb_fb_o1);
> + igt_plane_set_position(data->overlay1, 0, 0);
> + igt_plane_set_fb(data->overlay2, rgb_fb_o2);
> + igt_plane_set_position(data->overlay2, data->rgb_fb_o1.width, data->rgb_fb_o1.height);
> + igt_plane_set_fb(data->overlay3, rgb_fb_o3);
> + igt_plane_set_position(data->overlay3, data->rgb_fb_o1.width, 0);
> + igt_display_commit_atomic(&data->display, 0, NULL);
> +
> + /* Display the cursor. */
> + igt_plane_set_fb(data->cursor, cfb);
> + igt_plane_set_position(data->cursor, x, y);
> + igt_display_commit_atomic(&data->display, 0, NULL);
> +
> + /* Trigger cursor fall back due to a YUV plane;
> + * expect the atomic commit to fail due to no
> + * available overlay planes.
> + */
> + igt_plane_set_fb(data->primary, &data->yuv_fb);
> + ret = igt_display_try_commit_atomic(&data->display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
> +
> + /* Remove the overlay planes. */
> + igt_plane_set_fb(data->overlay1, NULL);
> + igt_plane_set_fb(data->overlay2, NULL);
> + igt_plane_set_fb(data->overlay3, NULL);
> + igt_plane_set_fb(data->cursor, NULL);
> + igt_display_commit_atomic(&data->display, 0, NULL);
> +
> + /* Expected atomic commit to fail due to no available overlay planes. */
> + igt_assert_f(ret == -EINVAL, "Expected atomic commit to fail due to no available overlay planes.\n");
> + return;
> + }
Is the TEST_MAX_PLANES testing the
1 PRIMARY + 2 OVERLAY + 1 Overlay CURSOR = 4 planes scenario?
If so, atomic commit is expected to succeed, not fail.
TEST_NO_PLANES here looks correct in that regard, since amdgpu_dm would
reject 1 PRIMARY + 3 OVERLAYS + 1 Overlay CURSOR = 5 planes.
These tests would only be valid for APUs that have 4 hw planes though.
Some DGPUs have more than 4, for which these tests wouldn't make sense.
Perhaps we can programatically determine the number of OVERLAYs via
get_overlay_planes_count(), and enable the right amount (count-1 for
MAX_PLANES and count for NO_PLANES)? We should be able to use the same
fb for all of them, instead of creating a new fb for each.
> +
> + /* Display the cursor. */
> + igt_plane_set_fb(data->cursor, cfb);
> + igt_plane_set_position(data->cursor, x, y);
> + igt_display_commit_atomic(&data->display, 0, NULL);
> +
> + /** Record a reference CRC */
> + igt_pipe_crc_start(data->pipe_crc);
> + igt_pipe_crc_get_current(data->drm_fd, data->pipe_crc, &ref_crc);
> +
> + /* Switch primary plane to use YUV Fb. */
> + if (flags & TEST_YUV) {
> + igt_plane_set_fb(data->primary, yuv_fb);
> + igt_plane_set_position(data->primary, 0, 0);
> + igt_plane_set_size(data->primary, yuv_fb->width, yuv_fb->height);
> + igt_display_commit_atomic(&data->display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
> +
> + /* Switch primary plane to use a quarter-sized FB. */
> + } else if (flags & TEST_QUARTER_FB) {
> + igt_plane_set_fb(data->primary, quarter_fb);
> + igt_plane_set_position(data->primary, 0, 0);
> + igt_display_commit_atomic(&data->display, 0, NULL);
> +
> + /* Switch primary plane to use a scaled FB. */
> + } else if (flags & TEST_SCALING) {
> + igt_create_fb(data->drm_fd,
> + data->rgb_fb.width * scaling_factor / 100,
> + data->rgb_fb.height * scaling_factor / 100,
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_MOD_LINEAR, &data->scale_fb);
> +
> + igt_plane_set_fb(data->primary, &data->scale_fb);
> + igt_plane_set_position(data->primary, 0, 0);
> + igt_plane_set_size(data->primary, data->mode->hdisplay, data->mode->vdisplay);
> +
> + igt_display_commit_atomic(&data->display, 0, NULL);
> + }
> +
> + /* Wait for one more vblank since cursor updates are not
> + * synchronized to the same frame on AMD hw.
> + */
> + if (is_amdgpu_device(data->drm_fd))
> + igt_wait_for_vblank_count(data->drm_fd, data->display.pipes[data->pipe_id].crtc_offset, 1);
> +
> + /* Record the new CRC. */
> + igt_pipe_crc_get_current(data->drm_fd, data->pipe_crc, &test_crc);
> + igt_pipe_crc_stop(data->pipe_crc);
> +
> + /** CRC Check is sufficient for this test */
> + igt_assert_crc_equal(&ref_crc, &test_crc);
> +}
> +
> +/*
> + * Tests the cursor on a variety of positions on the screen.
> + * Specific edge cases that should be captured here are the negative edges
> + * of each plane and the centers.
> + */
> +static void test_cursor_spots(data_t *data, int size, unsigned int flags, unsigned int scaling_factor)
> +{
> + int sw = data->mode->hdisplay;
> + int sh = data->mode->vdisplay;
> + int i;
> + const pos_t pos[] = {
> + /* Test diagonally from top left to bottom right. */
> + { -size / 3, -size / 3 },
> + { 0, 0 },
> + { sw / 4 - size, sh / 4 - size },
> + { sw / 4 - size / 3, sh / 4 - size / 3 },
> + { sw / 4, sh / 4 },
> + { sw / 4 + size, sh / 4 + size },
> + { sw / 2, sh / 2 },
> + { sw / 4 + sw / 2 - size, sh / 4 + sh / 2 - size },
> + { sw / 4 + sw / 2 - size / 3, sh / 4 + sh / 2 - size / 3 },
> + { sw / 4 + sw / 2 + size, sh / 4 + sh / 2 + size },
> + { sw - size, sh - size },
> + { sw - size / 3, sh - size / 3 },
> + /* Test remaining corners. */
> + { sw - size, 0 },
> + { 0, sh - size },
> + { sw / 4 + sw / 2 - size, sh / 4 },
> + { sw / 4, sh / 4 + sh / 2 - size }
> + };
> +
> + for (i = 0; i < ARRAY_SIZE(pos); ++i)
> + test_cursor_pos(data, pos[i].x, pos[i].y, flags, scaling_factor);
> +}
> +
> +static void test_cursor(data_t *data, int size, unsigned int flags, unsigned int scaling_factor)
> +{
> + int sw, sh;
> +
> + igt_skip_on(size > data->max_curw || size > data->max_curh);
> +
> + sw = data->mode->hdisplay;
> + sh = data->mode->vdisplay;
> +
> + test_cleanup(data);
> +
> + /* Create RGB FB for reference. */
> + igt_create_color_fb(data->drm_fd, sw, sh, DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_MOD_LINEAR, 0.0, 0.0, 0.0, &data->rgb_fb);
> +
> + /* Create YUV FB for RGB-to-YUV, MAX_PLANES and NO_PLANES subtests */
> + if (flags & TEST_YUV || flags & TEST_MAX_PLANES ||flags & TEST_NO_PLANES)
> + igt_create_fb(data->drm_fd, sw, sh, DRM_FORMAT_NV12,
> + DRM_FORMAT_MOD_NONE, &data->yuv_fb);
> +
> + /* Create a quarter-sized empty FB. */
> + if (flags & TEST_QUARTER_FB)
> + igt_create_color_fb(data->drm_fd, sw / 2, sh / 2, DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_MOD_LINEAR, 0.0, 0.0, 0.0, &data->quarter_fb);
> +
> + /* Create two RGB FBs for the overlay planes. */
> + if (flags & TEST_MAX_PLANES || flags & TEST_NO_PLANES) {
> + igt_create_color_fb(data->drm_fd, sw / 2, sh / 2, DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_MOD_NONE, 0.5, 0.0, 0.0, &data->rgb_fb_o1);
> + igt_create_color_fb(data->drm_fd, sw / 2, sh / 2, DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_MOD_NONE, 0.0, 0.5, 0.0, &data->rgb_fb_o2);
> + }
> +
> + /* Create a third overlay plane for TEST_NO_PLANES test */
> + if (flags & TEST_NO_PLANES) {
> + igt_create_color_fb(data->drm_fd, sw / 2, sh / 2, DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_MOD_NONE, 0.0, 0.0, 0.5, &data->rgb_fb_o3);
> + }
> +
> + /* Create a FB for scaling. */
> + if (flags & TEST_SCALING)
> + igt_create_color_fb(data->drm_fd, sw, sh, DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_MOD_LINEAR, 0.0, 0.0, 0.0, &data->scale_fb);
> +
> + /* Create a cursor FB. */
> + igt_create_color_fb(data->drm_fd, size, size, DRM_FORMAT_ARGB8888,
> + DRM_FORMAT_MOD_LINEAR, 1.0, 0.0, 1.0, &data->cfb);
> +
> + igt_output_set_pipe(data->output, data->pipe_id);
> +
> + /* Run the test for different cursor spots. */
> + test_cursor_spots(data, size, flags, scaling_factor);
> +
> +}
> +
> +igt_main
> +{
> + static const int cursor_sizes[] = { 64, 128, 256 };
> + data_t data = { .max_curw = 64, .max_curh = 64 };
> + enum pipe pipe;
> + igt_output_t *output;
> + igt_display_t *display;
> + int i, j;
> + struct {
> + const char *name;
> + unsigned int flags;
> + unsigned int scale_factor;
> + const char *desc;
> + } tests[] = {
> + { "rgb-to-yuv", TEST_YUV, 100,
> + "Tests native cursor fall back to overlay cursor when a top plane switches from RGB to YUV" },
> + {"non-full", TEST_QUARTER_FB, 100,
> + "Tests native cursor fall back to overlay cursor when a top plane does not fill the crtc"},
> + {"max-planes", TEST_MAX_PLANES, 100,
> + "Tests native cursor fall back to overlay cursor when a top plane is YUV and there are two overlay planes used."},
> + {"no-available-planes", TEST_NO_PLANES, 100,
> + "Tests native cursor attempt to fall back to overlay cursor required, but fails atomic commit due to no available overlay planes."},
> + {"scaling-50", TEST_SCALING, 50,
> + "Tests native cursor fall back to overlay cursor when a top plane is scaled"},
> + {"scaling-75", TEST_SCALING, 75,
> + "Tests native cursor fall back to overlay cursor when a top plane is scaled"},
> + {"scaling-125", TEST_SCALING, 125,
> + "Tests native cursor fall back to overlay cursor when a top plane is scaled"},
> + {"scaling-150", TEST_SCALING, 150,
> + "Tests native cursor fall back to overlay cursor when a top plane is scaled"},
> + {"scaling-175", TEST_SCALING, 175,
> + "Tests native cursor fall back to overlay cursor when a top plane is scaled"},
> + {"scaling-200", TEST_SCALING, 200,
> + "Tests native cursor fall back to overlay cursor when a top plane is scaled"},
> + };
> +
> + igt_fixture {
> + int ret;
> +
> + data.drm_fd = drm_open_driver_master(DRIVER_AMDGPU);
> +
> + igt_display_require(&data.display, data.drm_fd);
> + igt_require(data.display.is_atomic);
> + igt_display_require_output(&data.display);
> + display = &data.display;
> +
> + ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_WIDTH, &data.max_curw);
> + igt_assert(ret == 0 || errno == EINVAL);
> + ret = drmGetCap(data.drm_fd, DRM_CAP_CURSOR_HEIGHT, &data.max_curh);
> + igt_assert(ret == 0 || errno == EINVAL);
> +
> + kmstest_set_vt_graphics_mode();
> + }
> +
> +
> + for (i = 0; i < ARRAY_SIZE(tests); i++) {
> + igt_describe_f("%s", tests[i].desc);
> + igt_subtest_with_dynamic_f("%s", tests[i].name) {
> +
> + /* Skip YUV and NO_PLANES subtests if YUV is not supported*/
> + if (tests[i].flags & TEST_YUV || tests[i].flags & TEST_NO_PLANES)
> + igt_require(igt_display_has_format_mod(display,
> + DRM_FORMAT_NV12,
> + DRM_FORMAT_MOD_LINEAR));
> +
> + for_each_pipe_with_single_output(&data.display, pipe, output) {
> +
> + igt_display_reset(display);
> +
> + igt_output_set_pipe(output, pipe);
> + if (!intel_pipe_output_combo_valid(display))
> + continue;
> +
> + /* Skip TEST_NO_PLANES if the ASIC has less than 3 overlay planes*/
> + if (tests[i].flags & TEST_NO_PLANES)
> + igt_require(get_overlay_planes_count(&data.display, pipe) >= 3);
> +
> + /* Skip TEST_MAX_PLANES if the ASIC has less than 2 overlay planes*/
> + if (tests[i].flags & TEST_MAX_PLANES)
> + igt_require(get_overlay_planes_count(&data.display, pipe) >= 2);
The skip checks here don't quite make sense, see comment above.
Thanks,
Leo
> +
> + test_init(&data, pipe, output, tests[i].flags);
> +
> + for (j = 0; j < ARRAY_SIZE(cursor_sizes); j++) {
> + int size = cursor_sizes[j];
> +
> + igt_dynamic_f("pipe-%s-%s-size-%d",
> + kmstest_pipe_name(pipe),
> + igt_output_name(output),
> + size)
> + test_cursor(&data, size, tests[i].flags, tests[i].scale_factor);
> +
> + test_cleanup(&data);
> + }
> +
> + test_fini(&data);
> + }
> + }
> + }
> +
> + igt_fixture {
> + igt_display_fini(&data.display);
> + drm_close_driver(data.drm_fd);
> + }
> +}
> diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
> index 421e686d3..b9f1842e2 100644
> --- a/tests/amdgpu/meson.build
> +++ b/tests/amdgpu/meson.build
> @@ -10,6 +10,7 @@ if libdrm_amdgpu.found()
> 'amd_color',
> 'amd_cp_dma_misc',
> 'amd_cs_nop',
> + 'amd_cursor_overlay',
> 'amd_deadlock',
> 'amd_dp_dsc',
> 'amd_freesync_video_mode',
More information about the amd-gfx
mailing list