Compute LDS beyond the device's shared-memory limit lives in a storage
buffer, and its 64-bit atomics took a lock in that buffer. AMD's Windows
driver compiles the lock's acquire and release to s_barrier, which inside
the divergent lock loop pairs with the program's own barriers, so the
device-memory case of agc_driver_lds_lock_budget read half its sum.
With shaderBufferInt64Atomics the device-memory LDS now uses a 64-bit view
of the buffer instead: 64-bit atomics are compare-exchange loops on it and
32-bit atomics stay native, so no lock is taken. Without the feature the
lock is kept. The per-workgroup slice is rounded up to an even dword count
so that the 64-bit view stays aligned.
Homebrew built with the ps5-payload-dev SDK imports by symbol name and
names its system libraries with .sprx, while the libraries in libs/
are .prx files that export NIDs. Quake from the websrv launcher
stopped with 457 unresolved imports such as strlen and malloc.
An import without a module that no searched library exports under its
name is now looked up again under the NID of that name. A dependency
named with .sprx, .suprx or .debug_prx loads the .prx library of the
same stem, and libkernel_web also loads libkernel.prx, as
libSceLibcInternal already loads libc.prx.
Since #4048 enabled robustBufferAccess2, AMD's Windows driver draws
nothing in agc_driver_layered_volume_draw and agc_driver_layered_volume_vertex,
and the selected loads make the high half of agc_driver_subvector_loop's
wave64 skip its loop. Until the cause is found, that driver does not get
the feature, and its loads keep their selections.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Without VK_EXT_depth_range_unrestricted a viewport depth range outside
[0, 1] threw. Minecraft (PPSA17221) draws its world with scale 1 and
offset 0 in negative-one-to-one clip space, so its depth is the raw z/w
clamped by PA_SC_VPORT_ZMIN/ZMAX. On such a device the vertex shader now
scales clip z so z/w is the console's depth, the pipeline clamps depth at
the console's bounds, and two clip distances restore the near and far
planes that depth clamping removes. Mode, scale and offset travel as
pipeline specialization constants from the draw's vertex stage info, in
both the per-draw and the registration-module path; mesh and tessellation
draws with such a range still throw.
The console's depth clamp bounds are clipped to [0, 1]: exact for a
normalized depth target or none, and reported once for a tested or
written float depth target, where a depth below 0 is stored as 0
(Minecraft clamps its float depth target to [-1, 1]). The shader
validator accepts the remap's two extra clip distances next to the one
a program may already export.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
A sampled 32_UINT or 32_SINT T# with a depth swizzle that no live depth
surface matches threw, while the 16-bit case already falls back to guest
memory through an R16_UNORM view. The 32-bit case now reads the guest
bytes through an R32_SFLOAT view, which the shader casts back to the
stored dword.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
#6243's new head merges main f1af6c5915, whose #7325 adds
verifyChainedTableOffset next to the selected-record tests this
branch carries from #6243. That test reads the record words from the
snapshot's shared word list; this branch keeps the words with each
table's snapshot, so the merge reads them from the table it checks.
Main's #7325 adds verifyChainedTableOffset to the image table tests
where this branch adds its selected-record tests. Keep both, with
main's call after this branch's.
Main's EmitSetAttribute debt entry now says the generated rect-list and
barycentric tessellation stages forward the vertex shader's clip array.
It sits next to this branch's PERSP_SAMPLE and pixel position entries,
which main left as they were; keep main's entry and this branch's two.
sceVideoOutSubmitFlip went through queue 0 as a one-packet command
buffer, so every CPU flip waited until the queue worker had translated
all command buffers submitted before it. The PS5 RADV WSI flips from its
own thread once the frame's fence has signaled. vkQuake keeps two frames
in flight, so by then the next frame's command buffer is already queued,
and the flip waited about 10 ms for the worker to translate it. Presents
came in pairs, about 4.7 ms and 29 ms apart. Meanwhile the title waited
in acquire for the flip to be shown, leaving the worker idle for about
7.5 ms per pair.
A CPU flip from a thread that has never submitted queue-0 work now goes
to the presenter at once, unless a command-buffer or EOP flip ahead of it
has not been reached yet. Such a thread can only know that its frame is
done by waiting for it. A flip from a thread that submits its own frames
still waits for the work submitted ahead of it, because a title that
flips without waiting for its frame relies on that order.
APS5_CPU_FLIP_IN_ORDER=1 orders every CPU flip.
vkQuake (PPSA99010) on an RTX 4060: 60 -> 72-74 presents per second,
present-interval standard deviation 12.2 -> 2.1 ms, and intervals over
25 ms 40% -> 1%.
Main's #7269 keeps the synchronous settle's buffer, memory and fence
per device in ImportSettle, so clearing one device's imports releases
only that device's objects. This branch's settle batches move there
too: each device's ImportSettle holds its batch target, memory and
batches with their fences, so switching devices no longer drops a
device's batch handles, and clearing a device waits for and destroys
only its own batches. The per-import settle state is renamed
pendingSettles to stay clear of main's per-device map, and a submitted
settle records the device whose batch it is in.
USAGE.md describes the refused posted unlocks and their log line, and
says that the icon queries and a damaged or unwritable unlock or
statistics file stop the game with an error. The debt entries of
libSceNpTrophy2 and libSceNpUniversalDataSystem no longer say that any
posted id is stored. Both USAGE.md and the libSceNpTrophy2 entry say
that without trophy data the platinum is not unlocked when the other
trophies are.