Commit Graph
1726 Commits
Author SHA1 Message Date
Adrià 0c9c5db748 Merge pull request #12690 from MarcZX10/feat/host-system-report
feat(agc): host system report and an actionable missing-Vulkan-feature message
2026-10-30 02:52:18 +01:00
Adrià e8cfff0a08 Merge pull request #12171 from slopgobblercobbler/fix/agc-draw-pipeline-report-duplicate-format
fix(agc): eliminate duplicated read counters in pipelined draw reports
2026-10-30 02:51:11 +01: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
Adrià 086adee5e3 Merge pull request #12379 from MarcZX10/feat/msgdialog-overlay
feat(overlay): show PS5 system dialogs as real PC dialogs
2026-10-30 02:04:23 +01:00
Adrià f6fddd60d8 Merge pull request #9243 from fisherjoey/perf/draw-cache-indirect-admission
perf(agc): cache CPU-path indirect draws behind APS5_DRAW_CACHE_INDIRECT
2026-10-30 01:51:25 +01:00
Adrià 673fa865f4 Merge pull request #10140 from frankea/fix/user-data-callee-window
fix(agc): read user-data callees up to the 1 MiB raw shader program limit
2026-10-30 01:25:59 +01:00
Adrià 2a8274f328 Merge pull request #9738 from mugurc/fix/agc-preparation-lifecycle-exit
fix(agc): keep the shader preparation lifecycle mutex alive through exit
2026-10-30 00:56:51 +01:00
Adrià b68fff81f2 Merge pull request #11957 from Bram910/perf/shader-region-merge
perf(agc): merge shared shader regions with a heap
2026-10-29 21:20:26 +01:00
Dean bfc5ee4101 Merge pull request #12264 from Tehshortbus/perf/agc-written-buffer-index
perf(agc): find a range's newest writer through a granule index instead of scanning the ring
2026-10-30 09:19:10 +13:00
Adrià ce9394b844 Merge pull request #12566 from chitters2004/fix/agc-capture-host-only-msaa
fix(agc): write host-only multisample memory as zeros in a capture snapshot
2026-10-29 21:19:01 +01:00
MarcZX10 17ff9177fb fix(agc): read the host CPU model and missing features through the exported helpers
libSceAgcDriver.prx failed to load in the patched library check with an undefined symbol for HostCpuModel, because the host report called libkernel's plain C++ functions, which the patched libkernel does not export to it. The report now calls the extern C helpers and splits the joined feature list back into names.
2026-10-29 14:20:35 +00:00
MarcZX10 f0d5ff528f feat(libSceAgcDriver): draw the system dialog in the presentation
The presentation drew the system keyboard from SystemOverlayView and laid it out
inside its own recording. It now asks SystemOverlayLayout for the system panel
at the swapchain extent, which is already validated by then, and records
whichever of the keyboard and the dialog is set through the same overlay pass
and layout transitions. Presentations with neither set are unchanged.
2026-10-29 14:06:13 +00:00
MarcZX10 8210c987c9 feat(libSceAgcDriver): lay out a system dialog beside the system keyboard
LayOutDialog turns a ModalDialogView into the same rectangle list the system
keyboard uses: a centred panel, the message word-wrapped to 36 columns and at
most 8 lines (the last one ends in dots when the text is longer), and one to
three buttons in a row with an accent border on the focused one. The scale
follows the keyboard's rule and shrinks until the panel fits the target.

AgcDriverSetSystemDialog stores the view for the presenter, and
SystemOverlayLayout returns the keyboard's layout when a keyboard is set and the
dialog's otherwise, so only one system panel is drawn at a time.
2026-10-29 14:06:12 +00: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
slopgobblercobbler f65782302e fix(agc): eliminate duplicated read counters in pipelined draw reports
In DrawPipeline::report, reads was appended to drainText in addition to being passed as parameter 10 to %s right before `; drains:%s`, causing the read range counters to print twice per profile report.

Remove the redundant drainText += reads; append.

Fixes #10756.
2026-10-29 12:11:05 +01:00
Dean ba5b5330b3 Merge pull request #12706 from Gonic0/fix/agc-barycentric-patches-restart
fix(agc): draw compacted restart lists and restart-free strips through the barycentric patches
2026-10-29 23:56:52 +13:00
Adrià beb5e23f8f Merge pull request #9595 from NaitikJoshiPro/pr/agc-clear-state-num-interp
fix(agc): CLEAR_STATE leaves SPI_PS_IN_CONTROL at NUM_INTERP 2
2026-10-29 11:23:14 +01:00
Adrià b62989b8bb Merge pull request #12432 from kiansaeidnia/feat/agc-dump-shaders-address-filter
feat(agc): APS5_DUMP_SHADERS takes a list of program addresses
2026-10-29 11:23:04 +01:00
Adrià 071ecaba53 Merge pull request #9723 from Sam-mon7/feat/sample-worker-queue
feat(agc): select the queue worker to sample
2026-10-29 10:40:44 +01:00
Adrià 8ab0b15bb4 Merge pull request #9626 from MarcZX10/codex/6139-bounded-registration-preparation
fix(agc): bound registered shader preparation memory
2026-10-29 10:40:33 +01:00
Adrià 2a90fb105b Merge pull request #9431 from Get-fix/ps4/agc-gcn
feat(libSceAgcDriver): draw PS4 (GCN) command buffers
2026-10-29 09:31:13 +01:00
Dean 4c7d275bef Merge pull request #11684 from oneandonlydean/feat/agc-unclamped-normalized-blend-v2
feat(agc): blend into an unclamped normalized color target in the pixel shader
2026-10-29 20:48:48 +13:00
Adrià f4b33f1c90 Merge pull request #9490 from JJenkx/windows/held-reads-env-once
perf(agc): read APS5_NO_QUEUED_DRAW_READ_ORDER once in the held-read check
2026-10-29 08:48:25 +01:00
Nicolas GonzalezandClaude Opus 5.5 95e7deeaab fix(agc): draw compacted restart lists and restart-free strips through the barycentric patches
The barycentric tessellation path refused any draw with the primitive
restart bit set. A non-indexed strip ignores the bit, and on a device
without VK_EXT_primitive_topology_list_restart a list never restarts on
the host, since its indices are compacted on the CPU first, so both now
take the patches. Indexed strips with primitive restart still throw,
now also in Graphics::Draw, which knows the draw is indexed.
Patch-list pipelines never enable primitive restart, which Vulkan does not
allow for them without primitiveTopologyPatchListRestart.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 00:56:03 -03:00
MarcZX10 52fe8fd303 feat(agc): print the host report to stderr once with ANYPS5_HOST_REPORT=1
With the variable at 1, the first presenting device prints the report
(system, SDL, GPU and driver, Vulkan requirements, shader cache, APS5_,
ANYPS5_, VK_ and SDL_ switches) to stderr after the device is chosen, and
before a missing-requirement error so a failing start still has it. An
invalid value stops the start with an error that names the variable.
Unset, empty or 0 prints nothing and does no extra work beyond the GPU
query of the previous commit; compile-only devices never print.
2026-10-29 02:07:11 +00:00
MarcZX10 3b94f84a32 feat(agc): stop at start-up with the actionable message when the GPU lacks a required item
Right after the device is chosen, the driver queries the facts of the
host report and, when a required extension or feature is missing, throws
the message of DescribeMissingRequirements: the GPU, its driver, every
missing item and what to try. The device-creation code keeps its own
checks, so nothing that passed before changes; only a device that was
already going to fail now fails earlier with a message that names it. The
query itself reads no more than the properties the driver reads anyway,
and a failure to query is ignored so it cannot add a new way to stop.
2026-10-29 02:07:11 +00:00
MarcZX10 c89702d5eb feat(agc): query the GPU's identity, driver and Vulkan requirements for the report
CollectHostGpuFacts takes a vkGetInstanceProcAddr and handles instead of
a VulkanDevice, so a test can answer the queries with a fake. It reads the
name, type, vendor and device ids, Vulkan version, driver name, info and
raw version (VK_KHR_driver_properties when offered), the largest
device-local heap, and the surface's present modes. The required list is
the extensions and features the device code refuses to start without:
VK_KHR_swapchain with a window, VK_KHR_8bit_storage,
VK_KHR_buffer_device_address, VK_KHR_shader_float_controls,
storageBuffer8BitAccess, bufferDeviceAddress, shaderInt64,
shaderSignedZeroInfNanPreserveFloat32, vertexPipelineStoresAndAtomics,
fragmentStoresAndAtomics, samplerAnisotropy and textureCompressionBC. A
list of optional extensions the driver code uses when present is
reported next to them as optional.
2026-10-29 02:07:11 +00:00
MarcZX10 0e2458eb65 feat(agc): read the host facts from the running machine
SystemHostSources fills HostSources from the OS (uname with the machine
type, or RtlGetVersion), the CPU brand string and CPU gate from
libkernel's HostCpu, the hardware thread count, physical memory, both SDL
versions, the shader cache directory (state and size, counted over at most
200000 entries without following links) and the process environment. The
names to redact come from USER or LOGNAME, the host name and the home
directory (USERNAME, COMPUTERNAME and USERPROFILE on Windows). Windows
and macOS branches are written from the existing PerformanceTrace and
HostCpu code and were not run here.
2026-10-29 02:07:11 +00:00
MarcZX10 968598f69f feat(agc): list the facts that could not be read at the end of the host report
A fact whose source failed prints "unavailable" in its own line; the new
[unavailable] section, sorted and redacted like every other value, says
which source failed and why, so the report shows what is missing and
that the reader did not simply forget it. The section is absent when
every source worked, so the golden report is unchanged.
2026-10-29 02:07:11 +00:00
MarcZX10 a473a39798 feat(agc): collect host facts from injected sources
HostSources holds one callable per fact (OS, CPU model and threads,
memory, CPU gate, both SDL versions, shader cache, environment entries and
the names to redact). CollectHostFacts calls each one, keeps the values it
gets, and records the name and message of a source that throws or is
missing instead of stopping, so one failing query does not hide the rest.
FilterHostEnvironment keeps APS5_, ANYPS5_, VK_ and SDL_ entries sorted by
name, and HostRedactionNames turns the account name, the host name and
the home directory's last component into the list the formatter redacts.
Nothing here reads the machine; the real sources come in a later commit.
2026-10-29 02:07:11 +00:00
MarcZX10 cf4826f969 feat(agc): describe the Vulkan features a GPU lacks in one actionable message
Today a driver that lacks a required extension or feature stops the game
with one line such as "Vulkan presentation: VK_KHR_8bit_storage is
unavailable": no GPU, no driver, only the first of the missing items, and
nothing to try. DescribeMissingRequirements names the GPU with its driver
and Vulkan version, lists every required item the GPU lacks, points to
the other Vulkan devices that ANYPS5_GPU can select and to
ANYPS5_HOST_REPORT=1 for the report to attach. It returns an empty string
when nothing required is missing.
2026-10-29 02:07:11 +00:00
MarcZX10 047190bb12 feat(agc): parse ANYPS5_HOST_REPORT
Unset, empty or 0 leaves the report off and 1 turns it on. Any other
value throws an error that names ANYPS5_HOST_REPORT and the value, like
ANYPS5_OVERLAY, so a typo does not silently print nothing.
2026-10-29 02:07:11 +00:00
MarcZX10 6273761db8 feat(agc): replace the user and host names the caller lists with <redacted>
HostFacts::redactions carries the names that identify the machine (the
account name, the host name). The formatter replaces every occurrence
that is a whole word, so "al" does not damage "radeon" and "alice" is
not left inside "alice-pc".
2026-10-29 02:07:11 +00:00
MarcZX10 1a8c0c4b7a feat(agc): keep paths, URLs, hardware addresses and control characters out of the host report
Every string the formatter prints goes through RedactHostText first. A
word that starts with / or ~, contains a backslash or starts with a drive
letter and separator prints as <path>, a word with :// prints as <url>,
a MAC address prints as <redacted>, and control characters (newlines
included) become spaces so a value cannot add a line of its own. Names
such as LAHF/SAHF are not paths and are kept.
2026-10-29 02:07:10 +00:00
MarcZX10 bad73e9748 feat(agc): add the host facts struct and a deterministic text formatter
Nothing prints host facts in one place today: the CPU gate, the selected
GPU and the heaps are separate start-up lines, and the driver name and
version are only written into a performance trace summary.

HostFacts holds what an issue needs (OS, CPU, threads, memory, CPU gate,
SDL versions, the GPU with its driver and Vulkan requirements, present
modes, shader cache state, APS5/ANYPS5 switches). Every optional fact can
be absent and then prints as "unavailable". FormatHostReport turns it into
text with fixed sections and sorted entries, so two runs on one machine
give identical bytes. It reads no driver and no environment.
2026-10-29 02:07:10 +00:00
Dean 33acc03447 Merge pull request #8930 from JJenkx/perf/agc-write-changed-byte-stores
perf(agc): store a write-back's changed bytes without a masked non-temporal store
2026-10-29 12:15:29 +13:00
Dean 206970d663 Merge pull request #12234 from MarcZX10/fix/trace-file-remove-temporary-on-write-failure
fix(agc): remove the temporary benchmark file when its write fails
2026-10-29 12:11:02 +13:00
Dean 391cb15c3c Merge pull request #12200 from MarcZX10/fix/agc-thread-dimension-group-count
fix(agc): count thread-dimension dispatch groups without wrapping at 2^32
2026-10-29 12:09:53 +13:00
Dean c9207624bc Merge pull request #12180 from Gonic0/feat/agc-list-restart-emulation
feat(agc): emulate list primitive restart without VK_EXT_primitive_topology_list_restart
2026-10-29 11:50:11 +13:00
Joey Fisher 898083cae3 perf(agc): cache CPU-path indirect draws behind APS5_DRAW_CACHE_INDIRECT
cacheDrawStages never admitted a draw an indirect packet runs on the CPU
path, so a title whose draws are mostly DRAW_INDEX_INDIRECT packets with
a patched user word the vertex program reads as a value missed the draw
cache on nearly every lookup whatever its size. On Demon's Souls 97 % of
the draw packets are such draws and the hit rate stayed at 9 % with
APS5_DRAW_CACHE_ENTRIES=32768.

APS5_DRAW_CACHE_INDIRECT admits them. A hit reuses the fragment stage
and skips the first vertex pass; the stage whose user word the record
patches is still re-materialized per record, as the hit path already
provided for.

Tested: agc_driver_draw_cache_reuse_indirect (three DRAW_INDIRECT draws
patching an unfolded user word: one insert and one hit with the knob,
none without), the other draw_cache_reuse, key_miss, register_key and
draw_cache_relocation tests on lavapipe and an RTX 5070 Ti.
2026-10-28 16:13:29 -06:00
JamieandClaude Opus 5.5 fa2b143d5a fix(agc): zero host-only multisample memory in capture deltas
Late-added ranges and write-watched blocks are read through the same
host-only-aware read as the snapshot, so a CPU store over a guarded
multisample target no longer aborts a capture. The read is a helper
tested for ranges in the middle, at either edge, overlapping and
outside a block, and against a native target and its neighbor.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 21:58:54 +00:00
JamieandClaude Opus 5.5 7b38bca9e5 fix(agc): write host-only multisample memory as zeros in a capture snapshot
A capture snapshot read every committed block through the coherent path,
which refuses memory under a multisampled color target, its FMASK or
native multisample depth whose samples exist only on the host, so the
capture stopped there. The snapshot now writes those bytes as zeros,
counts them as host_only_sample_bytes in capture.json and adds a
warning, and the replay starts those targets without their earlier
contents.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 20:27:23 +00:00
Adrià 46e54cf1f7 Merge pull request #10800 from slopgobblercobbler/fix/shader-diagnostics-dump-safety
fix(libSceAgcDriver): handle failed shader request dumps and uncapped skips
2026-10-28 18:15:01 +01:00
Adrià 2f34dca5b3 Merge pull request #11638 from dantdmdarealguy/test/agc-skip-without-vulkan
test(agc): skip submit progress and pipelined metadata pass without a Vulkan device
2026-10-28 15:29:28 +01:00
Adrià bd15a91f99 Merge pull request #11696 from Astronaut10/perf/agc-shape-memo
perf(agc): repeat a draw shape's resident targets and pipeline instead of looking them up again
2026-10-28 14:49:03 +01:00
KianandClaude Opus 5.5 ae305dfd5d feat(agc): APS5_DUMP_SHADERS takes a list of program addresses
A comma-separated list of hex program addresses (optional 0x prefix) now
writes only those programs' requests, so one expensive shader can be
captured without serializing every request a title prepares. Any other
value, such as 1, keeps writing every request. A filtered-out program
returns no name, so diagnostics never point at a file that was not
written, and it stays eligible for a later list.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 23:26:48 +10:00
NaitikJoshiProandClaude Opus 5.5 5f3eab6425 fix(agc): CLEAR_STATE leaves SPI_PS_IN_CONTROL at NUM_INTERP 2
The GFX10 clear state sets SPI_PS_IN_CONTROL to 0x2 (amdgpu
clearstate_gfx10.h). radeonsi relies on it: si_set_tracked_regs_to_clear_state
records 0x2 after a CLEAR_STATE, so the register is not written for a pixel
shader with two interpolants. The driver cleared it to 0, and such a pixel
shader was recompiled with no inputs.

CLEAR_STATE and the push-clear CONTEXT_STATE now leave NUM_INTERP 2. The
starting context keeps 0, since registration-time decoding reads it and
prepares pixel programs only when NUM_INTERP is 0.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 13:45:02 +01:00
Get-fix 0bec339021 feat(libSceAgcDriver): draw PS4 (GCN) command buffers
PS4 color and depth targets, PS4 graphics EOP events, and the PS4 tile
modes (1D/2D thin and display, depth with tile split, PRT, linear
general) on the AGC executor, with a GPU detiler for every mode.
Textures sampled over the padded corner of a render target are GPU block
copies, and the PS4 SDK pattern-fill compute kernel runs as a GPU fill
when it repeats one dword, so render targets and HTILE are cleared
without a CPU drain. Two-dword patterns keep running the kernel: as
fills, Limbo's clears of its 64-bit target made its gameplay advance
about half as far per frame.
Tests cover the tiling equations against addrlib formulas, the GPU
detiler for every mode and element size, and the fill ranges.
2026-10-28 13:01:27 +01:00
Bram910 2ce643be49 perf(agc): merge shared shader regions with a heap 2026-10-28 11:14:35 +01:00
Dean 3917fa85ce Merge pull request #12188 from Gonic0/fix/shader-lds-lock-fences-moltenvk
fix(shader): fence the LDS lock's critical section on MoltenVK
2026-10-28 22:51:00 +13:00