66 E8, 66 E9 and 66 0F 80-8F without REX.W take a 16-bit displacement on
AMD processors, the console included. Every near relative branch with that
prefix truncates its target to 16 bits, so the decoder reports no branch
target for it and stubs refuse to move it.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_016TFMtUC4L4wMS4eeEqaNSR
scePthreadCondInit, and pthread_cond_init through it, threw when attr
pointed to a null attribute: a zeroed one that was never initialized or
one that scePthreadCondattrDestroy has set to null. FreeBSD 11.4 libthr
(thr_cond.c, cond_init) takes a null attribute as the default one and
creates a CLOCK_REALTIME condition variable. A PS5 (firmware 13.60)
takes a zeroed attribute as the default one in scePthreadMutexInit
(#4158). Take it as the default here too, as scePthreadMutexInit and
scePthreadCreate already do.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Texture format 43 holds unsigned floats of 10 bits (R, bit 0), 11 bits
(G, bit 10) and 11 bits (B, bit 21). VK_FORMAT_B10G11R11_UFLOAT_PACK32
holds R11 at bit 0, G11 at bit 11 and B10 at bit 22, so storing the
guest R field in the Vulkan B field and the guest B field in the Vulkan R
field moves every texel without changing a bit of any component. A
sampled texture of format 43 is now uploaded that way (a repack pass over
the detiled words, TextureRepack.comp) and viewed with R and B swapped
back (TextureComponentChannel), so the shader samples it natively: point
and bilinear filtering, every mip level and LOD, and cube faces
work as for any other float texture. A texture whose results a storage
image still holds is copied from that image (vkCmdCopyImageToBuffer, the
repack pass, vkCmdCopyBufferToImage) and copied again whenever the
image changed, like the depth and block copies. The recompiler treats a
sampled format-43 image as a float image without conversion; storage
reads and writes keep the packed R32_UINT path, and a 3D texture whose
results are still in a storage image is flushed and uploaded instead.
PPSA01317 samples a mipmapped format-43 texture at a LOD other than 0
and a format-43 cube map during boot.
AI-assisted: yes
Forever Launcher (PPSA99030) imports sceSystemServiceAddLocalProcessForPsmKit
and sceSystemServiceKillLocalProcessForPsmKit and stops at load without
them. AnyPS5 runs one process and starts no other, so both throw without
reading their arguments. The parameters follow the title's own firmware
probes (path, argv and a 0x90-byte parameter block; the kill takes the
returned handle), and the unknown results are recorded as technical debt.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
scriptingGetMem and scriptingFreeMem went through the title's registered
allocator. A title that ships its own libc.prx has already initialized that
allocator, and the application heap's lazy initialization then ran its
initializer a second time: Metal Gear Solid Master Collection (PPSA18194)
started a second Unity heap and aborted when it freed a block of the first.
The hooks now allocate and free through libc's guest heap, so they never
initialize the registered allocator; sizes that overflow return null.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Ship of Harkinian (PPSA99320) logs its heap use with malloc_stats_fast
every 10 s and stopped on the first call, since only an application
allocator could answer it. The default heap now keeps its system and
in-use byte counts with their peaks and fills the same managed-size
block as sceLibcMspaceMallocStatsFast, whose layout moves to a shared
header.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sysarch's AMD64_GET_FSBASE, AMD64_GET_GSBASE and AMD64_SET_GSBASE now
follow FreeBSD 11's amd64 sysarch on Linux x86-64 through arch_prctl: the
GS base is the calling thread's, a base at or above VM_MAXUSER_ADDRESS
returns EINVAL and a null argument EFAULT. AMD64_SET_FSBASE, whose base
guest and host code share for their TLS, other operations and other hosts
still throw. Wine sets its TEB this way.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sysctl {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, pid} for the calling process
returns packed FreeBSD 11 kinfo_vmentry records, one per used range of the
guest arena, with the protection sceKernelVirtualQuery reports. Other pids
return ESRCH, a write EPERM, a short buffer ENOMEM. GuestArena gains a
query for the used range at or after an address.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The Wine port (PPSA99995) ships an ntdll module that imports sysarch
(b7uXQmnfB2s). libkernel did not export it, so loading stopped with
"undefined symbol: b7uXQmnfB2s" before the title ran.
Export sysarch as a stub that reports that it is not implemented: the
title loads and runs its launcher without calling it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The binding plan refused every buffer atomic through a V# whose base is
not a multiple of 4. On RDNA2 such an atomic works when base + offset is
on a DWORD boundary and stops the dispatch otherwise, which the runtime
buffer atomic already does, so the refusal is dropped.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sampling a native multisampled color target through a texture of
another format was refused even when the two formats store the same
bytes in the other channel order. Rush 2 and Wave Race 64 render a
3840x2160 8x target as 8_8_8_8 with the alternate component swap
(B8G8R8A8_UNORM) and sample it through an 8_8_8_8 UNORM T#
(R8G8B8A8_UNORM), and stopped on "sampling multisampled color target
... (vk format 44) as a ... texture ... guest format 56 (vk 37) is not
implemented".
For the B8G8R8A8/R8G8B8A8 pairs of the same numeric type the texture is
now the target's own image with red and blue exchanged in its component
mapping, composed with the T#'s swizzle. Other format differences are
still refused.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceVideodec2Decode threw when it followed sceVideodec2Flush without
sceVideodec2Reset. It now resets FFmpeg's drained decoder and decodes the
unit, keeping the pictures the flush has not returned yet.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The generated rect-list control stage gave every corner of a rectangle the
flat inputs of its first vertex, so last mode was refused for rect lists.
BuildRectListShaders now also builds a control stage that takes them from
the rectangle's third vertex when the pixel shader has a flat input, and a
draw in last mode uses it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Windows run 39061030084: agc_shader_disk_cache_large_file wrote 2 GiB in 141 s next to 1399 parallel tests (limit 120 s), and conventions_function_bodies_shard_4 timed out at 30 s on the same loaded runner. The test is now RUN_SERIAL and its hang limit is 200 s (ctest timeout stays 240 s).
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
A multisampled color target with a CMASK fast clear seeds its state from
the CMASK when it is first used, and later fills of the CMASK update it.
Both read the bytes as DCC keys: 0x00 is a clear, 0xff uncompressed, and
anything else refuses ("reads as mixed"). But an MSAA CMASK nibble is
FMASK code | color code << 2 (Mesa ac_descriptors.h CMASK_MSAA_CODE), so
0xcc (FMASK cleared to fragment 0, color expanded), and the 2x and 4x
"FMASK uncompressed, color expanded" codes 0xdd and 0xee, are states with
no pending fast clear that were refused. Ruffle (PPSA68091) clears its
target's CMASK to 0xcc every frame and stopped on the refusal whenever
that clear landed before the target's first use.
The seed now reads the uniform CMASK byte (after pending writes, like the
key read) and both paths classify it by those codes: 0x00 (register color
clear, FMASK cleared) is the fast clear as before, any color-expanded code
(0xc to 0xf in both nibbles) is "no fast clear", and other codes, or bytes
that differ, are still refused.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Culprit: a03ccc6be (large cache files in chunks); failing run 39057904312.
The test used a fixed directory in the temp dir; the runners of one host
share it, so a concurrent run left a second entry behind.
Lavapipe reports no f64 DenormPreserve, so the shaders get no
DenormPreserve 64 and it may flush f64 denormals; the rows of modes that
keep them then fail with or without the recompiler change (frexp, floor,
ceil and fract of 2^-1074 on Mesa 25 and 26). As in F64FmaSubnormals,
a mismatch in those modes is reported as skipped on such a device. The
modes that flush f64 denormals are still checked on every device.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
v_floor_f64, v_ceil_f64, v_fract_f64, v_frexp_mant_f64 and
v_frexp_exp_i32_f64 ignored the FLOAT_MODE f16/f64 denormal field. On
RDNA2 (gfx1031) bit 6 clear flushes a denormal input to a zero of its
sign, so v_ceil_f64 of 2^-1074 is 0 instead of 1, and bit 7 clear
flushes the denormal result v_fract_f64 gives for a positive denormal.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A range turned unreadable must leave the next readable lease and show as
unreadable in the next lease of all ranges, the kept snapshots must not
count as a pin when the protection change waits for leases, and the
replaced range must not outlive the change.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The registry cached its lease snapshot only while a lease held it, so the
first lease taken after the others ended rebuilt the snapshot from the whole
registry: every address-based build and import refresh paid a walk of every
range and a reference to each. The registry now keeps the snapshot until the
next registry change, which drops it as before; the pin check of a mutation
drops it before counting the leases that hold a range.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
VulkanDevice::createComputePipeline, used by dispatches and the pipeline
journal's replay, had no PerformanceTimer, so a dispatch that compiles its
pipeline showed up in traces and frame timing as Driver.Dispatch time with
no slice under it. It is now Vulkan.ComputePipeline, as graphics pipeline
builds already are Vulkan.GraphicsPipeline.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A DIM 2D image_load through a cube T# already reads texel (x, y) of the
T#'s BASE_ARRAY face (#4139, measured on RDNA1). A DIM 2D image_store to
a cube T# had no matching runtime mode and threw "image descriptor is
incompatible with the static runtime image interface". Crimson Desert
writes a 16_16_16_16_FLOAT cube this way from a compute shader.
A mip-less image_store to an image the program only stores to now takes
the same face mode, writing texel (x, y) of the BASE_ARRAY face, the
face the measured load reads. Stores were not measured on hardware; the
debt entry says so. Formats that store through a conversion (SINT) keep
throwing.
Co-Authored-By: Claude Opus 5.5 <[email protected]>