From: Brian Starkey <brian.starkey@xxxxxxx> An output can be added as a clone of any other output(s) attached to a pipe using igt_output_clone_pipe() Signed-off-by: Brian Starkey <brian.starkey@xxxxxxx> --- lib/igt_kms.c | 90 +++++++++++++++++++++++++++++++++++++---------------------- lib/igt_kms.h | 3 ++ 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index aae32202..85dc0aa8 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -1560,6 +1560,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift) igt_assert(display->log_shift >= 0); } +static int igt_output_idx(igt_output_t *output) +{ + int i; + + for (i = 0; i < output->display->n_outputs; i++) + if (&output->display->outputs[i] == output) + return i; + + return -1; +} + static void igt_output_refresh(igt_output_t *output) { igt_display_t *display = output->display; @@ -1990,40 +2001,6 @@ void igt_display_fini(igt_display_t *display) display->pipes = NULL; } -static void igt_display_refresh(igt_display_t *display) -{ - igt_output_t *output; - int i; - - unsigned long pipes_in_use = 0; - - /* Check that two outputs aren't trying to use the same pipe */ - for (i = 0; i < display->n_outputs; i++) { - output = &display->outputs[i]; - - if (pipes_in_use & output->pending_crtc_idx_mask) - goto report_dup; - - pipes_in_use |= output->pending_crtc_idx_mask; - - if (output->force_reprobe) - igt_output_refresh(output); - } - - return; - -report_dup: - for (; i > 0; i--) { - igt_output_t *b = &display->outputs[i - 1]; - - igt_assert_f(output->pending_crtc_idx_mask != - b->pending_crtc_idx_mask, - "%s and %s are both trying to use pipe %s\n", - igt_output_name(output), igt_output_name(b), - kmstest_pipe_name(ffs(b->pending_crtc_idx_mask) - 1)); - } -} - static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output) { igt_display_t *display = output->display; @@ -2047,6 +2024,38 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output) return &display->pipes[pipe]; } +static void igt_display_refresh(igt_display_t *display) +{ + igt_output_t *output; + igt_pipe_t *pipe; + int i; + + unsigned long pipes_in_use = 0; + + /* Check that outputs and pipes agree wrt. cloning */ + for (i = 0; i < display->n_outputs; i++) { + output = &display->outputs[i]; + + pipe = igt_output_get_driving_pipe(output); + if (pipe) { + igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)), + "Output %s not expected to be using pipe %s\n", + igt_output_name(output), + kmstest_pipe_name(pipe->pipe)); + + if (pipes_in_use & output->pending_crtc_idx_mask) + LOG(display, "Output %s clones pipe %s\n", + igt_output_name(output), + kmstest_pipe_name(pipe->pipe)); + } + + pipes_in_use |= output->pending_crtc_idx_mask; + + if (output->force_reprobe) + igt_output_refresh(output); + } +} + static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx) { igt_assert_f(plane_idx >= 0 && plane_idx < pipe->n_planes, @@ -2941,6 +2950,16 @@ void igt_output_override_mode(igt_output_t *output, drmModeModeInfo *mode) pipe->mode_changed = true; } +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe) +{ + igt_display_t *display = output->display; + uint32_t current_clones = display->pipes[pipe].outputs; + + igt_output_set_pipe(output, pipe); + + display->pipes[pipe].outputs |= current_clones; +} + void igt_output_set_pipe(igt_output_t *output, enum pipe pipe) { igt_display_t *display = output->display; @@ -2952,6 +2971,7 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe) old_pipe = igt_output_get_driving_pipe(output); old_pipe->mode_changed = true; + old_pipe->outputs &= ~(1 << igt_output_idx(output)); } if (pipe == PIPE_NONE) { @@ -2963,6 +2983,8 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe) output->pending_crtc_idx_mask = 1 << pipe; display->pipes[pipe].mode_changed = true; + + display->pipes[pipe].outputs = (1 << igt_output_idx(output)); } output->config.pipe_changed = true; diff --git a/lib/igt_kms.h b/lib/igt_kms.h index ab8ec764..9ddcfade 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -358,6 +358,8 @@ struct igt_pipe { int32_t out_fence_fd; bool out_fence_requested; + + uint32_t outputs; }; typedef struct { @@ -402,6 +404,7 @@ const char *igt_output_name(igt_output_t *output); drmModeModeInfo *igt_output_get_mode(igt_output_t *output); void igt_output_override_mode(igt_output_t *output, drmModeModeInfo *mode); void igt_output_set_pipe(igt_output_t *output, enum pipe pipe); +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe); void igt_output_set_scaling_mode(igt_output_t *output, uint64_t scaling_mode); igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx); -- 2.13.2 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel