Commit Graph
84 Commits
Author SHA1 Message Date
Alex ColliniandClaude Opus 5.5 7a6cc71786 feat(agc): carry spanned waves in the target and require full subgroups
APS5_SPANNED_WAVE is now read once by the driver, which sets
SpirvTarget::spannedWaves only on a device with 32-lane compute subgroup
control and computeFullSubgroups. The recompiler no longer reads the
environment. The field is part of the cache key and of the request
serialization (version 32), so a cached or replayed module keeps the mode
it was built in.

A spanned module numbers its lanes SubgroupId * 32 +
SubgroupLocalInvocationId, which needs two full 32-lane subgroups. The
artifact records this as fullSubgroups (disk cache and pipeline identity
included), and the driver creates those pipelines with
REQUIRE_FULL_SUBGROUPS. Compute pipeline captures accept the flag with a
required subgroup size.

The two-lane fallback now catches only SpannedWaveUnsupported, thrown for
a shuffle wider than 32 bits; other emit errors surface as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:12:58 +02:00
Scott SchusterandClaude Opus 5.5 2ea25c53f7 fix(recompiler): the shader disk cache carries a result's shader-data user words
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:53:53 -05:00
Adrià 821c69e504 Merge pull request #5509 from billythemenace2/fix/shader-cube-tsharp-2d-access
fix(shader): read cube T#s through DIM 2D image_sample and image_load as face 0
2026-10-15 13:25:34 +02:00
Dean 8ae436891a Merge pull request #5181 from ThatsLeo/perf/shader-compact-resource-plans
perf(shader): keep only evaluable branch conditions in resource plans
2026-10-15 10:56:57 +13:00
billythemenace2andClaude Opus 5.5 3b96840e68 fix(shader): read cube T#s through DIM 2D image_sample and image_load as face 0
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 23:37:33 +02:00
Adrià 33001cebda Merge pull request #5466 from fdfawef324/codex/stencil-export-emulation
feat(agc): replay proven finite stencil reference exports
2026-10-14 22:49:30 +02:00
fdfawef324andCodex 383c8a6515 fix(agc): retain table feedback guards after cache refresh
Check sampled image-table entries with the existing stencil replay depth-feedback refusal. Keep the cache regression tied to current upstream format 33 while stencil artifacts use format 34.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:48 +02:00
fdfawef324andCodex ce83818dc5 test(agc): use current resource plan codec coverage
Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:48 +02:00
fdfawef324andCodex 97a0a4d098 refactor(agc): separate stencil replay from its follow-up topics
Move bounded vertex folding and empty-image feedback into separate topics. Keep the replay coverage proof, stage contracts, finite-reference tests and mapped cache regressions; version the stencil layout separately as format 34.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:48 +02:00
fdfawef324andCodex 92f0d1ad6a test(recompiler): reject the current upstream cache format
Keep format 33 and its previous-format 32 refusal; also cover the current main format 31 explicitly.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:36 +02:00
fdfawef324andCodex b0c7cef616 fix(recompiler): distinguish stencil cache artifacts from format 32
Advance stencil artifacts to format 33 after main's format 32 change. Keep explicit rejection of upstream format 32 while preserving the existing stencil fields and runtime image metadata.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:36 +02:00
fdfawef324andCodex 46a6f26f55 fix(recompiler): refresh stencil cache schema after rebase
Advance the stencil artifact schema past current main format 31 and retain explicit rejection of that format. Update Linux artifact size guards for main runtime image resource metadata.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:36 +02:00
fdfawef324andCodex b41bf66ca8 fix(recompiler): version stencil artifacts after disk resource plans
Main now uses disk cache format30 for persisted resource plans. Stencil replay
adds artifact and binding fields, so reject that format instead of sharing its
version. Keep format31 for the combined codec and cover rejection of a format30
artifact header.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:36 +02:00
fdfawef324andCodex 77521f7ad2 feat(agc): replay proven finite stencil reference exports
Preserve instance and triangle order with one dynamic-reference shader pipeline. Require bounded references, complete export coverage, replay-safe mask control and resources; refuse unsupported side effects and feedback.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:35 +02:00
eljackjoestar-cmd 89777fcaa1 fix(shader): sample single-level volumes through biased 2D accesses 2026-10-14 21:58:18 +02:00
Adrià 31d951edea Merge pull request #5375 from billythemenace2/fix/shader-3d-access-on-1d-tsharp
fix(shader): read 1D T#s through 3D image_sample and image_load accesses
2026-10-14 21:40:54 +02:00
ThatsLeo 8ddd1f92e4 fix(shader): keep resource plans in their arena through the disk cache
EncodePlan and DecodePlan from #4883 walked valueStorage as a vector of
owned values; they now use IrValueArena, and decoded operands are detached.
2026-10-15 08:22:09 +13:00
SaloQT 93ab137194 test(recompiler): cover prebuilt shader pack loading
Build packs from EncodeEntry output and check the hit and miss paths,
an entry stored under another key, a truncated entry, a damaged index,
an out-of-range record, a foreign compiler source version and an
unknown format. A child process covers pack discovery on a real disk
load, the ANYPS5_NO_PREBUILT_SHADERS opt out and fall-through to the
writable cache. ARCHITECTURE.md describes where the prebuilt lookup
sits.
2026-10-15 05:44:34 +11:00
billythemenace2andClaude Opus 5.5 bd09862e55 fix(shader): read 1D T#s through 3D image_sample and image_load accesses
A 3D image access bound to a 1D T# matched no runtime image mode and threw
"image descriptor is incompatible with the static runtime image interface"
(SONIC SUPERSTARS, PPSA06888, which reads a 1x1 1D T# as 3D with a plain
image_sample and an image_load). Add a 1D mode for 3D accesses whose only
uses are image_sample_lz, plain image_sample or mip-less image_load.

Measured on RDNA1 (RX 5700 XT, gfx1010) with the hardware oracle:
image_sample_lz reads the texel u selects and ignores v and r with every
addressing mode; a plain image_sample takes its texel and LOD from u alone;
image_load reads the x texel for any y when z is 0 and returns zero for any
other z, as the 3D-on-2D load measured in #2023 does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QQNVXyqeecpyneonkYL6H1
2026-10-14 18:32:22 +01:00
Celegans12 34525fdf7a feat(agc): implement image tables loaded through 64-bit pointers
Plan runtime-indexed T# and S# columns read through a 64-bit pointer.
Preserve the console offset alignment, signed immediate and key bounds.
Track the descriptor dwords consumed by each table in its invocation.
Reject table reads when a writable buffer or storage image overlaps them.
Cover the overlapping-storage fault and isolated second-table behavior.
2026-10-14 16:43:57 +02:00
Celegans12 d9e47d1e98 feat(agc): implement image and sampler tables indexed at runtime offsets
Materialize runtime-indexed image and sampler records into descriptor
tables while keeping descriptor selection in the shader. Report invalid
active entries through the existing deferred fault buffer.

Bind fragment tables in the fragment set when pipeline libraries split it,
and reserve a physical descriptor for empty tables. Reject unsupported
sampler, border, cube and anisotropic pairings per entry. Keep one column
per heap access shape, one T# shared by several image operations included
(milescoviello's #5550 case), and narrow it to the union of its keys'
domains when every key has one (SleglJan's key-domain changes). Plan
columns read at (key << n) & mask over their whole domain (tibzejoker's
fix). Read records in runs through SleglJan's bulk reader, and reject
entries whose surface has no mapped byte, as Tamalero proposed. Store
table columns in disk plans; update the runtime ABI and disk format. Bound
table-sized entries in the resource cache (65,536 table elements) and the
dispatch cache (256 MiB of captured words), evicting LRU.
2026-10-14 16:43:57 +02:00
Adrià FranchandClaude 353094a254 Revert "Merge pull request #5089 from fdfawef324/feat/recompiler-waterfall-descriptors"
agc_driver_waterfall_images fails on main since fd438f663: its compute shader
runs an LOD query with a local size of 8x1, and the module gets
DerivativeGroupQuadsKHR, which SPIR-V validation rejects unless both
dimensions are even (VUID-StandaloneSpirv-DerivativeGroupQuadsKHR-10151).

This reverts commit fd438f663, reversing changes made to 51031742e.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-14 14:38:28 +02:00
fdfawef324andCodex 3ce02f5928 fix(recompiler): preserve per-lane table modes in disk resource plans
The disk resource plan codec added on main must retain whether an indirect
image uses a per-lane key, an indexed record stride, and implicit derivatives.
Encode and decode those fields, update the aggregate field guard, and reject
the older resource-plan format. Cover all eight flag combinations so a loaded
plan cannot silently lose the stride or bound-mode checks.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 13:24:53 +02:00
Dean 43349d4337 Merge pull request #4806 from eljackjoestar-cmd/codex/file-backed-spirv
fix(shader): map retained SPIR-V from shader cache entries
2026-10-14 22:18:29 +13:00
eljackjoestar-cmd 4a0489a7a9 fix(shader): map shader cache files on Windows 2026-10-14 11:32:10 +04:00
Dean 78f1aea706 Merge pull request #5552 from Sam-mon7/fix/shader-cache-read-share-delete
fix(shader): share delete access when reading cache entries on Windows
2026-10-14 20:03:26 +13:00
ThatsLeo 895002149d perf(shader): map cached SPIR-V from the shader cache files
A cached variant kept its SPIR-V in memory for the whole run. On Linux and
macOS the words are now a view into the mapped cache file, and a freshly
compiled variant is written and mapped back, so the kernel can drop them.
2026-10-14 10:36:24 +04:00
SamandClaude Opus 5.5 af2b869281 fix(shader): share delete access when reading cache entries on Windows
WriteFileAtomically renames its handle over the published entry and
closes it afterwards. A std::ifstream reader opened in that window fails
with ERROR_SHARING_VIOLATION, and the cache reports the entry as gone.
Read through one CreateFileW handle that shares read, write and delete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:35:54 +01:00
NikoandClaude Opus 5.5 5d3ea5f511 test(recompiler): set layerExported in the disk cache entry round trip
#5097 added ShaderInfo::layerExported to the entry encoder, and this
series moves that line into encodeShaderInfo, which plan entries use
too. The entry round trip left the flag false, so an encoder and a
decoder that both skipped it still passed. Set it like the other
ShaderInfo flags: with layerExported dropped from both, the round trip
now fails with "entry round trip: shader info differs".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 19:30:21 +02:00
NikoandClaude Opus 5.5 ce8944f853 test(recompiler): plan an invariant descriptor phi in the disk cache test
The round trip requires some fixture to plan a phi, and only one did:
the loop counter of "bindless sample in a loop latch", which reaches the
plan through the latch condition. The counter is not invariant, so the
CPU walk can never evaluate that condition. A plan that keeps only the
conditions the walk can evaluate, as #5181 aims to, would hold no phi
and fail the check with "no fixture plans a phi".

"descriptor invariant phi" loads the image descriptor from the same SRT
offset on both sides of a branch on an SRT dword. Its eight dwords are
phis of equivalent reads: the tracker keeps them, since it splits only
descriptor phis that are not invariant, and the walk evaluates them
through the invariant read. The plan stores them as descriptor dwords,
whichever conditions it keeps, so the phi encoding stays covered. The
fixture goes after the other compute fixtures, so they keep their seeds
and their damaged-entry checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:31:17 +02:00
NikoandClaude Opus 5.5 70663fec42 test(recompiler): check that APS5_NO_PERF_DISK_PLANS=1 is cache-neutral
APS5_NO_PERF_DISK_PLANS=1 is listed as a neutral switch, so it stays out
of the variant key, and it exists to compare warm starts with and
without stored plans. Nothing tested either property: the cross-process
test ran with the switch unset only.

A fourth child process now sets the switch against the cache the first
process filled. It must run the front end for all 14 fixtures, neither
load nor store a plan, still hit all 14 stored variants, and produce the
same SPIR-V, bindings, push constants, snapshots, read traces and plans
as the first process.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:31:17 +02:00
NikoandClaude Opus 5.5 a69f5e0371 test(recompiler): compare stored resource plans field by field
The plan tests compared a decoded plan with the original only through
the codec itself (re-encoding must give the same bytes) and through
materialization. Neither catches a field that EncodePlan and DecodePlan
both leave out: the bytes still agree, and the walk does not read every
field. Leaving userDataBase, the plan's sRGB formats, the value ids or
several MemoryInfo fields (secondaryOffset, dataDwords, dataFormat,
planningOnly, idxen) out of both sides passed every test. The hand-built
plan also never materializes (its uniform values cannot be evaluated),
so its 1000 runtimes all failed with the same error, and no plan held an
immediate wider than 32 bits.

samePlan compares every field of two plans without the codec: the value
graph by storage index (opcode, type, id, flags, register, immediate,
arguments, phi blocks), the block ids, the roots, and the plain data
through the structures' own equality. The round trip now requires it
for the 14 fixtures and the hand-built plan, which sets every MemoryInfo
field, all indirect table fields, a second buffer, the whole uniform
fill and a 64-bit immediate to values other than their defaults. The
second process also builds each fixture's plan with its own front end
and requires it to equal the plan it used, so a stored plan must match
what the front end builds in another process, not only its own
re-encoding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:31:17 +02:00
NikoandClaude Opus 5.5 ed3f2776ed fix(recompiler): reject a stored plan whose image table names a missing source
DecodePlan checked every descriptor source index a plan holds except the
two inside an indirect image table: the heap source and the material
source. A damaged entry could therefore decode with a table that points
past the plan's descriptor sources, and only the materializer's own
bounds checks stood between it and an out-of-range read. The front end
interns both sources before the image source that names them, so a plan
it builds always passes the new check.

agc_shader_disk_cache now requires a plan whose table heap or material
source lies past the sources not to decode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:31:17 +02:00
NikoandClaude Opus 5.5 1ed6c21067 perf(recompiler): load the resource plan from the disk cache before the front end
getSource built ResourceProgram (PrepareResourceProgram and ExtractPlan)
for the first request of every shader a process saw, before
findOrCompileVariant looked in the disk cache. With a warm cache every
launch still decoded, built the CFG, structurized, translated and ran
SSA, the fold passes, SrtWalker and ResourceTracker for every shader;
only SPIR-V emission was skipped.

getSource now builds the plan key and tries LoadPlan first. On a hit it
sets the plan and leaves the program null: findOrCompileVariant already
rebuilds the program when no stored variant fits the layout. The loaded
plan takes the request's code address as its shader hash, as a plan
built in this process would. On a miss it builds the plan as before and
stores it. A plan the front end refuses is not stored. The disk is not
used when the cache is off, under the debug probe, with APS5_DUMP_IR
(which prints the front-end passes), or with APS5_NO_PERF_DISK_PLANS=1,
a cache-neutral switch for comparisons.

FrontEndBuilds() counts PrepareResourceProgram calls. The new
cross-process test prepares, captures and materializes 14 shader
fixtures in one process and repeats it in a second process sharing the
cache directory: the second process must run the front end 0 times, hit
14 plans and 14 variants, and produce byte-identical SPIR-V, bindings,
push constants, snapshots, read traces and plans. A damaged plan entry
is rejected and rebuilt alone with the same output and stored again; a
changed code word and another switch value miss.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:31:17 +02:00
NikoandClaude Opus 5.5 0c144502e5 feat(recompiler): store front-end resource plans in the shader disk cache
The disk cache keeps compiled variants (SPIR-V, shader info, binding
layout) but not the IrResourcePlan the front end extracts for the
resource walk, so a process can only get a plan by running the whole
front end. Since #471 the plan owns its values (ownPlanValues clones the
graph behind every root into valueStorage and blockStorage), so it can
be written out and rebuilt.

- EncodePlan writes the value graph in storage order, each value as
  LEB128 integers: opcode, type, id, flags, register, operand count,
  the immediate if it has one, each argument as the zigzag distance to
  the value's own index (0 for null) and, for phis, the index of each
  predecessor block. The roots (descriptor source dwords, SRT reads,
  control-flow conditions, uniform-fill values) are value indices; the
  plain data (memory info, indirect image tables, control-flow edges,
  materialization sources, guarded, clean and pure flat slots, the
  flags, the ShaderInfo through the variant's encoder) follows. A plan
  whose roots or arguments point outside its storage is not encoded.
  Control-flow conditions can pull most of a program into the plan:
  a synthetic 2,038-dword compute shader with a branch every 20 dwords
  has 42,775 plan values, which take 518 KB this way and 2.5 MB with
  fixed-width fields; its compiled variant entry is 935 KB.
- DecodePlan rebuilds the graph the way ownPlanValues does and rejects
  an unknown opcode, an overlong integer, an index past the values or
  blocks, a descriptor source, image, buffer or sampler past the
  sources, a branch without two successors, an edge past the blocks,
  and a uniform fill of more than four words.
- BuildPlanKey is the in-memory source key (RecompileCacheKey::Build and
  the host subgroup size), every code word and the switch key, after a
  plan entry tag. It leaves out the binding layout, so all layouts of a
  shader share one plan.
- EncodePlanEntry/DecodePlanEntry use the variant's header and hashes;
  LoadPlan and StorePlan use the same directory and background writer
  and count plan hits, misses, writes and load failures on their own.
- Size asserts cover the plan and the structures it is written from.
- FormatVersion 30.

agc_shader_disk_cache now round-trips the plans of 14 in-tree shader
fixtures (SRT reads, guarded and chained pointers, control-flow
conditions, an indirect image table, a loop phi, a fragment shader) and
a hand-built plan with a uniform fill. For each it materializes the
original and the decoded plan over 1000 random user-data and memory
runtimes and requires the same snapshot, poison, null-root count and
read trace, or the same error. Truncated, bit-flipped and
other-format entries are rejected, malformed plans do not decode, and
the key follows the code, the target and the host subgroup size but not
the layout, addresses or user data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:31:17 +02:00
Karan Vora e4f212b2e2 perf(shader): convert f16 operands with UnpackHalf2x16 where f16 denormals are kept
Since #1463, every f16 operand read decodes sign, exponent and mantissa
with integer operations, 8 to 12 instructions more per read than
UnpackHalf2x16 on NVIDIA. The decode works around an AMD Windows driver
that folds the mask of a byte-selected half into UnpackHalf2x16.

A new target flag, float16DenormPreserve, is set when the device reports
shaderDenormPreserveFloat16 and denormBehaviorIndependence ALL, the same
rule as float64DenormPreserve. With it, EmitF16BitsToF32 uses
UnpackHalf2x16 and declares DenormPreserve for 16-bit floats, under
which SPV_KHR_float_controls keeps unpacked subnormal halves. NVIDIA
returns the default NaN for every NaN half, so the NaN bits are rebuilt
from the half: its sign at bit 31, its payload at bits 22:13. The
DenormPreserve 16 mode is declared once, shared with the native f32 to
f16 conversion. Without the flag (lavapipe; RADV reports 32_BIT_ONLY)
the integer decode stays. Halves of fields narrower than 16 bits, such
as SDWA byte selects, keep the integer decode on every device.

The flag is serialized (request version 17) and part of the cache key.

New test agc_driver_f16_to_f32_unpack converts all 65,536 halves, with
nonzero high bits, through v_cvt_f32_f16, and byte-selected halves
through v_add_f16 SDWA, with each decode the device supports, and
compares the bits with an exact decode. agc_driver_f16_to_f32_unpack_spirv
checks which decode the SPIR-V uses with and without the flag.
2026-10-13 12:15:00 +02:00
AlxcBTWandClaude Opus 5.5 18d9874a06 feat(shader): give reads the masked-select pass keeps the whole pixel ancillary word
A packed ancillary word that still reaches an export, or any other read
the masked-select pass cannot drop, no longer stops the recompile. After
that pass every remaining use gets the composed word: the primitive class
at bits 0-1, SampleId at bits 8-11 and Layer at bits 16-28, with every
other bit zero. Those lanes do export the ancillary VGPR on the console,
so the word has to be right, not just present.

The primitive class (0 point, 1 line, 2 triangle, 3 rectangle) comes from
the draw. RasterPrimitiveOf maps rect lists to 3, line lists on the vertex
path to 1 and everything else the driver accepts to 2, because its
geometry and tessellation paths only output triangles. It reaches the
shader as pipeline specialization constant 8233, the way dual-source
blending does: a request field that is folded into the specialized
module and is part of the result memo, the draw key and the serialized
request (version 17).

Only shaders that read the class pay for it. ShaderInfo records the read
(disk cache format 28), and only those shaders put the class in their
module key, so a shader that reads just the sample or layer field keeps
one module for every primitive class. The draw sets the class only when
the pixel shader loads the ancillary VGPR, so other draws keep the draw
cache entries they have today.

The VRS rates (bits 2-5) and the eye id (bit 7) are 0 because the driver
supports neither VRS nor multiview. SampleId is 0 because the driver
rejects MSAA and per-sample shading, and Layer is 0 while it ignores
vertex layer exports. TechnicalDebt.md records the layout sources and
these assumptions.

Tests:
- pixel_ancillary builds an export to target 0 whose two channels select
  between a packed value and a phi carrying the word. It checks the word
  for each primitive class, sample and layer, checks that the three
  shapes the masked-select pass keeps now compile with the composed word,
  and that a program whose select the pass drops reads no class.
- agc_driver_pixel_ancillary_word exports the word from a draw and reads
  back 2, 3 and 1 for triangle, rectangle and line. A shader that reads
  only the sample field shares one module across the classes, and the
  whole-word shader gets one per class. It also checks RasterPrimitiveOf.
- agc_shader_memory covers the version 17 round trip, and
  agc_shader_disk_cache the new flag.

Both ancillary tests fail with the old refusal when the composition is
disabled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 13:06:21 +13:00
Adrià FranchandClaude 361c7e2024 perf(agc): keep oversized shaders specialized and prebuild libraries on their own thread
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-12 09:50:41 +02:00
Celegans12 f32bbf2e9e fix(cache): replace entries while Windows readers retain old files
Publish Windows cache entries with the POSIX rename operation so an
open delete-sharing reader keeps its original file after replacement.
Close the rename handle before returning and retain the existing
fallback only when the extended operation is unsupported.
Exercise old and new reader contents, deletion lifetime and temporary
file cleanup in the registered disk-cache regression on both platforms.
2026-10-11 16:03:37 +02:00
Adrià FranchandClaude ac1c3b775b fix(agc): read the base level of a mipmapped view through unnormalized coordinates only where the hardware does
Multi-level views, and views starting above mip 0, are bound as their base
level only when every use of the image is image_sample_lz through an
unnormalized S# without minimum LOD or LOD bias, the case measured exact on
RDNA2. Selected-LOD, implicit-LOD and offset uses keep throwing.

The recompiler records selected-LOD uses (SamplerUseNonZeroLod) and proves
the case per image (imageUnnormalizedBaseLevel); the shader disk cache
format goes to 27.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-11 11:07:25 +02:00
Celegans12 d0d127b17d feat(agc): accept texel offsets with unnormalized sampler coordinates
Explicit-LOD offset samples through FORCE_UNNORMALIZED samplers now add
sign-extended texel offsets to f32 coordinates before clamping, using
OpFAdd with NoContraction and a sampler specialization selector.

Without native nonconstant-offset support, retain only runtime image
modes valid for unnormalized sampling and reject normalized samplers.
Preserve constant-swizzle handling, indirect-image rejection and main's
flat-volume and flat-line compatibility rules when selecting those modes.

Serialize image compatibility and folding flags and the sampler folding
flag in cache format 34, with roundtrip, preparation and execution coverage.
Retain main's request format 15 and runtime ABI 11.
2026-10-11 10:08:25 +02:00
Adrià c757e8eaa7 Merge pull request #3220 from kr4y4/fix/agc-sampler-border-color-class
fix(agc): pick float or integer sampler border colours from the paired images
2026-10-11 09:19:14 +02:00
ThatsLeo 24c4dbae1e fix(shader): keep f64 denormals where the device can preserve them
Shaders with f64 instructions now declare DenormPreserve for 64-bit floats
when the device reports shaderDenormPreserveFloat64. Without it Mesa ANV
flushed the subnormal result of v_fma_f64 to zero.

(cherry picked from commit 7df6c709de994cea0019707d45b6e7b96698fad1)
2026-10-11 03:09:34 +00:00
krishnarayaandClaude Opus 5.5 1ce9790481 fix(agc): pick float or integer sampler border colours from the paired images
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 21:57:09 -04:00
Dean Galvin 2fb7a77acc feat(shader): note which guest buffer elements a shader loads from
DescriptorBinding gains bufferRead next to bufferWritten and bufferAtomic,
filled from the resource tracker's per-buffer read flag and kept in the
shader disk cache (format 24).
2026-10-10 23:45:38 +13:00
Celegans12 7144bb57ee feat(shader): implement compute LDS beyond the device's shared memory limit
Route oversized compute LDS through a per-workgroup storage buffer.
Retain native shared memory for programs that fit the device limit.
Carry the spill stride through prepared shader results and dispatches.
Preserve the stride in the full-result codec and its round-trip fixture.
Keep the Linux RecompileResult size guard aligned with the added field.
Exercise interleaved workgroups and the device-limit boundary.
This topic contains only the LDS change and its reviewer-requested repair.
The base includes upstream's separately merged NaN result correction.
2026-10-10 10:56:56 +02:00
Nahuel Genchi eb06284c78 fix(shader): read 2D image accesses through 1D T#s as measured
A compute shader in Astro Bot samples an image as 2D while the bound
T# is 1D, and the recompiler refused it. Offer a 1D runtime mode for
sampled images used only by image_sample_lz and mip-less image_load,
which reads the texel the first coordinate selects, as measured on
RDNA2 in #2237.
2026-10-10 09:35:34 +02:00
Adrià 1a668689d6 Merge pull request #2133 from queeeef/fix/agc-3d-access-on-2d-texture
fix(shader): bind 2D textures to 3D sample and load accesses as measured
2026-10-10 08:25:22 +02:00
Daan DehingandClaude Opus 5.5 70d190cdd5 fix(shader): bind 2D textures to 3D sample and load accesses as measured
A 3D image access bound to a 2D T# matched no runtime image mode and
threw "image descriptor is incompatible with the static runtime image
interface" (Sonic Origins, #2023). CouchRiv measured RDNA2 (gfx1036)
with the hardware oracle: image_sample_lz with dim 3D ignores r and
reads the (u,v) texel, and image_load reads the (x,y) texel when z is
0 and returns zero otherwise. Add a 2D mode for 3D accesses whose only
uses are those two forms, and make the load return zero for z != 0.
Every other access keeps throwing.

Fixes #2023

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 05:15:30 +02:00
russhil 4a2e60546c feat(shader): emulate fragment barycentrics with a generated geometry stage
Without VK_KHR_fragment_shader_barycentric the recompiler dropped
v_interp_p1_f32 and made v_interp_p2_f32 read the attribute Vulkan
interpolated, but never wrote the I/J VGPRs: a pixel shader that read
them for anything else got 0, and v_interp_mov_f32 of P10/P20 (or P0 of
an interpolated input) needed PerVertexKHR and failed pipeline
validation.

The fallback translation now loads the I/J VGPRs and marks v_interp_p1
and v_interp_p2 with witnesses. After the front-end simplification
(SSA, folding, DCE, read-lane and masked-select elimination),
HostInterpolationChecker requires every p2 to read its J, and its p1's
I, from a barycentric of the parameter's kind, every p1 result to reach
only the matching p2 (through a write masked by the p2's EXEC, whose
inactive lanes keep the old register), no parameter read as raw
vertices and no slot shared by different interpolations. It then
lowers the witnesses to the host-interpolated attribute as before,
reruns DCE and masked-select elimination, and accepts the program only
when no barycentric read remains, so reusing the I/J VGPRs after
interpolating keeps host interpolation and the previous SPIR-V. Any other
program is translated with the barycentric path and marked as emulated:
its barycentrics become vec3 inputs (NoPerspective for the linear
weights) and its per-vertex parameters flat vec4[3] inputs, placed in
the free locations by LayoutBarycentricEmulation. The driver then
inserts a generated geometry stage between the vertex and fragment
shaders that copies the position and parameters, writes the one-hot
weights of each vertex and the three vertices' parameter values, so the
rasterizer interpolates the same weights the extension provides.

The stage needs geometryShader and a vertex shader before it;
tessellation, mesh and rect-list pipelines, other primitive types and
interfaces beyond 32 locations or the device's geometry limits throw.
CompiledShaderArtifact carries the emulation (shader disk cache format 21).

Hardware snaps window corners to 1/256 pixel before interpolating
(measured by yahya308 on an RTX 4070 Laptop and a Radeon 780M in #1547);
lavapipe snaps only for coverage (lp_rast.h FIXED_ORDER 8), so the test
accepts either reference per pixel at the original 1e-4 margin.

Sources:
- v_interp_p1_f32/v_interp_p2_f32/v_interp_mov_f32 semantics (P0,
  P10, P20, I/J): AMD RDNA2 ISA, "Parameter Interpolation".
- BaryCoordKHR/BaryCoordNoPerspKHR weights and PerVertexKHR vertex order:
  SPV_KHR_fragment_shader_barycentric, VK_KHR_fragment_shader_barycentric.
- Geometry shader triangle input order and provoking vertex: Vulkan
  specification, "Primitive Topologies" and "Geometry Shading".
- Interpolation decorations decided by the fragment input: Vulkan
  specification, "Interpolation Decorations".
- lavapipe interpolation: Mesa src/gallium/drivers/llvmpipe/lp_rast.h
  (FIXED_ORDER 8), lp_setup_tri.c (subpixel_snap for coverage only),
  lp_state_setup.c (init_args, plane setup from float positions).
2026-10-10 03:24:50 +02:00