[PATCH i-g-t 1/2] tests/kms_joiner: Add tests for Ultrajoiner validation
Karthik B S
karthik.b.s at intel.com
Mon Aug 12 04:47:38 UTC 2024
Add a subtest to validate basic ultrajoiner modeset and a negative test
to validate invalid pipe configs during an ultrajoiner modeset.
Signed-off-by: Karthik B S <karthik.b.s at intel.com>
---
lib/igt_kms.c | 44 +++++
lib/igt_kms.h | 3 +
.../intel/{kms_big_joiner.c => kms_joiner.c} | 150 ++++++++++++++++--
tests/meson.build | 2 +-
4 files changed, 183 insertions(+), 16 deletions(-)
rename tests/intel/{kms_big_joiner.c => kms_joiner.c} (74%)
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index e030b35a6..08b628f1a 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -6347,6 +6347,50 @@ bool bigjoiner_mode_found(int drm_fd, drmModeConnector *connector,
return found;
}
+/**
+ * igt_ultrajoiner_possible:
+ * @mode: libdrm mode
+ * @max_dotclock: Max pixel clock frequency
+ *
+ * Ultrajoiner will come into the picture, when the requested
+ * mode resolution > 10K or mode clock > 2 * max_dotclock.
+ *
+ * Returns: True if mode requires Ultrajoiner, else False.
+ */
+bool igt_ultrajoiner_possible(drmModeModeInfo *mode, int max_dotclock)
+{
+ return (mode->hdisplay > 2 * MAX_HDISPLAY_PER_PIPE ||
+ mode->clock > 2 * max_dotclock);
+}
+
+/**
+ * Ultrajoiner_mode_found:
+ * @drm_fd: drm file descriptor
+ * @connector: libdrm connector
+ * @max_dot_clock: max dot clock frequency
+ * @mode: libdrm mode to be filled
+ *
+ * Ultrajoiner will come in to the picture when the
+ * resolution > 10K or clock > 2 * max-dot-clock.
+ *
+ * Returns: True if big joiner found in connector modes
+ */
+bool ultrajoiner_mode_found(int drm_fd, drmModeConnector *connector,
+ int max_dotclock, drmModeModeInfo *mode)
+{
+ bool found = false;
+
+ igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc);
+ found = igt_ultrajoiner_possible(&connector->modes[0], max_dotclock);
+ if (!found) {
+ igt_sort_connector_modes(connector, sort_drm_modes_by_clk_dsc);
+ found = igt_ultrajoiner_possible(&connector->modes[0], max_dotclock);
+ }
+ if (found)
+ *mode = connector->modes[0];
+ return found;
+}
+
/**
* igt_has_force_joiner_debugfs
* @drmfd: A drm file descriptor
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index e8582a45b..c8e89b076 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -1216,6 +1216,9 @@ int igt_get_max_dotclock(int fd);
bool igt_bigjoiner_possible(drmModeModeInfo *mode, int max_dotclock);
bool bigjoiner_mode_found(int drm_fd, drmModeConnector *connector,
int max_dotclock, drmModeModeInfo *mode);
+bool igt_ultrajoiner_possible(drmModeModeInfo *mode, int max_dotclock);
+bool ultrajoiner_mode_found(int drm_fd, drmModeConnector *connector,
+ int max_dotclock, drmModeModeInfo *mode);
bool igt_has_force_joiner_debugfs(int drmfd, char *conn_name);
bool igt_check_force_joiner_status(int drmfd, char *connector_name);
bool igt_check_bigjoiner_support(igt_display_t *display);
diff --git a/tests/intel/kms_big_joiner.c b/tests/intel/kms_joiner.c
similarity index 74%
rename from tests/intel/kms_big_joiner.c
rename to tests/intel/kms_joiner.c
index 7c370bc60..633bf51c7 100644
--- a/tests/intel/kms_big_joiner.c
+++ b/tests/intel/kms_joiner.c
@@ -37,13 +37,20 @@
#include "igt.h"
/**
- * SUBTEST: invalid-modeset
+ * SUBTEST: invalid-modeset-big-joiner
* Description: Verify if the modeset on the adjoining pipe is rejected when
* the pipe is active with a big joiner modeset
*
- * SUBTEST: basic
+ * SUBTEST: invalid-modeset-ultra-joiner
+ * Description: Verify if the modeset on the other pipes are rejected when
+ * the pipe A is active with ultra joiner modeset
+ *
+ * SUBTEST: basic-big-joiner
* Description: Verify the basic modeset on big joiner mode on all pipes
*
+ * SUBTEST: basic-ultra-joiner
+ * Description: Verify the basic modeset on ultra joiner mode on all pipes
+ *
* SUBTEST: invalid-modeset-force-joiner
* Description: Verify if modeset on adjacent pipe is declined when force joiner modeset is active.
* Force joiner applies bigjoiner functionality to non-bigjoiner outputs,
@@ -54,20 +61,24 @@
* Force joiner applies bigjoiner functionality to non-bigjoiner outputs thus,
* the test exclusively targets non-bigjoiner outputs.
*/
-IGT_TEST_DESCRIPTION("Test big joiner / force joiner");
+IGT_TEST_DESCRIPTION("Test joiner / force joiner");
#define INVALID_TEST_OUTPUT 2
typedef struct {
int drm_fd;
int big_joiner_output_count;
+ int ultra_joiner_output_count;
int non_big_joiner_output_count;
+ int non_ultra_joiner_output_count;
int mixed_output_count;
int output_count;
int n_pipes;
uint32_t master_pipes;
igt_output_t *big_joiner_output[IGT_MAX_PIPES];
+ igt_output_t *ultra_joiner_output[IGT_MAX_PIPES];
igt_output_t *non_big_joiner_output[IGT_MAX_PIPES];
+ igt_output_t *non_ultra_joiner_output[IGT_MAX_PIPES];
igt_output_t *mixed_output[IGT_MAX_PIPES];
enum pipe pipe_seq[IGT_MAX_PIPES];
igt_display_t display;
@@ -286,6 +297,81 @@ static void test_joiner_on_last_pipe(data_t *data, bool force_joiner)
}
}
+static void test_ultra_joiner(data_t *data, bool invalid_pipe, bool two_display)
+{
+ int i, j, k, ret;
+ igt_output_t *output, *non_ultra_joiner_output;
+ igt_plane_t *primary;
+ igt_output_t **outputs;
+ igt_fb_t fb;
+ drmModeModeInfo mode;
+
+ outputs = data->ultra_joiner_output;
+ igt_display_reset(&data->display);
+ igt_display_commit2(&data->display, COMMIT_ATOMIC);
+
+ for (i = 0; i < data->ultra_joiner_output_count; i++) {
+ output = outputs[i];
+ igt_require(ultrajoiner_mode_found(data->drm_fd, output->config.connector, max_dotclock, &mode));
+ igt_output_override_mode(output, &mode);
+ for (j = 0; j < data->n_pipes; j++) {
+ /* Ultra joiner is only valid on PIPE_A */
+ if (invalid_pipe && j == PIPE_A)
+ continue;
+ if (!invalid_pipe && j != PIPE_A)
+ continue;
+ if (two_display && j != PIPE_A)
+ continue;
+
+ igt_output_set_pipe(output, data->pipe_seq[j]);
+
+ primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+ igt_create_pattern_fb(data->drm_fd, mode.hdisplay, mode.vdisplay, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_MOD_LINEAR, &fb);
+ igt_plane_set_fb(primary, &fb);
+
+ if (invalid_pipe)
+ ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC);
+ else
+ igt_display_commit2(&data->display, COMMIT_ATOMIC);
+
+ if (two_display) {
+ for_each_connected_output(&data->display, non_ultra_joiner_output) {
+ if (output->id != non_ultra_joiner_output->id) {
+ for (k = 1; k < data->n_pipes; k++) {
+ igt_plane_t *plane;
+ drmModeModeInfo *mode1;
+
+ mode1 = igt_output_get_mode(non_ultra_joiner_output);
+
+ igt_output_set_pipe(non_ultra_joiner_output, data->pipe_seq[k]);
+ plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+
+ igt_plane_set_fb(plane, &fb);
+ igt_fb_set_size(&fb, plane, mode1->hdisplay, mode1->vdisplay);
+ igt_plane_set_size(plane, mode1->hdisplay, mode1->vdisplay);
+
+ ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC);
+
+ igt_plane_set_fb(plane, NULL);
+ igt_assert_f(ret != 0, "Commit expected to fail on second display\n");
+ }
+ /* Validation with one output is sufficient */
+ break;
+ }
+ }
+ }
+
+ igt_display_reset(&data->display);
+ igt_plane_set_fb(primary, NULL);
+ igt_remove_fb(data->drm_fd, &fb);
+
+ if (invalid_pipe)
+ igt_assert_f(ret != 0, "Commit shouldn't have passed\n");
+ }
+ }
+}
+
igt_main
{
bool force_joiner_supported;
@@ -297,7 +383,9 @@ igt_main
igt_fixture {
force_joiner_supported = false;
data.big_joiner_output_count = 0;
+ data.ultra_joiner_output_count = 0;
data.non_big_joiner_output_count = 0;
+ data.non_ultra_joiner_output_count = 0;
data.mixed_output_count = 0;
data.output_count = 0;
j = 0;
@@ -310,24 +398,31 @@ igt_main
max_dotclock = igt_get_max_dotclock(data.drm_fd);
for_each_connected_output(&data.display, output) {
- bool found = false;
+ bool ultrajoiner_found = false, bigjoiner_found = false;
drmModeConnector *connector = output->config.connector;
/*
* Bigjoiner will come in to the picture when the
* resolution > 5K or clock > max-dot-clock.
+ * Ultrajoiner will come in to the picture when the
+ * resolution > 10K or clock > 2 * max-dot-clock.
*/
- found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock, &mode);
+ bigjoiner_found = bigjoiner_mode_found(data.drm_fd, connector, max_dotclock, &mode);
+ ultrajoiner_found = ultrajoiner_mode_found(data.drm_fd, connector, max_dotclock, &mode);
- if (found) {
+ if (igt_has_force_joiner_debugfs(data.drm_fd, output->name))
+ force_joiner_supported = true;
+
+ if (ultrajoiner_found)
+ data.ultra_joiner_output[data.ultra_joiner_output_count++] = output;
+ else if (force_joiner_supported)
+ data.non_ultra_joiner_output[data.non_ultra_joiner_output_count++] = output;
+
+ if (bigjoiner_found)
data.big_joiner_output[data.big_joiner_output_count++] = output;
- igt_output_override_mode(output, &mode);
- } else {
- if (igt_has_force_joiner_debugfs(data.drm_fd, output->name)) {
- force_joiner_supported = true;
- data.non_big_joiner_output[data.non_big_joiner_output_count++] = output;
- }
- }
+ else if (force_joiner_supported)
+ data.non_big_joiner_output[data.non_big_joiner_output_count++] = output;
+
data.output_count++;
}
if (data.big_joiner_output_count == 1 && data.non_big_joiner_output_count >= 1) {
@@ -337,6 +432,7 @@ igt_main
data.mixed_output[data.mixed_output_count++] = data.big_joiner_output[0];
data.mixed_output[data.mixed_output_count++] = data.non_big_joiner_output[0];
}
+
data.n_pipes = 0;
for_each_pipe(&data.display, i) {
data.n_pipes++;
@@ -346,7 +442,7 @@ igt_main
}
igt_describe("Verify the basic modeset on big joiner mode on all pipes");
- igt_subtest_with_dynamic("basic") {
+ igt_subtest_with_dynamic("basic-big-joiner") {
igt_require_f(data.big_joiner_output_count > 0,
"No bigjoiner output found\n");
igt_require_f(data.n_pipes > 1,
@@ -358,9 +454,19 @@ igt_main
test_multi_joiner(&data, data.big_joiner_output_count, false);
}
+ igt_describe("Verify the basic modeset on ultra joiner mode on all pipes");
+ igt_subtest_with_dynamic("basic-ultra-joiner") {
+ igt_require_f(data.ultra_joiner_output_count > 0,
+ "No ultrajoiner output found\n");
+ igt_require_f(data.n_pipes > 3,
+ "Minimum 4 pipes required\n");
+ igt_dynamic_f("single-joiner")
+ test_ultra_joiner(&data, false, false);
+ }
+
igt_describe("Verify if the modeset on the adjoining pipe is rejected "
"when the pipe is active with a big joiner modeset");
- igt_subtest_with_dynamic("invalid-modeset") {
+ igt_subtest_with_dynamic("invalid-modeset-big-joiner") {
igt_require_f(data.big_joiner_output_count > 0, "Non big joiner output not found\n");
igt_require_f(data.n_pipes > 1, "Minimum of 2 pipes are required\n");
if (data.big_joiner_output_count >= 1)
@@ -374,6 +480,20 @@ igt_main
test_invalid_modeset_two_joiner(&data, true, false);
}
+ igt_describe("Verify if the modeset on the other pipes are rejected "
+ "when the pipe A is active with a ultra joiner modeset");
+ igt_subtest_with_dynamic("invalid-modeset-ultra-joiner") {
+ igt_require_f(data.ultra_joiner_output_count > 0, "Ultra joiner output not found\n");
+ igt_require_f(data.n_pipes > 3, "Minimum of 4 pipes are required\n");
+
+ igt_dynamic_f("ultra_joiner_on_invalid_pipe")
+ test_ultra_joiner(&data, true, false);
+ if (data.non_ultra_joiner_output_count > 0) {
+ igt_dynamic_f("2x")
+ test_ultra_joiner(&data, false, true);
+ }
+ }
+
igt_describe("Verify the basic modeset on big joiner mode on all pipes");
igt_subtest_with_dynamic("basic-force-joiner") {
igt_require_f(force_joiner_supported,
diff --git a/tests/meson.build b/tests/meson.build
index e649466be..7cf359962 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -242,7 +242,6 @@ intel_i915_progs = [
intel_kms_progs = [
'kms_big_fb',
- 'kms_big_joiner' ,
'kms_busy',
'kms_ccs',
'kms_cdclk',
@@ -255,6 +254,7 @@ intel_kms_progs = [
'kms_flip_scaled_crc',
'kms_flip_tiling',
'kms_frontbuffer_tracking',
+ 'kms_joiner',
'kms_legacy_colorkey',
'kms_mmap_write_crc',
'kms_pipe_b_c_ivb',
--
2.39.1
More information about the igt-dev
mailing list