Measured on a PS5 (firmware 12.70): the getter reports 0, and of the
values 0, 1, 2 and -1 the setter accepts only 0 and checks the value
before the attribute. A null or uninitialized attribute, or a null
output, crashes the console; here it throws.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
On a PS5 (firmware 12.70), of the values 0, 1, 2 and -1,
pthread_spin_init, pthread_barrierattr_setpshared and
pthread_mutexattr_setpshared accept only PTHREAD_PROCESS_PRIVATE (0);
1, 2 and -1 return EINVAL and leave the attribute unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PPSA34015 (EA SPORTS FC 27) registers EVFILT_READ for descriptor 0 in a
new kqueue at start-up, ignores the result, and stopped with "kevent:
EVFILT_READ on a non-socket descriptor not implemented". A read event on
the host stream on descriptor 0 is now accepted and never triggers, as
select never reports descriptor 0 readable.
Shader registration and the shader ABI resolves run on the title's own
threads, which never bound a trace buffer, so their Shader.Register and
Shader.Resolve* scopes were missing from every trace and summary. Those
entry points now bind the calling thread as `title` with the 32,768-event
buffer the shader preparation threads use.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
An image_sample_*_a sampler whose dword 3 is built only from values
inside the reserved bits 12-29 was refused with "GetSamplerResource
dword 3 is not a valid runtime value" when the value was not an OR at the
top. The reserved bits of a sample-adjust S# are already dropped term by
term from an OR (canonicalizeSampleAdjustDword3); a dword 3 whose
possible bits all lie in that mask, such as a shifted field with nothing
else, is now dropped whole the same way. PPSA01317 builds such a dword 3
from a wave ballot shifted to bit 12 for image_sample_a in a pixel
shader. A plain image_sample with the same S# is still refused.
AI-assisted: yes
lowerPackedAncillary follows the selects, phis and identities that
forward the packed ancillary word to its readers by recursing once per
link (collectReaders), with a linear scan of the visited list at each
step. A long forwarding chain overflowed the stack of the thread that
compiles the shader: PPSA01317 crashes about 30 s into boot in that
recursion on a guest job thread, with a 0xc00000fd stack overflow inside
malloc. The readers are now collected with an explicit stack and a
visited set, in the same order.
AI-assisted: yes
The blend-refusal case used CB_BLEND_CONTROL 0x60010001, which is
ONE * source + ZERO * destination: a replace blend that writes the source
unchanged. A packed target can draw such a blend with blending disabled,
so the case now uses the additive blend 0x60010101, which a packed target
must still refuse.
AI-assisted: yes
An 11_11_10 float color target with CB_COLOR_INFO ROUND_MODE (bit 18) clear
asks the CB to round, but the export packing truncates toward zero, so such a
target now throws. A CB resolve whose source is a packed 10_11_11 unorm or
11_11_10 float target would resolve the raw R32_UINT words, which an integer
resolve cannot average, so it now throws at decode.
AI-assisted: yes
Color format 7 (COLOR_11_11_10, float) keeps its 10-bit component in the
low bits; with the reversed component order (COMP_SWAP 2) that is blue,
with red in the high 11 bits. Vulkan has no such layout, so the target was
refused at decode.
Render it the way 10_11_11 unorm targets are rendered: an R32_UINT
attachment, the reversed export mapping 0xc6, and a new
ColorExportPacking::Float11_11_10 that makes the pixel shader pack each
export with the format-43 image store conversion (toward zero, overflow to
the largest finite value, negatives to zero, NaN kept). Blending, partial
writes, 16-bit integer exports, DCC and the other component orders throw.
AI-assisted: yes
An ITIMER_REAL or alarm expiry while SIGALRM is blocked is marked on the
pending set of sigtimedwait instead of throwing, as kern_psignal leaves a
blocked signal pending. sigwait, sigwaitinfo and sigtimedwait take it,
repeated expiries merge into one pending signal, and unblocking it runs a
guest handler on the unblocking thread or, with the default disposition,
exits the process with status 142 as FreeBSD's default action does.
The expiry rechecks the mask after marking the signal, so an unblock that
races it does not leave SIGALRM pending while unblocked, and TakePending
clears the bit with the value it read so one signal is taken once.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PublishRegisteredShader copied the whole code-address map, with every
header vector and snapshot reference, for each registration under the
driver mutex, so a title registering its shaders while it loads paid
O(n^2). The registry now keeps its entries in address-ordered chunks of
at most 64 shared by every version that has not changed them; a write
clones only the chunk it touches.
Co-Authored-By: Claude Opus 5.5 <[email protected]>