A thread that sceKernelRaiseException redirects resumes through
RtlRestoreContext with a CONTEXT that has no XSTATE, so the upper halves
of ymm0-ymm15 came back as the handler and the delivery path left them.
A handler or host routine that runs vzeroupper or any VEX instruction
(Zen 2 guest code, the CRT's memcpy) cleared the upper lanes of a thread
interrupted in the middle of AVX code. The entry stub now stores
ymm0-ymm15 next to the delivery when the CPU and the OS enable AVX, and
the exit loads them back right before RtlRestoreContext, which restores
only the low halves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeC9bA3n74TzJRYv9AgBE8
Color targets with the SW_64KB_S swizzle (CB_COLOR_ATTRIB3 tile mode 9) use the standard element
order of the 4 KiB mode extended by the texture detiler's 64 KiB bits, and are resident like the
other tiled targets. The standard blocks are now wider than tall for 2- and 8-byte elements, as the
standard swizzle and the texture layout have them (they were transposed, aliasing texels).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
BnMAMrsfVWo is _ZSt19_Throw_bad_weak_ptrv. Replace the unknown stub
with a throw of a guest std::bad_weak_ptr, and add its type info,
vtable, destructors and what().
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gathering every iovec into one host buffer threw for a total above
INT_MAX, which a console readv/writev accepts, and copied the whole
transfer twice. Each iovec is now read or written in place, in chunks
of at most INT_MAX bytes. A readv on a pipe returns after one read so
it does not block once the available bytes are consumed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UTjpbMX7BUFMZZaxJE98zV
sceKernelReadv, sceKernelWritev, sceKernelPreadv and sceKernelPwritev threw on Windows. They now gather or scatter through one host buffer and issue a single read or write, with the same argument checks and error codes as the Linux path. Positioned transfers restore the file offset afterwards, as pread and pwrite do on POSIX, and report ESPIPE for handles that are not disk files. guest_file_vector now runs on Windows as well.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UTjpbMX7BUFMZZaxJE98zV
COPY_DATA rejected source select 9 (GPU clock count) and any cache
policy bits. PPSA16064 (Minecraft Dungeons II, Unreal Engine)
calibrates its GPU timer at start-up with a submission of five
COPY_DATA packets, control 0x06016209: GPU clock source, memory
destination, 64-bit count, source and destination cache policy 3. The
submission was rejected and the title aborted.
The clock source now writes the same counter as a RELEASE_MEM
timestamp (the host steady clock in 10 ns ticks), read when the packet
runs, through the direct execute path and through ResolveStore for
stores recorded on the GPU. A 32-bit count writes its low half. The
source and destination cache policy fields are accepted and ignored,
as for WRITE_DATA and DMA_DATA. The reference clock (source select 10)
and the other unimplemented sources still throw.
agc_driver_pm4 runs the title's packet twice and checks a nonzero,
non-decreasing counter and an 8-byte resolved store, and that source
select 10 is still rejected.
The guest's wchar_t is 16 bits, but wcslen, wcscmp, wcsncmp, wcscpy, wcsncpy, wcschr, wcsrchr, wcsstr, wcspbrk, wcsspn and the wmem functions forwarded to the host's wchar_t functions, which use 32-bit units on Linux. Implement them on char16_t. The wide conversions that still use the host's wchar_t are listed in TechnicalDebt.
NVIDIA (595.91.07) refuses VK_EXT_external_memory_host imports of
read-only or executable mappings with VK_ERROR_OUT_OF_DEVICE_MEMORY and
then fails every later vkAllocateMemory on the device. Check the range
is mapped read-write before importing on Linux, as the Windows path
already does for read-only memory, and copy it otherwise.
Refs #1022
A CMASK holds 4 KiB per 1024x512-pixel metablock, not one nibble per 8x8
tile of the target: 1920x1080 spans 0x6000 bytes, as titles clear it,
not 16200. The swizzled nibbles of the lower-right tiles lie past the
packed size, so the fast-clear check missed them and the expanded store
left them cleared.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The driver copies a submission's packets when it is submitted, but
SET_SH_REG_INDIRECT, SET_UCONFIG_REG_INDIRECT and SET_CONTEXT_REG_INDIRECT
read their (offset, value) lists from guest memory only when the queue
worker reaches the packet. A title that reuses its per-frame memory once
it expects the GPU to be done with it can rewrite a list in between, and
the worker then throws on the data it finds there ("extended register
semantics are not implemented (offset dword 0x3a888889)").
The lists are now read with the packets, after validation, in Submit and
for a rewind tail, and the worker writes the registers from that copy.
Pm4::Execute keeps reading the list itself for direct callers.
PPSA21402 (Balatro) keeps three frame slots and does not wait for the GPU
before reusing one: its slot labels start at 0xffffffff and the GPU only
ever writes 0xffffffff to them, so the poll before a slot is reused never
blocks. When the worker falls more than two frames behind, the title
writes per-draw constants over a SET_CONTEXT_REG_INDIRECT list the worker
has not read yet.
The console's PFP reads the list when it reaches the packet; the
difference is recorded in TechnicalDebt.md.
Both return -1/EINVAL: FreeBSD kern_mprotect (sys/vm/vm_mmap.c) maps only
PROTECTION_FAILURE, RESOURCE_SHORTAGE and OUT_OF_BOUNDS to their own errno, so
KERN_INVALID_ADDRESS falls to EINVAL.
Co-Authored-By: Claude <noreply@anthropic.com>