Commit Graph
1087 Commits
Author SHA1 Message Date
Adrià 87aee045df Merge pull request #6821 from JJenkx/fix/point-context-sdk-defaults
fix(agc): initialize point size and limits from SDK defaults
2026-10-19 13:45:12 +02:00
Adrià 2b6c1112b8 Merge pull request #6763 from SP4C3B4R-8/perf/windows-draw-input-copies
perf(agc): copy draw inputs on NVIDIA's Windows driver instead of binding host imports in place
2026-10-19 13:45:06 +02:00
Adrià f6eeca4f5f Merge pull request #6786 from fdfawef324/claude/agc-indirect-args-stale
fix(agc): wait for address-based writers before reading indirect dispatch arguments
2026-10-19 13:16:24 +02:00
Adrià 12e42b2730 Merge pull request #6660 from al3w0f205/fix/agcdriver-wait-reg-mem-masking-and-pipeline-drain
fix(libSceAgcDriver): mask WAIT_REG_MEM addresses and elide non-overlapping pipeline drains
2026-10-19 13:15:39 +02:00
Adrià c82ffb0f20 Merge pull request #6647 from binarycleric/fix/agc-table-update-after-bind
fix(agc): bind image and sampler tables through update-after-bind limits
2026-10-19 12:20:50 +02:00
SP4C3B4R-8andClaude Opus 5.5 4a6069481f perf(agc): copy draw inputs on NVIDIA's Windows driver instead of binding host imports in place
NVIDIA's Windows driver reads a host import of guest memory far slower than a buffer it allocated.
Since draw vertex and index ranges are bound in place from host imports (#2253, measured on Linux), Astro
Bot's Crash Site on Windows 11 with an RTX 5070 Ti spends 164 ms of every frame in draws on the GPU, and
45 ms with the ranges copied as before; with the same build, 4.71 fps in place against 7.52 copied. An
RTX 3060 shows the same (draws 32.3 against 24.3 ms per frame), while AMD's Windows driver reads them in
place about as fast as a copy (RX 9070 XT: 69.8 against 73.1 ms), so copying there only costs CPU.

The device decides once (DrawInputsInPlaceUsable, Context::drawInputsInPlace): ranges are copied with
VK_DRIVER_ID_NVIDIA_PROPRIETARY on Windows and bound in place everywhere else. APS5_DRAW_INPUTS_IN_PLACE=1
binds them in place and APS5_NO_DRAW_INPUTS_IN_PLACE=1 copies them on any device, the second winning.
agc_draw_inputs_in_place_driver checks the decision per driver and host; agc_draw_inputs_copied checks
that an aligned imported range is copied and its read not noted when the context copies, whatever the
inherited environment.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01GN8FJFTedayRXLHythXkZ4
2026-10-19 11:48:36 +02:00
al3w0f205 d59934a67c fix(libSceAgcDriver): mask WAIT_REG_MEM addresses and elide non-overlapping pipeline drains 2026-10-19 11:22:48 +02:00
Adrià d53d0e2d40 Merge pull request #6606 from veosett/codex/indirect-index-prefix
fix(agc): resolve sparse indirect index ranges per record
2026-10-19 10:47:44 +02:00
Adrià e12c913571 Merge pull request #6650 from WallisSkill/perf/agc-host-alloc-cache
perf(agc): cache freed small blocks per thread on Windows
2026-10-19 10:34:42 +02:00
f6c8e8474f fix(agc): wait for address-based writers before reading indirect dispatch arguments
A CPU read of DISPATCH_INDIRECT arguments waited only through the flush
hook, which waits for the ranges recorded work noted as pending writes.
An address-based store (FLAT/GLOBAL, or through a descriptor the
recompiler cannot resolve to a static buffer) is not recorded as a
pending write: its batch leases the registered allocations, and only the
guest pin waiter finished that batch. So the thread-dimension,
misaligned and disabled paths, the fill-kernel path and the device's CPU
fallback read the arguments from before an address-based producer ran.
GTA V (PPSA04264) dies loading Story on such a read: a 64-thread clear
kernel read {160, 288, 0xffffffff} as thread dimensions
(3x288x4294967295 groups), bytes its 1-thread setup kernel had not yet
overwritten with {n, 1, 1}, and threw "workgroup count
3x288x4294967295 exceeds device limits".

Every CPU read of dispatch arguments at execution now first finishes the
recorder up to the newest batch recorded with a lease
(Graphics::FinishLeaseWork). The group read-ahead still reads without
waiting; a dispatch it resolved is adopted only when the execution-time
read gives the same counts, and one that differs is dropped and counted
in the [groupcap] line. The device limit error names the argument
address and cpuReason, and the driver adds the queue, path and
read-ahead outcome. The [indirect] read time includes the lease wait,
and the [recorder] sync-site table records the offset of
FinishLeaseWork's caller. The CPU reads that still miss address-based
writes (indirect draw arguments and count, the copy kernel's count
record, the awaits-title checks) are listed in the technical debt.

IndirectArgumentsPendingProducer covers the execution-time CPU argument
reads on compute queues and the pending-label CPU fallback in the Vulkan
device. Its sixth case records a real argument label behind a host Vulkan
event in an earlier batch and an address-based producer in the later open
batch. The event releases only after that producer batch is submitted;
a bounded watchdog releases for cleanup but fails the case. It requires
a deferred producer lease, an unsubmitted producer at the argument
decision, cpuReason 2 and the fresh arguments and counter result. Small
valid stale counts keep a broken-wait control finite on every driver.
Exact CPU-reason and watchdog diagnostics identify the failing path. This
replaces a spinning workload whose earlier label could retire before
the fallback decision on lavapipe, allowing a false green with cpuReason 0.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Codex <[email protected]>
2026-10-19 10:18:11 +02:00
Adrià a8c934dc82 Merge pull request #6535 from gguerra26/fix/agc-unused-viewport-depth
fix(agc): normalize unused viewport depth ranges
2026-10-19 10:14:02 +02:00
Adrià d8d0222d02 Merge pull request #6616 from hashaam1217/fix/agc-eop-flip-pipelined-draws
fix(agc): present EOP flips when draws are pipelined
2026-10-19 09:38:12 +02:00
Adrià 75ec3b5671 Merge pull request #6543 from karanvora2599/fix/agc-radv-fill-memory-hle
fix(agc): take RADV's fill-memory kernel as a buffer fill
2026-10-19 09:37:38 +02:00
Jon Daniel 070a3f12c6 fix(agc): bind image and sampler tables through update-after-bind limits
Image and sampler table capacity came only from the regular descriptor
limits. MoltenVK reports Metal's argument table limits there (256 sampled
images and 16 samplers per stage), below the typed heaps the tables are
reserved on top of, so both capacities were 0 and every table draw or
dispatch was refused as if the device lacked descriptor indexing. Its
update-after-bind limits are 1000000 sampled images and 500000 samplers.

- descriptorBindingSampledImageUpdateAfterBind is queried and enabled, and
  the update-after-bind limits are read when either it or the storage
  buffer feature is present.
- A table whose regular capacity is 0 takes its capacity from the
  update-after-bind limits. Its binding is update-after-bind and its set
  layout and pool are update-after-bind ones, in ShaderResources and in
  DescribeSetLayouts alike. A table that fits the regular limits is
  unchanged.
- An update-after-bind set layout and its allocation are checked against
  the update-after-bind sampled image and sampler limits when the device
  has descriptorBindingSampledImageUpdateAfterBind. Vulkan counts the
  descriptors of such sets against those limits in place of the regular
  ones, and requires them to be at least the regular ones only when the
  feature is supported, so without it, and for storage images, the
  regular limits are kept as before. Storage buffers keep their own
  update-after-bind flag.
- Compute pipeline capture and replay accept update-after-bind sampled
  image and sampler bindings.
2026-10-19 09:34:13 +02:00
gguerra26 538b63ef4c fix(agc): normalize unused viewport depth ranges
Use representable viewport endpoints only when the draw has no depth attachment and its pixel shader does not read PositionZ. Preserve XY coverage, clip-space mode, depth clamping, and validation of non-finite inputs.

Balatro (PPSA21402) reaches rendering on Apple M1 with MoltenVK after this change instead of stopping at VK_EXT_depth_range_unrestricted. Depth-dependent draws retain their original behavior.
2026-10-19 09:02:24 +02:00
JJenkx c8d7e37f4c fix(agc): initialize point size and limits from SDK defaults 2026-10-19 02:48:17 -04:00
Adrià 8b54728061 Merge pull request #6360 from hypermoist/fix/agc-gpu-indirect-dispatch-limit
fix(agc): check GPU-side indirect dispatch group counts against the device limit
2026-10-19 08:37:32 +02:00
Karan Vora 2907ca6cac fix(agc): take RADV's fill-memory kernel as a buffer fill
RADV initializes and fast-clears DCC keys with its fill_memory compute
kernel, which stores through a global address. Run as an ordinary
dispatch, its stores name no range. The DCC key tracking therefore saw
a key fill only once it had landed in guest memory, which could be
after later writes to the surface had already been recorded.

vkQuake (PPSA99010) hits this on every item pickup:
- the scene renders into a second color buffer;
- RADV's UNDEFINED -> GENERAL barrier fills color buffer 0's keys with
  DCC_CLEAR_0000;
- a screen-effects compute pass writes color buffer 0;
- the UI pass draws on color buffer 0.
The keys landed while the UI pass was being recorded. The refresh took
them for a clear made after the compute pass, dropped its results and
cleared the image to black. For the length of the pickup flash the
scene was black, with only the HUD drawn.

The fill HLE now matches the 16-byte variant of the kernel as a fill of
min(threads * 16, user[4] + 16) bytes. The kernel takes its address in
user[2..3], its largest store offset in user[4] and its value in
user[5]. A key fill through it is handled where it is in the command
stream.
2026-10-19 08:21:36 +02:00
Adrià 63e4a63804 Merge pull request #6538 from TheAggie/perf/agc-dma-prefetch-keeps-pipeline
perf(agc): a DMA_DATA prefetch keeps the draw pipeline
2026-10-19 08:11:46 +02:00
hypermistandClaude Opus 5.5 6a33a080bf Merge upstream main into fix/agc-gpu-indirect-dispatch-limit
recordDispatch now reads its indirect offset through HostImportOffset,
which adds the import's lead. The unchecked path passes that offset to
vkCmdDispatchIndirect; the clamp kernel reads from import.address plus
the guest offset, since import.address already includes the lead.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 18:57:30 +13:00
Dean 323ece2445 Merge pull request #7445 from elliot1377/fix/agc-dispatch-split-base
fix(agc): split oversized dispatches with workgroup offset specialization
2026-10-19 18:51:58 +13:00
Scott SchusterandClaude Fable 5.1 e8377c9144 perf(agc): a DMA_DATA prefetch keeps the draw pipeline
A DMA_DATA whose destination is nowhere writes no memory, so the draws ahead of it have nothing to order against. RADV issues one per draw, and each drained the pipeline and idled the queue worker until the committer caught up.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-19 07:43:15 +02:00
ThatsLeo ac14d6317d perf(shader): flush f32 denormals in hardware when a startup probe matches the emulation
Devices with DenormFlushToZero for f32 run the mixed denormal-flush programs with and
without the hardware mode at startup; when every result matches, add, sub, mul, fma,
floor and ceil in the default rounding mode drop their software flush.
2026-10-19 07:00:13 +02:00
Adrià e0b8be9dc5 Merge pull request #6530 from milescoviello/feat/smoothing-mixed-samples
feat(agc): draw radeonsi line and polygon smoothing (SAMPLE_COVERAGE, merged mixed samples)
2026-10-19 06:06:26 +02:00
Adrià 3904ce6cf5 Merge pull request #6505 from keravyn-ops/fix/htile-pending-fill
perf(agc): take the HTILE words pending fills leave instead of reading them
2026-10-19 06:03:19 +02:00
elliot 11a7b61d72 fix(agc): split oversized dispatches with workgroup offset specialization
A dispatch over maxComputeWorkGroupCount was split into vkCmdDispatchBase
chunks whose base reached the limit, which VUID-vkCmdDispatchBase-baseGroupX-00421
forbids, and NVIDIA refused the split outright.

Compute modules now declare WorkgroupOffset specialization constants (default 0)
that the recompiler adds to WorkgroupId and GlobalInvocationId and keeps
unmaterialized. Each chunk is recorded with vkCmdDispatch from group 0, bound to
a pipeline variant specialized with the chunk's base. The NVIDIA throw is gone;
device-memory LDS splits still throw.

Fixes #7375
2026-10-18 22:54:33 -05:00
Dean 3ddbc4accc Merge pull request #4650 from Mouad-Scriptz-0/feat/agc-depth-range-remap
feat(agc): remap a viewport depth range the device cannot express into the vertex shader
2026-10-19 16:52:31 +13:00
Kovalev Vladislav 94bd3c3872 fix(agc): preserve indirect index tests alongside current main 2026-10-19 09:25:11 +06:00
Dean fd423f9b2e Merge pull request #7709 from Scramblrrrr/codex/agc-shared-log-flush-main
fix(agc): flush the shared logger from native clients
2026-10-19 16:25:06 +13:00
keravyn-ops fac1979549 perf(agc): take the HTILE words pending fills leave instead of reading them
A depth target's bind (storeBackClearedHtile) reads its HTILE words to find a fast clear and
stores them back expanded. When a recorded fill over the HTILE was still pending, that read
made the flush hook submit the open batch and wait for the GPU, under the GPU mutex. A title
that clears its depth targets with buffer fill kernels pays that wait at every clear.

Uniform fills now note their 32-bit word with the pending write (NotePendingWordFill; the byte
value the DCC key paths use is unchanged). When every pending write over the HTILE is such a
fill and the rest of the range already holds the same word, the bind takes the landed word
from the notes, and stores the expanded words as a GPU fill recorded behind the pending ones.
Any other pending write keeps the read. APS5_NO_PENDING_HTILE_FILLS=1 always reads.

PPSA12544 on a Radeon 780M (Windows): 1271 pending-write syncs per 10 s waited 5.5 s at the
bind, about 4.3 ms each; with this change there are none, and the scene runs at 60-61 fps
instead of 44-46.
2026-10-19 05:16:01 +02:00
Adrià c8e3fcb703 Merge pull request #6507 from karanvora2599/perf/videoout-unordered-cpu-flips
perf(videoout): don't hold a flip thread's CPU flips behind queued work
2026-10-19 04:49:51 +02:00
Dean Galvin 41764f27ac Merge main into pr-4650
# Conflicts:
#	core/shader/recompiler/ShaderDiskCache.cpp
2026-10-19 15:36:07 +13:00
Adrià 2ed7048426 Merge pull request #6495 from winstrex/perf/agc-pattern-fill-compare-order
perf(agc): match the dword pattern-fill kernel with its two compares in either order
2026-10-19 04:35:31 +02:00
Scramblrrrr 88c8320e35 fix(agc): flush the shared logger from native clients 2026-10-18 23:03:58 -03:00
Adrià 9d4382d268 Merge pull request #6475 from EagleBearerYS/fix/agc-guard-lazy-capture-pages
fix(agc): run the read guard over a shader capture's lazy pages and raw word reads
2026-10-19 03:39:11 +02:00
Adrià 23629c2847 Merge pull request #6454 from EagleBearerYS/perf/shader-image-table-reuse-v3-pr
perf(agc): share one image table per heap and write epoch through capture, compare, resolution and descriptors
2026-10-19 03:39:03 +02:00
Adrià 72b0ab3e8e Merge pull request #6312 from meh7an/perf/agc-cut-draw-allocations
perf(agc): cut per-draw heap allocations
2026-10-19 03:38:58 +02:00
Dean Galvin 4d4ae6e5eb Merge main into pr-4650
# Conflicts:
#	core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
#	core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
#	core/shader/recompiler/tests/RequestSerializerTests.cpp
2026-10-19 14:32:36 +13:00
Adrià 7978a4b585 Merge pull request #6366 from EagleBearerYS/fix/agc-defer-unpreparable-abi-stages-v3
fix(agc): leave a stage the title's pipeline ABI cannot prepare to its first use
2026-10-19 03:26:59 +02:00
Adrià c7892bf6c6 Merge pull request #6471 from SleglJan/pr/readwords-lazy-blocks
perf(agc): run reads copy the missing blocks of a page mapped whole at once
2026-10-19 03:26:49 +02:00
milescovielloandClaude Opus 5.5 7f59934b7d feat(agc): draw radeonsi line and polygon smoothing through merged mixed samples
A radeonsi-style GL driver smooths lines and polygons by rasterizing four
samples into a one-sample color target: PA_SC_AA_CONFIG has 4 samples,
DB_EQAA.OVERRASTERIZATION_AMOUNT is log2(4), and the pixel shader reads
SAMPLE_COVERAGE to scale alpha by the covered samples. The pixel is written when
any of the four samples is covered. DecodeState refused the one-sample target as
a sample-count mismatch.

Such a draw (MSAA_ENABLE set, no depth target, no per-sample shading, every
color target one-sample, OVERRASTERIZATION_AMOUNT matching the raster samples)
now decodes with mergedCoverage. Its pipeline keeps the raster sample count,
gives the color attachments one sample (VkAttachmentSampleCountInfoNV or the
render pass) and merges coverage (VK_COVERAGE_REDUCTION_MODE_MERGE_NV). The
device enables VK_NV_framebuffer_mixed_samples and VK_NV_coverage_reduction_mode
when it reports that combination; elsewhere the pipeline throws.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 01:25:33 +00:00
Adrià 00666eeb36 Merge pull request #6470 from EagleBearerYS/fix/recompiler-once-per-pixel-sample-inputs
fix(recompiler): run a pixel shader the guest does not iterate once per pixel
2026-10-19 03:21:34 +02:00
Mehran 9d6279ccfa perf(agc): cut per-draw heap allocations 2026-10-19 02:39:16 +02:00
JJenkx 4ee25dc4f1 fix(agc): include draw committer work in CPU traces 2026-10-19 02:27:57 +02:00
Yunus Shaikh 106b79e007 Merge main into perf/shader-image-table-reuse-v3-pr
The data-hit verification keeps this branch's pending-span query on its ShaderMemory and takes #5958's CaptureInvocation, which retries a capture with converted samples.
2026-10-18 17:04:23 -07:00
Yunus Shaikh 10b798fb99 Merge main into perf/shader-image-table-reuse-v3-pr
Keeps this branch's tagVariantRuns declaration next to main's dumpRequest suffix parameter in Driver.hpp, and reads #6232's pointer-chain test words from its table's snapshot, where this branch keeps them.
2026-10-18 17:03:39 -07:00
Adrià 925b85e43a Merge pull request #6375 from sanxchep/codex/shader-export-layout-fallback
fix(agc): preserve position export layout on undecodable tail
2026-10-19 01:56:44 +02:00
Adrià 8f49a89958 Merge pull request #6346 from SleglJan/pr/unchanged-shared-block
perf(agc): stores beside a range in its 64 KiB block leave the range unchanged
2026-10-19 01:32:32 +02:00
Adrià a4a1021208 Merge pull request #6234 from Ondra97/codex/fix-file-write-gpu-coherence
fix(libs): flush pending GPU results before file writes
2026-10-19 01:24:42 +02:00
Adrià b8b9fed361 Merge pull request #6324 from ps54all/fix/agc-alias-copy-store-destination
fix(agc): store an image-copied buffer copy's destination before later labels
2026-10-19 01:23:29 +02:00