diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2b34fcb4f..009033208 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,9 +4,11 @@ on: push: branches: - main + - fizzy pull_request: branches: - main + - fizzy workflow_dispatch: jobs: @@ -54,3 +56,129 @@ jobs: run: | SDK="$(xcrun --sdk iphoneos --show-sdk-path)" zig build -Dtarget=aarch64-ios -Dinclude_path="$SDK/usr/include" -Dframework_path="$SDK/System/Library/Frameworks" --summary all + + # fizzyedit/SDL's suites for fizzy's patches (`zig build test-fizzy`). Vulkan is Mesa's software + # driver, lavapipe, on a display with no screen: Xvfb for X11, headless weston for Wayland. + # + # In an Ubuntu 26.04 container, not on the 24.04 runner: this package builds SDL against + # libxkbcommon 1.13's headers, so SDL's Wayland driver needs `xkb_keymap_mod_get_mask` (1.10+) + # at run time, and 24.04 ships libxkbcommon 1.6. There the Wayland driver doesn't load. + test-fizzy-linux: + strategy: + fail-fast: false + matrix: + video: [x11, wayland] + runs-on: ubuntu-latest + container: ubuntu:26.04 + steps: + - name: Install tools, lavapipe and a headless display + run: | + apt-get update + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates git xz-utils \ + mesa-vulkan-drivers libvulkan1 vulkan-tools \ + xvfb xauth weston \ + libx11-6 libxext6 libxrandr2 libxcursor1 libxi6 libxfixes3 libxss1 libxtst6 \ + libwayland-client0 libwayland-cursor0 libwayland-egl1 libxkbcommon0 libdecor-0-0 + dpkg-query -W libxkbcommon0 libwayland-client0 mesa-vulkan-drivers weston + ls /usr/share/vulkan/icd.d + # The manifest's name moves between Mesa releases (lvp_icd.json, lvp_icd.x86_64.json) + echo "VK_DRIVER_FILES=$(ls /usr/share/vulkan/icd.d/lvp_icd*.json | head -n 1)" >> "$GITHUB_ENV" + + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Zig + uses: mlugg/setup-zig@v2 + with: + version: 0.16.0 + + - name: Workaround Zig 0.16.0 ZIP unpack failure + # https://codeberg.org/ziglang/zig/issues/31964 + run: mkdir -p "${ZIG_GLOBAL_CACHE_DIR}/tmp" + + - name: Build test-fizzy + run: zig build test-fizzy --summary all -- --list + + - name: Run test-fizzy on X11 (Xvfb) + if: matrix.video == 'x11' + env: + SDL_VIDEO_DRIVER: x11 + run: | + xvfb-run -a -s "-screen 0 1280x1024x24" vulkaninfo --summary + xvfb-run -a -s "-screen 0 1280x1024x24" zig build test-fizzy --summary all -- --require-gpu vulkan + + - name: Run test-fizzy on Wayland (headless weston) + if: matrix.video == 'wayland' + env: + SDL_VIDEO_DRIVER: wayland + WAYLAND_DISPLAY: wayland-fizzy + run: | + export XDG_RUNTIME_DIR="$(mktemp -d)" + chmod 700 "$XDG_RUNTIME_DIR" + weston --backend=headless --socket="$WAYLAND_DISPLAY" --idle-time=0 & + weston_pid=$! + for i in $(seq 50); do [ -S "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" ] && break; sleep 0.1; done + vulkaninfo --summary + zig build test-fizzy --summary all -- --require-gpu vulkan + kill "$weston_pid" + + # Do GitHub's hosted macOS runners have a Metal device? The probe says, and the suite requires + # Metal wherever the probe found one, so a runner with Metal can't skip the Metal tests. (On + # macos-14, MTLCreateSystemDefaultDevice() is nil from a command-line tool though + # MTLCopyAllDevices() lists the paravirtual GPU, and SDL's Metal driver works; hence the list.) + test-fizzy-macos: + strategy: + fail-fast: false + matrix: + os: [macos-14, macos-15, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Zig + uses: mlugg/setup-zig@v2 + with: + version: 0.16.0 + + - name: Workaround Zig 0.16.0 ZIP unpack failure + # https://codeberg.org/ziglang/zig/issues/31964 + run: mkdir -p "${ZIG_GLOBAL_CACHE_DIR}/tmp" + + - name: Displays + run: | + sw_vers + uname -m + system_profiler SPDisplaysDataType + + - name: Metal probe + id: probe + run: | + cat > metal_probe.m <<'EOF' + #import + #import + #include + int main(void) + { + @autoreleasepool { + id device = MTLCreateSystemDefaultDevice(); + NSArray> *all = MTLCopyAllDevices(); + printf("MTLCreateSystemDefaultDevice: %s\n", device ? device.name.UTF8String : "nil"); + printf("MTLCopyAllDevices: %lu\n", (unsigned long)all.count); + for (id d in all) { + printf(" %s (low power: %d, headless: %d)\n", d.name.UTF8String, d.lowPower, d.headless); + } + return all.count > 0 ? 0 : 1; + } + } + EOF + clang -fobjc-arc metal_probe.m -framework Foundation -framework Metal -o metal_probe + if ./metal_probe; then + echo "args=--require-gpu metal" >> "$GITHUB_OUTPUT" + else + echo "::warning::${{ matrix.os }}: no Metal device" + fi + + - name: Run test-fizzy + run: zig build test-fizzy --summary all -- ${{ steps.probe.outputs.args }} diff --git a/build.zig b/build.zig index c58fa5520..24c1bcfbe 100644 --- a/build.zig +++ b/build.zig @@ -171,4 +171,67 @@ pub fn build(b: *std.Build) !void { const run_example = b.addRunArtifact(example); const run_step = b.step("run-example", "Run the example app"); run_step.dependOn(&run_example.step); + + // fizzyedit/SDL's suites for fizzy's patches, on SDL's own test harness. Built only by this + // step, against the library above; nothing here is installed or reaches a consumer's build. + const sdl_test = b.addLibrary(.{ + .name = "SDL3_test", + .root_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + }), + }); + sdl_test.root_module.addIncludePath(upstream.path("include")); + sdl_test.root_module.addCSourceFiles(.{ + .files = &sdl_test_sources, + .root = upstream.path("src/test"), + }); + + const test_fizzy = b.addExecutable(.{ + .name = "testfizzy", + .root_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + }), + }); + test_fizzy.root_module.addIncludePath(upstream.path("include")); + test_fizzy.root_module.addCSourceFiles(.{ + .files = &fizzy_test_sources, + .root = upstream.path("test"), + }); + test_fizzy.root_module.linkLibrary(sdl_test); + test_fizzy.root_module.linkLibrary(lib); + + // Arguments after `--` reach the runner: `--filter `, `--require-gpu vulkan`. + const run_test_fizzy = b.addRunArtifact(test_fizzy); + if (@hasDecl(std.Build.Step.Run, "addPassthruArgs")) { + // Zig after 0.16.0, which drops `b.args` + run_test_fizzy.addPassthruArgs(); + } else if (b.args) |args| { + run_test_fizzy.addArgs(args); + } + const test_fizzy_step = b.step("test-fizzy", "Build and run fizzyedit/SDL's suites for fizzy's patches"); + test_fizzy_step.dependOn(&run_test_fizzy.step); } + +/// SDL_test, SDL's test library (`src/test`). +const sdl_test_sources = [_][]const u8{ + "SDL_test_assert.c", + "SDL_test_common.c", + "SDL_test_compare.c", + "SDL_test_crc32.c", + "SDL_test_font.c", + "SDL_test_fuzzer.c", + "SDL_test_harness.c", + "SDL_test_log.c", + "SDL_test_md5.c", + "SDL_test_memory.c", +}; + +/// The runner and the suites for fizzy's patches (`test`), one suite per patch. +const fizzy_test_sources = [_][]const u8{ + "testfizzy.c", + "testautomation_fizzy_gpu.c", +}; diff --git a/build.zig.zon b/build.zig.zon index 6fb961ce7..c02703651 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -5,13 +5,13 @@ .minimum_zig_version = "0.16.0", .dependencies = .{ // fizzyedit/SDL: release-3.4.16 with fizzy's patches on top. TEST PIN: branch - // `claude/windows-live-resize`, `fizzy-3.4` (tag `fizzy-3.4.16-4`) plus the Windows - // live-resize patch, untagged until it has been seen on hardware and moved onto `fizzy-3.4`. - // Pinned by commit. `.version` is still the SDL release it is based on: `build.zig` reads - // it for the library's SO version. + // `test/fizzy-gpu-suite`, `fizzy-3.4` (tag `fizzy-3.4.16-5`) plus the test suite for + // patch 1, untagged until it is reviewed and moved onto `fizzy-3.4`. Pinned by commit. + // `.version` is still the SDL release it is based on: `build.zig` reads it for the + // library's SO version. .sdl = .{ - .url = "https://github.com/fizzyedit/SDL/archive/ee721bf7c211654cf3c386a11044b9de375e9cbc.tar.gz", - .hash = "N-V-__8AAOBm-AINYw1BlSsIYXPujghEnITReiFr_ImJLoCw", + .url = "https://github.com/fizzyedit/SDL/archive/4839ede0ed6edf3d0f94af83bc79e59b20340aef.tar.gz", + .hash = "N-V-__8AABSV-AKS32FsG_ErVq84xfWjO_iibVYaWCROsjJy", .version = "3.4.16", }, .dbus = .{