Expand the host active-lane mask to whole quads for pixel-stage EXEC value reads so saving and restoring WQM does not drop derivative inputs. Keep the existing host-lane mask in other stages. Add a GPU regression for implicit mip selection after an EXEC save/restore, across wave32/wave64 and native/emulated barycentrics.
A depth surface lives only in its Vulkan image, so a view of its memory
with another layout could only throw, and a matching view kept reading
the image after other writes over its memory. Retire the surface when a
color target or a written storage image it does not serve overlaps its
planes, or when a view it cannot serve finds guest memory over the planes
written since the surface was last bound; lookups then skip it and the
view reads the memory like any texture. Binding the target again brings
the surface back.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
On Windows a receive on a datagram socket with no local address waits
for one. A sceNetShutdown of the receive side now ends that wait, and
later receives return 0 at once; a zero-length receive returns 0 without
waiting. FreeBSD's soreceive_dgram returns 0 in both cases. Before, a
thread blocked in such a receive kept waiting after the socket was shut
down.
An image table cannot store, update atomically or read PCK and BY2/BY4
through its records (#757): those operations fault and read zeros. #6243
turns a heap T# whose words and record offset the SRT walker evaluates
into a selected one-record table, which kept that limitation although
such a T# is one known descriptor, as #5188's direct images were.
PlanTableColumns now binds such a T# directly, for every operation of the
shader on it, when any of them is a store, an atomic, a packed or a
BY2/BY4 access. A T# keyed per lane, or by a value the walker cannot
evaluate, keeps its table and its unsupported-operation fault. The disk
format moves to 37 so that plans cached by #6243's builds are not reused.
A kept column the runtime cannot vouch for is read and compared with its kept words. When they
differ, the fresh walk read the same runs again, so a capture that follows every change to a table
read each word twice: 1,048,576 words per capture for a 65,536-record column, 12% slower than
before the reuse with the write watch and 16% slower outside it.
The compare now leaves its words with the snapshotter, and the fresh walk takes them instead of
reading when its plan has the same runs: words the capture has already read read the same again.
Such a capture reads each word once, as before the reuse, and the 65,536-record column costs 7%
(12% outside the write watch) more than before the reuse; the rest is keeping the column. With 16
distinct T#s it costs 5 to 8% less. agc_shader_table_snapshot_reuse expects a changed table to be
read exactly once per capture.
Every read and store through GuestMemory calls the flush hook first. Recorder's FlushForAccess waits
for recorded GPU work over the range, records a queued label that writes it, publishes the unit
shadows over it and stores the storage image results kept on the GPU for it. A storage image result
is stamped only when it is stored (its write-back's MarkWritten), so ShaderMemory's stamp and check,
which never read the column, could vouch for words a read would have replaced: the column skipped
its read and the snapshot kept the T#s from before the result.
stampWrites and unchangedSince now call GuestMemory::FlushGpuWrites over the range after the pending
write query and before the tracker, as a read does, and as the dispatch cache stores pending images
before it validates an entry. The stamp then covers what the flush stored, so the capture after it
skips the read again.
agc_shader_table_snapshot_reuse installs a flush hook that stores a new T# into the table on its first
call over it. Without the flush in unchangedSince the reused snapshot keeps the old T#; without the
one in stampWrites the next capture compares the table instead of skipping its read.
Every capture of a shader with an image table read every record of each column and looked each
record up among the snapshot's distinct descriptors. A 32,768-record column of distinct T#s cost
6.1 ms per capture here (2.3 ms with 16 distinct T#s), and Resident Evil Village's title captures
such columns on nearly every draw.
TableSnapshotter now keeps the last 16 column snapshots per thread (at most 4 Mi words in all,
least recently used first out), keyed by heap base and size, record shape and key count: the runs
it read, their words, each record's state and code, and the distinct T#s. A narrowed, selected or
pointer-indirect column, or one with an unmapped record, is not kept. A capture of a kept column
takes the codes and the distinct T#s from it with no per-record work. When they are the snapshot's
first words they are taken as they are, and the words index is built only if a later column needs
it, so the result is the snapshot a fresh walk would produce, codes and words order included.
The runtime gets three optional callbacks: stampWrites gives a stamp for a range before any of it is
read, unchangedSince tells whether nothing wrote the range since, and supplyWords hands words that
equal guest memory to the capture as read, so they stay in the captured regions the draw cache
compares. ShaderMemory implements them with the write tracker. The stamp is CollectWrites's
generation, refused when this ShaderMemory already fetched a page of the range or recorded GPU work
writes it. A range is unchanged while no block of it is stamped after the stamp (collected CPU
stores, the driver's Write, WriteChanged and StoreOwnBytes, MarkWritten for GPU writes into
imports), no recorded GPU work writes it and the guest allocation generation is the stamp's. When
every run is vouched for, the column is not read at all; otherwise its runs are read and the
snapshot is reused only when they are equal word for word.
The 32,768-record column now costs 0.48 ms per capture with no word read when unwritten, and about
0.9 ms outside the write watch. APS5_NO_TABLE_SNAPSHOT_REUSE=1 turns the reuse off. The [image-table]
profile line counts the reuses, and ResourceMaterializer::TableReuse returns them with the words the
snapshotter read.
A pixel that PA_SC_AA_MASK leaves uncovered is demoted to a helper
invocation so the covered pixels keep their derivatives. When the guest
exports under an EXEC mask that clears that lane, the colour output is
never written. On the Radeon 860M (Windows driver 32.0.13058.8001) such
a demoted invocation still writes undefined colour to the target, so
agc_driver_quad_pixel_mask fails at its first implicit-LOD sample under a
partial mask (2). Killing the uncovered invocations at the return, after every
derivative is taken, discards them on every driver.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The second queue that settles imports is always created on Windows, and a device without one keeps
the comparisons. The other-family settle path is tested through the recorder test device built
with its settle queue on another family (agc_import_watch_other_family) instead of
APS5_SETTLE_OTHER_FAMILY.
The settle read keeps a private import's window open for one round trip on the settle queue, so a
store from another thread can land inside it. CheckImportWindowOtherThread: a store of new bytes from
another thread within the window counts as written, and a same-value one keeps its possible CPU
touch. The debt entry notes the longer window.
On Windows a host import without a section alias left guest write tracking, and its changes were
found by comparison. Since resident direct memory became private MEM_WRITE_WATCH memory, its
imports take that path, and every storage-texture refresh over it compares its whole snapshot.
ProbeImportWriteProtection gets a Windows body on MEM_WRITE_WATCH scratch memory, and
decideImportWatch keeps direct imports of private read-write memory watched when GetWriteWatch
stays honest after an import's first GPU use. The driver marks every imported page written until
that use completes, so each such import is settled inside ImportWatched's window by a 4-byte read on
a second queue of the graphics family (the imports lock comes after GpuMutex, so the main queue
cannot be used there). APS5_NO_WATCHED_PRIVATE_IMPORTS=1 keeps the comparisons.
On a new knote EV_FORCEONESHOT is dropped from the flags; on an
existing one it sets EV_ONESHOT and fires the knote, as
kqueue_register does at l.1339-1341. A modify no longer ORs
EV_ONESHOT, EV_CLEAR or EV_DISPATCH into the knote.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
A knote registered or modified with EV_DISABLE stays registered but is
not polled, fired or reported until an EV_ENABLE change re-arms it, as
kern_event.c does with KN_DISABLED. EV_DISPATCH reports an event once
and then disables the knote, and EV_FORCEONESHOT registers as oneshot.
A negative nevents fails with EINVAL instead of throwing.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Account id 0 or a null output returns SCE_NP_ERROR_INVALID_ARGUMENT;
otherwise the always signed-out NP returns SCE_NP_ERROR_SIGNED_OUT, as
sceNpGetAccountIdA does. PPSA14632 imports it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Since #5056, sceNetCtlGetInfo throws for every info code it does not
model. Ghost of Yotei (PPSA26344) asks for code 12, the DHCP host name,
during boot and now aborts one second in.
The configuration #5056 reports (wired, DHCP, HTTP proxy off) sets no
DHCP host name, no PPPoE user name and no proxy server, so codes 12, 13
and 20 now return 0 with an empty string. The Wi-Fi codes (5-10) and
the proxy port (21) still throw. GuestNetCtl checks the three empty
answers and keeps the throw check for the rest; the libSceNetCtl debt
line says the same.
The relative vector addressing entry still said every window register
lives in one function-scope array. It now describes the array of the
bounded slots, the per-slot variables, the OpSwitch fallback and
APS5_NO_WINDOW_NARROWING, with the RTX 3060 measurement.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Uzy15wqYTt6iWyxYXEzUWo
Since #757, a T# loaded from a buffer heap at a runtime offset is an
image table column, and every capture snapshots the whole heap, up to
65,536 records, even when user data or an SRT read fixes the offset.
When the T#'s eight dwords and its offset are runtime values the SRT
walker evaluates, the column is now selected: the offset is kept as a
descriptor source, the shader indexes entry 0, and the snapshot reads
only the record at the evaluated offset, with the heap base moved to
that record.
The column keeps a table's semantics. An invalid T#, an unmapped record
or an offset that carries past 32 bits is poison that faults only when a
lane selects it; an offset the walker cannot read faults the table
instead of throwing; the record's mode is picked per entry, so no
pipeline variant is added; and a dispatch that writes the record faults
it as written by its dispatch. Dwords past the heap read zeros, as the
scalar loads would, and a record past the key cap is read rather than
poisoned.
A column stays a whole table when its offset is chosen per lane, or when
the shader may write the memory the offset is read from at run time: the
buffer it is read from (by V#), or any memory when the read or a write
goes through a pointer or a GPU-only descriptor. Samplers are unchanged:
an S# the walker evaluates is already a direct sampler. The plan stores
the selection, so the disk cache format is 36.
Five agc_shader_memory and agc_shader_bindless checks asserted the old
planning and now assert the selected record:
- "image table SRT key": a key read through the SRT narrowed a 4-key
table to records 0 and 2. It now selects record 2 alone, captures no
other record, and a changed key moves the capture without changing the
module or its disk key.
- "image table key union" and "image table late key": two keys of one
heap shared one column with two value key domains. Each key now
selects its own record, as two one-record tables.
- "image table unkeyed access": a read keyed through the SRT shared a
whole column with a read keyed per lane. The first now selects its
record; the second keeps the whole, unnarrowed table.
- "uniform table image": the T# at a user data offset was one key of a
full table. It is now the one selected record, and the record the user
data does not select is not read.
A value key domain only arises for a key the walker evaluates, so it no
longer narrows an image column; key buffer domains (keys loaded per
lane) still do.
Return the RLIMIT_NOFILE soft limit that getrlimit reports, capped at INT_MAX: FreeBSD sys_getdtablesize returns the smaller of that limit and maxfilesperproc, and the guest limit never exceeds the hard limit that bounds it here. The guest test now asserts the value instead of the throw, and the debt entry records the semantics.
A draw with PA_SC_AA_CONFIG.MSAA_NUM_SAMPLES 2 (4x) and MSAA_ENABLE
clear into a 4x depth/stencil and color pair threw "multisampled
targets rasterized without MSAA_ENABLE are unsupported for points,
lines, a depth target or alpha-to-coverage", which stops METAL GEAR
SOLID: Peace Walker (PPSA18216) at its first presentation (draw B on
#5268). A depth target with the same sample count now gets the same
pixel center samples as the color targets, so each depth and stencil
sample is tested and written with the depth at the pixel center, as GL
allows when multisampling is disabled.
DB_EQAA Z interpolation or overrasterization and a sample-mask export
with a depth target throw on this path.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Decode the four PA_SC_AA_MASK fields at the rasterized sample count. Use the native Vulkan mask when all four pixels agree and apply varying masks in the fragment shader, preserving helpers and combining coverage with alpha-to-coverage and shader mask exports. Add the normalized masks to pipeline, draw and shader keys and the versioned replay request.
Refuse unsupported conservative-raster, centroid and early depth/stencil memory-write cases. Synthetic readbacks cover driver submission, depth/stencil suppression, fragment stores and one-sample and four-sample coverage.
Reject native sampled views of the depth image attached by the same draw before pipeline creation. Keep unrelated views, other devices and the single-sample path unaffected. Add unrun native-view refusal and scope controls; full dependency-stack build and runtime validation remain pending.
Adapt our preserved native-depth sampling work from c0d9edf and sample-aware footprint work from 6e35a877, retaining creation-time coherence and initial HTILE proof. The descriptor interface in upstream PR 4820 remains a separate prerequisite. This source draft has not been built or run.
Follows mlockall (#4386) for XPSemu (PPSA97358, QEMU os-posix.c), which
imports munlockall (NpLBpgVV7PU) from libkernel.prx. Predicted stop:
FAIL: unresolved ELF import NpLBpgVV7PU from libkernel.prx
The NID is computed with tools/nid_names.py and matches aerolib.
Follows FreeBSD 11.4 sys/vm/vm_mmap.c sys_munlockall
(8c639945a44588f6cfdddfb057bb5aad88735da0): checks PRIV_VM_MUNLOCK,
clears wire state and returns 0. To match, munlockall unlocks ranges
locked by mlock (through VirtualUnlock on Windows, tolerating
ERROR_NOT_LOCKED, and munlockall on Linux).
Implement __modti3, the signed 128-bit integer modulo runtime helper complementing __divti3, __udivti3 and __umodti3. Add unit test coverage in guest_crt_tests and document zero-divisor exception behavior in technical debt.
A dump is fully installed, so scePlayGoGetSupportedOptionalChunk and
scePlayGoGetOptionalChunk report every optional chunk (language pack) like
scePlayGoGetLanguageMask reports every language. They returned an empty
bitmask, so PPSA01748 hid every text language its playgo-scenario.json
lists as a chunk language, English included.
Co-Authored-By: Claude Opus 5.5 <[email protected]>