sceHttp2GetMemoryPoolStats, sceSslGetMemoryPoolStats and
sceNetGetMemoryPoolStats threw. PPSA16064 (Minecraft Dungeons II,
Unreal Engine) queries all three while its HTTP module starts, and
aborted there.
Each library now records the pool size given at sceHttp2Init,
sceSslInit or sceNetPoolCreate and reports it with a peak and current
use of 0: the offline Http2 and Ssl models and the host-socket Net
library allocate nothing from these pools. The layouts follow the PS4
SDK's *MemoryPoolStats structures. Net returns EBADF for an unknown
pool and EINVAL for a null output, like its other pool calls; Http2 and
Ssl throw for both, as their error codes are unknown. Terminating a
context or destroying a pool forgets its size.
sceHttp2SetResolveRetry, which the title calls next, accepts and
ignores its value like the other Http2 settings. The four Http2
WebSocket exports the title imports are added as unimplemented.
guest_http2, guest_ssl and guest_sce_net check the reported sizes;
guest_sce_net also checks the null-output and unknown-pool errors.
A program's entry EXEC is the ballot of !gl_HelperInvocation in a pixel program and the ballot of true in vertex, local and tessellation programs (emitEntryPrologue). The half-wave reduction matcher only accepted the pixel form, so a wave64 vertex program that scans keys selected under its EXEC and reads lane 63 threw that the lane is outside the 32-lane host subgroup.
EntryLaneWalk now also accepts a ballot of true as within the entry EXEC for those stages. Every invocation is live at their entry, and a later ballot of true holds only invocations that are still active. Pixel programs keep the !gl_HelperInvocation form, because a ballot of true there includes helper invocations. Compute and mesh programs keep their own form too, because their entry EXEC can bound the local invocation index.
A draw's guest buffer region inside a host import at an offset off
minStorageBufferOffsetAlignment was copied per build (a new buffer, an
input snapshot, a vkCmdCopyBuffer that ends the open render pass), and
DirectRegions refused such builds as templates.
Descriptor already binds any DWORD-aligned view from the aligned offset
below it and passes the remainder through the shader's memory offset
slot. A draw build that is not address-based and whose every guest buffer
element has such a slot (a push constant byte, or a shader data byte
inside its data buffer) now binds a region whose offset in its import is
DWORD aligned in place, like an aligned one: its read-only views are
snapshotted per draw by PrepareDrawBindings at address - adjustment, the
import serial keys the template, and Revalidate proves it per use.
Dispatches keep the copy (they read in-place inputs at execution, not at
record).
agc_driver_recorder_tests misalignedRegionTests: a misaligned read-only
draw region is read in place, the build is reusable, the push constant
carries the adjustment, and the per-draw snapshot starts at the aligned
offset below the view.
CachedPipeline keeps at most 256 pipelines. A level with a larger working
set thrashes the LRU: every miss creates a new VkPipeline (modules,
layout, render pass and a driver compile from the pipeline cache). The
bound is now 1024. A cached pipeline is a pure function of its key, so
the bound changes only memory and time.
The half-wave reduction read (v_readlane_b32 of lane 31 or 63 after a DPP row scan) is exact on a narrower host subgroup only when the scan's keys are the identity outside the entry EXEC. EntryLaneWalk::ZeroBit now also proves that through a constant false, a SelectU1 whose two values both prove it, and a bool Phi whose inputs all do. A mask written inside a divergent branch reaches the key select in that form, so such a scan threw that lane 63 is outside the 32-lane host subgroup.
A draw with DB_RENDER_CONTROL.RESUMMARIZE_ENABLE recomputes the HTILE summary of the bound depth surface from its depth values. HTILE is not modeled, so such a draw with depth and stencil tests off and no color writes changes no modeled state. It now passes the maintenance check and draws nothing, instead of throwing. Resummarize draws with depth, stencil or color work, and copy and decompress draws, still throw.
ctest loads the libraries from libs/unpatched, so an import that nid_patcher
renames out of another library's exports only shows when a title loads the
patched prx. patched_libraries loads each patched .prx with LoadLibraryEx on
Windows and dlopen(RTLD_NOW) on Linux, and depends on the libs target so the
patched files are current.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The unified and service entitlement info list requests and polls threw.
They now return SCE_NP_ERROR_SIGNED_OUT, like the consume requests in
the same library. Their signatures are unknown, so they stay declared
without parameters.
PPSA15657 calls the unified request during start-up and continues past
the error.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0134RWCyiyydJBbfKz8g9Bwe
Sackboy: A Big Adventure (PPSA01289) imports nine functions that no library
exports, so eager binding fails before it starts.
- libSceVoiceChat: sceVoiceChatRequestLeaveVoiceChatGroup and
sceVoiceChatRequestDeleteVoiceChatGroup, offline requests like the other
sceVoiceChatRequest* calls
- libSceNpSessionSignaling: sceNpSessionSignalingGetConnectionFromPeerAddress,
a throwing stub; the signature is unknown
- libSceCdlgG2P, a new library: the six sceG2PDialog* functions, throwing
stubs declared without parameters
TechnicalDebt records the assumed and unknown signatures.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The param is void*, as RommPS declares it. The test also passes a null and an empty URI and a param that must stay untouched, and compares against 0x8002002D itself. The debt entries now say the error is returned for any arguments and that the param layout and the console's argument checks are unknown.
PPSA01289 (Sackboy: A Big Adventure) calls sceAudioOut2MasteringTerm when it
replaces its world, which threw. Like Init and SetParam it has no effect, as
there is no mastering stage. The title creates its next world's audio device
before it destroys the previous one, so Init runs twice before Term runs
twice; whether the console reports an error for either is unknown, so both
return 0 and the case is recorded in TechnicalDebt.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceSystemServiceLaunchWebBrowser fails with the kernel's EOPNOTSUPP: there is no web browser to open. RommPS PPSA76677 stops on main at this import and shows a QR code instead when the browser does not open.
sceAmprCommandBufferClearBuffer detaches a command buffer's memory and
returns it so the caller can free it. It returned 0. PPSA01289 (Sackboy: A
Big Adventure) frees the result after every streaming read, so each read
leaked its 16 KiB command buffer until the allocator ran out of memory
during the first world load.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
With depth bias enabled, RADV sets POLY_OFFSET_PARA_ENABLE in
PA_SU_SC_MODE_CNTL next to the front and back enables, whatever the
topology; vkQuake's draws carry 0x3a46. The bit applies the offset to
points and lines, so it changes nothing for triangles, and Vulkan applies
depth bias only to polygons. It is now accepted with depth bias on
triangle topologies; point and line draws with it are still rejected.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A label in memory the device has no host import of was stored when its
batch was reaped, after later labels the GPU had already made visible.
A title that reused that memory saw its next command buffer overwritten
by the stale value (#1458). Wait for the recorded work and store it then.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A title that replaces the allocator through its libc parameters also
supplies malloc_stats_fast in that table, and PPSA28997 calls it. It is
now forwarded to the title's function. Without a replacement allocator
that provides it, the call throws.
Without TZ, glibc's localtime and mktime run tzset on every call and
re-check /etc/localtime each time. PPSA28997 calls them every frame
during its intro, which then spent most of its time there. TZ is set
to :/etc/localtime when unset, so the zone is read once.
With f32 denormals flushed, as in the 0xc0 float mode titles use, the
hardware flushes the denominator and numerator of v_div_fixup_f32 but
keeps a denormal quotient and result. The recompiler kept all three,
so a denormal divisor gave the quotient back instead of an infinity.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
PrepareMultisampledStorage only inspects the SPIR-V that the recompiler
emits for multisampled storage writes and atomics, but it took its
target from the device, so on a device without
shaderStorageImageMultisample, such as MoltenVK, the emission failed
and agc_driver_prepared_shaders failed in all its variants. The target
now has the StorageImageMultisample capability, and the check that a
target without it is refused still removes it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PixelProgramSkipped only treated SPI_SHADER_PGM_LO/HI_PS written as 0 as
a draw without a pixel program, while the draw decoder already reads an
unwritten address as 0 and binds the null pixel program for it. A
depth/stencil-only draw whose pixel program address was never written
was instead rejected by the precheck with "depth/stencil-only draws
without a pixel shader are not implemented".
An unwritten address is now unset in PixelProgramSkipped too, so such a
draw goes through the null pixel program like one with the address
written as 0, and one that writes color is rejected as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
With IEEE=1, v_pk_min_f16 and v_pk_max_f16 return a quieted NaN for a
signaling NaN operand, and DX10_CLAMP=1 clamps it to +0. The clamped
form skipped the bit-level NaN selection and saturated the driver's
min/max, which returns the other operand, so it gave that operand.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Sonic Origins (PPSA05324) imports sce::Json::Object::empty() const
(i2l3IYvQ9UE) and fails to load without it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceSystemServiceKillApp now ends the title as guest exit() does, so driver calls that wait for the exit park instead of throwing ProcessShutdown, and a second exit waits for the first. The test now fails when the kill returns, exits with a status other than 0 or bypasses the coordinator, and checks why a rejected call throws.
Report an app ID for the running title from sceSystemServiceGetAppIdOfRunningBigApp, and shut the guest down and exit when sceSystemServiceKillApp receives that ID with the arguments -1, 0 and 0. SwanStationPS5 (PPSA98510) 1.0.6 closes itself this way and stops on both imports on main.
ReadRawComputeShader decodes a growing prefix of guest memory and reads
more when the decoder throws std::out_of_range, which the vector, scalar
and instruction-length checks throw for an instruction cut off by the end
of the span. The memory (SMEM, DS, MUBUF, MTBUF, FLAT), image and export
decoders threw std::runtime_error instead, so a two-word instruction
across a window boundary failed the read: vkQuake terminated on "truncated
FLAT instruction". These now throw std::out_of_range too.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The hardware findings give 0xF_F000_0000, which is 0xFF0000000, not 0xFF00000000. Check the ring across threads, at ps5-opengl's size of 0x1b000 and with a canary after the outputs, and say in the debt entry that nothing is written to the ring.
Record the tessellation factor ring that sceAgcDriverSetTFRing receives and report it from sceAgcDriverGetTFRing, with the console's default of 0xFF00000000 and 128 KiB before a title sets one. VITA5 (PPSA39410) and Homebrew UI Lab (PPSA99050) stop on this import once sceVideoOutGetResolutionStatus resolves.