Commit Graph
2181 Commits
Author SHA1 Message Date
Dean 263eee0a77 Merge pull request #10837 from Raghav314/perf/agc-depth-plane-copies
perf(agc): keep depth plane copies resident instead of remaking them on each use
2026-10-27 08:18:34 +13:00
Dean 930a681f2a Merge pull request #9879 from thuanquang/fix/linear-target-import-creation
perf(agc): create the host import of a linear color target in registered memory
2026-10-27 08:18:22 +13:00
Adrià 035ac96edd Merge pull request #9940 from EagleBearerYS/fix/agc-compared-import-initial-dcc
fix(agc): accept a compared host import for an initial multisampled DCC import
2026-10-26 13:51:02 +01:00
Dean 9bbb7f37c6 Merge pull request #8898 from camezaro-intc/format11-11-10-float-stores
fix(shader_recompiler): pack format 11_11_10 float image stores in shader
2026-10-27 01:03:40 +13:00
Adrià 6641f48356 Merge pull request #9789 from rooklz/fix/agc-uint-color-export
fix(libSceAgcDriver): export raw 32-bit values into UINT color targets as integers
2026-10-26 12:48:04 +01:00
Yunus Shaikh 9b0ff5ccc2 fix(agc): accept a compared host import for a multisampled target's FMASK range
be write-watched at the initial import ("native FMASK contents require
watched guest memory") and at each reuse ("native FMASK sampling requires
watched guest memory"). In Linux comparison mode a host import over the
FMASK unwatches it, so the target is refused one check after the color,
DCC and CMASK ranges that the previous commit accepts.

Treat an FMASK range that a compared host import covers
(ComparedHostImportCovers) as the color and metadata ranges are treated:
keep a copy and its NewestStamp at the initial import, skip it in the
import's UnchangedSinceAll, and at reuse require the stamp and the bytes
to be unchanged, comparing them at most once per collect epoch. An
explicitly unwatched FMASK range is still refused.

Four-sample targets take no FMASK range, so this changes nothing for them.

Refs https://github.com/boykopovar/AnyPS5/issues/9724
2026-10-26 12:30:14 +01:00
Yunus Shaikh c10d1eae66 fix(agc): accept a compared host import for an initial multisampled DCC import
Rush 2 Recompiled (PPSA69423) and Wave Race 64 Recompiled (PPSA69424)
stop with "AGC graphics: initial multisampled DCC contents require
watched guest memory"
(https://github.com/boykopovar/AnyPS5/issues/9724). On Linux with
lavapipe, the write-watch probe finds that device accesses to a host
import trip the write watch, so every imported range is compared rather
than watched. A multisampled DCC target whose color, DCC or CMASK range
lies in such an import was then refused at its first draw: importing the
target takes a write generation for each range, and a compared range has
none.

A range that is not watched but lies in a live host import the probe
compares is now copied when the target is imported, and its metadata
again when a whole fill is taken as its fast clear. Each later use
compares the range with that copy, at most once per collect epoch, and
counts any driver or GPU store over its 64 KiB blocks since the copy as
a write, so a guest store of new bytes or any store by the driver
refuses the resident target as a watched range does. A range left
unwatched outside such an import is refused as before.

This covers the Linux comparison mode, not the Windows deferred settle
(BF-150): compared imports on Windows still refuse.
2026-10-26 12:30:01 +01:00
Dean 9d906c833c Merge pull request #10681 from PYTHONRETARDE/fix/d16-depth-take-storage-discard
fix(agc): discard a new depth surface's depth before taking storage writes
2026-10-26 21:29:52 +13:00
Dean 19af7f44e4 Merge pull request #10368 from Ondra97/codex/fix-storage-native-overlap-span
fix(agc): check whole storage views for native surface overlap
2026-10-26 21:20:04 +13:00
Dean fdb3925940 Merge pull request #9913 from HQasper/claude/project-thread-75dvwh
fix(agc): draw stencil AND, OR, XOR and XNOR on the bits they change
2026-10-26 20:03:59 +13:00
Dean 14c99b52ac Merge pull request #9007 from EagleBearerYS/perf/agc-library-lto-info-when-optimized
perf(agc): retain link-time optimization info only where a link is optimized
2026-10-26 18:26:44 +13:00
Dean 1eb66943ba Merge pull request #8615 from Lindamea1/fix/agc-stencil-replay-push-data
fix(agc): put a stencil replay shader's guest buffer offsets where its shader data is
2026-10-26 18:26:40 +13:00
Dean d31f372e33 Merge pull request #10062 from imellag/fix/agc-moltenvk-destroy-at-idle
fix(agc): destroy buffers and memory on MoltenVK only while the graphics queue is idle
2026-10-26 14:28:45 +13:00
Dean e45c9191bd Merge pull request #8926 from EagleBearerYS/fix/agc-retired-import-rewatch
fix(agc): put a retired import's unchanged ranges back in the write watch
2026-10-26 14:11:43 +13:00
Adrià acb900c194 Merge pull request #9737 from imellag/feat/agc-depth-bounds-emulation
feat(agc): emulate a one-sided depth bounds test without the depthBounds feature
2026-10-26 00:35:49 +01:00
Adrià cceb6c3c41 Merge pull request #9961 from daviaaze/fix/agc-dcc-sliced-array-window
fix(agc): serve sampled DCC array views from their viewed slices
2026-10-25 21:53:47 +01:00
thuanquangandClaude e1fa56c7bf perf(agc): drop the armed-page case from the color target import gate
#9181 stopped write-protecting resident runs on Windows: the write watch
no longer arms them read-only, and the import access opens nothing on
them. The gate's case that counted armed read-only private pages as
writable can no longer change a decision, and the tests that armed a
resident run first could only skip.

Remove the case: resident runs are read-write private pages and pass the
writable check as they are. --armed becomes --direct, the same 2 MiB
direct-memory run without the arming step. --armed-gate becomes
--private-gate and keeps the checks that can still be reached: the
direct run is refused under Unwatch and imported under Watch, and a
block committed read-only while registered writable is refused without
being counted.

Co-Authored-By: Claude <[email protected]>
2026-10-26 03:29:04 +07:00
Dean 7ce95893f9 Merge pull request #10551 from JJenkx/perf/agc-storage-reclaim-ceiling
fix(agc): reclaim idle device buffers up to the storage cache's current cap
2026-10-26 09:10:30 +13:00
thuanquang 6adad6733c Merge main into fix/linear-target-import-creation 2026-10-26 02:07:34 +07:00
Adrià d17785dba8 Merge pull request #9551 from JJenkx/perf/agc-sparse-mirror-range-run
perf(agc): mirror a sparse heap whose committed span crosses adjacent ranges
2026-10-25 19:26:00 +01:00
Adrià 5d48c6233e Merge pull request #9401 from tibzejoker/perf/grow-pipeline-store
perf(agc): size the pipeline store to the title's working set
2026-10-25 19:07:59 +01:00
Dean 68cc9d4e75 Merge pull request #10369 from krishalivaibhav/fix/import-watched-write-opt-in
fix(agc): let imports that cannot write guest memory keep the watch armed
2026-10-26 06:14:06 +13:00
Davi Azevedo b166232c72 fix(agc): refresh DCC sampled array windows 2026-10-25 14:13:27 -03:00
Dean 79f061ba5b Merge pull request #9685 from thuanquang/fix/linear-target-completion-stores
fix(agc): store resident linear color targets at completion points, limited to their drawn rectangles
2026-10-26 05:44:21 +13:00
Dean 8864d0e323 Merge pull request #10500 from dotaku22/contribution/agc-uncommitted-depth-reuse
perf(agc): reuse uncommitted depth plane layers
2026-10-26 04:55:09 +13:00
Dean 006c3648bd Merge pull request #8911 from Celegans12/perf/agc-held-read-skip-empty-flush
perf(agc): skip the queued-draw read check when a storage flush stores nothing
2026-10-26 04:19:29 +13:00
Ondra97 d1dc3a5920 fix(agc): check whole storage views for native surface overlap 2026-10-25 15:04:47 +01:00
Adrià 0658bc8749 Merge pull request #9186 from fma-rc/fix/agc-retire-undrawn-filled-msaa
fix(agc): retire an undrawn filled multisampled color target that a guest access overlaps
2026-10-25 14:25:07 +01:00
Adrià a8b199d103 Merge pull request #7618 from mrfelek/perf/stage-swept-write-only
perf(agc): stage written-only buffer elements a dispatch sweeps on discrete GPUs
2026-10-25 13:19:08 +01:00
Adrià a703a18496 Merge pull request #10046 from jotitadev/fix/agc-moltenvk-tessellation-pipeline-cache
fix(agc): create tessellation pipelines without the pipeline cache on MoltenVK
2026-10-25 12:38:16 +01:00
Adrià e317f41d59 Merge pull request #10440 from SuarezPM/ai/atomic64-keyed-tables
feat(shader): support 64-bit image atomics through keyed image tables
2026-10-25 11:58:35 +01:00
Adrià defc9674df Merge pull request #10375 from Ondra97/codex/fix-native-depth-attachment-alias
fix(agc): retire native depth before binding an overlapping layout
2026-10-25 11:58:29 +01:00
Adrià acbfd7c7fe Merge pull request #9941 from EagleBearerYS/fix/agc-sync-settle-initial-dcc-main2
fix(agc): settle a pending import synchronously before an initial multisampled DCC import
2026-10-25 10:50:05 +01:00
Adrià 1240b5da19 Merge pull request #9597 from milescoviello/fix/mipmapped-dcc-target-keys
fix(agc): keep a mipmapped DCC color target's keys on its resident image
2026-10-25 09:29:51 +01:00
Adrià fc41709ff3 Merge pull request #9564 from EagleBearerYS/port/fable-fix-template-bindings
fix(agc): find a template's data bindings by binding number
2026-10-25 09:29:46 +01:00
Jota 2fd07f181d fix(agc): keep tessellation pipelines off pipeline libraries without the pipeline cache 2026-10-25 08:55:44 +01:00
Jota 5daac82d32 fix(agc): create tessellation pipelines without the pipeline cache on MoltenVK
MoltenVK runs the tessellation evaluation stage as a post-tessellation
vertex function that reads the control stage's per-vertex outputs from a
raw buffer, and pads the evaluation input struct to every output of the
control shader it is linked with. The shader library cache of a
VkPipelineCache matches a cached conversion when the new pipeline has the
inputs that conversion used, so an evaluation shader converted next to a
hull with one 16-byte output is reused next to the merged hull, whose LDS
record adds a second per-vertex output. The domain stage then reads the
merged hull's control points at a 16-byte stride over a 48-byte buffer and
the patch lands elsewhere. Created without the pipeline cache, each
tessellation pipeline converts its stages for its own interface.
2026-10-25 08:55:34 +01:00
Adrià 811ffe10af Merge pull request #9514 from EagleBearerYS/fix/agc-address-copy-evict-main
fix(agc): an address-based build evicts idle imports instead of copying past the cap
2026-10-25 08:40:37 +01:00
Dean e5f23554c9 Merge pull request #10632 from noir39/fix/journal-replay-priority
fix(agc): build the pipeline journal replay at a lower thread priority
2026-10-25 20:23:57 +13:00
camezaro-intc 68fc51f81c fix(agc): use native b10g11r11 layout for packed float dcc clears 2026-10-24 21:32:14 -06:00
camezaro-intc e3f644040c fix(shader_recompiler): pack format 11_11_10 float image stores in shader 2026-10-24 21:32:14 -06:00
raghav314andClaude Opus 5.5 ce9c6cbd6a fix(agc): share one depth plane copy across a surface's layer ranges
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 08:22:53 +05:30
raghav314andClaude Opus 5.5 90c2600c44 fix(agc): return a depth plane copy's memory to the device pool
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 08:22:53 +05:30
milescovielloandClaude Opus 5.5 52f36c8aa2 fix(agc): keep a mipmapped DCC color target's keys on its resident image
DecodeColorBuffer dropped the DCC address of a color target with more than
one mip, so the target's resident image had no keys: it was uploaded from
guest memory under the game's fast-clear keys, and no draw into it marked
them uncompressed. The game's textures over the same chain name the keys,
so they kept sampling the clear (0000 reads as (0,0,0,0)) whatever was
drawn. MXGP 26, Borderlands 4 and Forspoken render such targets.

- ColorTarget.chainDccAddress keeps the keys of a 2D single-layer chain;
  dccAddress stays 0, so the per-draw single-mip key handling is unchanged.
- SurfaceForTarget gives the resident surface those keys, and the image
  then treats them as a multi-mip storage image does: a uniform clear is
  cleared on the GPU at upload, and the first write marks every key
  uncompressed.
- A draw recipe's key check uses the surface's keys.
- sizeof(State) is 840: the recipe codec and CanonicalPipelineState do not
  copy the field.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 00:31:53 +00:00
thibautandClaude Opus 5.5 ad047899bb perf(agc): grow the pipeline store from 1024 up to 4096 entries
The graphics pipeline store kept a fixed 1024 entries and the pipeline journal replayed at most
1024 records, and a replayed pipeline that found the store full was dropped. A title whose
working set is larger rebuilt the rest at the draw on every run, and evicted pipelines it kept
using were rebuilt again and again.

The bound now starts at 1024 and doubles up to 4096: a journal replay that does not fit grows it
instead of dropping the pipeline, and so does eviction churn (a ghost list of evicted keys, checked
every bound/32 evictions: more than half of them came back). It never shrinks during a run;
APS5_PIPELINE_STORE_ENTRIES still fixes it. The journal loads its last 4096 records by default
(APS5_PIPELINE_JOURNAL_ENTRIES). Resident pipelines are bounded by count, not bytes.

agc_driver_recorder_tests --benchmark-pipeline-store-memory [count] (opt-in, not registered)
builds count graphics pipelines with one fragment module each through CachedPipeline and prints
process private bytes and VK_EXT_memory_budget heap usage before and after: with the triangle
shaders about 59 KiB host and no device memory per pipeline on an RTX 4090, 100 KiB host and
8 KiB device-local on a UHD 770.

Tests: agc_pipeline_store_growth (fails on main), agc_pipeline_store_fixed_bound,
agc_pipeline_store_replay_growth (replays on one thread: the mock Vulkan is not thread-safe).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017SNUYRd7sRKZrMYpquAsnU
2026-10-25 02:02:41 +02:00
Dean Galvin f139561693 Merge main into fix/linear-target-completion-stores 2026-10-25 12:57:20 +13:00
Dean Galvin a5e015f7b7 Merge main into fix/linear-target-import-creation 2026-10-25 12:56:51 +13:00
JJenkxandClaude Opus 5.5 7fd7ae4064 perf(agc): keep a heap mirror that an import covers only in part
An address-based build releases the heap mirror at the base of each range
it imports. A mirror over a joined run of ranges starts at its first range
but spans the others too, so importing that range alone released it, and
the next descriptor bind rebuilt it: in Echoes of the End, 140 releases
and rebuilds of a 544 MiB mirror in 480 s. A heap mirror is now released
only when the imported range covers its reserved span.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 17:48:30 -04:00
JJenkxandClaude Opus 5.5 01e74052c7 perf(agc): mirror a sparse heap whose committed span crosses adjacent ranges
A sparse heap the guest grows by mapping an adjacent range is no longer
covered by one leased range, so bindSparseMirror refused it and every
use copied the heap's committed pieces on the CPU. The mirror now takes
a joined range over the run of continuing ranges (crossedRun), kept
while its member ranges stay the same.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 17:39:34 -04:00
Adrià Franch 0aa8b09eb0 fix(agc): pass the host-only flag at the first-sample sampling path 2026-10-24 22:41:08 +02:00