sceNpEntitlementAccessAbortRequest and sceNpEntitlementAccessDeleteRequest threw a bare logic_error on every call, so progress.py counted them as done. The library keeps no request table, and no source gives their behaviour, so both now go through NotImplemented_nid_no_patch. Their check moves from guest_offline_imports to the library's own guest_entitlements test.
Seven pending add-content exports take dlc_emu's prototypes and the
answers dlc_emu gives for content it does not know, after the
library's initialization guard: NOT_FOUND for the entitlement-id mount
and enqueue, the Sp enqueue and Shrink; DRM_NO_ENTITLEMENT for the
entitlement-id info; 0 entries for the IRO-tag list; PFT flag 0.
A padded label answers PARAMETER from SDK 0x03500000. dlc_emu checks
the padding at every SDK while the done label calls gate it, so Sp and
Shrink throw for a padded label below 0x03500000.
This reverts commit da6c581a02, reversing changes made to 10a41a0d50.
On D:, the runner does not create 8.3 short names, so guest_named_shm_windows_short_temp and guest_named_shm_windows_long_short_temp skip and check_skips fails the Windows job.
agc_write_tracking_metadata_commit fails now and then on Windows with
"an untouched leaf has a write stamp". CheckMetadataCommit requires
UnchangedSince on one 64 KiB block every 4 GiB of the guest arena. On
Windows the arena is reserved around whatever the process has already
mapped, and those ranges stay arena host regions. The PEB, the TEBs and
the stacks of the main thread and of ntdll's start-up threads are mapped
by then at an address ASLR picks, and when one of them covers a probe,
UnchangedSince is false there: write tracking leaves host regions out on
purpose, and the --host-hole mode of the same test requires that answer.
Each probe now checks NewestStamp as before and expects the exact
UnchangedSince answer: unchanged off host regions, changed on them.
CheckHostHoleInChild takes the mode and the hole address, and the test
also runs a --metadata-commit child with a 64 KiB host hole reserved on
the probe in the middle of the arena, so the host-region case runs on
every run instead of by chance.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
SDL documents that a default open can succeed when SDL_GetNumAudioDevices
returns zero, for instance ALSA whose default PCM works without device
hints. The shortcut now applies only to the wasapi driver, which
enumerates active render endpoints synchronously when the subsystem
starts; with none, its default open has no endpoint to use and fails after
SDL's 8 s retry.
audio_out_default_open runs AudioOut.cpp against a stubbed SDL in four
modes: zero devices on alsa with a working default, zero on wasapi, a
positive count and an unknown count.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The _FSinh and _FCosh special-value checks read the raised flags with
fetestexcept(FE_ALL_EXCEPT). On macOS FE_ALL_EXCEPT also holds the x86
denormal-operand flag, which an SSE operation on a subnormal input such
as 0x1p-149 raises, so the check saw 0x2e where it expects 0x2c. glibc
and FreeBSD leave that flag out of FE_ALL_EXCEPT. The checks now read
the five C exception flags.
With no audio endpoint, SDL's WASAPI backend retries the default device
for 8 s before it fails. Every port open paid that before falling back
to virtual pacing. Ask SDL for the output device count first and take
the virtual path at once when it is zero.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The reader held the pipe for a fixed 100 ms after the main thread flagged
the raise, so a main thread descheduled before sceKernelRaiseException let
the write finish first and the test passed without the system-call path.
The reader now waits until the writer is suspended (NtQueryInformationThread
ThreadSuspendCount), which only the raise does while the write is blocked,
then holds 100 ms.
The handler checked that the write had returned through a flag the writer
sets after fwrite, so a correct delivery between the two failed. It now
checks that the interrupted rip lies in the test's own image.
Two more registrations run the same test with a 200 ms pause before the
raise and with a guest-code spin between fwrite and the flag.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
No source establishes whether the console keeps the callback table of
sceNetCtlRegisterCallbackForLibIpcInt, UnregisterCallbackForLibIpcInt and
CheckCallbackForLibIpcInt apart from the NpToolkit one or shares it. The
three throw again, as on main, and their table, test and debt entry go.
The writer used to publish its block number just before fwrite, so a
delayed raise could land before the call and pass without exercising the
system-call path. The stream is now unbuffered, so each block is one 16 KiB
WriteFile into the 4 KiB pipe. The reader counts the bytes, signals when the
first byte of a block arrives (the writer is then inside WriteFile with more
than a pipe's worth left), and stops reading until the main thread has
started the raise, then 100 ms more. It checks the write has not returned,
and the handler checks the delivery came after it did.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
On a busy Windows runner the writer could stay inside NtWriteFile for
over a second, because each 64 KiB block waited on 16 reader wake-ups.
The raise then hit its 1 s retry limit and redirected the writer inside
the call with the stream lock held, so the test deadlocked until ctest
killed it at 30 s.
Each raise now targets one 8 KiB write that blocks for about 100 ms on a
single reader wake-up, and the writer spins in its own code until the
raise is delivered. The watchdog uses a steady_clock deadline, so a hang
aborts at 25 s instead of outliving the ctest timeout.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
With APS5_DUMP_FRAMES, PresentDisplayBuffer reads most dumped frames back
on the GPU and hands them to the frame dump writer thread. The frames it
takes from the CPU were written with WriteFrameBmp on the presenter
instead: every dumped frame with APS5_NO_GPU_DUMP=1, and on an HDR10
swapchain the linear display buffers and the tiled ones not shown from a
resident image. The write ran inside Driver::Present with the GPU mutex
held, and VideoOut completes the flip only after Present returns, so a
slow disk stopped the title and the queue workers.
A trace on main 4997726a5f (PPSA14363 at 1920x1080, APS5_NO_GPU_DUMP=1,
APS5_DUMP_FRAMES_EVERY=60, during a parallel build and another game) has
its five longest presents, 16.0 s, 8.2 s, 3.2 s, 1.0 s and 0.84 s, spent
in Driver.Present.present_display_buffer while the queue worker waited
for the GPU mutex. The traced display buffer decode inside them takes 11 to
17 ms; the rest is the write of one 518 KB BMP.
These frames are now reduced by the dump scale on the presenter, as
WriteFrameBmp did, and queued to the writer, which writes them in order
on its own thread. Every queued frame is now already reduced, so
WriteFrameBmp writes it as it is and the writer no longer carries a
scale. What stays the same:
- the index is taken before present(), so file names and numbering are
unchanged and a dropped presentation keeps its CPU dump;
- the queue holds reduced frames, as for GPU readbacks since #4320, and
the presenter waits only once 64 MiB are queued (#8807);
- the writer skips frames once the output is disabled and writes the
queued ones when the device is torn down, as for GPU dumps.
What differs from GPU readbacks: those are usually queued after the GPU
mutex is released, while a CPU dump is always queued inside Present, so a
wait for the 64 MiB limit still holds the GPU mutex. At the default
APS5_DUMP_SCALE=4 that wait starts once 129 frames of 1920x1080 are
queued; at APS5_DUMP_SCALE=1 and 3840x2160, from the third. CPU dumps still
queued are lost when the process ends without tearing the device down,
as GPU dumps already are; before, each was on disk when Present returned.
takeScreenshot takes a requested screenshot only while the writer has
nothing queued. A present's CPU dump is queued after that check, so the
dump of the same frame does not hold the screenshot back; it moves to a
later present only while earlier frames are still being written, as with
GPU dumps.
video_out_frame_dump_cpu_queue runs the frame dump queue test with
APS5_NO_GPU_DUMP=1: frame_000.bmp is a FIFO nobody reads until all four
presents have completed.
Co-Authored-By: Claude <[email protected]>
The Windows compare buffer in equalsCommittedBytes was a raw thread_local
vector, whose destructor runs after emulated TLS has freed it in a PRX on
Windows. It now lives in HostThreadLocal and keeps its capacity between
calls. RunVanishedPageReadTests now requires the guest arena instead of
returning silently when it is unavailable.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
ImpliesNot returned at a negated condition, so a predicate !!a against
the condition !a, or !!a in either order of a conjunction, never reached
the negated-predicate and conjunction cases, which prove it. Lane-bit
lowering makes such a predicate from a complemented own-lane ballot of
!a, and the address evaluator then read both arms of a select on !a
instead of the one the predicate implies. Each case now falls through
when it does not prove the negation. Three hull reads under that
complemented ballot bit, alone and conjoined on either side, check it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A triangle patch at level n tessellates into about 3n²/2 triangles,
more than the (n + 1)² slots its capture had from level 5 on, and the
capture shader drops the triangles past its capacity. Every domain now
gets 2(n + 1)² slots per patch, which covers both triangles and quads.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The entry was over the 1000-character limit the conventions check
warns about. Same content, tighter wording.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 12 (main took 5
for the recipe codec change of #5656, 6 for the polygon modes of #7869,
7 for the truncated coverage of #8115, 8 for the point lists of #6801
9 for the 4_4_4_4 UNORM target merges of #8564 and 10 for the colour
logic operation of #9348; #8365 uses 11, and the number is set to main+1
when this lands). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The first 16-bit case split a write that the hull part never reads back.
The new case splits the x position's write into its high and low halves,
so the second half's read-modify-write must keep the first, and reads it
back through the control point's own record. The registered merged hull
is also resolved with HS_W32, which Crimson Desert sets.
Co-Authored-By: Jan Šlégl <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.
Registered type-3 merged hulls come from #6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.
Co-Authored-By: Claude Opus 5.5 <[email protected]>