Commit Graph
12196 Commits
Author SHA1 Message Date
Ishmam AhmedandClaude Opus 5.5 d7ebcf7712 fix(relinker): check PT_LOAD and uncovered PT_SCE_RELRO file ranges
ElfReader::ReadProgramHeaders checked that a PT_LOAD's file size does
not exceed its memory size, but not that its file range lies inside the
input. The Windows and macOS writers reject such a segment later; the
Linux patcher keeps the original PT_LOADs and appends its own block at
the old end of the file, so a load reaching past the input mapped the
relinker's .dynstr, .dynsym and entry stub into the guest segment.

A PT_SCE_RELRO that no PT_LOAD covers is turned into a PT_LOAD after
the per-header checks, so it skipped them: a file size larger than its
memory size was accepted for Linux, and Windows and macOS reported a
file-range error instead.

Reject a PT_LOAD whose file range exceeds the input, and run the same
two checks on an uncovered PT_SCE_RELRO before converting it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01P9JfvrCsztJtbkd5SATAzL
2026-10-15 12:16:49 +01:00
CapibaraandClaude Sonnet 5 6dc4567335 feat(libSceRegMgr): add sceRegMgrNonSysGetInt stub
AstroBot's import log (issue #4720) names sceRegMgrNonSysGetInt as the
only libSceRegMgr export it needs; no other RegMgr export appears in
its 1909 unique imports. The signature and NID are sourced from a
community dump of PS5 3.20 firmware, cross-checked against the
open-source ChonkyStation4 emulator, not from Sony documentation, so
the export throws per the project's unknown-behavior convention
instead of guessing a return value.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-15 08:14:37 -03:00
Adrià FranchandClaude d22872b19d test(agc): register the other-family import-watch test on Windows only
The settle queue on another family is only created under _WIN32, so on
Linux the test always skipped with a reason check_skips does not accept
and the linux job failed on every main build since #6060.

Co-Authored-By: Claude <[email protected]>
2026-10-15 13:11:32 +02:00
Adrià Franch 63c46c6ac7 refactor(agc): drop no-op temporary in drawRegisterKey 2026-10-15 13:06:33 +02:00
MarcZX100 ee0eb0ff8a fix(agc): mix shader identity into trace key 2026-10-15 13:06:28 +02:00
MarcZX100 de2ddda453 feat(agc): trace draw-key cache misses 2026-10-15 13:06:28 +02:00
Adrià FranchandClaude 3e3c3bfed1 test(agc): name serialization version 30 in the reversed-order blend fixture message
Co-Authored-By: Claude <[email protected]>
2026-10-15 13:01:37 +02:00
Yunus Shaikh a34ba0c7c7 Merge branch 'main' into perf/shader-direct-cpu-evaluable-images 2026-10-15 03:54:08 -07:00
Adrià FranchandClaude 6a523c1378 style(agc): drop the code comment from the stencil export decode
Co-Authored-By: Claude <[email protected]>
2026-10-15 12:51:37 +02:00
tv7andClaude Opus 5.5 ab41871622 fix(agc): keep the stencil export on devices with VK_EXT_shader_stencil_export
Dropping an unused stencil reference export changes the pixel variant key, so
a device that has the extension would compile a second variant and pipeline
for a shader drawn both with and without a stencil test. Only a device that
lacks the extension needs the drop, so the draw decode now checks the device's
capabilities first.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 12:51:31 +02:00
NikoandClaude Opus 5.5 0bf89cd30d test(agc): cover moving the export into a reversed-order blend factor
TranslateReversedBlend may write 1 into a channel of the first color
whose source factor is ONE and take that channel's export into the
factor through the second color, when one second color cannot carry
both the source and the destination factor. None of the blends in
agc_driver_reversed_order_blend took that route, so no GPU test ran it.

The test now also blends 0x61010504 (SRC_ALPHA + ONE_MINUS_SRC_ALPHA,
alpha ONE + ONE), whose alpha channel is routed that way, into both
formats with both reversed swaps, and compares it with the exact blend
and bit for bit with the same draw into a SWAP_STD target. It passes on
an RTX 5080 and lavapipe. With 9a8816126's shader-computed factors it
fails on the RTX 5080: 160 where SWAP_STD stores 159.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 12:51:27 +02:00
NikoandClaude Opus 5.5 c434467f6c fix(agc): form reversed-order blend factors from copies of the export
The reversed-order blend computed the factors Vulkan cannot apply per
channel in the pixel shader (1 - x in fp32, a clamp for UNORM targets
and, when both positions needed it, a premultiplied export) and passed
them to the blend as a dual-source second color. A plain blend converts
the export once and forms 1 - x and the products from that converted
value, so the two paths can round differently. On UNORM8 the difference
reaches one step per substituted factor: an Intel iGPU stored 161 where
the exact blend is 159.75 for SRC_COLOR + ONE_MINUS_SRC_COLOR with an
export of 0.5 over 192 (160 through SWAP_STD), and on an RTX 5080 and
lavapipe the split path differed from the same draw into a SWAP_STD
target by up to 2 steps on other inputs.

The pixel shader now only copies values. Each channel of the second
color is the exported alpha, the channel's own export or the constant 0
or 1, and a channel of the first color whose source factor is ONE may
become 1 with its export moved into the factor. Every factor, 1 - x and
product comes from the blend through SRC1_COLOR, SRC1_ALPHA and their
ONE_MINUS forms, applied to copies of the same export values that the
first color carries. TranslateReversedBlend searches for Vulkan factors
and copy routes that reproduce each channel's guest factors and throws
for combinations no routing reproduces, such as ONE_MINUS_SRC_ALPHA in
the alpha equation next to SRC_COLOR in the color equation: of the 1995
factor combinations the shader used to compute, 932 are routed and the
others throw again, as on main. GT7's 0x65010504 is among the routed
ones. The code is now four 2-bit routes for each color, the same for
every format, and the post-pass emits no arithmetic.

agc_driver_reversed_order_blend also draws each case into a SWAP_STD
target, which Vulkan blends alone, and requires identical stored bits;
the comparison with the exact blend keeps its 1-step tolerance.
agc_driver_graphics checks every factor combination TranslateReversedBlend
accepts against the guest equations and that the post-pass adds no
arithmetic instructions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 12:51:27 +02:00
NikoandClaude Opus 5.5 16ea32c97d feat(agc): blend into color targets with a reversed component order
8_8_8_8 and 16_16_16_16 targets with COMP_SWAP 2 or 3 keep the exported
alpha in their first channel and red or blue in their fourth, so a plain
Vulkan blend would run the alpha equation on a color channel. Such draws
threw "blending into a color target with a reversed component order is
not implemented" (Gran Turismo 7, #4782).

The AMD SI and CIK register references describe CB_TARGET_MASK in the
order of components after blending and before COMP_SWAP is applied, and
RADV programs CB_BLENDn_CONTROL without regard to the swap while it
renders R4G4B4A4, B4G4R4A4, R5G5B5A1 and B5G5R5A1 through SWAP_STD_REV
and SWAP_ALT_REV and passes the CTS blend tests on Navi10. The color
block is therefore taken to blend in export order: the alpha equation
and source-alpha factors use the exported alpha and the destination
alpha is the first channel.

TranslateReversedBlend keeps the factor pairs Vulkan applies per channel
in the pipeline. Other source factors are computed by the pixel shader
from its MRT0 export (clamped for UNORM targets, as BLEND_CLAMP says)
and handed to the blend as a dual-source second color, which the
fragment output post-pass adds at location 0 index 1; when both
positions need it, the export is premultiplied by its source factor.
The code is a pipeline specialization, serialized in request version
26, and stays out of the prepared shader key.

sRGB, SNORM and integer targets, constant and second-source factors,
destination alpha in the color equation, destination factors the two
equations do not share, different color and alpha operations, MIN or
MAX with factors other than ONE, other color exports when the shader
computes factors, and devices without dualSrcBlend still throw, now
with the blend control, mapping and format in the message.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 12:51:27 +02:00
fdfawef324andCodex 21dd7b06bc test(agc): check draws with an unused stencil reference
Exercise ALWAYS with KEEP and INVERT using the existing pixel program and complete color and stencil readbacks. Keep dependent comparisons and replacement operations behind the existing native extension refusal.

Co-Authored-By: Codex <[email protected]>
2026-10-15 12:51:25 +02:00
fdfawef324andCodex 3490838653 fix(agc): omit reference-independent stencil exports
Co-Authored-By: Codex <[email protected]>
2026-10-15 12:51:24 +02:00
tv7andClaude Opus 5.5 ac50b9869d fix(agc): drop an unused stencil test value export from draws without a stencil test
A pixel shader with DB_SHADER_CONTROL.STENCIL_TEST_VAL_EXPORT_ENABLE needs
VK_EXT_shader_stencil_export, which NVIDIA's driver does not offer. In a draw
without a stencil test the exported value has no effect, so the draw decode
drops the export there. On a device without the extension, the pixel shader is
no longer prepared when its ABI is resolved, where the draw's stencil test is
not known yet; it is prepared at its first draw.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 12:51:17 +02:00
Ondra97 0cbec9f8f4 fix(libkernel): release flexible memory budget through munmap 2026-10-15 12:50:29 +02:00
MarcZX100 bc347e92a6 fix(shader): qualify SRT memory flags template 2026-10-15 10:36:45 +00:00
Yunus Shaikh 0b099964f0 Merge branch 'main' into perf/shader-direct-cpu-evaluable-images 2026-10-15 03:19:52 -07:00
MarcZX100 c00b0dfb9f fix(shader): avoid retaining IR after plan cache misses 2026-10-15 10:15:33 +00:00
MarcZX100 f95dc97134 perf(agc): release unused registered shader resource plans 2026-10-15 10:15:33 +00:00
Adrià FranchandClaude 03401459f9 perf(agc): pipelined draws and exact draw write ranges on by default
Queue 0 now pipelines draw commits unless APS5_PIPELINED_DRAWS=0, and draw write ranges use the exact
color, DCC, CMASK, depth and stencil sizes unless APS5_EXACT_DRAW_WRITES=0. The base tests now run the
pipeline; agc_driver_pm4_failure_inline and agc_driver_draw_cache_reuse_inline keep the inline path
covered.

Co-Authored-By: Claude <[email protected]>
2026-10-15 12:13:26 +02:00
Michon 99a0be48e3 fix(agc): a pipelined DMA_DATA fill notes HTILE and CMASK fills
With APS5_PIPELINE_DMA=1 a DMA_DATA was enqueued before the
packet path's metadata notes ran, so a fill of 0 over a depth surface's HTILE (#374) or a color
target's CMASK (#419) never reached the surface: agc_driver_depth_fast_clear_submit failed. The
queued commit now notes the fill in order before it stores it, and a DMA copy is checked against
multisampled targets at enqueue, as on the packet path.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit fda7dbf0416fe91ea4767ad2e94ba63b530c1dc2)
2026-10-15 12:13:23 +02:00
Adrià e49ec591dc Merge pull request #1201 from MichonGoddijn231849/perf/pipelined-draws
perf(agc): pipeline queue-0 draw commits behind the packet worker
2026-10-15 12:11:00 +02:00
Romans Pokrovskis da9fe3c708 fix(agc): retire fully released native depth owners
Track successful releases cumulatively across the complete depth and HTILE ownership ranges. Preserve color retirement and share its single callback; keep retired image contents alive through sampled views and recorded work. Add registry, partial/failure/protection, remap and mixed teardown regressions. Depends on native depth sampling in PR5496 and its descriptor prerequisite PR4820.
2026-10-15 13:08:13 +03:00
Parth Bhanti c9d3ff87d9 fix(libkernel_sys): handle AT_SYMLINK_NOFOLLOW natively on macOS and document silent stub 2026-10-15 03:04:18 -07:00
Adrià a08de6827f Merge pull request #6131 from ivica00/perf/atrac9-peekint-bswap
perf(ajm): optimize ATRAC9 PeekInt with 32-bit bswap fast-path
2026-10-15 11:49:52 +02:00
Dean 2c4574adff Merge pull request #6247 from oneandonlydean/carry/register-clear-wait
perf(agc): clear a register fast clear without waiting for a known key store
2026-10-15 22:47:15 +13:00
Dean 2848b55b92 Merge pull request #6230 from oneandonlydean/fix/relinked-name-scan
fix(libc): list the directory once for a missing path that may be a relinked module
2026-10-15 22:46:44 +13:00
Nuno Silva bc316c7341 revert(libSceAgcDriver): drop the unused StoreAtLabelRequested helper
The eager-writeback commits added StorageTexture::StoreAtLabelRequested
(APS5_STORE_AT_LABEL). Nothing reads that variable, so the helper is dead
code; the deferred-writeback revert kept it by accident. Remove it so the
PR changes only the staged-clear sampled-read flush and its test.
2026-10-15 10:43:54 +01:00
Adrià FranchandClaude 43d7c11b80 fix(agc): a pipelined draw owns its ShaderMemory through a unique_ptr now that it cannot be moved
Co-Authored-By: Claude <[email protected]>
2026-10-15 11:36:09 +02:00
Adrià FranchandClaude 1df509baff test(agc): run the failure and draw cache reuse tests with pipelined draws, pin CMASK write ranges
Co-Authored-By: Claude <[email protected]>
2026-10-15 11:34:29 +02:00
Adrià FranchandClaude 62e5bc28d0 fix(agc): a pipelined draw keeps its patched and freshly materialized stages alive
The commit lambda held raw pointers into the draw's stage-data hits and compiled stages, which
were freed when the worker returned (agc_driver_draw_cache_reuse with APS5_PIPELINED_DRAWS=1).

Co-Authored-By: Claude <[email protected]>
2026-10-15 11:34:29 +02:00
Adrià FranchandClaude 5c09de1510 fix(agc): a failed pipelined commit stops queue 0 like a failed worker
Co-Authored-By: Claude <[email protected]>
2026-10-15 11:34:29 +02:00
Adrià FranchandClaude ee0a1889b5 fix(agc): an emptied buffer pool size class is erased again
Keeping it made evictOldest read the front of an empty deque (agc_buffer_pool aborted with a
double free) and stopped Take at an empty class instead of trying the next size.

Co-Authored-By: Claude <[email protected]>
2026-10-15 11:34:29 +02:00
Adrià FranchandClaude 5d5aeab1fb fix(agc): a queued draw's writes include its color targets' CMASK
Co-Authored-By: Claude <[email protected]>
2026-10-15 11:34:29 +02:00
Adrià FranchandClaude bacd50a568 fix(agc): a failed pipelined commit is rethrown like an inline draw error
Co-Authored-By: Claude <[email protected]>
2026-10-15 11:34:28 +02:00
Adrià FranchandClaude 3826c13146 fix(agc): a pipelined memory-value or buffer-pattern fill reads its source after queued writes
Co-Authored-By: Claude <[email protected]>
2026-10-15 11:34:28 +02:00
Dean Galvin a719fdca60 fix(agc): a pipelined fill reads its inputs after queued writes and never waits for room under the GPU lock
A pattern fill reads its count and pattern from guest memory on the queue worker. With pipelined
draws it read them while earlier commit items that write them (labels, DMA stores, draws) were
still queued, so it stored the stale value (agc_driver_pattern_buffer_fill under load). It now
drains the draw pipeline first when a queued item writes one of its input ranges.

The same fill held the GPU lock from the input read through DrawPipeline::Enqueue. With the
pipeline full, Enqueue waited for the committer while the committer's next item waited for the GPU
lock: a deadlock. The input lock is released before the fill is queued, and Enqueue throws when it
would wait for room while the calling thread holds the GPU lock.

(cherry picked from commit c653e9ea1d1030ebf691015b30ea04f1cdd59ef8)
2026-10-15 11:34:28 +02:00
Eli Yarson 084d1fe0ae fix(agc): a label packet behind a deferred label is not enqueued ahead of it
enqueueLabelPacket lacked the empty-deferred-labels guard that enqueueDmaPacket and the draw path
have. A predicated WRITE_DATA is never enqueued, so it is deferred on the worker; an unpredicated
WRITE_DATA to the same address that follows it was enqueued and committed first, and the deferred
store was recorded after it, leaving the older value (an EOP interrupt could fire out of order the
same way). With the guard the later label takes the packet path, which drains and orders it behind
the earlier one.

(cherry picked from commit 1f894c9b641da3460b684a8356655fbf1aeee635)
2026-10-15 11:34:28 +02:00
Eli Yarson 6ad05318c9 fix(agc): a predicated packet drains queued writes to its predicate before reading it
A predicated draw, dispatch or register packet stays on the pipelined keep list, so it did not drain
before the worker read its predicate. A WRITE_DATA or label to the predicate address, queued behind
earlier commit items, was not stored yet: SET_PREDICATION on P, WRITE_DATA P = 1, then a predicated
dispatch skipped it as if P were still 0 (and ran it when P was cleared). The worker now drains the
draw pipeline first when a queued item writes the predicate's bytes.

(cherry picked from commit 56b94480b3de04dfb5c4f4a1bfc5731df59eae29)
2026-10-15 11:34:28 +02:00
raghav314 dc027cc004 fix(agc): note an HTILE depth clear after the pipeline drain
The note landed ahead of the draws still queued over that depth surface.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
(cherry picked from commit 41f385acbf8da99fdf3f8a8c0bd9a8802383d05f)
2026-10-15 11:34:28 +02:00
raghav314 7b40c05a60 fix(agc): entry validation drains queued draws that write its runs
A capture already drains first; validation compared the runs with guest memory while a queued draw could still write them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
(cherry picked from commit a9c15be3e1c27e48b2e6a04e44c47dd5203a3057)
2026-10-15 11:34:28 +02:00
raghav314 a39261b75c fix(agc): a CB metadata pass drains the draw pipeline before it runs
The resolve, CMASK and DCC passes read the color target on the worker while queued draws could still be writing it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
(cherry picked from commit c50e23120c5f139d3e11391b78b9ab228acee2c0)
2026-10-15 11:34:28 +02:00
2cd5c75dc8 fix(agc): a pipelined release with INT_SEL 3 raises no interrupt
The pipelined label path treated every nonzero RELEASE_MEM INT_SEL as an end-of-pipe interrupt;
main's PacketMemory excludes 3 (send data after write confirm). agc_driver failed on it with
APS5_PIPELINED_DRAWS=1 ("release with INT_SEL send data after write confirm raised an interrupt").

Co-Authored-By: TheAggie <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-15 11:34:28 +02:00
a18ab8c009 fix(agc): a null storage image in a draw's written set writes nothing
DrawWriteRanges decoded every written storage image element, and DecodeTextureResource refuses a zero
base address, so a draw with a null storage image bound failed (PPSA01317) instead of skipping it.
The element is now skipped by the binder's own null rule (base address words zero) before it is
decoded. agc_driver_draw_write_ranges binds a null image next to a written one.

Co-Authored-By: Gjon Gojcevic <[email protected]>
Co-Authored-By: SleglJan <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-15 11:34:28 +02:00
3b34d1fdb6 perf(agc): pipeline queue-0 draw commits behind the packet worker (APS5_PIPELINED_DRAWS)
With APS5_PIPELINED_DRAWS=1, queue 0's worker decodes, captures and recompiles a draw and hands it to
a committer thread that records it (Graphics::Draw under the GPU lock), so the two run in parallel
instead of one after the other. Work the committer has not reached yet is tracked by the guest ranges
it will write; a later packet that reads or writes them, or one the pipeline cannot order, drains it.

Ordered as commit items instead of drains:
- labels (WRITE_DATA, RELEASE_MEM) and same-queue waits on them; APS5_PIPELINE_DRAIN_LABELS=1 drains;
- the end of a queue-0 submission and a released REWIND tail; APS5_PIPELINE_DRAIN_SUBMISSIONS=1 drains;
- the title's buffer fill kernels; APS5_PIPELINE_DRAIN_FILLS=1 drains;
- DMA_DATA immediates and copies (APS5_PIPELINE_DMA=1).
A draw's write ranges include the storage images it writes and its exact color and depth target
ranges (APS5_EXACT_DRAW_WRITES=1), not estimates.

Draw-path costs the pipeline exposed:
- ShaderMemory moves, so a commit owns its capture's pages;
- a submission made before the worker's current collect epoch began keeps the epoch, so a worker
  behind a queue of submissions walks a surface once per catch-up (APS5_SUBMISSION_EPOCH_EACH=1 bumps
  at every submission); a thread remembers the ranges it walked for the whole epoch;
- the pipeline signals only threads that wait; the pending-image and unit-shadow registries take a
  spinning slim lock instead of std::mutex (winpthreads contention was kernel events); ScanPending skips
  the registry walk when no pending image can overlap;
- fewer heap allocations per recorded draw (reused descriptor sets and scratch vectors, buffer pool
  size classes kept).

GTA V Performance mode, prologue bank interior, RTX 5080: 11.7 -> about 20 fps together with the cheaper
captures below it.
Off by default here; the follow-up turns it on.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Co-Authored-By: Gjon Gojcevic <[email protected]>
2026-10-15 11:34:28 +02:00
Yunus Shaikh 896b737700 fix(libSceNet): keep one receive timeout across the wait for a local address
When the address came during the wait, the host receive that followed
waited its whole SO_RCVTIMEO again, so a receive could take up to twice
the timeout. FreeBSD's soreceive_dgram sleeps once per timeout. Now the
receive waits for a datagram with WSAPoll only for what is left of the
timeout, and fails with EAGAIN when it runs out, as before. Nothing
changes when the socket already had an address or has no timeout.
2026-10-15 02:34:12 -07:00
Adrià 1db84d5748 Merge pull request #1193 from MichonGoddijn231849/perf/capture-plan-walk
perf(agc): cheaper shader-memory captures per draw
2026-10-15 11:34:10 +02:00
ee6aba54 d6b002887c fix(agc-driver): size the staging pool from the device's reported memory budget
The device tier of the buffer pool kept an eighth of the device-local heap (2 GiB on a 16 GiB card) whatever VK_EXT_memory_budget said the process may use. Its budget is now the smaller of an eighth of the heap and an eighth of the reported budget, at least 512 MiB; APS5_STAGING_POOL_MIB still overrides it.

(cherry picked from commit b039e1da12d7cedc3bfdf0c1d3c0c354f3cd58aa)
2026-10-15 11:32:07 +02:00