The recompiler asked for DenormPreserve only for 16-bit and 64-bit floats,
so a device that flushes 32-bit denormals by default (RADV, MoltenVK) flushed
them whatever the guest's float mode said. target.float32DenormPreserve is set
from shaderDenormPreserveFloat32 when denormBehaviorIndependence allows a 32-bit
mode, is part of the cache key and of the request serialization (version 41),
and makes the module declare DenormPreserve 32 unless the 32-bit flush is
already taken in hardware. APS5_NO_HW_F32_PRESERVE=1 turns it off.
sceKernelGetProcessTimeCounter counted nanoseconds and
sceKernelGetProcessTimeCounterFrequency returned 1 GHz, while
sceKernelGetTscFrequency reports the host TSC rate. On the console the
process time counter runs at the TSC frequency, so a title may scale
the counter by sceKernelGetTscFrequency. PPSA34501 does, and its clock
ran 3.4 times slow on a 3.4 GHz host: it paced its 60 Hz frames to
17.6 fps and its game time and audio drifted apart.
The counter now ticks at sceKernelGetTscFrequency, over the same
monotonic clock and APS5_TIME_SCALE, and its frequency is that rate.
With APS5_DUMP_FRAMES, FrameDumpWriter::Enqueue threw "frame dump queue exceeded 64 MiB" when the
writer thread fell more than 64 MiB behind, which failed the presentation and ended the title.
#4320 made that rare at the default APS5_DUMP_SCALE=4; at APS5_DUMP_SCALE=1 a 1920x1080 title
reaches it within nine frames and a 3840x2160 one on the third.
Enqueue now waits on the writer's condition variable until the frame fits, and the writer
notifies after each file; a single frame larger than the queue still throws. The VideoOut frame
dump queue test gets a wait mode at scale 1 whose third frame has to wait for the held first one.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
The change removed a technical-debt entry from origin/main that documents four
libSceVoiceChat exports it does not touch, left the new include out of the
quoted include group, put a forward declaration away from the other type
declarations, and cited a prototype source without a line anchor.
gethostbyname_r and sysinfo are names of host C library functions. Defining
them in libScePosixForWebKit made the library's own call to
::gethostbyname_r in Resolver.cpp bind to the new declaration, and the
guest_resolver test failed with "gethostbyname_r not implemented". Export
the two NIDs through a helper with the library's own prefix, the way
libSceAmpr re-exports the libc functions.
AnyPS5 resolves a title's imports by NID, so a title that imports a system
function that no AnyPS5 library provides fails to load with an unresolved
import. This declares 222 such exports across 11 PS5 system libraries that
AnyPS5 implements but does not provide.
Each declaration calls NotImplemented_nid_no_patch and returns 0; none of
them implements the function. A declaration with a credible prototype uses
it and cites the source with a pinned commit; the rest are declared without
parameters, which resolves the import without making an ABI claim. The
technical-debt files record the limitation per library.
The list is the intersection of the export table of the console's library
(function symbols only), the pinned aerolib names and the functions not yet
defined anywhere in the repo. Every name recomputes to its NID with
tools/nid_names.py.
libSceAudio3d and libSceVoice are left out because #8331 declares them.
On Windows, freopen reopened a stream through _wfreopen, which opens the file without FILE_SHARE_DELETE, so remove or rename of the file failed while the stream was open, unlike fopen streams and POSIX unlink/rename of an open file. freopen now closes the previous stream and opens the new file through the same CreateFileW path fopen uses, so the reopened stream shares delete access. Host standard streams and an empty filename keep the _wfreopen path. Reference: FreeBSD 11 unlink(2) and rename(2) succeed on a file that is open.
CreateFileW fails a symbolic link that resolves to itself with
ERROR_CANT_RESOLVE_FILENAME (1921). WindowsOpenError_nid_no_patch had no
case for it, so sceKernelOpen, open and fopen reported EINVAL where
FreeBSD reports ELOOP.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceAudio3dBedWrite2 stored the bed in a single slot that
sceAudio3dPortAdvance mixed without clearing, so an advance with no new
write replayed the previous block instead of mixing silence, and two
writes before one advance kept only the second.
The writes are queued now, as shadPS4's ConvertAndEnqueue does: the
queue is bounded by queue_depth and returns NOT_READY when full, an
advance consumes one bed, and an advance with nothing queued mixes
silence through the mixer's empty-source path, which the mixer test
already covers.
guest_audio3d_port gains the queue case: fill the queue, require
NOT_READY, advance, and require the consumed bed to make room. It fails
on the old code at the NOT_READY of the full queue.
The mixer test links libc and loads libc.prx, so on Windows its executable
exits 0xC0000135 unless the unpatched library directory is on PATH. Every
other test in the tree that links libc prepends it, and the two tests next
to this one only prepend the libSceAudio3d directory because they link the
library as well. Prepend the libc directory here too.
The push hands the mixed frames to an AudioOut port, so the pacing
comes from the AudioOut queue and not from a local wait. The test
pushes 200 frames of 256 samples at 48 kHz and requires the elapsed
time to be the duration of the audio within 150 ms below and 300 ms
above, the shape libSceAudioOut's own real-time test uses.
The branch invented AUDIO3D_ERROR_NOT_SUPPORTED as 0x80EA0005, which
shadPS4's error enum names OUT_OF_MEMORY. Both shadPS4 and prosper
put the unsupported buffer mode at 0x80EA0008, prosper from the PS5
module's own error table.
The debt entries now name the reference behind each unverified
choice: the downmix coefficients and the dropped LFE follow shadPS4
(fpPS4 agrees) against prosper's contradiction, the channel order
follows shadPS4, prosper and fpPS4, the return of
sceAudio3dAudioOutOutput follows KytyPS5 and prosper against
shadPS4's total-sample answer, and the full-queue NOT_READY follows
shadPS4, the only reference with a body.
The stubs leave the branch: this pull request carries the bed path
alone.
Pop the associated frame under g_mutex before submitting it, so two
concurrent PortPush calls cannot submit the same frame twice or drop
another, and restore it at the front if the submission fails. Open the
lazy internal AudioOut port for PortPush outside g_mutex, re-checking the
port before storing the handle and closing it when the port vanished.
Move the rollback close in sceAudio3dAudioOutOpen outside the lock too.
Queue the explicit AudioOut buffers instead of submitting them straight
away: sceAudio3dAudioOutOutput now copies the block into the associated
port's pending queue and returns the sample count, so the queue_depth
backpressure clears instead of wedging the port in NOT_READY forever.
PortPush drains every associated port's pending queue outside g_mutex,
popping a frame only once its submission succeeds. PortFlush keeps
draining the ports with a null output while clearing their queues.
sceAudio3dAudioOutOpen rejects a non-zero index and an unknown format
before opening and opens the AudioOut port outside g_mutex, re-checking
the port before it registers the handle.
sceAudio3dAudioOutOutputs returns 0 on success, matching the reference;
sceAudio3dAudioOutOutput returns the granularity as the sample count.
Deliver and close the AudioOut port outside g_mutex: the queued frames are
moved out of the mixed deque under the lock and submitted after it is
released, and a failed output is returned instead of being dropped.
Make the blocking modes distinct: BLOCKING_SYNC drains every queued frame so
the queue level reaches 0, while BLOCKING_ASYNC submits only the excess and
leaves up to queue_depth - 1 frames buffered. Map a failed sceAudioOutOpen to
AUDIO3D_ERROR_OUT_OF_RESOURCES and rename the handle member to
audio_out_handle.