Skip to content

M4.04

Pre-release
Pre-release

Choose a tag to compare

@VTSTech VTSTech released this 18 Oct 22:20
· 54 commits to main since this release

[M4.04] — 2026-10-18/19

The conformance + hardware wave that closes M4: the two M3 leftovers ship
as one conformance/perf tool with the first real-GPU (RX 560) numbers and
pixel-level cross-backend verification, the fallback contract gains a
standing regression drill, docs/API.md lands as the M5 freeze baseline,
and the sweep's one real fork failure became a library fix — integer
samplers now join the canonical descriptor layout.

Added

  • docs/API.md (draft) — the full public-surface reference pulled from
    include/slangvk/: core + runner layers, std::expected error model,
    descriptor-convention table, lifetimes/threading rules, headless
    walkthrough, swapchain-mode contract, v1 limitation list and the M5
    freeze-review checklist. Marked pre-freeze; the M5 deliverable becomes
    "review + freeze against it".
  • Docs sync (2026-10-19): CHECKLIST updated for the M4.03/M4.04 waves
    (25/25 evidence base, golden-image + perf-budget rows closed with the
    refined-scope notes, miss list #6/#7 closed, M5 boundary reflects the
    API.md draft); PLAN bumped to v0.3 (M3 fully ✅, §5.1 module map refreshed,
    §6 gains the delivered-API deltas paragraph, §10 documents the shipped
    conformance/budget tools); SPEC gained the M4.03 preprocessed-text
    sampling oracle (§4.5 + matrix + divergence #22) and the parameters-are-
    not-preprocessor-macros divergence (§4.2).
  • Golden-image conformance suite + perf budgets — the two M3 leftovers
    ship as one tool, examples/conformance.cpp (M4.04 scope). conformance golden renders every preset in tests/golden/manifest.txt (20 bundled
    fixtures covering every chain semantic: blit, multi-pass, feedback
    ping-pong, history ring, mipmap refill, FBO formats, push-fragment
    uniforms, parameters, size uniforms, smoothness qualifiers, named /
    User# LUTs, LUT mipmaps, LUT size, rotation, include composition, the
    two demo presets) from a deterministic procedural testcard at a fixed
    target and compares the final frame against committed PNGs in
    tests/golden/images/ — per-channel delta + mismatched-fraction
    tolerances per entry, --update regenerates, and the manifest's
    # generated-by: stamp names the backend that produced the goldens
    (a different local device warns once). conformance perf times
    --timed frames per preset after --warmup (wall-clock around the
    synchronous fenced Chain::render), writes a TAB --report ledger and
    gates --budgets files (path<TAB>max-ms, breach exits 1, unmeasured
    entries tolerated); tests/golden/budgets-lavapipe.txt documents the
    format with generous sandbox reference budgets. Both modes skip cleanly
    without a Vulkan device; ctests example_conformance_golden /
    example_conformance_perf (suite now 25/25); the CI shader-demo
    artifacts bundle conformance(.exe) with the golden kit and fixture
    presets so the suite runs from the artifact.
  • Hardware perf baseline (RX 560) + regression-guard budgets — first
    real-GPU numbers committed alongside the sandbox references:
    tests/golden/perf-rx560.txt (Radeon RX 560 Series, Windows, 640×480
    from 320×240, warmup 3 / timed 20; all 20 fixtures measured twice via two
    roots — means 0.29–1.20 ms, 835–3,457 fps, every fixture ≥ 14× the 60 fps
    bar) and tests/golden/budgets-rx560.txt derived from it
    (max(1.5 × mean, 1.0 ms); the duplicate-root runs put the tightest
    cross-run headroom at 38%, and observed single-frame spikes up to 4.3×
    mean stay invisible to the mean-of-20 gate). Opt-in on hardware —
    ctest/CI keep budgets-lavapipe.txt.
  • Fallback drill closed (CHECKLIST miss #11), both halves. (a) The
    event
    — on the fork (Radeon RX 560, exe 996e5afcc, 2026-10-19) the
    broken preset test/feedback-noncausal.slangp was rejected in 25 ms
    with the precise diagnosis (slang: PassOutput0 is not causal in pass 0), the scaler session shut down cleanly into "GPU scaler unavailable,
    using the regular renderer instead", the error surfaced on the OSD, and
    the next session recovered end-to-end. (b) The standing regression —
    new conformance drill mode + tests/golden/drill/ fixtures (7
    expect-fail cases across distinct failure layers: comments-only preset,
    missing shader, GLSL compile error, live-sampled unknown sampler,
    missing LUT, absent #reference, PassOutput0 causality): each case
    must reject cleanly, leave zero validation messages, and let a
    pixel-identical recovery render of runner/blit.slangp succeed on the
    same device; surprises, poisoned devices or drifted frames exit 1
    (pass and fail directions both verified). ctest
    example_conformance_drill (suite 25→26); drill fixtures + a USAGE
    line ship in the CI shader-demo artifacts.
  • Hardware golden conformance (RX 560, PROVENANCE Session 7) + the
    demo-glow cross-backend tolerance
    — first pixel-level comparison of
    the committed (llvmpipe-generated) goldens against a real GPU: 19/20
    within manifest tolerances, every passing entry at worst delta ≤ 3 —
    feedback ping-pong (worst 2 / 0.000%), mipmap refill (worst 3 /
    0.104%), history, FBO formats, LUTs, rotation, params and size
    uniforms all pixel-verified cross-backend (CHECKLIST M2 hardware
    halves closed). The one DIFF, presets/demo-glow.slangp, was
    root-caused to boundary-exact box taps at the fixture's exactly-0.5×
    downsample — deterministic per backend (byte-exact across repeated
    runs on both llvmpipe and the RX 560), so rounding, not a race — and
    now carries the manifest's only non-default tolerance (200 / 12.0,
    ~28% headroom over the measured envelope). --update + re-compare on
    the RX 560: 20/20 byte-exact. Committed goldens stay llvmpipe-
    generated; CI keeps its byte-exact baseline.
  • **Hardware sweep, first shortlist batch (RX 560, PROVENANCE Session 8)
    • sharper pipeline errors.** Fork sessions verified the named
      MainPassFeedback reader form (test/pragma-name, ~1,166 frames) and
      the TextGeneratePassFeedback generate-and-cache feedback pattern
      (misc/print-resolution, visually confirmed) — with Session 7's
      numeric/mipmap results, every F2 feedback form is now
      hardware-covered. One real finding: test/format.slangp fails to
      load on the fork (pass pipeline: VK_ERROR_UNKNOWN) —
      [attribution corrected in Session 9: the failing preset was the
      upstream corpus file (2-pass R32_UINT round-trip), not the 3-pass
      field fixture the golden suite covers; the root cause is the
      integer-sampler rewrite gap under Fixed below — not the present
      path, sRGB, or final-FBO formats]
      . The fallback contract held
      (second failure class). Isolation kit shipped to the maintainer;
      diagnosis closed in Session 9. Library-side: pass/present pipeline
      and render-pass errors now name the pass index, shader path and
      target format (pass 2 'shaders/fmt_srgb.slang': pass pipeline (format R8G8B8A8_SRGB): VkResult …) via a new FormatShortName
      helper, so hardware logs identify the failing pipeline directly.
  • Integer FBO round-trip golden (format-uint, suite entry 21).
    Verbatim port of the upstream corpus test/format.slangp pair at
    the pinned revision (e1d75632): pass 0 packs the testcard into an
    R32_UINT FBO (uint fragment output), pass 1 decodes through
    usampler2D + texelFetch + unpackUnorm4x8 — the exact shape the
    fork field log exposed and the fix below targets. Byte-exact on
    llvmpipe; the RX 560's first golden run predates this entry and
    covers the original 20. 12 new test_slang_translate assertions pin
    the rewrite behavior (re-home + type preservation + orphan-drop
    parity for usampler2D/isampler2D).

Fixed

  • Integer samplers never joined the canonical descriptor layout
    (PROVENANCE Session 9). RewriteSamplers re-homed only float
    sampler2D declarations — the regex could not match
    usampler2D/isampler2D, and the scan index deliberately skipped
    them — so an explicit source-level layout(set = 0, binding = 1) on
    an integer sampler reached SPIR-V unmodified while the chain's
    canonical pipeline layout provides an empty set 0 and hosts textures
    at set 2. Observed symptoms: llvmpipe segfaults the host at draw;
    the AMD Windows driver (RX 560, fork field log Session 8) returns
    VK_ERROR_UNKNOWN from vkCreateGraphicsPipelines when it validates
    the shader-layout interface. The entire 2,658-preset corpus contains
    exactly one integer-sampler file — upstream test/decode-format.slang
    — which is also the only file the corpus-wide no-regression gate
    needed to prove safe (gate PASSED at the pinned revision; MBZ
    MEGATRON + crt-royale spot-checked). Fix: the rewrite regex matches
    (?:u|i)?sampler2D and re-emits the matched type at the canonical
    set/binding; the declaration scans and directive classifier treat
    integer samplers on par with float ones; stage.textures records
    them identically (combined-image-sampler descriptors are
    type-agnostic).

Full Changelog: M4.03...M4.04