mirror of
https://github.com/libretro/virtualjaguar-libretro.git
synced 2026-11-07 12:47:58 -10:00
* feat(app): --shader PRESET|off for one run, and a [shader] result line per chain `--shader PRESET.slangp` runs this one run through that preset and `--shader off` through none; neither is written back to config.ini (like --theme). A missing or malformed preset is a usage error (exit 2) instead of a plain picture with a toast. shaders.cpp now logs one stderr line when a chain is built or cannot be: [shader] <preset> built: GLSL 410 on OpenGL 4.1 [shader] <preset> refused: ... (the GL_ARB_arrays_of_arrays limit, macOS GL 4.1) [shader] <preset> failed: ... (librashader's message) so a CI run has a record of what the chain did (#1155 GL qualification). Refs #1155 Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci: GL qualification workflow: windowed boot + every shader preset on Linux, Windows, macOS One reusable workflow, gl-qualification.yml, boots the desktop app windowed with a real OpenGL context on hosted runners and renders every bundled .slangp through librashader, keeping the screenshots. Legs: Linux (ubuntu-24.04, Xvfb + llvmpipe), Windows x64 (hosted, no vendor GL: the automatic bundled-Mesa relaunch of #1138/#1143 must fire), Windows arm64 (folds in windows-gl-test.yml, which is retired), macOS arm64 (Apple OpenGL 4.1; the 15 arrays-of-arrays presets are allowlisted as refused). Per leg: one build, cmake --install into stage/, vj_shader_tests gl run directly (exit 77 = skipped = failure here), then app/test/gl-qualification/gl_qualify.py launches --shader off and every preset with --screenshot and asserts exit 0, the last [gl] renderer line, a non-black PNG, a [shader] built line and a picture that differs from the plain one. Artifacts upload pass or fail; the job summary lists failures with the [gl]/[shader] log tail. Goldens are designed (app/test/golden/gl/<os>/<preset>.png, refresh_goldens input) but not gated. Triggers: pull_request on the GL/shader/packaging paths, workflow_call (release.yml requires it on tags and release/**), nightly schedule, workflow_dispatch. Closes #1155 Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): judge shaders_gl after the preset loop, fail fast, time the x64 fallback First run (41565368188) findings: shaders_gl fails on llvmpipe and on Apple's software renderer (crt-royale renders black in the 128x64 test picture) and the step stopped the leg before any screenshot existed; the x64 automatic-fallback boot hit `timeout 120` where arm64 took 3 s; the arm64 shaders_gl could not load the upstream prebuilt librashader.dll (eager D3DX9_43.dll import, #1153/#1161). - shaders_gl runs with continue-on-error and a "shaders_gl verdict" step fails the job after the preset loop, so the screenshots and logs upload either way. - gl_qualify.py --fail-fast N (default 8): the loop stops after N consecutive failed presets and the summary says how many were not run. - Windows fallback step: timeout 300 s, elapsed seconds logged (automatic-seconds.txt). Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): empty-array expansion safe for macOS bash 3.2 (set -u) Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): Windows leg records the boot, runs timing diagnostics, gates the loop Second run (41567744247): the x64 automatic-fallback boot did not return within 300 s although the screenshot was written (frame 20 reached); arm64 does the same in 2 s. - the loader probe (context create/draw/destroy through the bundled Mesa) runs before the app boot, timed; - the boot step records exit code, seconds and each side condition (automatic-seconds.txt) instead of aborting at the first failed check; a verdict step fails the leg later; - when the boot did not come back, three bounded experiments (the Mesa-side child run directly, --emu-thread off, video.vsync=0 seeded) go to timing.txt; - the preset loop runs only once the plain boot works (500 launches of a boot that does not return are hours of nothing); per-launch timeout 150 s. Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): known-broken allowlist for presets librashader rejects everywhere The second Linux run (41567744247) built and rendered 494 of the 500 bundled presets in ~13 minutes of wall time; the six nedi bilateral-variant presets (all but variant2) fail reflection with UnknownSemantics("play"): they chain vhs/shaders/vhs.slang, whose `play` sampler is an LUT the presets never declare. A preset bug, not a GL one, the same on every leg, so it gets the same treatment as the macOS refused set: an allowlist with the reason that may only shrink (a listed preset that builds is an error). Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): verdict steps run after an earlier failed step too (always()) Co-Authored-By: Claude Fable 5.1 <[email protected]> * test(app): shaders_gl renders the bundled presets at 640x480, not the 128x64 pixel-check picture On llvmpipe (Linux) and Apple's software renderer (hosted macOS) crt-royale came out black in shaders_gl: its mask passes scale by 0.0625 of the viewport and the preset says "Safe for >= 341.333 horizontal triads at viewport size", so at 128x64 they are 8x4 px. The app at 960x760 renders it (gl-qualification run 41567744247, 76% of pixels differ from the plain picture). The pixel checks keep their 128x64 (an exact 4x of the 32x16 source); the bundled loop and VJ_TEST_PRESETS render at a real-world 640x480. Refs #1155 Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): every Windows Mesa launch bounded; llvmpipe single-thread and softpipe probes Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): own librashader artifacts, macOS from source and sized down, release staging excludes qualification artifacts Review (Codex P1/P2 on #1160) and run 41571727219: - librashader.yml gains an `artifact_suffix` input; this workflow calls it with `-glq`, so a release run (app-package.yml + gl-qualification.yml) uploads no colliding artifact names. - release.yml's two staging sweeps exclude artifacts/gl-qualification-* (screenshots, logs and the arm64 test zip are not release assets). - macOS leg: the from-source aarch64 runtime the package ships, not upstream's prebuilt 0.12.0 (crt-black_crush-koko.slangp fails to parse on the prebuilt, parses on the pinned source); 3 launches at once in a 480x360 window (small-window.ini via gl_qualify.py --seed-config): Apple's software renderer managed 205 of 500 presets in 150 min at 960x760 and 2 jobs. - refused-<os>.txt also covers presets the leg's GL cannot COMPILE (macOS: fsr and smaa+fsr need packHalf2x16, GLSL 4.20); a listed preset that builds is an error, the set only shrinks. Co-Authored-By: Claude Fable 5.1 <[email protected]> * test(app): gl_context_integration prints unbuffered stage markers (where does the x64 Mesa probe stop?) Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): tracked known failures; the x64 exit hang counted, not masked; loop before shaders_gl app/test/gl-qualification/known-failures.txt lists one failure per line (<leg> <kind> <reference>); the workflow reads it and turns exactly that failure into a recorded pass with a note. Nothing else on the leg is forgiven, and removing the line makes the leg fail again. First entry: windows-x64 exit-hang (#1167), the app never exits on the bundled MSYS2 MINGW64 Mesa 26.2.3 llvmpipe (SDL_DestroyWindow/SDL_Quit hang after "context destroyed"; LP_NUM_THREADS=0 and softpipe exit at once, arm64 Mesa exits in 2 s). gl_qualify.py: --known-exit-hang <ref> polls the launch, kills its process tree 5 s after the screenshot is complete (IEND present) and counts the preset, noting the known failure in summary.md and results.json; a launch without a complete screenshot still times out and fails. The Windows boot step accepts exit 124 when the screenshot and the [gl] lines are there, the loaders step accepts it on PASS, and shaders_gl passes without its final OK line only when nothing failed or skipped and its last check (the broken shader) ran. Every leg runs the preset loop before shaders_gl: on the macOS software renderer a SIGALRM-killed GL process left the next window creation hanging. shaders_gl's bundled loop and VJ_TEST_PRESETS render at 384x288 (crt-royale's mask passes need >= 341 px; 640x480 exceeded a 600 s alarm on Apple's software renderer), the macOS alarm is 1200 s. gl_context_integration prints unbuffered stage markers so a log shows where a probe stops. docs/agent/testing.md describes the lists. Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): capture waits for core frames; unbuffered shaders_gl; macOS 640x480 + capture diagnostics Run 41727418224 (3eef3305) read per leg: - Windows x64: the preset loop passed under the tracked exit hang (494 built, 501 launches killed 5 s after their screenshot, #1167) but the shaders_gl allowance failed: the test's stdout verdict lines were lost when the hung process was killed (a pipe is fully buffered; only the stderr [shader] lines survived). vj_shader_tests writes stdout unbuffered from main() on. - Windows arm64: 493 built, CuNNy-8x32-nvl-2x-rgb timed out at 150 s on the 128-bit llvmpipe. The Windows per-launch timeout is 240 s like the other legs. - macOS: shaders_gl passes at 384x288 (10 min). In the seeded 480x360 window every capture, --shader off included, came back a uniform white picture at 1.9 s a launch; not the game (yarc is black at core frame 1-2 and shows its picture from frame 10 on), not the theme. The leg seeds 640x480 (fits the hosted display, keeps crt-royale above 341 px) and a "Capture diagnostics" step launches `off` once per window configuration (default, 480x360, +frame 120, +emu frames, no viewports, no vsync, 480x362, 640x480, 960x760) and prints each picture's statistics to the step summary, so the artifact names the variable. App: --screenshot-emu-frames M (dev): the capture also waits until the core has shown M frames, with a line and a capture anyway 600 UI frames later if it never does; gl_qualify.py --emu-frames passes it, every leg uses 60. VideoOut::emuFrames() exposes the counter. Co-Authored-By: Claude Fable 5.1 <[email protected]> * ci(gl-qualification): even indentation in the x64 shaders_gl allowance (editorconfig-checker) Co-Authored-By: Claude Opus 5.5 <[email protected]> * ci(gl-qualification): macOS captures after 4 UI frames, 240 min budget; 480x360 white = ImGui viewports Run 41760278887 (6afaae1a): Linux, Windows x64 (loop and shaders_gl under #1167) and Windows arm64 green. macOS: the capture diagnostics named the white picture's variable. With ImGui's extra OS windows on (ui.viewports, the default) a 480x360 or 480x362 window captures uniform white; with them off, or at 640x480 and up, it captures the game. The 640x480 leg then built every chain it reached but ran out of time: 172 built, 57 timeouts at 240 s (49 of them had built the chain; Apple's software renderer spends ~12 s a frame on the heavy ones), fail-fast after 250 presets, and the job hit its 150 min limit right after the upload. - The macOS loop captures after 4 UI frames instead of 20; --emu-frames 60 already makes the capture the game's picture. The other legs keep 20. - macOS timeout-minutes 240 (build ~4 min, shaders_gl 10-18 min), shaders_gl alarm 1800 s. - The diagnostics step keeps four launches (default, 480x360 with and without viewports, 640x480). Co-Authored-By: Claude Opus 5.5 <[email protected]> * ci(gl-qualification): shard the macOS leg 3 ways, track presets over 120 s as macos-arm64 slow Apple's software OpenGL 4.1 renderer on hosted Macs cannot render ~500 presets in one job (runs 41760278887 and 41776934638 each ran out of time). The macOS job becomes a 3-shard matrix (gl_qualify.py --shard I/N: sorted preset index modulo N, every preset once, each shard with its own `off` baseline, 2 launches at once), the GL probe, capture diagnostics and shaders_gl in shard 0 only, and a macos-summary job joins the shards with --merge, failing when a shard is missing or the shards did not run every preset exactly once. Only the joined table goes to the run summary. known-failures.txt gains a `macos-arm64 slow <measured>@<run> <preset>` kind: 68 presets slow in every run that measured them. A listed preset is stopped at --slow-threshold (120 s) and counted as a known failure, not a checked picture; an unlisted one over the limit fails and the summary prints its line to paste; a listed one that renders in time is flagged for removal. A launch with no [gl] line is retried once and never counts as slow; POSIX kills send SIGTERM first (--graceful-kill) and report a surviving process group. Every run writes times.tsv and a "Slowest launches" table. macOS captures after SHOT_FRAME UI frames again. Co-Authored-By: Claude Opus 5.5 <[email protected]> * ci(gl-qualification): no exit allowance for app launches (#1172); test programs under #1179 #1172 ends the app's bundled-Mesa child without unloading Mesa, so the `windows-x64 exit-hang #1167` entry and every app-launch allowance go: the automatic-fallback boot step and the preset loop (--known-exit-hang) fail again if an app launch does not exit on its own. The two test programs, vj_gl_context_integration and `vj_shader_tests gl`, load the bundled Mesa in-process and still hang in its DllMain after SDL_Quit; their allowances stay, unchanged in what they require (the probe's `PASS GL loader` line; shaders_gl with no FAIL/SKIP and its last check run), now keyed to `windows-x64 test-exit-hang #1179`. The macOS summary states plainly how many presets are listed `macos-arm64 slow` and therefore not rendered, with their measured times (finished median and range, timeouts counted apart) and how many this run stopped. Co-Authored-By: Claude Opus 5.5 <[email protected]> * ci(gl-qualification): macOS slow list from the first sharded run; ntsc-blastem refused on GL 4.1 Run 41891214865 (3 shards, all 500 presets, every one run once): Linux, Windows x64 and Windows arm64 green; macOS 384 built, 57 listed presets stopped at 120 s, 36 failures. - 31 presets took over 120 s with the chain built (12 timed out at 240 s): listed as `macos-arm64 slow` with their measured times. 7 listed presets that rendered in under 100 s are dropped; 4 that took 102-114 s stay listed (a listed preset that renders in time is still checked). 92 presets are listed. - ntsc/ntsc-blastem fails to link on Apple's GL 4.1 ("Input of fragment shader 'LIBRA_VARYING_2' differs in type/qualifiers"); it builds on GL 4.6: refused-macos.txt. - 4 consecutive shard-0 launches (and their retries) never got a window for ~15 min, then the runner recovered, as in run 41760278887: on macOS a launch that times out with no [gl] line now leaves a `sample` stack of where the app was stuck. The summary sentence now says a listed preset stopped at the limit is not rendered or checked, and counts how many this run stopped and how many rendered in time. Co-Authored-By: Claude Opus 5.5 <[email protected]> * ci(gl-qualification): fail a slow macOS preset only if it never renders; reset Apple's GL compile service; no Windows exit allowances Gate change (option b): an unlisted preset now FAILS only if it does not render within the 240 s timeout. One that renders but takes over SLOW_LIMIT (120 s) is a ::notice:: with the line to paste into known-failures.txt and a count in the summary ("Unlisted, rendered but over 120 s"). Hosted-Mac times swing ~2x between runs (sabr-hybrid-deposterize: 131 s, 91 s, 229 s), so the hard 120 s line failed a few new presets every run. Listed presets keep the 120 s cap; the summary sentence states both rules. Run 41957577821 (fd76515e): Linux, Windows x64, Windows arm64 green; macOS 18 failures: - 10 rendered in 121-205 s: notices under the new gate, not listed. - 2 built and timed out at 240 s: listed (vectorscale-exact-energy-single-aa, xbr-lv2-sharp). 94 presets are listed; fd76515e's three lines (all rendered within 240 s) are not. - 6 never got a window, again in the vectorscale/xbr stretch (third run). The new stack samples all wait in CGLChoosePixelFormat -> cvms_connection_create on an XPC reply from CVMServer (com.apple.cvmsServ, Apple's GL compile service) that never came. --reset-cvms (macOS leg) kills CVMCompiler/CVMServer with sudo -n before the no-[gl] retry; launchd starts a fresh one; the summary counts the resets and how many retries then got a window. #1181 fixed #1179 (the GL test programs now exit without unloading the bundled Mesa): the `windows-x64 test-exit-hang #1179` entry, the Known failures step and both test-program allowances are gone, so any Windows process that does not exit on its own fails the leg. Co-Authored-By: Claude Opus 5.5 <[email protected]> * ci(gl-qualification): list the 2 macOS presets that timed out with a chain on run 42110580090 crt-yah/presets/pure-lcd (204.9 s on 41957577821, over 240 s now) and vectorscale (no window on 41957577821, the CVMServer stall; chain built but no picture in 240 s now) are added as macos-arm64 slow, 96 listed. The 15 unlisted presets that rendered in 121-205 s on that run are notices under the current rule and are not listed. Also corrects the SMOKE_PRESETS comment (Kimi review): PR runs render all presets; only workflow_dispatch's preset_set=smoke selects the subset. Co-Authored-By: Claude Opus 5.5 <[email protected]> --------- Co-authored-by: Claude Fable 5.1 <[email protected]>