Skip to content

[Task] Headless Vulkan CI tests for swapchain resize state machine #627

Description

@JeanPhilippeKernel

Type

  • Task / chore

Overview

PR #623 introduced RecreationState to fix swapchain resize hangs on Linux/Mesa Intel.
A headless Vulkan test suite was drafted (PR #626) to exercise the state machine in CI
without a physical GPU, but was removed from #623 because the tests skip on every CI
runner tried so far — the Vulkan ICD is not being found by the test binary.

Context

The test infrastructure exists and is correct:

  • HeadlessWindowCoreWindow via VK_EXT_headless_surface, no display needed.
  • ForceRecreation(RecreationState) — debug API on DeviceSwapchain to inject state.
  • 11 test cases covering Pending, FrameAborted, rapid cycles, size changes, minimize/restore.

The blocker is that the CI test binary uses a Vulkan loader from the build artifacts
(LD_LIBRARY_PATH=$workspace/lib). This loader does not pick up the system ICD
(VK_ICD_FILENAMES/VK_DRIVER_FILES) because it was compiled against the build
machine's Vulkan environment, not the test runner's.

Attempts tried:

  • Mesa lavapipe (mesa-vulkan-drivers + VK_DRIVER_FILES=lvp_icd.x86_64.json)
  • SwiftShader via LunarG Vulkan SDK (vulkan-sdk + VK_ICD_FILENAMES=vk_swiftshader_icd.json)
  • Updated apt key format (modern gpg --dearmor instead of deprecated apt-key add)
  • Prepending /usr/lib/x86_64-linux-gnu to LD_LIBRARY_PATH
  • Replaced vkEnumerateInstanceExtensionProperties check with vkCreateInstance probe

All attempts produce the same result: IsSupported() returns false on Linux CI.

What needs to be done

The root issue is that the build artifacts ship their own libvulkan.so and the test runner
uses it instead of the system loader. One of these approaches should fix it:

  1. Exclude libvulkan.so from artifacts — let the test runner use its own system loader.
    The test runner installs SwiftShader, system loader finds it via VK_ICD_FILENAMES.

  2. Separate headless test binary — build a dedicated ZEngineHeadlessTests target that
    is statically linked or explicitly depends on the system Vulkan loader, separate from the
    main ZEngineTests.

  3. Use a Docker-based CI runner with SwiftShader pre-installed, so the Vulkan environment
    is fully controlled.

Acceptance criteria

  • SwapchainResizeFixture.* tests run (not skip) on Linux x64 CI
  • AggressiveRecreation_HundredCycles_NoHang passes on Ubuntu 24.04 without a GPU
  • AlternatingAbortAndPending_NoHang passes (the specific Intel/Ubuntu pattern)
  • No regression on macOS/Windows (all 11 tests skip cleanly there)
  • CI runtime increase < 2 minutes for the headless test suite

Estimated effort

Half a day (CI plumbing only — test code already exists in the test/swapchain-headless branch).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions