A null or uninitialized attribute, and a kind outside 1 to 4, threw
std::invalid_argument. They now go through NotImplemented_nid_no_patch,
as pthread_rwlockattr_settype_np's unmeasured types do. FreeBSD 11
libthr stores an unknown kind unchecked and answers a null attribute
with -1 and errno EINVAL, so scePthreadMutexattrSettype's
SCE_KERNEL_ERROR_EINVAL would match neither answer.
hasStructuredConstructs tested every block of the graph against each merge header, and searched every block for a block's innermost loop, with dominator binary searches each time. Under APS5_FORCE_STRUCTURIZER_FALLBACK, Ghostrunner's compute shader 0x200c520000 becomes a 32,490-block reach-flag graph with 6,647 merge headers, and the check took 44 to 50 s of the 49 to 55 s.
The innermost loop is now searched among the loop headers only. Every other block failed the loop-header test first, so the candidates and their order are unchanged.
When constructsFollowDominance holds for the structural graph, the member checks visit only the blocks dominatedBlocks finds from the header, stopping at its merge, and for a loop also from its continue block, in block order. Only a block in the header's construct or in the loop's continue construct can fail a member check. A construct block is dominated by the header and not by the merge, so some path from the entry reaches it without the merge, and from the last header on that path every block is dominated by the header, so the walk reaches it. A continue-construct block is dominated by the continue block and is reached from it the same way. The walk finds every such block, and the blocks it skips passed every check, so the result is unchanged. Otherwise every block is checked as before, and APS5_NO_PERF_DOMINATOR_TREE keeps the old loop.
On an M4 Pro the check takes 0.27 s instead of 44 to 50 s on that graph, and the forced fallback takes 5.1 to 5.4 s instead of 49 to 55 s. The default structurization of the shader makes one check, which takes 0.03 s instead of 0.36 s.
recomputeAnalyses runs after every merge split, and its dominator and post-dominator fixpoints intersected a bitset of every block for every block until nothing changed. They now build the tree with the Cooper-Harvey-Kennedy iteration over a reverse post-order from a virtual root above the entry block, or above every exit for post-dominators, and write each block's sorted set as its parent's set plus the block itself.
The sets are the same. When every block is reachable from the virtual root, the greatest fixpoint of the old equations is the dominance relation of that rooted graph, which the tree describes. When a block is unreachable from the entry, or cannot reach an exit, the old fixpoint runs as before.
The post-dominator tree also keeps each block's immediate post-dominator, and FindNearestCommonPostDominator climbs it when both blocks have one: the sets are the tree's paths, so the deepest common block is the one the set intersection found. Blocks added or cloned after the analysis have no parent and take the set path, as before.
APS5_NO_PERF_DOMINATOR_TREE turns both off, and the structurizer and control-flow tests also run with it set. On an M4 Pro the structurization of Ghostrunner's compute shader 0x200c520000 takes 18 s instead of 37 s.
A second sceCommonDialogInitialize returned 0x80B80004
(ALREADY_INITIALIZED), the code each dialog's own Initialize returns.
The common-dialog system initializer returns 0x80B80002
(ALREADY_SYSTEM_INITIALIZED), as shadPS4 and the SDK error names have
it, so callers that accept only SCE_OK or ALREADY_SYSTEM_INITIALIZED
treated a second call as a failure. The header keeps
ALREADY_INITIALIZED for the dialog libraries that return it. The test
pins the literal instead of the header constant, and the debt entry
records that a repeated call's value is not measured on a console.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A guest read over the depth or HTILE range of a native multisample depth
surface threw even when the host had not written the surface since its
import. Its samples are then still the clear value the import took from
the guest HTILE, so the guest bytes already describe it. Retire such a
surface and its guards instead, and keep the refusal for a surface the
host wrote: draws with depth or stencil writes, depth/stencil copies and
storage write-back.
Onimusha: Way of the Sword (PPSA27836) imports a 4-sample D32 target,
draws into it once with depth tests only and no color target, then reads
the memory back as a structured buffer in a compute dispatch.
Unblocks PPSA27836.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Forward scePthreadBarrier*, scePthreadBarrierattr*, scePthreadGetcpuclockid,
scePthreadGetconcurrency and sceKernelMsync to libkernel's POSIX
implementations and return POSIX errors as SCE kernel errors.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Implement sceVoiceSetMuteFlagAll, sceVoiceSetBitRate and
sceVoiceUpdatePort on main's port model. They return the
not-initialized, port-range and missing-port codes of the other port
calls, validate bitrates against the table sceVoiceCreatePort uses and
throw where the console's code is unknown.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Take main's restored signatures (the firmware-database sweep of 2026-10-21):
the typed UsbStorageCallback across the register/unregister family, the
UsbStorageDeviceInfo-typed device-info query, IsExist's three-argument bool
form (succeeds and reports non-existence with no device attached), and
RequestMap's six parameters with the trailing reserved pair dropped. The
no-device answers and the argument validation are unchanged; the guest test
passes an APS5_VABI callback and pins the exists out-parameter.
The first entry in the libSceNpSns debt file lists 24 names, but Export.cpp declares 21. The note two entries below says that sceNpSnsFacebookCreateRequest, sceNpSnsFacebookDeleteRequest and sceNpSnsFacebookGetAccessToken are omitted from this module because another module declares them. They are declared in libSceNpManager (Export.cpp, since f04d16d702), not in libSceNpSnsFacebookDialog by #6977 as the note still says. The three names are removed from the entry so that it names exactly the 21 declared functions, and the note now names libSceNpManager. No code changes.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
PPSA34501 calls sceNetCtlGetInfo often enough that GetAdaptersAddresses and its
RPC took about a fifth of a game thread at the Kino der Toten spawn. The
answers are now kept per address family and for the IPv4 interface, and
dropped when an address, interface or route change notification arrives.
sceVideodec2Flush drained libavcodec with an empty packet whenever the decoder
was not already flushing, and the next sceVideodec2Decode then restarted the
decoder with avcodec_flush_buffers, dropping its reference pictures. A caller
that flushes after every access unit, as Sony's PSP emulator does for its
H.264 movies, lost every P picture after the first: libavcodec withholds
pictures after a restart until it reaches a keyframe, so Daxter (PPSA09695)
got 8 pictures from 459 access units and showed a black screen ("Failed to
obtain a video frame") instead of its intro movie.
Flush now drains only when a decoded access unit has not produced its picture
yet. With nothing pending there is nothing to return, and the decoder keeps its
references for the units that follow.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
pthread_rwlockattr_settype_np stored any type and returned 0. The console's answer to a type outside 0 to 2 is unknown, and shadPS4 returns EINVAL once the stored type is above 2, so such a type now goes through NotImplemented_nid_no_patch. Types 0 to 2 are stored but not applied, so the debt entry moves to the silent stubs.