NVIDIA's proprietary driver flushes f32 add, multiply and fma denormals by default but not the inputs of floor and ceil, so its startup probe failed only on those two. Drop their software flush only where the device declares DenormFlushToZero 32.
The driver declares no shaderDenormFlushToZeroFloat32, so every f32 add, mul and fma kept the software flush. Run the same probe as on MoltenVK and use the driver's default handling when it matches the emulated flush.
main's Resources.cpp already uses std::byte in Buffer::Bytes() on every
platform without including <cstddef>; it arrives through the project headers
this file includes first. Guarding a second include under __APPLE__ suggested
otherwise, so drop it. Also keep the blank line inside the __APPLE__ block so
the text outside it stays identical to main.
MaskReplaySafety counted every use reaching a conditional branch condition as a quad observation, including EXEC/VCC guards that control() itself already proves replay-safe, and every Ballot regardless of how its bits are read. Nested optional regions (a merged phi re-used as the predicate of an inner execz) and ballots consumed only through the own-lane funnel (word extract, lane<32 select, lane&31 shift, &1 isolate) were refused even though neither crosses lane boundaries; the same reasoning exempts explicit-lod samples, which do not compute implicit quad derivatives.
The check now runs conditional branches through a memoized controlProven() with a visiting set, exempts those condition uses in quadObserved, walks past own-bit ballots into the isolated per-lane bools, and treats explicit-lod samples as lane-local in both quadObserved and helperObserved. optionalBody now uses a local region set so nested control proofs do not corrupt the outer walk. Anything not matching these shapes is refused as before.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
IrProgram does not intern values, so titles that evaluate the same
whole-quad ballot twice emit distinct WqmU64 nodes for the low and
high mask words. maskStable and helpers paired those words by object
identity and rejected the split form. Compare the two evaluations
structurally instead: same-block ballots must agree on their source
tree and must not be separated by an execution-mask change, and every
newly accepted node is recorded as restricted. Assassins Creed
Shadows (PPSA20397) hits this in shader 0x407325e400.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Pixel-stage ballots and EXEC reads count only lanes that are not helper
invocations, so a waterfall loop over a saved whole-quad EXEC picks and
clears live lanes only. In programs that execute s_wqm on EXEC, writing
EXEC from a value keeps a helper invocation active while a live lane of
its quad is, so implicit-LOD sampling after a save/restore still has its
helpers.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
agc_driver_sampled_cache_budget_memory reports a 64 GiB budget on the
largest device-local heap but kept the heap's real size. On an APU that
heap is 512 MiB, so the storage image cache ceiling is the 512 MiB
floor, and both checks failed: half of the heap or of the budget
(256 MiB) and the budget under pressure (1024 MiB). The test now raises
the heap it reports to at least the reported budget, so its
expectations hold whatever heap the device has.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The decode test now expects a CB resolve of an 11_11_10 float target to
decode into a resolve pass instead of refusing it; the 10_11_11 unorm
refusal stays. A new execution test fills a multisampled R32_UINT image with
a different packed word per sample (2, 4 and 8 samples, fractions that need
truncation, denormals, large values, an infinite field), resolves it through
the new pass, and compares every texel with the float32 average of the
unpacked samples packed with truncation toward zero. With the pass summing
only the first sample the two-sample case fails (texel 0x701c0380 instead of
0x80200400); with the full pass it passes on an RTX 4080 SUPER and an
RX 6400.
AI-assisted: yes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
A CB resolve whose source is an 11_11_10 float target stopped the title at
decode ("CB resolves of 11_11_10 float color targets are unsupported"): the
target is an R32_UINT image, and the subpass resolve of an integer format
takes one sample instead of averaging. The resolve now draws a pass that
reads every sample of the multisampled R32_UINT image, unpacks the three
unsigned small floats, averages them in float32 in sample order, and packs
the result with truncation toward zero, matching the ROUND_MODE the target
is already required to have. An infinite or NaN field in any sample is
passed through from the first sample that has one.
The averaging is assumed to match the console's CB resolve of an unpacked
float target; it is not measured on hardware. 10_11_11 unorm and 4_4_4_4
unorm targets still refuse the resolve.
AI-assisted: yes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>