* [PATCH i-g-t 0/3] New rotation test
@ 2024-03-12 9:38 Louis Chauvet
2024-03-12 9:38 ` [PATCH i-g-t 1/3] lib/igt_kms: Add reflection name and mask Louis Chauvet
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Louis Chauvet @ 2024-03-12 9:38 UTC (permalink / raw)
To: igt-dev
Cc: miquel.raynal, jeremie.dautheribes, thomas.petazzoni,
arthurgrillo, Louis Chauvet
The actual kms_rotation_crc test does not test all the rotation with all
the formats. Create the test kms_rotation, which only test "full plane
rotation", but for all the formats, plane and rotations configuration.
This new test allows to detect issues in [1], where the YUV rotation is
faulty for reflect_x and reflect_y cases.
[1]: https://lore.kernel.org/dri-devel/20240304-yuv-v4-11-76beac8e9793@bootlin.com/
To: igt-dev@lists.freedesktop.org
Cc: miquel.raynal@bootlin.com
Cc: jeremie.dautheribes@bootlin.com
Cc: thomas.petazzoni@bootlin.com
Cc: arthurgrillo@riseup.net
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Louis Chauvet (3):
lib/igt_kms: Add reflection name and mask
tests/kms_rotation: Add extensive rotation test
tests/kms_rotation: Add command line option to reduce the number of tests
lib/igt_kms.c | 23 +++
lib/igt_kms.h | 3 +
tests/kms_rotation.c | 434 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/meson.build | 1 +
4 files changed, 461 insertions(+)
---
base-commit: a44ebfe43edc96acab22a19b6a8850eef9202eea
change-id: 20240312-new_rotation-c034a68b3b9d
Best regards,
--
Louis Chauvet <louis.chauvet@bootlin.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH i-g-t 1/3] lib/igt_kms: Add reflection name and mask
2024-03-12 9:38 [PATCH i-g-t 0/3] New rotation test Louis Chauvet
@ 2024-03-12 9:38 ` Louis Chauvet
2024-03-12 9:38 ` [PATCH i-g-t 2/3] tests/kms_rotation: Add extensive rotation test Louis Chauvet
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Louis Chauvet @ 2024-03-12 9:38 UTC (permalink / raw)
To: igt-dev
Cc: miquel.raynal, jeremie.dautheribes, thomas.petazzoni,
arthurgrillo, Louis Chauvet
As for IGT_ROTATION_MASK and igt_plane_rotation_name, create the mask
IGT_REFLECT_MASK and the function igt_plane_reflect_name.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/igt_kms.c | 23 +++++++++++++++++++++++
lib/igt_kms.h | 3 +++
2 files changed, 26 insertions(+)
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index e18f6fe59882..85d278f3cae3 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -5142,6 +5142,29 @@ const char *igt_plane_rotation_name(igt_rotation_t rotation)
}
}
+
+/**
+ * igt_plane_reflect_name:
+ * @reflect: Plane reflection value (x, y)
+ *
+ * Returns: Plane reflection value as a string
+ */
+const char *igt_plane_reflect_name(igt_rotation_t reflect)
+{
+ switch (reflect & IGT_REFLECT_MASK) {
+ case 0:
+ return "none";
+ case IGT_REFLECT_X:
+ return "X";
+ case IGT_REFLECT_Y:
+ return "Y";
+ case IGT_REFLECT_X | IGT_REFLECT_Y:
+ return "XY";
+ default:
+ igt_assert(0);
+ }
+}
+
/**
* igt_plane_set_rotation:
* @plane: Plane pointer for which rotation is to be set
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index b3882808b42f..4760394428f3 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -371,6 +371,8 @@ typedef enum {
#define IGT_ROTATION_MASK \
(IGT_ROTATION_0 | IGT_ROTATION_90 | IGT_ROTATION_180 | IGT_ROTATION_270)
+#define IGT_REFLECT_MASK \
+ (IGT_REFLECT_X | IGT_REFLECT_Y)
/**
* igt_rotation_90_or_270:
@@ -562,6 +564,7 @@ static inline bool igt_plane_has_rotation(igt_plane_t *plane, igt_rotation_t rot
return (plane->rotations & rotation) == rotation;
}
const char *igt_plane_rotation_name(igt_rotation_t rotation);
+const char *igt_plane_reflect_name(igt_rotation_t reflect);
void igt_wait_for_vblank(int drm_fd, int crtc_offset);
void igt_wait_for_vblank_count(int drm_fd, int crtc_offset, int count);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH i-g-t 2/3] tests/kms_rotation: Add extensive rotation test
2024-03-12 9:38 [PATCH i-g-t 0/3] New rotation test Louis Chauvet
2024-03-12 9:38 ` [PATCH i-g-t 1/3] lib/igt_kms: Add reflection name and mask Louis Chauvet
@ 2024-03-12 9:38 ` Louis Chauvet
2024-03-12 10:48 ` Louis Chauvet
2024-03-12 9:39 ` [PATCH i-g-t 3/3] tests/kms_rotation: Add command line option to reduce the number of tests Louis Chauvet
` (2 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Louis Chauvet @ 2024-03-12 9:38 UTC (permalink / raw)
To: igt-dev
Cc: miquel.raynal, jeremie.dautheribes, thomas.petazzoni,
arthurgrillo, Louis Chauvet
The actual kms_rotation_crc test does not tes all the rotation with all
the formats. Create the test kms_rotation, which only test "full plane
rotation", but for all formats, planes and rotations.
This allow the detection of issues like in [1], where the YUV rotation is
not working for specific rotations.
[1]: https://lore.kernel.org/dri-devel/20240304-yuv-v4-11-76beac8e9793@bootlin.com/
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/kms_rotation.c | 366 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/meson.build | 1 +
2 files changed, 367 insertions(+)
diff --git a/tests/kms_rotation.c b/tests/kms_rotation.c
new file mode 100644
index 000000000000..4062549a0beb
--- /dev/null
+++ b/tests/kms_rotation.c
@@ -0,0 +1,366 @@
+#include "igt.h"
+
+/**
+ * TEST: kms_rotation
+ * Category: Display
+ * Description: Tests all rotations for all planes and formats.
+ * Driver requirement: none
+ * Functionality: plane, rotation
+ * Mega feature: General Display Features
+ * Test category: functionality test
+ */
+
+/**
+ * SUBTEST: rotations
+ * Description: Test for all rotations, planes and formats.
+ */
+
+/**
+ * struct data_t - Stores the test configuration
+ *
+ * @fd: file descriptor for the current drm device
+ * @display: display used for the tests
+ */
+struct data_t {
+ int fd;
+ igt_display_t display;
+};
+
+/**
+ * colors - List of colors used to put things on the plane
+ *
+ * Those colors are used to create a color pattern on the plane, which is not invariant by rotation or reflexion.
+ *
+ * At least black and white must be in this list to properly test black and white formats.
+ */
+static const struct igt_vec4 colors[] = {
+ {{1.0f, 0.0f, 0.0f, 0.0f}},
+ {{1.0f, 1.0f, 1.0f, 0.0f}},
+ {{0.0f, 0.0f, 0.0f, 0.0f}},
+ {{0.0f, 1.0f, 1.0f, 0.0f}},
+ {{0.0f, 0.0f, 0.0f, 0.0f}},
+};
+
+/**
+ * tested_rotation - List of all tested rotation configuration
+ */
+static uint32_t tested_rotation[] = {
+ IGT_ROTATION_0,
+ IGT_ROTATION_0 | IGT_REFLECT_X,
+ IGT_ROTATION_0 | IGT_REFLECT_Y,
+ IGT_ROTATION_0 | IGT_REFLECT_X | IGT_REFLECT_Y,
+ IGT_ROTATION_90,
+ IGT_ROTATION_90 | IGT_REFLECT_X,
+ IGT_ROTATION_90 | IGT_REFLECT_Y,
+ IGT_ROTATION_90 | IGT_REFLECT_X | IGT_REFLECT_Y,
+ IGT_ROTATION_180,
+ IGT_ROTATION_180 | IGT_REFLECT_X,
+ IGT_ROTATION_180 | IGT_REFLECT_Y,
+ IGT_ROTATION_180 | IGT_REFLECT_X | IGT_REFLECT_Y,
+ IGT_ROTATION_270,
+ IGT_ROTATION_270 | IGT_REFLECT_X,
+ IGT_ROTATION_270 | IGT_REFLECT_Y,
+ IGT_ROTATION_270 | IGT_REFLECT_X | IGT_REFLECT_Y,
+};
+
+/**
+ * non_equals_crc() - Check if at least one CRC is different
+ *
+ * Check if at least one CRC is different, so we can verify that the rendering is working.
+ *
+ * @crcs: List of all tested crcs
+ * @crc_count: Number of crcs in the list
+ */
+static bool non_equals_crc(igt_crc_t crcs[], int crc_count) {
+ if (!crc_count) {
+ return true;
+ }
+ for (int i = 0; i < crc_count; i++)
+ if (!igt_check_crc_equal(&crcs[i], &crcs[0]))
+ return true;
+ return false;
+}
+
+/**
+ * create_fb() - Create a framebuffer
+ *
+ * This create a framebuffer and fill it with a pattern. This pattern is not invariant by rotation and reflection.
+ *
+ * The @width and @height parameters are automaticaly inverted according to @rotation if needed. If the requested plane
+ * is 1024*768 with IGT_ROTATION_90, the returned plane will have the size 768*1024.
+ *
+ * @data: Current test configuration
+ * @rotation: Rotation to apply to the pattern
+ * @format: Format of the requested plane
+ * @modifier: Modifier for the requested plane
+ * @width: Width of the requested plane
+ * @height: Height of the requested plane
+ * @fb: Place to store the created framebuffer
+ */
+static void create_fb(struct data_t *data, igt_rotation_t rotation, uint32_t format, uint64_t modifier, int width,
+ int height, igt_fb_t *fb)
+{
+ int step_x, step_y, color_index, current_n, current_m;
+ cairo_t *cr;
+
+ switch (rotation & IGT_ROTATION_MASK) {
+ case IGT_ROTATION_90:
+ case IGT_ROTATION_270:
+ igt_swap(width, height);
+ break;
+ case IGT_ROTATION_0:
+ case IGT_ROTATION_180:
+ default:
+ break;
+ }
+
+ igt_create_fb(data->fd, width, height, format, modifier, fb);
+ cr = igt_get_cairo_ctx(data->fd, fb);
+
+ step_x = (width) / ARRAY_SIZE(colors);
+ step_y = (height) / ARRAY_SIZE(colors);
+ /* Iterate over all colors in x and y direction. The pattern is a colored chessboard */
+ for (int n = 0; n < ARRAY_SIZE(colors); n++) {
+ for (int m = 0; m < ARRAY_SIZE(colors); m++) {
+ color_index = (n + m) % ARRAY_SIZE(colors);
+ current_n = n;
+ current_m = m;
+
+ /*
+ * If a reflexion and a rotation is requested, apply this to the pattern rendering
+ * If a reflexion is given, it must be applied before the rotation.
+ */
+ switch (rotation & IGT_REFLECT_MASK) {
+ case IGT_REFLECT_X:
+ current_n = ARRAY_SIZE(colors) - 1 - current_n;
+ break;
+ case IGT_REFLECT_Y:
+ current_m = ARRAY_SIZE(colors) - 1 - current_m;
+ break;
+ case IGT_REFLECT_X | IGT_REFLECT_Y:
+ current_n = ARRAY_SIZE(colors) - 1 - current_n;
+ current_m = ARRAY_SIZE(colors) - 1 - current_m;
+ break;
+ }
+ switch (rotation & IGT_ROTATION_MASK) {
+ case IGT_ROTATION_0:
+ break;
+ case IGT_ROTATION_90:
+ igt_swap(current_n, current_m);
+ current_m = ARRAY_SIZE(colors) - 1 - current_m;
+ break;
+ case IGT_ROTATION_180:
+ current_n = ARRAY_SIZE(colors) - 1 - current_n;
+ current_m = ARRAY_SIZE(colors) - 1 - current_m;
+ break;
+ case IGT_ROTATION_270:
+ igt_swap(current_n, current_m);
+ current_n = ARRAY_SIZE(colors) - 1 - current_n;
+ break;
+ }
+
+ igt_paint_color(cr,
+ current_n * step_x,
+ current_m * step_y,
+ step_x,
+ step_y,
+ colors[color_index].d[0],
+ colors[color_index].d[1],
+ colors[color_index].d[2]);
+ }
+ }
+
+ igt_put_cairo_ctx(cr);
+}
+
+/**
+ * get_ref_crcs() - Compute the reference CRC for a specific format
+ *
+ * The rotation are done by create_fb in software.
+ *
+ * @data: Test configuration
+ * @output, @pipe, @plane: Plane to use for the test
+ * @format, @modifier: Format description to test
+ * @ref_crc: Array to store the resulting CRC. Its size must be at least ARRAY_SIZE(tested_rotation).
+ */
+static void get_ref_crcs(struct data_t *data, igt_output_t *output, enum pipe pipe, igt_plane_t *plane, uint32_t format,
+ uint64_t modifier, igt_crc_t ref_crc[ARRAY_SIZE(tested_rotation)])
+{
+ drmModeModeInfo *mode;
+ igt_pipe_crc_t *pipe_crc;
+ igt_fb_t fb;
+
+ igt_display_reset(&data->display);
+ igt_output_set_pipe(output, pipe);
+
+
+ for (int r = 0; r < ARRAY_SIZE(tested_rotation); r++) {
+ int rotation = tested_rotation[r];
+ /* Configure the pipe for reference frame */
+ igt_display_reset(&data->display);
+ igt_output_set_pipe(output, pipe);
+ igt_plane_set_rotation(plane, IGT_ROTATION_0);
+ igt_display_commit2(&data->display, COMMIT_ATOMIC);
+ mode = igt_output_get_mode(output);
+
+ /* Start the CRC */
+ pipe_crc = igt_pipe_crc_new(data->fd, pipe, IGT_PIPE_CRC_SOURCE_AUTO);
+ igt_pipe_crc_start(pipe_crc);
+
+ create_fb(data, rotation, format, modifier, mode->vdisplay, mode->hdisplay, &fb);
+ igt_plane_set_fb(plane, &fb);
+ igt_display_commit2(&data->display, COMMIT_ATOMIC);
+
+ igt_pipe_crc_get_current(
+ data->display.drm_fd, pipe_crc,
+ &ref_crc[r]);
+
+ igt_pipe_crc_stop(pipe_crc);
+ igt_pipe_crc_free(pipe_crc);
+ igt_remove_fb(data->fd, &fb);
+ }
+}
+
+/**
+ * get_crcs() - Compute the CRC for a specific format
+ *
+ * @data: Test configuration
+ * @output, @pipe, @plane: Plane to use for the test
+ * @format, @modifier: Format description to test
+ * @crc: Array to store the resulting CRC. Its size must be at least ARRAY_SIZE(tested_rotation).
+ */
+static void get_crcs(struct data_t *data, igt_output_t *output, enum pipe pipe, igt_plane_t *plane, uint32_t format,
+ uint64_t modifier, igt_crc_t crc[ARRAY_SIZE(tested_rotation)])
+{
+ drmModeModeInfo *mode;
+ igt_pipe_crc_t *pipe_crc;
+ igt_fb_t fb;
+
+ igt_display_reset(&data->display);
+ igt_output_set_pipe(output, pipe);
+
+
+ for (int r = 0; r < ARRAY_SIZE(tested_rotation); r++) {
+ int rotation = tested_rotation[r];
+ /* Configure the pipe for reference frame */
+ igt_display_reset(&data->display);
+ igt_output_set_pipe(output, pipe);
+ igt_plane_set_rotation(plane, rotation);
+
+ if (!igt_plane_has_rotation(plane, rotation))
+ continue;
+
+ igt_display_commit2(&data->display, COMMIT_ATOMIC);
+ mode = igt_output_get_mode(output);
+
+ /* Start the CRC */
+ pipe_crc = igt_pipe_crc_new(data->fd, pipe, IGT_PIPE_CRC_SOURCE_AUTO);
+ igt_pipe_crc_start(pipe_crc);
+
+ create_fb(data, IGT_ROTATION_0, format, modifier, mode->vdisplay, mode->hdisplay, &fb);
+ igt_plane_set_fb(plane, &fb);
+ if (igt_rotation_90_or_270(rotation))
+ igt_plane_set_size(plane, fb.height, fb.width);
+ igt_display_commit2(&data->display, COMMIT_ATOMIC);
+
+ igt_pipe_crc_get_current(
+ data->display.drm_fd, pipe_crc,
+ &crc[r]);
+
+ igt_pipe_crc_stop(pipe_crc);
+ igt_pipe_crc_free(pipe_crc);
+ igt_remove_fb(data->fd, &fb);
+ }
+}
+
+/**
+ * run_test() - Run the subtests for a specific plane
+ *
+ * @data: Test configuration
+ * @output, @pipe, @plane: Plane to use for the test
+ * @format, @modifier: Format description to test
+ */
+static void run_test(struct data_t *data, igt_output_t *output, enum pipe pipe, igt_plane_t *plane, uint32_t format, uint64_t modifier)
+{
+ igt_crc_t ref_crc[ARRAY_SIZE(tested_rotation)];
+ igt_crc_t crc[ARRAY_SIZE(tested_rotation)];
+
+ igt_display_reset(&data->display);
+ igt_output_set_pipe(output, pipe);
+ /* Check that the rotation is supported */
+ igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
+
+ /* Generate reference CRC with software rotation */
+ get_ref_crcs(data, output, pipe, plane, format, modifier, ref_crc);
+ igt_assert_f(non_equals_crc(ref_crc, ARRAY_SIZE(tested_rotation)), "All the reference CRC are equals.");
+
+ /* Generate CRC with hardware rotation */
+ get_crcs(data, output, pipe, plane, format, modifier, crc);
+
+ for (int c = 0; c < ARRAY_SIZE(tested_rotation); c++) {
+ int rotation = tested_rotation[c];
+ igt_dynamic_f("pipe-%s-format-%s-modifier-%s-rotation-%s-reflect-%s", kmstest_pipe_name(pipe),
+ igt_format_str(format),
+ igt_fb_modifier_name(modifier), igt_plane_rotation_name(rotation),
+ igt_plane_reflect_name(rotation)) {
+ igt_assert_crc_equal(&ref_crc[c], &crc[c]);
+ }
+ }
+}
+
+/**
+ * test_all_formats() - Run all the tests for all planes
+ *
+ * @data: Test configuration
+ */
+static void test_all_formats(struct data_t *data)
+{
+ enum pipe pipe;
+ struct igt_plane *plane;
+ igt_output_t *output;
+ for_each_pipe_with_single_output(&data->display, pipe, output) {
+ for_each_plane_on_pipe(&data->display, pipe, plane) {
+ for (int f = 0; f < plane->format_mod_count; f++) {
+ uint32_t format = plane->formats[f];
+ uint32_t modifier = plane->modifiers[f];
+
+ if (!igt_fb_supported_format(format))
+ continue;
+ run_test(data, output, pipe, plane, format, modifier);
+ }
+ }
+ }
+}
+
+static int opt_handler(int opt, int opt_index, void *void_data)
+{
+ return IGT_OPT_HANDLER_SUCCESS;
+}
+
+static const struct option long_opts[] = {
+ {}
+};
+
+static const char help_str[] = "";
+
+static struct data_t global_data;
+
+igt_main_args("", long_opts, help_str, opt_handler, &global_data)
+{
+ igt_fixture {
+ global_data.fd = drm_open_driver_master(DRIVER_ANY);
+
+ kmstest_set_vt_graphics_mode();
+
+ igt_display_require(&global_data.display, global_data.fd);
+ igt_require(global_data.display.is_atomic);
+ igt_display_require_output(&global_data.display);
+ igt_display_reset(&global_data.display);
+ }
+
+ igt_describe("Testing different rotation and reflexions for different formats");
+ igt_subtest_with_dynamic_f("rotation") {
+ test_all_formats(&global_data);
+ }
+
+}
\ No newline at end of file
diff --git a/tests/meson.build b/tests/meson.build
index a856510fcea7..71b628b86e96 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -82,6 +82,7 @@ test_progs = [
'tools_test',
'vgem_basic',
'vgem_slow',
+ 'kms_rotation',
]
intel_i915_xe_progs = [
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH i-g-t 3/3] tests/kms_rotation: Add command line option to reduce the number of tests
2024-03-12 9:38 [PATCH i-g-t 0/3] New rotation test Louis Chauvet
2024-03-12 9:38 ` [PATCH i-g-t 1/3] lib/igt_kms: Add reflection name and mask Louis Chauvet
2024-03-12 9:38 ` [PATCH i-g-t 2/3] tests/kms_rotation: Add extensive rotation test Louis Chauvet
@ 2024-03-12 9:39 ` Louis Chauvet
2024-03-12 9:59 ` ✗ Fi.CI.BUILD: failure for New rotation test Patchwork
2024-03-12 10:07 ` ✗ GitLab.Pipeline: warning " Patchwork
4 siblings, 0 replies; 7+ messages in thread
From: Louis Chauvet @ 2024-03-12 9:39 UTC (permalink / raw)
To: igt-dev
Cc: miquel.raynal, jeremie.dautheribes, thomas.petazzoni,
arthurgrillo, Louis Chauvet
As it is often needed to reduce the number of tests (for example during
development), add few command line options to reduce the number of
subtests.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
tests/kms_rotation.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 71 insertions(+), 3 deletions(-)
diff --git a/tests/kms_rotation.c b/tests/kms_rotation.c
index 4062549a0beb..f09ce9db665c 100644
--- a/tests/kms_rotation.c
+++ b/tests/kms_rotation.c
@@ -20,10 +20,17 @@
*
* @fd: file descriptor for the current drm device
* @display: display used for the tests
+ * @format: If not zero, the format to test
+ * @rotation_mask: A mask of IGT_ROTATION_* / IGT_REFLECT_*. This allows running only the subtests where all the values
+ * in this mask are used. So for example:
+ * IGT_ROTATION_0 | IGT_REFLECT_X will run rot_0, rot_0+reflect_x, rot_0+reflect_x+reflect_y
+ * IGT_ROTATION_180 | IGT_ROTATION_90 will not run anything, it's not possible to rotate by 90 and 180 simultaneously
*/
struct data_t {
int fd;
igt_display_t display;
+ uint32_t format;
+ uint32_t rotation_mask;
};
/**
@@ -63,6 +70,18 @@ static uint32_t tested_rotation[] = {
IGT_ROTATION_270 | IGT_REFLECT_X | IGT_REFLECT_Y,
};
+/**
+ * should_skip() - Returns true if a specific rotation must be skipped
+ *
+ * Check if a rotation mus be skipped by comparing it to @data->rotation_mask. See @data->rotation_mask for the expected behavior.
+ *
+ * @data: Test configuration
+ * @rotation: Rotation to check for skipping
+ */
+static bool should_skip(struct data_t *data, uint32_t rotation) {
+ return (rotation & data->rotation_mask) != data->rotation_mask;
+}
+
/**
* non_equals_crc() - Check if at least one CRC is different
*
@@ -196,6 +215,8 @@ static void get_ref_crcs(struct data_t *data, igt_output_t *output, enum pipe pi
for (int r = 0; r < ARRAY_SIZE(tested_rotation); r++) {
int rotation = tested_rotation[r];
+ if (should_skip(data, rotation))
+ continue;
/* Configure the pipe for reference frame */
igt_display_reset(&data->display);
igt_output_set_pipe(output, pipe);
@@ -242,6 +263,8 @@ static void get_crcs(struct data_t *data, igt_output_t *output, enum pipe pipe,
for (int r = 0; r < ARRAY_SIZE(tested_rotation); r++) {
int rotation = tested_rotation[r];
+ if (should_skip(data, rotation))
+ continue;
/* Configure the pipe for reference frame */
igt_display_reset(&data->display);
igt_output_set_pipe(output, pipe);
@@ -299,6 +322,8 @@ static void run_test(struct data_t *data, igt_output_t *output, enum pipe pipe,
for (int c = 0; c < ARRAY_SIZE(tested_rotation); c++) {
int rotation = tested_rotation[c];
+ if (should_skip(data, rotation))
+ continue;
igt_dynamic_f("pipe-%s-format-%s-modifier-%s-rotation-%s-reflect-%s", kmstest_pipe_name(pipe),
igt_format_str(format),
igt_fb_modifier_name(modifier), igt_plane_rotation_name(rotation),
@@ -324,6 +349,9 @@ static void test_all_formats(struct data_t *data)
uint32_t format = plane->formats[f];
uint32_t modifier = plane->modifiers[f];
+ if (data->format != 0 && data->format != format)
+ continue;
+
if (!igt_fb_supported_format(format))
continue;
run_test(data, output, pipe, plane, format, modifier);
@@ -334,15 +362,55 @@ static void test_all_formats(struct data_t *data)
static int opt_handler(int opt, int opt_index, void *void_data)
{
- return IGT_OPT_HANDLER_SUCCESS;
+ struct data_t *data = void_data;
+ switch (opt) {
+ case 'f':
+ data->format = igt_drm_format_str_to_format(optarg);
+ return IGT_OPT_HANDLER_SUCCESS;
+ case 'x':
+ data->rotation_mask |= IGT_REFLECT_X;
+ return IGT_OPT_HANDLER_SUCCESS;
+ case 'y':
+ data->rotation_mask |= IGT_REFLECT_Y;
+ return IGT_OPT_HANDLER_SUCCESS;
+ case '0':
+ data->rotation_mask |= IGT_ROTATION_0;
+ return IGT_OPT_HANDLER_SUCCESS;
+ case '9': // 90
+ data->rotation_mask |= IGT_ROTATION_90;
+ return IGT_OPT_HANDLER_SUCCESS;
+ case '1': // 180
+ data->rotation_mask |= IGT_ROTATION_180;
+ return IGT_OPT_HANDLER_SUCCESS;
+ case '2': // 270
+ data->rotation_mask |= IGT_ROTATION_270;
+ return IGT_OPT_HANDLER_SUCCESS;
+ default:
+ return IGT_OPT_HANDLER_ERROR;
+ }
}
static const struct option long_opts[] = {
+ { .name = "format", .has_arg = true, .val = 'f'},
+ { .name = "reflect_x", .has_arg = false, .val = 'x'},
+ { .name = "reflect_y", .has_arg = false, .val = 'y'},
+ { .name = "rot_0", .has_arg = false, .val = '0'},
+ { .name = "rot_90", .has_arg = false, .val = '9'},
+ { .name = "rot_180", .has_arg = false, .val = '1'},
+ { .name = "rot_270", .has_arg = false, .val = '2'},
{}
};
-static const char help_str[] = "";
-
+static const char help_str[] = ""
+ " --format\tSet a specific format to test\n"
+ "All the following options are used to select a specific rotation to test\n"
+ "For example --reflect_x --rot_0 will test all rotation involving reflect_x AND rot_0\n"
+ " --reflect_x\tOnly test cases where X-reflexion is involved\n"
+ " --reflect_y\tOnly test cases where Y-reflexion is involved\n"
+ " --rot_0\tOnly test cases where a 0° rotation is involved\n"
+ " --rot_90\tOnly test cases where a 90° rotation is involved\n"
+ " --rot_180\tOnly test cases where a 180° rotation is involved\n"
+ " --rot_270\tOnly test cases where a 270° rotation is involved\n";
static struct data_t global_data;
igt_main_args("", long_opts, help_str, opt_handler, &global_data)
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* ✗ Fi.CI.BUILD: failure for New rotation test
2024-03-12 9:38 [PATCH i-g-t 0/3] New rotation test Louis Chauvet
` (2 preceding siblings ...)
2024-03-12 9:39 ` [PATCH i-g-t 3/3] tests/kms_rotation: Add command line option to reduce the number of tests Louis Chauvet
@ 2024-03-12 9:59 ` Patchwork
2024-03-12 10:07 ` ✗ GitLab.Pipeline: warning " Patchwork
4 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2024-03-12 9:59 UTC (permalink / raw)
To: Louis Chauvet; +Cc: igt-dev
== Series Details ==
Series: New rotation test
URL : https://patchwork.freedesktop.org/series/131011/
State : failure
== Summary ==
IGT patchset build failed on latest successful build
a44ebfe43edc96acab22a19b6a8850eef9202eea tests/xe_ccs: Separate inc dimension start width
Tail of build.log:
Warning: igt@sysfs_heartbeat_interval@off Category documentation is missing
Warning: igt@sysfs_heartbeat_interval@precise Functionality documentation is missing
Warning: igt@sysfs_heartbeat_interval@precise Sub-category documentation is missing
Warning: igt@sysfs_heartbeat_interval@precise Category documentation is missing
Warning: igt@sysfs_preempt_timeout@idempotent Functionality documentation is missing
Warning: igt@sysfs_preempt_timeout@idempotent Sub-category documentation is missing
Warning: igt@sysfs_preempt_timeout@idempotent Category documentation is missing
Warning: igt@sysfs_preempt_timeout@invalid Functionality documentation is missing
Warning: igt@sysfs_preempt_timeout@invalid Sub-category documentation is missing
Warning: igt@sysfs_preempt_timeout@invalid Category documentation is missing
Warning: igt@sysfs_preempt_timeout@off Functionality documentation is missing
Warning: igt@sysfs_preempt_timeout@off Sub-category documentation is missing
Warning: igt@sysfs_preempt_timeout@off Category documentation is missing
Warning: igt@sysfs_preempt_timeout@timeout Functionality documentation is missing
Warning: igt@sysfs_preempt_timeout@timeout Sub-category documentation is missing
Warning: igt@sysfs_preempt_timeout@timeout Category documentation is missing
Warning: igt@sysfs_timeslice_duration@duration Functionality documentation is missing
Warning: igt@sysfs_timeslice_duration@duration Sub-category documentation is missing
Warning: igt@sysfs_timeslice_duration@duration Category documentation is missing
Warning: igt@sysfs_timeslice_duration@idempotent Functionality documentation is missing
Warning: igt@sysfs_timeslice_duration@idempotent Sub-category documentation is missing
Warning: igt@sysfs_timeslice_duration@idempotent Category documentation is missing
Warning: igt@sysfs_timeslice_duration@invalid Functionality documentation is missing
Warning: igt@sysfs_timeslice_duration@invalid Sub-category documentation is missing
Warning: igt@sysfs_timeslice_duration@invalid Category documentation is missing
Warning: igt@sysfs_timeslice_duration@off Functionality documentation is missing
Warning: igt@sysfs_timeslice_duration@off Sub-category documentation is missing
Warning: igt@sysfs_timeslice_duration@off Category documentation is missing
Warning: igt@sysfs_timeslice_duration@timeout Functionality documentation is missing
Warning: igt@sysfs_timeslice_duration@timeout Sub-category documentation is missing
Warning: igt@sysfs_timeslice_duration@timeout Category documentation is missing
Warning: igt@vgem_basic@bad-fence Sub-category documentation is missing
Warning: igt@vgem_basic@bad-flag Sub-category documentation is missing
Warning: igt@vgem_basic@bad-handle Sub-category documentation is missing
Warning: igt@vgem_basic@bad-pad Sub-category documentation is missing
Warning: igt@vgem_basic@busy-fence Sub-category documentation is missing
Warning: igt@vgem_basic@create Sub-category documentation is missing
Warning: igt@vgem_basic@debugfs Sub-category documentation is missing
Warning: igt@vgem_basic@dmabuf-export Sub-category documentation is missing
Warning: igt@vgem_basic@dmabuf-fence Sub-category documentation is missing
Warning: igt@vgem_basic@dmabuf-fence-before Sub-category documentation is missing
Warning: igt@vgem_basic@dmabuf-mmap Sub-category documentation is missing
Warning: igt@vgem_basic@mmap Sub-category documentation is missing
Warning: igt@vgem_basic@second-client Sub-category documentation is missing
Warning: igt@vgem_basic@setversion Sub-category documentation is missing
Warning: igt@vgem_basic@sysfs Sub-category documentation is missing
Warning: igt@vgem_basic@unload Sub-category documentation is missing
[1669/1673] Generating intel-ci-tests with a custom command.
[1670/1673] Generating xe_tests.html with a custom command.
ninja: build stopped: subcommand failed.
^ permalink raw reply [flat|nested] 7+ messages in thread
* ✗ GitLab.Pipeline: warning for New rotation test
2024-03-12 9:38 [PATCH i-g-t 0/3] New rotation test Louis Chauvet
` (3 preceding siblings ...)
2024-03-12 9:59 ` ✗ Fi.CI.BUILD: failure for New rotation test Patchwork
@ 2024-03-12 10:07 ` Patchwork
4 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2024-03-12 10:07 UTC (permalink / raw)
To: Louis Chauvet; +Cc: igt-dev
== Series Details ==
Series: New rotation test
URL : https://patchwork.freedesktop.org/series/131011/
State : warning
== Summary ==
Pipeline status: FAILED.
see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/1125655 for the overview.
build:tests-debian-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/56172970):
[1790/1793] Compiling C object 'runner/527aa9f@@runner_test@exe/runner_tests.c.o'.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/823] Generating version.h with a custom command.
[2/6] Linking target runner/runner_test.
[3/6] Generating intel-ci-tests with a custom command.
[4/6] Generating i915_tests.html with a custom command.
[5/6] Generating kms_tests.rst with a custom command.
FAILED: docs/testplan/kms_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/kms_test_config.json --rest docs/testplan/kms_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: Documented igt@kms_rotation@rotations doesn't exist on source files
Warning: Missing documentation for igt@kms_rotation@rotation
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1710237700:step_script
section_start:1710237700:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1710237700:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/56172965):
[1796/1799] Compiling C object 'runner/527aa9f@@runner_test@exe/runner_tests.c.o'.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/825] Generating version.h with a custom command.
[2/6] Linking target runner/runner_test.
[3/6] Generating i915_tests.html with a custom command.
[4/6] Generating intel-ci-tests with a custom command.
[5/6] Generating kms_tests.rst with a custom command.
FAILED: docs/testplan/kms_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/kms_test_config.json --rest docs/testplan/kms_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: Documented igt@kms_rotation@rotations doesn't exist on source files
Warning: Missing documentation for igt@kms_rotation@rotation
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1710237773:step_script
section_start:1710237773:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1710237774:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-clang has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/56172969):
[1796/1799] Generating intel-ci-tests with a custom command.
[1797/1799] Generating xe_tests.html with a custom command.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/825] Generating version.h with a custom command.
[2/5] Generating intel-ci-tests with a custom command.
[3/5] Generating i915_tests.html with a custom command.
[4/5] Generating kms_tests.rst with a custom command.
FAILED: docs/testplan/kms_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/kms_test_config.json --rest docs/testplan/kms_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: Documented igt@kms_rotation@rotations doesn't exist on source files
Warning: Missing documentation for igt@kms_rotation@rotation
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1710237725:step_script
section_start:1710237725:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1710237725:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-no-libdrm-nouveau has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/56172968):
[1630/1633] Compiling C object 'runner/527aa9f@@runner_test@exe/runner_tests.c.o'.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/775] Generating version.h with a custom command.
[2/6] Linking target runner/runner_test.
[3/6] Generating intel-ci-tests with a custom command.
[4/6] Generating i915_tests.html with a custom command.
[5/6] Generating kms_tests.rst with a custom command.
FAILED: docs/testplan/kms_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/kms_test_config.json --rest docs/testplan/kms_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: Documented igt@kms_rotation@rotations doesn't exist on source files
Warning: Missing documentation for igt@kms_rotation@rotation
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1710237697:step_script
section_start:1710237697:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1710237698:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-no-libunwind has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/56172966):
[1796/1799] Compiling C object 'runner/527aa9f@@runner_test@exe/runner_tests.c.o'.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/825] Generating version.h with a custom command.
[2/6] Linking target runner/runner_test.
[3/6] Generating i915_tests.html with a custom command.
[4/6] Generating intel-ci-tests with a custom command.
[5/6] Generating kms_tests.rst with a custom command.
FAILED: docs/testplan/kms_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/kms_test_config.json --rest docs/testplan/kms_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: Documented igt@kms_rotation@rotations doesn't exist on source files
Warning: Missing documentation for igt@kms_rotation@rotation
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1710237689:step_script
section_start:1710237689:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1710237689:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-oldest-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/56172967):
[1796/1799] Compiling C object 'runner/runner@@runner_test@exe/runner_tests.c.o'.
ninja: build stopped: subcommand failed.
ninja: Entering directory `build'
[1/825] Generating version.h with a custom command.
[2/6] Linking target runner/runner_test.
[3/6] Generating intel-ci-tests with a custom command.
[4/6] Generating i915_tests.html with a custom command.
[5/6] Generating kms_tests.rst with a custom command.
FAILED: docs/testplan/kms_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/kms_test_config.json --rest docs/testplan/kms_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: Documented igt@kms_rotation@rotations doesn't exist on source files
Warning: Missing documentation for igt@kms_rotation@rotation
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1710237691:step_script
section_start:1710237691:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1710237692:cleanup_file_variables
ERROR: Job failed: exit code 1
== Logs ==
For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/1125655
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH i-g-t 2/3] tests/kms_rotation: Add extensive rotation test
2024-03-12 9:38 ` [PATCH i-g-t 2/3] tests/kms_rotation: Add extensive rotation test Louis Chauvet
@ 2024-03-12 10:48 ` Louis Chauvet
0 siblings, 0 replies; 7+ messages in thread
From: Louis Chauvet @ 2024-03-12 10:48 UTC (permalink / raw)
To: igt-dev; +Cc: miquel.raynal, jeremie.dautheribes, thomas.petazzoni,
arthurgrillo
Le 12/03/24 - 10:38, Louis Chauvet a écrit :
> The actual kms_rotation_crc test does not tes all the rotation with all
> the formats. Create the test kms_rotation, which only test "full plane
> rotation", but for all formats, planes and rotations.
>
> This allow the detection of issues like in [1], where the YUV rotation is
> not working for specific rotations.
>
> [1]: https://lore.kernel.org/dri-devel/20240304-yuv-v4-11-76beac8e9793@bootlin.com/
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> tests/kms_rotation.c | 366 +++++++++++++++++++++++++++++++++++++++++++++++++++
> tests/meson.build | 1 +
> 2 files changed, 367 insertions(+)
>
> diff --git a/tests/kms_rotation.c b/tests/kms_rotation.c
> new file mode 100644
> index 000000000000..4062549a0beb
> --- /dev/null
> +++ b/tests/kms_rotation.c
> @@ -0,0 +1,366 @@
> +#include "igt.h"
> +
> +/**
> + * TEST: kms_rotation
> + * Category: Display
> + * Description: Tests all rotations for all planes and formats.
> + * Driver requirement: none
> + * Functionality: plane, rotation
> + * Mega feature: General Display Features
> + * Test category: functionality test
> + */
> +
> +/**
> + * SUBTEST: rotations
> + * Description: Test for all rotations, planes and formats.
> + */
> +
> +/**
> + * struct data_t - Stores the test configuration
> + *
> + * @fd: file descriptor for the current drm device
> + * @display: display used for the tests
> + */
> +struct data_t {
> + int fd;
> + igt_display_t display;
> +};
> +
> +/**
> + * colors - List of colors used to put things on the plane
> + *
> + * Those colors are used to create a color pattern on the plane, which is not invariant by rotation or reflexion.
> + *
> + * At least black and white must be in this list to properly test black and white formats.
> + */
> +static const struct igt_vec4 colors[] = {
> + {{1.0f, 0.0f, 0.0f, 0.0f}},
> + {{1.0f, 1.0f, 1.0f, 0.0f}},
> + {{0.0f, 0.0f, 0.0f, 0.0f}},
> + {{0.0f, 1.0f, 1.0f, 0.0f}},
> + {{0.0f, 0.0f, 0.0f, 0.0f}},
> +};
> +
> +/**
> + * tested_rotation - List of all tested rotation configuration
> + */
> +static uint32_t tested_rotation[] = {
> + IGT_ROTATION_0,
> + IGT_ROTATION_0 | IGT_REFLECT_X,
> + IGT_ROTATION_0 | IGT_REFLECT_Y,
> + IGT_ROTATION_0 | IGT_REFLECT_X | IGT_REFLECT_Y,
> + IGT_ROTATION_90,
> + IGT_ROTATION_90 | IGT_REFLECT_X,
> + IGT_ROTATION_90 | IGT_REFLECT_Y,
> + IGT_ROTATION_90 | IGT_REFLECT_X | IGT_REFLECT_Y,
> + IGT_ROTATION_180,
> + IGT_ROTATION_180 | IGT_REFLECT_X,
> + IGT_ROTATION_180 | IGT_REFLECT_Y,
> + IGT_ROTATION_180 | IGT_REFLECT_X | IGT_REFLECT_Y,
> + IGT_ROTATION_270,
> + IGT_ROTATION_270 | IGT_REFLECT_X,
> + IGT_ROTATION_270 | IGT_REFLECT_Y,
> + IGT_ROTATION_270 | IGT_REFLECT_X | IGT_REFLECT_Y,
> +};
> +
> +/**
> + * non_equals_crc() - Check if at least one CRC is different
> + *
> + * Check if at least one CRC is different, so we can verify that the rendering is working.
> + *
> + * @crcs: List of all tested crcs
> + * @crc_count: Number of crcs in the list
> + */
> +static bool non_equals_crc(igt_crc_t crcs[], int crc_count) {
> + if (!crc_count) {
> + return true;
> + }
> + for (int i = 0; i < crc_count; i++)
> + if (!igt_check_crc_equal(&crcs[i], &crcs[0]))
> + return true;
> + return false;
> +}
> +
> +/**
> + * create_fb() - Create a framebuffer
> + *
> + * This create a framebuffer and fill it with a pattern. This pattern is not invariant by rotation and reflection.
> + *
> + * The @width and @height parameters are automaticaly inverted according to @rotation if needed. If the requested plane
> + * is 1024*768 with IGT_ROTATION_90, the returned plane will have the size 768*1024.
> + *
> + * @data: Current test configuration
> + * @rotation: Rotation to apply to the pattern
> + * @format: Format of the requested plane
> + * @modifier: Modifier for the requested plane
> + * @width: Width of the requested plane
> + * @height: Height of the requested plane
> + * @fb: Place to store the created framebuffer
> + */
> +static void create_fb(struct data_t *data, igt_rotation_t rotation, uint32_t format, uint64_t modifier, int width,
> + int height, igt_fb_t *fb)
> +{
> + int step_x, step_y, color_index, current_n, current_m;
> + cairo_t *cr;
> +
> + switch (rotation & IGT_ROTATION_MASK) {
> + case IGT_ROTATION_90:
> + case IGT_ROTATION_270:
> + igt_swap(width, height);
> + break;
> + case IGT_ROTATION_0:
> + case IGT_ROTATION_180:
> + default:
> + break;
> + }
> +
> + igt_create_fb(data->fd, width, height, format, modifier, fb);
> + cr = igt_get_cairo_ctx(data->fd, fb);
> +
> + step_x = (width) / ARRAY_SIZE(colors);
> + step_y = (height) / ARRAY_SIZE(colors);
> + /* Iterate over all colors in x and y direction. The pattern is a colored chessboard */
> + for (int n = 0; n < ARRAY_SIZE(colors); n++) {
> + for (int m = 0; m < ARRAY_SIZE(colors); m++) {
> + color_index = (n + m) % ARRAY_SIZE(colors);
> + current_n = n;
> + current_m = m;
> +
> + /*
> + * If a reflexion and a rotation is requested, apply this to the pattern rendering
> + * If a reflexion is given, it must be applied before the rotation.
> + */
> + switch (rotation & IGT_REFLECT_MASK) {
> + case IGT_REFLECT_X:
> + current_n = ARRAY_SIZE(colors) - 1 - current_n;
> + break;
> + case IGT_REFLECT_Y:
> + current_m = ARRAY_SIZE(colors) - 1 - current_m;
> + break;
> + case IGT_REFLECT_X | IGT_REFLECT_Y:
> + current_n = ARRAY_SIZE(colors) - 1 - current_n;
> + current_m = ARRAY_SIZE(colors) - 1 - current_m;
> + break;
> + }
> + switch (rotation & IGT_ROTATION_MASK) {
> + case IGT_ROTATION_0:
> + break;
> + case IGT_ROTATION_90:
> + igt_swap(current_n, current_m);
> + current_m = ARRAY_SIZE(colors) - 1 - current_m;
> + break;
> + case IGT_ROTATION_180:
> + current_n = ARRAY_SIZE(colors) - 1 - current_n;
> + current_m = ARRAY_SIZE(colors) - 1 - current_m;
> + break;
> + case IGT_ROTATION_270:
> + igt_swap(current_n, current_m);
> + current_n = ARRAY_SIZE(colors) - 1 - current_n;
> + break;
> + }
> +
> + igt_paint_color(cr,
> + current_n * step_x,
> + current_m * step_y,
> + step_x,
> + step_y,
> + colors[color_index].d[0],
> + colors[color_index].d[1],
> + colors[color_index].d[2]);
> + }
> + }
> +
> + igt_put_cairo_ctx(cr);
> +}
Hi all,
I just found an issue in create_fb when using different plane size. The
current implementation does not works when width % ARRAY_SIZE(colors) != 0
or height % ARRAY_SIZE(colors) != 0.
I did not see it during my tests because I was using only 4 colors and the
default size of VKMS, which is a multiple of 4.
I'm currently working on a fix to this, adding an offset to ensure that
"software rotated buffers" and "hardware rotated buffers" are the same.
I will also fix the typo in the test name reported by the CI.
In the mean time, don't hesitate to make comments on the rest of the
series, its content being mostly unchanged.
Kind regards,
Louis Chauvet
> +
> +/**
> + * get_ref_crcs() - Compute the reference CRC for a specific format
> + *
> + * The rotation are done by create_fb in software.
> + *
> + * @data: Test configuration
> + * @output, @pipe, @plane: Plane to use for the test
> + * @format, @modifier: Format description to test
> + * @ref_crc: Array to store the resulting CRC. Its size must be at least ARRAY_SIZE(tested_rotation).
> + */
> +static void get_ref_crcs(struct data_t *data, igt_output_t *output, enum pipe pipe, igt_plane_t *plane, uint32_t format,
> + uint64_t modifier, igt_crc_t ref_crc[ARRAY_SIZE(tested_rotation)])
> +{
> + drmModeModeInfo *mode;
> + igt_pipe_crc_t *pipe_crc;
> + igt_fb_t fb;
> +
> + igt_display_reset(&data->display);
> + igt_output_set_pipe(output, pipe);
> +
> +
> + for (int r = 0; r < ARRAY_SIZE(tested_rotation); r++) {
> + int rotation = tested_rotation[r];
> + /* Configure the pipe for reference frame */
> + igt_display_reset(&data->display);
> + igt_output_set_pipe(output, pipe);
> + igt_plane_set_rotation(plane, IGT_ROTATION_0);
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> + mode = igt_output_get_mode(output);
> +
> + /* Start the CRC */
> + pipe_crc = igt_pipe_crc_new(data->fd, pipe, IGT_PIPE_CRC_SOURCE_AUTO);
> + igt_pipe_crc_start(pipe_crc);
> +
> + create_fb(data, rotation, format, modifier, mode->vdisplay, mode->hdisplay, &fb);
> + igt_plane_set_fb(plane, &fb);
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> + igt_pipe_crc_get_current(
> + data->display.drm_fd, pipe_crc,
> + &ref_crc[r]);
> +
> + igt_pipe_crc_stop(pipe_crc);
> + igt_pipe_crc_free(pipe_crc);
> + igt_remove_fb(data->fd, &fb);
> + }
> +}
> +
> +/**
> + * get_crcs() - Compute the CRC for a specific format
> + *
> + * @data: Test configuration
> + * @output, @pipe, @plane: Plane to use for the test
> + * @format, @modifier: Format description to test
> + * @crc: Array to store the resulting CRC. Its size must be at least ARRAY_SIZE(tested_rotation).
> + */
> +static void get_crcs(struct data_t *data, igt_output_t *output, enum pipe pipe, igt_plane_t *plane, uint32_t format,
> + uint64_t modifier, igt_crc_t crc[ARRAY_SIZE(tested_rotation)])
> +{
> + drmModeModeInfo *mode;
> + igt_pipe_crc_t *pipe_crc;
> + igt_fb_t fb;
> +
> + igt_display_reset(&data->display);
> + igt_output_set_pipe(output, pipe);
> +
> +
> + for (int r = 0; r < ARRAY_SIZE(tested_rotation); r++) {
> + int rotation = tested_rotation[r];
> + /* Configure the pipe for reference frame */
> + igt_display_reset(&data->display);
> + igt_output_set_pipe(output, pipe);
> + igt_plane_set_rotation(plane, rotation);
> +
> + if (!igt_plane_has_rotation(plane, rotation))
> + continue;
> +
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> + mode = igt_output_get_mode(output);
> +
> + /* Start the CRC */
> + pipe_crc = igt_pipe_crc_new(data->fd, pipe, IGT_PIPE_CRC_SOURCE_AUTO);
> + igt_pipe_crc_start(pipe_crc);
> +
> + create_fb(data, IGT_ROTATION_0, format, modifier, mode->vdisplay, mode->hdisplay, &fb);
> + igt_plane_set_fb(plane, &fb);
> + if (igt_rotation_90_or_270(rotation))
> + igt_plane_set_size(plane, fb.height, fb.width);
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> + igt_pipe_crc_get_current(
> + data->display.drm_fd, pipe_crc,
> + &crc[r]);
> +
> + igt_pipe_crc_stop(pipe_crc);
> + igt_pipe_crc_free(pipe_crc);
> + igt_remove_fb(data->fd, &fb);
> + }
> +}
> +
> +/**
> + * run_test() - Run the subtests for a specific plane
> + *
> + * @data: Test configuration
> + * @output, @pipe, @plane: Plane to use for the test
> + * @format, @modifier: Format description to test
> + */
> +static void run_test(struct data_t *data, igt_output_t *output, enum pipe pipe, igt_plane_t *plane, uint32_t format, uint64_t modifier)
> +{
> + igt_crc_t ref_crc[ARRAY_SIZE(tested_rotation)];
> + igt_crc_t crc[ARRAY_SIZE(tested_rotation)];
> +
> + igt_display_reset(&data->display);
> + igt_output_set_pipe(output, pipe);
> + /* Check that the rotation is supported */
> + igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
> +
> + /* Generate reference CRC with software rotation */
> + get_ref_crcs(data, output, pipe, plane, format, modifier, ref_crc);
> + igt_assert_f(non_equals_crc(ref_crc, ARRAY_SIZE(tested_rotation)), "All the reference CRC are equals.");
> +
> + /* Generate CRC with hardware rotation */
> + get_crcs(data, output, pipe, plane, format, modifier, crc);
> +
> + for (int c = 0; c < ARRAY_SIZE(tested_rotation); c++) {
> + int rotation = tested_rotation[c];
> + igt_dynamic_f("pipe-%s-format-%s-modifier-%s-rotation-%s-reflect-%s", kmstest_pipe_name(pipe),
> + igt_format_str(format),
> + igt_fb_modifier_name(modifier), igt_plane_rotation_name(rotation),
> + igt_plane_reflect_name(rotation)) {
> + igt_assert_crc_equal(&ref_crc[c], &crc[c]);
> + }
> + }
> +}
> +
> +/**
> + * test_all_formats() - Run all the tests for all planes
> + *
> + * @data: Test configuration
> + */
> +static void test_all_formats(struct data_t *data)
> +{
> + enum pipe pipe;
> + struct igt_plane *plane;
> + igt_output_t *output;
> + for_each_pipe_with_single_output(&data->display, pipe, output) {
> + for_each_plane_on_pipe(&data->display, pipe, plane) {
> + for (int f = 0; f < plane->format_mod_count; f++) {
> + uint32_t format = plane->formats[f];
> + uint32_t modifier = plane->modifiers[f];
> +
> + if (!igt_fb_supported_format(format))
> + continue;
> + run_test(data, output, pipe, plane, format, modifier);
> + }
> + }
> + }
> +}
> +
> +static int opt_handler(int opt, int opt_index, void *void_data)
> +{
> + return IGT_OPT_HANDLER_SUCCESS;
> +}
> +
> +static const struct option long_opts[] = {
> + {}
> +};
> +
> +static const char help_str[] = "";
> +
> +static struct data_t global_data;
> +
> +igt_main_args("", long_opts, help_str, opt_handler, &global_data)
> +{
> + igt_fixture {
> + global_data.fd = drm_open_driver_master(DRIVER_ANY);
> +
> + kmstest_set_vt_graphics_mode();
> +
> + igt_display_require(&global_data.display, global_data.fd);
> + igt_require(global_data.display.is_atomic);
> + igt_display_require_output(&global_data.display);
> + igt_display_reset(&global_data.display);
> + }
> +
> + igt_describe("Testing different rotation and reflexions for different formats");
> + igt_subtest_with_dynamic_f("rotation") {
> + test_all_formats(&global_data);
> + }
> +
> +}
> \ No newline at end of file
> diff --git a/tests/meson.build b/tests/meson.build
> index a856510fcea7..71b628b86e96 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -82,6 +82,7 @@ test_progs = [
> 'tools_test',
> 'vgem_basic',
> 'vgem_slow',
> + 'kms_rotation',
> ]
>
> intel_i915_xe_progs = [
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-03-12 10:48 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-12 9:38 [PATCH i-g-t 0/3] New rotation test Louis Chauvet
2024-03-12 9:38 ` [PATCH i-g-t 1/3] lib/igt_kms: Add reflection name and mask Louis Chauvet
2024-03-12 9:38 ` [PATCH i-g-t 2/3] tests/kms_rotation: Add extensive rotation test Louis Chauvet
2024-03-12 10:48 ` Louis Chauvet
2024-03-12 9:39 ` [PATCH i-g-t 3/3] tests/kms_rotation: Add command line option to reduce the number of tests Louis Chauvet
2024-03-12 9:59 ` ✗ Fi.CI.BUILD: failure for New rotation test Patchwork
2024-03-12 10:07 ` ✗ GitLab.Pipeline: warning " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox