Repository navigation
M4.04
Pre-release
Pre-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::expectederror 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 goldenrenders every preset intests/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,--updateregenerates, and the manifest's
# generated-by:stamp names the backend that produced the goldens
(a different local device warns once).conformance perftimes
--timedframes per preset after--warmup(wall-clock around the
synchronous fencedChain::render), writes a TAB--reportledger and
gates--budgetsfiles (path<TAB>max-ms, breach exits 1, unmeasured
entries tolerated);tests/golden/budgets-lavapipe.txtdocuments the
format with generous sandbox reference budgets. Both modes skip cleanly
without a Vulkan device; ctestsexample_conformance_golden/
example_conformance_perf(suite now 25/25); the CI shader-demo
artifacts bundleconformance(.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) andtests/golden/budgets-rx560.txtderived 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 keepbudgets-lavapipe.txt. - Fallback drill closed (CHECKLIST miss #11), both halves. (a) The
event — on the fork (Radeon RX 560, exe996e5afcc, 2026-10-19) the
broken presettest/feedback-noncausal.slangpwas 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 —
newconformance drillmode +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,PassOutput0causality): each case
must reject cleanly, leave zero validation messages, and let a
pixel-identical recovery render ofrunner/blit.slangpsucceed 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
MainPassFeedbackreader form (test/pragma-name, ~1,166 frames) and
theTextGeneratePassFeedbackgenerate-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.slangpfails 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 newFormatShortName
helper, so hardware logs identify the failing pipeline directly.
- sharper pipeline errors.** Fork sessions verified the named
- Integer FBO round-trip golden (
format-uint, suite entry 21).
Verbatim port of the upstream corpustest/format.slangppair at
the pinned revision (e1d75632): pass 0 packs the testcard into an
R32_UINT FBO (uintfragment 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 newtest_slang_translateassertions pin
the rewrite behavior (re-home + type preservation + orphan-drop
parity forusampler2D/isampler2D).
Fixed
- Integer samplers never joined the canonical descriptor layout
(PROVENANCE Session 9).RewriteSamplersre-homed only float
sampler2Ddeclarations — the regex could not match
usampler2D/isampler2D, and the scan index deliberately skipped
them — so an explicit source-levellayout(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_UNKNOWNfromvkCreateGraphicsPipelineswhen it validates
the shader-layout interface. The entire 2,658-preset corpus contains
exactly one integer-sampler file — upstreamtest/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)?sampler2Dand 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.texturesrecords
them identically (combined-image-sampler descriptors are
type-agnostic).
Full Changelog: M4.03...M4.04