[igt-dev] [PATCH i-g-t v6 3/3] tests/kms_writeback: Enhance kms_writeback for custom modes
Rohith Iyer
quic_rohiiyer at quicinc.com
Thu Aug 4 22:02:35 UTC 2022
Enhance kms_writeback to add support for the below options:
- View all writeback modes
Usage: "./kms_writeback --list-modes"
- Test a built-in mode from connector list
Usage: "./kms_writeback --built-in <mode_index>"
- Test a custom mode from user input
Usage: "./kms_writeback --custom <mode_parameters>"
Refer to --help for exact syntax
- Dump the writeback output buffer to png file
Usage: "IGT_FRAME_DUMP_PATH=filepath FRAME_PNG_FILE_NAME=filename ./kms_writeback --dump"
Changes made in V4:
- Added header for writeback mode list
- Changed built-in mode short option from -s to -b for clarity
Changes made in V6:
- Fixed alignment for function arguments spilling over one line
Signed-off-by: Rohith Iyer <quic_rohiiyer at quicinc.com>
---
tests/kms_writeback.c | 173 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 153 insertions(+), 20 deletions(-)
diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
index 3866345c..82c244ff 100644
--- a/tests/kms_writeback.c
+++ b/tests/kms_writeback.c
@@ -26,6 +26,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
+#include <limits.h>
#include "igt.h"
#include "igt_core.h"
@@ -39,6 +40,17 @@ IGT_TEST_DESCRIPTION(
"by using CRC."
);
+typedef struct {
+ bool builtin_mode;
+ bool custom_mode;
+ bool list_modes;
+ bool dump_check;
+ int mode_index;
+ drmModeModeInfo user_mode;
+} data_t;
+
+static data_t data;
+
static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
{
drmModePropertyBlobRes *blob = NULL;
@@ -58,29 +70,15 @@ static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
return blob;
}
-static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
+static bool check_writeback_config(igt_display_t *display, igt_output_t *output,
+ drmModeModeInfo override_mode)
{
igt_fb_t input_fb, output_fb;
igt_plane_t *plane;
uint32_t writeback_format = DRM_FORMAT_XRGB8888;
uint64_t modifier = DRM_FORMAT_MOD_LINEAR;
int width, height, ret;
- drmModeModeInfo override_mode = {
- .clock = 25175,
- .hdisplay = 640,
- .hsync_start = 656,
- .hsync_end = 752,
- .htotal = 800,
- .hskew = 0,
- .vdisplay = 480,
- .vsync_start = 490,
- .vsync_end = 492,
- .vtotal = 525,
- .vscan = 0,
- .vrefresh = 60,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
- .name = {"640x480-60"},
- };
+
igt_output_override_mode(output, &override_mode);
width = override_mode.hdisplay;
@@ -112,6 +110,23 @@ static igt_output_t *kms_writeback_get_output(igt_display_t *display)
int i;
enum pipe pipe;
+ drmModeModeInfo override_mode = {
+ .clock = 25175,
+ .hdisplay = 640,
+ .hsync_start = 656,
+ .hsync_end = 752,
+ .htotal = 800,
+ .hskew = 0,
+ .vdisplay = 480,
+ .vsync_start = 490,
+ .vsync_end = 492,
+ .vtotal = 525,
+ .vscan = 0,
+ .vrefresh = 60,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .name = {"640x480-60"},
+ };
+
for (i = 0; i < display->n_outputs; i++) {
igt_output_t *output = &display->outputs[i];
@@ -121,7 +136,12 @@ static igt_output_t *kms_writeback_get_output(igt_display_t *display)
for_each_pipe(display, pipe) {
igt_output_set_pipe(output, pipe);
- if (check_writeback_config(display, output)) {
+ if (data.custom_mode)
+ override_mode = data.user_mode;
+ if (data.builtin_mode)
+ override_mode = output->config.connector->modes[data.mode_index];
+
+ if (check_writeback_config(display, output, override_mode)) {
igt_debug("Using connector %u:%s on pipe %d\n",
output->config.connector->connector_id,
output->name, pipe);
@@ -356,7 +376,108 @@ static void writeback_check_output(igt_output_t *output, igt_plane_t *plane,
igt_remove_fb(output_fb->fd, &second_out_fb);
}
-igt_main
+static void do_single_commit(igt_output_t *output, igt_plane_t *plane, igt_fb_t *in_fb,
+ igt_fb_t *out_fb)
+{
+ uint32_t in_fb_color = 0xffff0000;
+
+ fill_fb(in_fb, in_fb_color);
+
+ igt_plane_set_fb(plane, in_fb);
+ igt_output_set_writeback_fb(output, out_fb);
+
+ igt_display_commit_atomic(output->display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ if (out_fb)
+ get_and_wait_out_fence(output);
+}
+
+static void commit_and_dump_fb(igt_display_t *display, igt_output_t *output, igt_plane_t *plane,
+ igt_fb_t *input_fb, drmModeModeInfo *mode)
+{
+ cairo_surface_t *fb_surface_out;
+ char filepath_out[PATH_MAX];
+ cairo_status_t status;
+ char *path_name;
+ char *file_name;
+ unsigned int fb_id;
+ igt_fb_t output_fb;
+
+ path_name = getenv("IGT_FRAME_DUMP_PATH");
+ file_name = getenv("FRAME_PNG_FILE_NAME");
+ fb_id = igt_create_fb(display->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888,
+ igt_fb_mod_to_tiling(0), &output_fb);
+ igt_require(fb_id > 0);
+
+ do_single_commit(output, plane, input_fb, &output_fb);
+
+ fb_surface_out = igt_get_cairo_surface(display->drm_fd, &output_fb);
+ snprintf(filepath_out, PATH_MAX, "%s/%s.png", path_name, file_name);
+ status = cairo_surface_write_to_png(fb_surface_out, filepath_out);
+ igt_assert_eq(status, CAIRO_STATUS_SUCCESS);
+
+ igt_remove_fb(display->drm_fd, &output_fb);
+}
+
+static igt_output_t *list_writeback_modes(igt_display_t *display)
+{
+ for (int i = 0; i < display->n_outputs; i++) {
+ igt_output_t *output = &display->outputs[i];
+
+ if (output->config.connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) {
+ igt_info("\tname vref hdis hss hse htot vdis vss vse vtot flags type clock\n");
+ for (int j = 0; j < output->config.connector->count_modes; j++) {
+ igt_info("[%d]", j);
+ kmstest_dump_mode(&output->config.connector->modes[j]);
+ }
+ break;
+ }
+ }
+ return NULL;
+}
+
+static int opt_handler(int option, int option_index, void *_data)
+{
+ switch (option) {
+ case 'l':
+ data.list_modes = true;
+ break;
+ case 'b':
+ data.builtin_mode = true;
+ data.mode_index = atoi(optarg);
+ break;
+ case 'c':
+ data.custom_mode = true;
+ if (!igt_parse_mode_string(optarg, &data.user_mode))
+ return IGT_OPT_HANDLER_ERROR;
+ break;
+ case 'd':
+ data.dump_check = true;
+ break;
+ default:
+ return IGT_OPT_HANDLER_ERROR;
+ }
+ return IGT_OPT_HANDLER_SUCCESS;
+}
+
+const char *help_str =
+ " --list-modes | -l List of writeback connector modes\n"
+ " --built-in | -b Commits a built-in mode\n"
+ " --custom | -c Commits a custom mode inputted by user"
+ " <clock MHz>,<hdisp>,<hsync-start>,<hsync-end>,<htotal>,"
+ "<vdisp>,<vsync-start>,<vsync-end>,<vtotal>\n"
+ " --dump | -d Prints buffer to file location $IGT_FRAME_DUMP_PATH"
+ "/$FRAME_PNG_FILE_NAME "
+ "before running dump. Will skip all other tests.\n";
+
+static const struct option long_options[] = {
+ { .name = "list-modes", .has_arg = false, .val = 'l', },
+ { .name = "built-in", .has_arg = true, .val = 'b', },
+ { .name = "custom", .has_arg = true, .val = 'c', },
+ { .name = "dump", .has_arg = false, .val = 'd', },
+ {}
+};
+
+igt_main_args("b:c:dl", long_options, help_str, opt_handler, NULL)
{
igt_display_t display;
igt_output_t *output;
@@ -395,10 +516,19 @@ igt_main
&input_fb);
igt_assert(fb_id >= 0);
igt_plane_set_fb(plane, &input_fb);
- }
+ if (data.list_modes)
+ list_writeback_modes(&display);
+ if (data.dump_check)
+ commit_and_dump_fb(&display, output, plane, &input_fb, &mode);
+ }
+ /*
+ * When dump_check or list_modes flag is high, then the following subtests will be skipped
+ * as we do not want to do CRC validation.
+ */
igt_describe("Check the writeback format");
igt_subtest("writeback-pixel-formats") {
+ igt_skip_on(data.dump_check || data.list_modes);
drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
const char *valid_chars = "01234568 ABCGNRUVXY";
unsigned int i;
@@ -421,6 +551,7 @@ igt_main
"(output framebuffer and fence); this test goes through"
"the combination of possible bad options");
igt_subtest("writeback-invalid-parameters") {
+ igt_skip_on(data.dump_check || data.list_modes);
igt_fb_t invalid_output_fb;
fb_id = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
mode.vdisplay / 2,
@@ -436,6 +567,7 @@ igt_main
igt_describe("Validate WRITEBACK_FB_ID with valid and invalid options");
igt_subtest("writeback-fb-id") {
+ igt_skip_on(data.dump_check || data.list_modes);
igt_fb_t output_fb;
fb_id = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
DRM_FORMAT_XRGB8888,
@@ -450,6 +582,7 @@ igt_main
igt_describe("Check writeback output with CRC validation");
igt_subtest("writeback-check-output") {
+ igt_skip_on(data.dump_check || data.list_modes);
igt_fb_t output_fb;
fb_id = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
DRM_FORMAT_XRGB8888,
--
2.17.1
More information about the igt-dev
mailing list