MacOsMachOPatcher::Patch discarded its lazyBinding argument, so a
module-free `--macos --lazy-binding` conversion exited 0 and wrote the
same eagerly bound Mach-O as a run without the flag. The Mach-O writer
puts every import in the LC_DYLD_INFO_ONLY bind stream and leaves the
lazy_bind stream empty, with no __la_symbol_ptr or stub helper, so the
macOS target cannot honour the flag. The patcher now throws "macOS
target does not support --lazy-binding", in the form of its
--windows-diagnostics check, so such a conversion exits 2 and writes no
output. Conversions with bundled modules were already refused by the
guest module builder.
Next to CloseWhileWaitingOnFile: 2000 rounds of watching a regular file and replacing its descriptor with dup2 while another thread waits on the queue.
dup2 called EqueueDescriptorClosed(to) while holding the positioned-transfer lock of the descriptor, and the in-flight measurement it waits for needs that lock for its sceKernelLseek, so dup2 onto a watched descriptor deadlocked. The events are removed first, before the lock is taken.
MeasureFiles registered the descriptors it measures in m_measuring and removed them only on the normal path, so an exception between unlocking and relocking left them there and every later RemoveDescriptorEvents for one of them waited forever. Both vectors are reserved before anything is registered, and a guard owns the registration: on every exit it relocks if needed, removes the entries and notifies.
A press published before the keyboard captured the pad stayed in the
read latch and in the sample queue. The first ReadState after the
handoff returned it beside the Intercepted bit, and Read drained the
queued samples from before the capture unmasked. Clear both when a
sample starts the capture, so every read while it lasts holds only the
Intercepted bit.
Found by MarcZX10's review.
sceImeDialogInit opens the pad keyboard beside the host-text sink and
registers the pad sink and the keyboard view; Finish, Term and
ForceClose release all three. Pad edits go through the same text,
caret and cap as host text: Done copies the text and its terminator
and ends Ok, Cancel ends UserCanceled with the buffer untouched, as
Enter and Escape do. Typed characters end a one-shot shift only when
they fit.
The options follow the dialog's parameters: the multiline option,
the supported languages' currency, the enter label, the extended
parameters' starting page and shift lock (SET_PRIORITY,
PRIORITY_SHIFT), and disable_device, whose controller bit keeps the
pad from editing.
An open dialog can now take the pad the way it takes host text: a pad
sink it sets, ImePublishPad_nid_postfix forwarding each pad sample to
it, and ImeCapturesPad_nid_postfix telling the pad's owner that the
dialog has it. A keyboard view provider lets the presentation thread
read the text, caret and key grid it draws. Each is modelled on the
host-text sink: an atomic pointer the dialog sets and clears.
A pure model of the controller keyboard: the Latin, Symbols and
Specials pages with their spanned keys, and a step function from pad
samples to edits. It follows shadPS4 30f4170896's on-screen keyboard
(ime_ui_shared.cpp:805-887, ime_dialog_ui.cpp and ime_kb_layout.cpp):
- Cross activates the selected key, armed once Cross is seen up, and
repeats only the editing keys; the D-pad and left stick move on the
grid and wrap, a held direction waits half a second at the edge.
- The shortcuts run only when the grid did nothing, in the source's
order: L2+Triangle symbols, Triangle space (not while L2 is held),
L3 specials, R2 done, L1+Square clear, Square backspace, L1 and R1
caret, R3, L2 shift; Circle cancels and loses to Done.
- L2 cycles lower, one-shot upper and caps lock, re-armed once the
trigger is back at 0.20.
- Repeats use ImGui's default delay and rate, 0.275 s and 0.05 s.
Every button and stick direction held in the first sample is ignored
until it is released, so nothing held when the dialog opens types,
deletes or repeats. The keyboard, menu and R3 mode keys of the source
are left empty, and the currency key and the Done label follow the
dialog's languages and enter label.
The guest memory lifetime tests' host import query and the indirect
arguments pending producer gate opened libvulkan.so.1 on every
non-Windows host, so on macOS they failed with "cannot load Vulkan"
before running. They now open libvulkan.1.dylib there, as the other
driver tests do.
The deferred destruction registry kept the first device's
vkGetDeviceProcAddr after that device was destroyed. VulkanDevice
unloads the Vulkan loader with the device, and on macOS the next load
can map it at another address, so every later device in the process
failed with "deferred destruction found two different device
resolvers". The check now applies only while another device is still
registered; the new device's resolver replaces the old one.
TestReadOnlyStalePlaneFlush flushes a stale depth plane, which creates
the plane's mirror with StorageTexture::Create(context, *context.detiler).
The fixture's context has no detiler, so the reference is bound to a
null pointer, which UBSan reports and stops agc_driver_graphics and
agc_driver_graphics_maps_fallback on. The device always creates its
detiler, so this only happens in the test. Give the test's context a
detiler built over stub entry points.
The depth plane copy budget (APS5_DEPTH_PLANE_COPY_MIB, 256 MiB) evicted
the least recently used copy even when it had been sampled in the same
frame. When one frame samples more than the budget, every use evicts a
copy the next use needs, so each copy is made and refilled again on every
use. ASTRO BOT (PPSA21564) samples a 1536x1536x16 D32 copy (288 MiB with
its staging buffer) and a 2048x2048x3 D16 copy (48 MiB) alternately in
its intro and thrashes this way.
A copy sampled in the current or the previous present now stays while
all copies hold at most twice the budget. Past that, the least recently
used copies leave whenever they were sampled, so the copies never hold
more than twice the budget, or the one copy being sampled if it is
larger. Older copies still leave first by least recent use down to the
budget.
DepthPlaneCopyBytes reports the bytes the copies hold, for the tests.
The pooled-memory rounds of agc_driver_depth_plane_guest_layers now
advance two presents between samples, since two copies sampled in one
present may now be kept together.
A resident direct memory mapping created a SharedPage, a Physical, a
physical map node and an aliases buffer for every 16 KiB page, about
18 MiB of heap per GiB mapped, although a page mapped once holds no
state there. Resident pages now keep only their View, with pins and the
compare-when-shared mark in it; an index from (section, offset) to the
resident run finds a live resident mapping of a physical page, and the
shared state is created when a run is demoted, or when it is evicted
with data or a compare mark. ForgetSection drops the index entries of
the section's runs.
guest_memory on Windows 11 26200 (Ryzen 5 5600X): private memory per
GiB mapped at map time drops from 30.9 MiB to 13.4 MiB.
Co-Authored-By: Claude <[email protected]>
Since #8898 ResolveTextureFormat gives format 36 (11_11_10 float) its storage form R32_UINT, while a sampled
format 36 image is read through its native B10G11R11_UFLOAT view (SampledTextureFormat). MultisampleTargetTexture
and MultisampleTargetFirstSample still matched the resident target by ResolveTextureFormat, so a 10_11_11 float
color target (B10G11R11_UFLOAT) sampled as a format 36 texture of the same shape was refused.