The existing writeback tests validate captured framebuffer contents, but
do not keep pipe CRC capture active across writeback completion. This
misses the VKMS bug where writeback cleanup disables the composer while
CRC capture still needs it, leaving subsequent CRC reads waiting for
samples that never arrive.

Add a VKMS-only writeback-preserves-crc subtest. Complete the initial
modeset before starting capture and establish reference CRCs for separate
red and blue input framebuffers. Keep capture open across four alternating
writebacks, wait for each output fence, and compare three fresh CRC samples
with the corresponding reference after each writeback. Do not allow
modesets once capture starts, since they may disrupt CRC generation.

Clear the pending out-fence request left by the configuration probe before
the initial modeset so the subtest also works when run independently.
Use the final fixture to close capture, disable the output, and remove the
two new framebuffers so subtest failure or skip also cleans them up.

Check output fence status in the shared wait helper so a signalled error
fence cannot be treated as a successful writeback.

On ARM64 QEMU with one and two CPUs, the new subtest fails with a CRC read
timeout on the unmodified kernel and passes with the VKMS composer-user
lifetime fix, both independently and in the full writeback suite.

Signed-off-by: Aditya Tipre <[email protected]>
---
Changes in v3:
- Add the preceding writeback-fb-id completion fix so earlier subtests do
  not race while reusing the shared input framebuffer.
- Restrict the new subtest to VKMS in metadata and at runtime.
- Explain why commits after starting CRC capture do not allow modesets.
- Release the new framebuffers in the final fixture after disabling output.
- Clear the configuration probe's pending writeback out-fence request so
  the subtest works independently of earlier writeback subtests.

Changes in v2:
- Use my full name in the author and Signed-off-by fields.
- No code changes.

Validation on ARM64 QEMU/HVF with one and two CPUs:
- With both patches applied, all four existing applicable subtests pass on
  the unfixed and fixed kernels; both XRGB2101010 cases skip.
- The new regression, independently and in the full suite, times out at
  the post-writeback CRC read on the unfixed kernel and passes with the
  VKMS composer lifetime fix.
- Disposable probes verify FB and buffer-handle cleanup before DRM FD close
  after partial setup, CRC comparison failure while blue is scanned out,
  the natural baseline timeout, success, and skip.

 tests/kms_writeback.c | 67 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
index 550d603..e277752 100644
--- a/tests/kms_writeback.c
+++ b/tests/kms_writeback.c
@@ -64,6 +64,10 @@
  *
  * SUBTEST: writeback-pixel-formats
  * Description: Check the writeback format
+ *
+ * SUBTEST: writeback-preserves-crc
+ * Description: CRC capture remains active across completed writebacks
+ * Driver requirement: vkms
  */
 
 IGT_TEST_DESCRIPTION(
@@ -321,6 +325,7 @@ static void get_and_wait_out_fence(igt_output_t *output)
 
        ret = sync_fence_wait(output->writeback_out_fence_fd, 1000);
        igt_assert_f(ret == 0, "sync_fence_wait failed: %s\n", strerror(-ret));
+       igt_assert_eq(sync_fence_status(output->writeback_out_fence_fd), 1);
        close(output->writeback_out_fence_fd);
        output->writeback_out_fence_fd = -1;
 }
@@ -541,6 +546,8 @@ int igt_main_args("b:c:f:dl", long_options, help_str, 
opt_handler, NULL)
        igt_output_t *output;
        igt_plane_t *plane;
        igt_fb_t input_fb, input_fb_10bit;
+       static igt_pipe_crc_t *pipe_crc;
+       static igt_fb_t crc_blue_fb, crc_output_fb;
        drmModeModeInfo mode;
        unsigned int fb_id;
        int ret;
@@ -713,8 +720,68 @@ int igt_main_args("b:c:f:dl", long_options, help_str, 
opt_handler, NULL)
                igt_remove_fb(display.drm_fd, &output_fb);
        }
 
+       igt_describe("CRC capture remains active across completed writebacks");
+       igt_subtest("writeback-preserves-crc") {
+               igt_fb_t *colors[] = { &input_fb, &crc_blue_fb };
+               igt_crc_t reference[2], crc;
+               int i, j;
+
+               igt_skip_on(data.dump_check || data.list_modes);
+               igt_require(is_vkms_device(display.drm_fd));
+               igt_require(data.supported_colors & XRGB8888);
+               igt_require_pipe_crc(display.drm_fd);
+
+               igt_create_color_fb(display.drm_fd, mode.hdisplay, 
mode.vdisplay,
+                                   DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
+                                   0.0, 0.0, 1.0, &crc_blue_fb);
+               igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
+                             DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
+                             &crc_output_fb);
+               fill_fb(&input_fb, 0x00ff0000);
+               igt_plane_set_fb(plane, &input_fb);
+               igt_output_set_writeback_fb(output, NULL);
+               /* Discard the out-fence request left by the configuration 
probe. */
+               igt_output_set_prop_value(output, 
IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
+                                         to_user_pointer(NULL));
+               igt_display_commit_atomic(&display, 
DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+               /* Finish the modeset before starting continuous CRC capture. */
+               pipe_crc = igt_pipe_crc_new(display.drm_fd, 
output->config.crtc_index,
+                                           IGT_PIPE_CRC_SOURCE_AUTO);
+               igt_pipe_crc_start(pipe_crc);
+
+               /*
+                * Establish both references before writeback can affect 
capture.
+                * Do not allow modesets below: they may disrupt continuous CRC
+                * generation.
+                */
+               for (i = 0; i < ARRAY_SIZE(colors); i++) {
+                       igt_plane_set_fb(plane, colors[i]);
+                       igt_display_commit_atomic(&display, 0, NULL);
+                       igt_pipe_crc_get_current(display.drm_fd, pipe_crc, 
&reference[i]);
+               }
+
+               for (i = 0; i < 4; i++) {
+                       int color = i % ARRAY_SIZE(colors);
+
+                       igt_plane_set_fb(plane, colors[color]);
+                       igt_output_set_writeback_fb(output, &crc_output_fb);
+                       igt_display_commit_atomic(&display, 0, NULL);
+                       get_and_wait_out_fence(output);
+
+                       /* Require fresh frames without stopping or restarting 
capture. */
+                       for (j = 0; j < 3; j++) {
+                               igt_pipe_crc_get_current(display.drm_fd, 
pipe_crc, &crc);
+                               igt_assert_crc_equal(&reference[color], &crc);
+                       }
+               }
+       }
+
        igt_fixture() {
+               igt_pipe_crc_free(pipe_crc);
                cleanup_writeback(&display, output);
+               igt_remove_fb(display.drm_fd, &crc_blue_fb);
+               igt_remove_fb(display.drm_fd, &crc_output_fb);
                igt_remove_fb(display.drm_fd, &input_fb);
 
                if (data.supported_colors & XRGB2101010)
-- 
2.50.1 (Apple Git-155)

Reply via email to