Commit Graph
198 Commits
Author SHA1 Message Date
Dean d9e14126da Merge pull request #7694 from Ondra97/codex/fix-descriptor-phi
fix(shader): split scalar-address descriptor phis
2026-11-02 20:56:24 +13:00
Ondra97 4c4b442a12 fix(shader): retain descriptor phi guards on current main 2026-11-01 17:08:29 +01:00
JJenkx 218ca18e42 fix(agc): render mesh layers within device limits 2026-11-01 06:07:38 -05:00
Dean 5d3ad2112f Merge pull request #10720 from meh7an/perf/shader-fast-f32
perf(shader): let APS5_FAST_F32 compile f32 arithmetic with host float rules
2026-11-01 16:41:29 +13:00
Dean Galvin 7ec2940c11 Merge main into perf/shader-fast-f32 2026-11-01 13:38:19 +13:00
Celegans12 068f2b3ecf fix(shader): reuse bound specialization fields for null buffer slots
Null buffer descriptors still split modules on unused specialization
fields after buffer presence moved to run time. Learn the first valid
bound fields per slot and use them for absent descriptors, retaining
actual runtime presence and independent bound formats.
Snapshot the learned fields once for result memo keys and materialization
so identical null captures cannot retain a module made before learning.
Cover direct, captured and prepared calls, null stores, and changed formats.
Keep the process-local table and an off switch for main's module selection.

AI-assisted: yes
2026-10-31 23:22:39 +01:00
Adrià d998343ced Merge pull request #12039 from milescoviello/perf/ir-use-arena
perf(shader): allocate a program's use lists from an arena
2026-10-30 14:38:29 +01:00
Ondra97 bb83b43b7d chore(shader): reconcile guarded descriptor cache with main 2026-10-30 11:54:36 +01:00
Adrià 25ff0a6d88 Merge pull request #12561 from milescoviello/fix/msaa-sample-adjusted
fix(shader): read a 2D MSAA T# through image_sample_a as its sample 0
2026-10-30 10:56:12 +01:00
milescoviello 0fe2329ee8 Merge main 422f96b3a9 into perf/ir-use-arena 2026-10-30 04:34:36 +00:00
Adrià d0cf19b2cb Merge pull request #12233 from beardsciences/fix/nvidia-mesh-window-buffer
fix(shader): keep mesh register windows out of local memory on NVIDIA
2026-10-30 02:31:36 +01:00
milescovielloandClaude Opus 5.5 f27177dd9b fix(shader): keep image_sample_a out of the cube-face and volume-array image modes
ResourceTracker masks the adjust bit before deciding cubeFaceSample, so the 2D
MSAA plane read takes image_sample_a. That predicate also feeds the cube-face and
2D-array-through-3D modes, which nothing has measured with _a. An image now
records adjustedSample when any of its samples sets the bit, and those two modes
refuse it. Disk cache format 50 for the new ImageResource field.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 22:49:34 +00:00
AdriàandClaude Sonnet 5.5 6a98793e3b fix(shader): IrValue is 144 bytes with the use allocator
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-29 21:17:50 +01:00
Christian 6f79055a00 fix(shader): keep mesh register windows out of local memory on NVIDIA
On NVIDIA's proprietary driver, function arrays that live in local memory
and are read under a data-dependent branch return wrong values in
subgroups 1-3 of a mesh workgroup; subgroup 0 is correct. A wave64
geometry program whose relative addressing keeps its VGPRs in the vector
window therefore loses register writes in every wave but the first. In
the clipping geometry program of Sony's PS5 PSP emulator (PPSA07550) the
empty waves never cleared their candidate primitive slots and wrote
degenerate triangles over wave 0's, so the 3D menu drew spikes.

On that driver a mesh program's window now lives in a device-local
storage buffer of 256 workgroup slots of 65536 dwords, claimed through a
per-slot lock and released after the final barrier. The pool is created
before the first draw that uses it records anything, and its header is
zeroed in a batch of its own that is submitted and waited for; the pool
is published only after that wait, and a failure releases it. Direct
register accesses keep one function variable per register; a direct
store also writes the buffer when a buffer read can see it, relative
reads load the buffer, relative writes store only to it, and a direct
read that may follow a relative write loads the buffer and refreshes the
variable. A buffer entry is zeroed only when a buffer read can see it
before a write. APS5_NO_MESH_WINDOW_BUFFER=1 keeps the arrays.
2026-10-29 08:56:39 -04:00
Adrià c33bb03591 Merge pull request #11820 from milescoviello/perf/ir-inline-operands
perf(shader): keep up to three IR operands inside the value
2026-10-29 12:58:07 +01:00
JJenkxandClaude Opus 5.5 e2f86a2047 fix(shader): read shader cache file times natively on Windows
The MinGW std::filesystem::last_write_time reads and sets file times
through the UCRT stat and utime calls, which convert through local time
using TZ. With a TZ other than the Windows zone, including the one libc
applies from the guest environment, times shifted by the difference:
under TZ=IST-5:30 on an Eastern host a temporary written that second
was 9.5 hours old, so housekeeping deleted it, and a TZ west of the host
set the active cache stamp hours in the past. Housekeeping now reads
times with GetFileAttributesExW, refreshes the stamp with SetFileTime
and compares in system_clock. The housekeeping test runs its child
with a TZ 12 hours from the host zone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 21:05:40 -04:00
milescovielloandClaude Opus 5.5 02260c6060 perf(shader): keep up to three IR operands inside the value
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 11:43:27 +00:00
Ondra97 fefe7bc97e fix(shader): update guarded descriptor source size assertion 2026-10-27 09:12:24 +01:00
Ondra97 7e01f3435e fix(shader): guard rematerialized descriptor reads by source blocks 2026-10-27 09:12:24 +01:00
hugodearaujo b9f4f65904 fix(shader): encode both new image fields under disk cache format 49
main took format 48 and a 45th ImageResource field (optionalDescriptor) with #8077; the merge kept both sides's 48 and 44.
2026-10-27 03:46:24 -03:00
hugodearaujo 5a5e54a455 Merge main into fix/agc-short-cube-sampling 2026-10-27 03:46:24 -03:00
Dean 37c6b4bc25 Merge pull request #8077 from 0xcrstn/ufc6/descriptor-web-fold
fix(shader): split descriptor webs whose paths fold or hold invalid arms
2026-10-27 14:56:47 +13:00
hugodearaujo 787b6a6720 fix(agc): sample cube descriptors with fewer than six slices as six faces 2026-10-26 15:11:35 -03:00
0xcrstnandClaude Opus 5.5 ec06ba2973 fix(agc): read back descriptor faults of shaders that also use image tables
A shader with an image table map read its fault buffer back only when a
table record was poisoned, an SRT read was poisoned, it had window lane
guards or the loop guard was on. A DescriptorFault only set the fault
buffer, so with a valid table and no copied write nothing ran the fault
check, and a lane that took a folded descriptor web path or selected an
undefined arm read arm 0 or zeros with no report.

The compiled artifact now counts its DescriptorFault instructions
(descriptorFaults, stored in the shader disk cache, format 48), and the
readback gate requests the fault check when it is nonzero. The result a
capture materializes copies the count, and also windowLaneGuards, which
that copy had dropped, so the gate's window lane guard condition never
saw it. sizeof(CompiledShaderArtifact) is 288 and sizeof(RecompileResult)
552 with the new field.

agc_driver_descriptor_web_faults adds a wave32 shader that reads an image
table and then the descriptor web, storing only to LDS so no copied write
forces completion: it binds an image table and no BDA address table, a
valid arm and an unselected undefined arm stay clean, the folded path and
a selected undefined arm fault at the read, and nothing faults with EXEC
empty. Without the gate change the folded case does not fault.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 14:46:11 +02:00
0xcrstnandClaude Opus 5.5 ac0c125999 Merge upstream main into ufc6/descriptor-web-fold
Resolve the overlap with main's WindowLaneGuard and image-resource changes
by keeping both sides: DescriptorFault sits next to WindowLaneGuard in the
opcode list, metadata and side-effect switch, and its emitter next to
EmitWindowLaneGuard; optionalDescriptor is serialized after
remappedDepth1D; undefinedImageWords follows the new image helpers; the
descriptor web debt entry follows main's new entries.

The ImageResource field-count assertion is derived from the merged
structure (44 fields: main's 43 plus optionalDescriptor). sizeof
(ImageResource) stays 96 and sizeof(MemoryInfo) stays 80, so those
assertions are unchanged. The undefined-format test keeps its captured
regions in a variable, as MemoryRegionView no longer binds a temporary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 14:10:30 +02:00
milescovielloandClaude Opus 5.5 8868e09624 fix(shader): bound the bytes the recompiler's result memos hold
Every shader source keeps up to 256 materialized results of
Recompile(request, capture) in its result memo, and as many patch
recipes in its masked memo, with no limit on their bytes. In Ghost of
Tsushima's opening the memos held about 500 MiB after 5 minutes and
kept growing, at a 13 % hit rate.

Each memo entry now counts the bytes its result's vectors keep (the
bindings' vectors included; the module is shared with the prepared
module cache), plus its patch recipe in the masked memo. A result held
by both tables counts once in each. Past a budget, 256 MiB unless
APS5_RESULT_MEMO_MB sets another (0 sets none), the least recently used
entries of both tables of all sources are dropped until three quarters
of the budget is left. The recency stamps come from one clock for all
sources and both tables so they compare across them. The profile line
also reports the trimmed and held entries and their MiB.

The trim takes its lock blocking and repeats, re-reading the bytes held,
until they are within the budget, so the insertion that pushed them
over has its trim run after any other; it stops when nothing is left to
drop.

SetResultMemoBudget and ResultMemoBytes let agc_shader_result_memo_budget
check that a memo over its budget keeps the most recently used results
and drops the oldest one, with the masked memo off. A one-shot hook
inside the trim (SetResultMemoTrimHook) lets
agc_shader_result_memo_budget_threads insert two results from other
threads after the trim has read the bytes held: the memo must still end
within its budget. agc_shader_result_memo_budget_masked, with the masked
memo on, checks that a first result counts its masked entry too and that
a trim empties the masked memo.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 05:04:18 +00:00
Mehran 7d6cc57fdf perf(shader): let APS5_FAST_F32 compile f32 arithmetic with host float rules 2026-10-24 21:24:07 +03:00
Adrià 522e32e3b6 Merge pull request #7550 from gjonn/fix/shader-resinfo-any-descriptor-dimension
fix(shader): answer image_get_resinfo on any T# dimension
2026-10-24 15:30:15 +02:00
milescovielloandClaude Opus 5.5 38ac888dbb fix(shader): share resource plans loaded from the same disk cache payload
A shader source loading its resource plan from the disk cache decoded
its own copy, also when another source had already loaded the same
plan: the same code registered under another plan key (another host
subgroup size or interface) stores byte-identical plan entries. In Ghost
of Tsushima's cache, 14,043 plan entries hold 8,170 distinct payloads.
Loaded plans now go through a table of weak references keyed by two
hashes of the payload, its size and the shader address the plan carries,
so equal payloads for one shader decode once and share the plan, its
compact form and its compiled SRT tape while any source uses it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 04:23:05 +00:00
Adrià FranchandClaude Opus 5.5 7b4b9d9814 fix(shader): zero the resinfo layer count for DIMs without layers
image_get_resinfo returns 0 in its third component when the instruction's
DIM has no layers (1D, 2D, 2D MSAA) and the T# is not 3D, as measured on
RDNA 2 in #7550. Keep 1D-array T#s on their first layer and MSAA T#s
refused, and record the unmeasured forms in the shader debt file.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 04:21:06 +02:00
Gjon Gojcevic 3ba1d39db6 fix(shader): answer image_get_resinfo on any T# dimension
image_get_resinfo with DIM 1D on a cube, 3D or 2D-array T# was refused
with "image address has too few coordinate components": the tracker made
a 1D image that only the query uses, and no 1D mode matches such a T#.
The returned size, layer count and levels come from the T#; DIM only sets
the number of address registers. A 1D image used only by dimension
queries now decodes the T#'s own dimension and accepts 2D, 1D array,
2D array, 3D and cube views.
The flag is stored in the shader disk cache, so FormatVersion moves to 38.

PPSA01317 queries a 64x64 cube with DIM 1D in a pixel shader.

AI-assisted: yes
2026-10-24 04:07:24 +02:00
Adrià dcd7e3a61e Merge pull request #8564 from JAB-dev/feat/agc-4-4-4-4-partial-writes
feat(agc): merge partial writes into 4_4_4_4 UNORM color targets
2026-10-23 23:23:11 +02:00
Adrià a0e858ff7b Merge pull request #8881 from thuanquang/fix/writelane-spill-window
fix(shader): keep a v_writelane lane known across computed-index window stores
2026-10-23 23:17:12 +02:00
JAB-devandClaude Sonnet 5.5 8d54357e79 Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-23 21:18:00 +02:00
mazen 287b149950 fix(shader): keep an unbounded pixel LDS array in a storage buffer
A Function array of 8192 dwords faults NVIDIA driver 617.42. The guest array stays that size, and each invocation gets its own region in a buffer.
2026-10-23 20:52:46 +04:00
Adrià b066e5cb77 Merge pull request #8145 from TheSovietWaffle/fix/recompiler-stencil-replay-readonly-bda
fix(recompiler): replay stencil exports of pixel shaders that only read through BDA
2026-10-23 18:46:24 +02:00
JAB-devandClaude Sonnet 5.5 870bacd092 Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-23 08:59:06 +02:00
Adrià 0db47b263d Merge pull request #7831 from MarcZX10/codex/fix-perspective-offset-barycentrics-7825
fix(shader): normalize offset perspective barycentrics after interpolation
2026-10-23 07:37:02 +02:00
MarcZX10 f6826208fb fix(shader): normalize offset perspective barycentrics 2026-10-23 06:32:27 +02:00
raghav314andClaude Opus 5.5 c0dbd1871c perf(agc): draw finisher pipeline (APS5_DRAW_PIPELINE)
The second half of a pipelined draw (stage materialization, cache insert,
enqueue) runs on a finisher thread, overlapping the next draw's packet
work; draws whose stages could write memory are held back. Commits skip
work whose inputs did not change since the last commit, color metadata
passes are ordered through the pipeline, resource and storage-image proofs
are reused within one collect epoch until a write breaks them, and a shape
entry is refreshed in place at the second sight of the same read user words.
APS5_VERIFY_DRAW_PIPELINE checks reused proofs against a full check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 03:46:57 +05:30
JAB-devandClaude Sonnet 5.5 7576430edd Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-22 19:59:20 +02:00
LeandroLP23andClaude Opus 5.5 1bf43f9b02 fix(recompiler): read P20 of a flat input as the provoking vertex
A FLAT_SHADE input without pass-through that a pixel shader reads
through v_interp_mov_f32 P20 and not P10 stayed an explicit per-vertex
input and read vertex 2 minus vertex 0. For a flat value that is the same
on every vertex the difference is 0, and with the first provoking vertex
nothing refused it.

ps5-opengl lowers every flat input to a load of one vertex: vertex 1
(P10) by default, which #4030 reads as the provoking vertex, and vertex 2
(P20) for triangles when GL's flatshade_first is set. SuperTuxKart's
deferred point lights are drawn that way, so all twelve flat inputs of
pointlight.frag read 0, the attenuation 0 * -inf was NaN, nothing was
discarded, and the starting-line referee's light quad blacked out the
scene behind it (#8364).

A P20-only read now returns the provoking vertex's value, as P10 and P0
do. The lane was not measured on the console either, so FragmentParameter
records it and a pipeline using the last provoking vertex throws. An input
read through both P10 and P20 keeps its per-vertex differences.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 18:37:47 +02:00
JAB-devandClaude Sonnet 5.5 4aaf26e3f3 Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-22 14:24:38 +02:00
Get-fix 4b717912d7 feat(shader): decode PS4 (GCN) shaders by re-encoding them to RDNA
Each GCN instruction is re-encoded to its RDNA form and decoded by the
existing RDNA decoder, so the PS4 path shares the recompiler. Covers the
legacy VS stage (program at the VS slot, user SGPRs from s0, vertex and
instance index in v0-v3), fetch shaders linked as user-data calls, MIMG
(image_sample and friends), PS4 buffer descriptors (GCN DATA_FORMAT /
NUM_FORMAT, 44-bit base) and T# image descriptors (GCN tiling in word 7).
The GCN switch is keyed into the shader disk cache. PS5 behaviour is
unchanged: every PS4-only rule is gated on GcnGuestShaders().
2026-10-22 12:17:44 +03:00
JAB-devandClaude Sonnet 5.5 8ed185a51c Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-21 20:13:17 +02:00
1a74a6cdd9 fix(shader): keep a v_writelane lane known across computed-index window stores
fdfawef324 notes that current LLVM spills SGPRs into VGPRs it allocates like any other
register, so one window register can be an ordinary register early in a
program and hold spill lanes later. ReadLaneEliminator only followed a
spilled lane across M0-indexed window stores for slots never used as
ordinary registers, so RESIDENT EVIL 4 (PPSA07411) and LEGO Horizon
Adventures (PPSA14632) kept their reloaded descriptors as run-time
values and stopped. A known lane can only come from a v_writelane chain,
so keep it across a computed-index store instead; a constant-index store
of the slot still ends the spill. This is fdfawef324's suggestion on
#6277.

That such a store misses the spill cannot be proven for these programs,
so it is checked at run time where a replaced read depends on it: a
backward liveness over each slot and lane whose known value a replaced
read used puts a WindowLaneGuard before every computed-index store at
which that lane is live, and the guard records a WindowLaneSpill fault
when the store changes that lane of the slot. The driver reads the fault
buffer back for every program with such a guard and reports the dispatch
or draw as failed, so a broken assumption is no longer silent. This also
covers the pure spill slots main already folds.

Co-authored-by: fdfawef324 <[email protected]>
Co-Authored-By: Claude <[email protected]>
2026-10-21 20:17:08 +07:00
Dean 854a514bbe Merge pull request #7945 from veosett/codex/windows-cache-housekeeping-safety
fix(shader): avoid unsafe Windows cache directory traversal
2026-10-21 20:57:27 +13:00
Dean Galvinandmazen dc38f31983 Merge main into fix/skip-inaccessible-branched-scalar-load
Shader disk cache FormatVersion 43: main took 42 with #7966, and this
change also changes the cached plan.

Co-authored-by: mazen <[email protected]>
2026-10-21 14:23:05 +13:00
Dean 1faa800f08 Merge pull request #7966 from KarthikeyaAnna/fix/agc-1d-depth-compare-2d
fix(agc): back 1D depth comparison textures with 2D images
2026-10-21 14:21:13 +13:00
Dean 01fbf1060d Merge pull request #8580 from veosett/codex/windows-prebuilt-cache-discovery
fix(shader): discover prebuilt caches through native Windows paths
2026-10-21 11:45:12 +13:00