| Commit message (Collapse) | Author | Age | Files | Lines |
| |\
| |
| | |
Diagnoses to fix vibration support
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
This branch supports vibration by achieving proper rumble reading from
games and uses regular eglantine/eden logic from ns1 to send them over.
Tested on windows 10 on Mario Kart World
Assisted-by: Claude Opus 5.5 (code cleanup)
|
| | |\
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
# src/core/hle/service/hid/hid_server.cpp
# src/core/hle/service/hid/hid_server.h
|
| | | | |
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Two threads closing the same fd both copied the descriptor and both called
Close(), so a host socket could be closed twice, and the second closesocket
could hit an unrelated socket that had reused the host fd. CloseImpl now
frees the slot under file_descriptors_mutex first and only that thread closes
the socket; the other gets EBADF.
OnProxyPacketReceived decompressed every room packet when any fd had a
socket, including native sockets and proxy sockets on other ports. Sockets
now report through AcceptsProxyPacket whether they want a packet, and only
those are collected, so an unwanted packet is not decompressed.
DecompressDataZSTD passed the frame's declared size straight to the vector
constructor, so a malformed or unsized frame from a room member threw on the
room thread. The new TryDecompressDataZSTD rejects invalid, unsized and
oversized frames, and bsd drops such packets with a warning.
DecompressDataZSTD now returns an empty vector for them instead of throwing.
Assisted-by: Claude Opus 5.5 (investigation and implementation)
|
| |\ \ \ |
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Bananza's movie player acquires one decoded frame every time a released
output image's fence completes, and aborts (2111-3604) when the ring is
empty. Completing those fences at once after the end of a stream (the
Mario Kart World workaround) made it acquire from an empty ring the
moment its cutscene movies ended.
Released images now keep their normal pending fence after the end of a
stream. Stop (207) and Finalize (115) complete every fence handed out
so far, so a client that waits on its returned images after a movie is
still released when it stops the decoder.
EDEN_NX2_VDEC_EOS_RELEASE_NOW=1 restores the old immediate completion;
EDEN_NX2_VDEC_TRACE=1 logs every decoder call.
Tested on Bananza: the post-breakout cutscene movie ends and gameplay
continues (mining tunnel). Mario Kart World not retested.
Assisted-by: Claude (Anthropic) for investigation and code.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 0f8eaa54be5bff351de7c9a80cc06a4b3453bc76)
(cherry picked from commit 8ed051843a33a5dec086d1ec6985798c8b336a6a)
|
| | | | |
| | | |
| | | |
| | | |
| | | | |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 144b193c841a4b291e5eca065c94cbe82136a4b1)
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
stream is H.264 (Yoshi demo)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| | | |/
| |/|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
- Complete pending fences immediately on release once the stream ends and no
frames remain to be processed, preventing infinite waits in movie teardown.
- Stop re-arming m_ready->room when an end-of-stream packet arrives or the final
frame is output, avoiding spurious wakeups and subsequent empty queue queries.
- Reset m_stream_ended when new input is submitted or on Flush/Stop.
Fixes an abort (2111-3604 / 0x1c286f) in Donkey Kong Bananza during the tutorial
transition scene when the video decoder stream ends.
Assisted-by: Gemini (vdecsvc end-of-stream fence completion and timer de-arming)
(cherry picked from commit b180df1ed77568da7c3e78dd97c0c46d84e54494)
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
A receive with MSG_DONTWAIT restored the blocking mode from the descriptor copy taken
before the call. When fcntl(SETFL, O_NONBLOCK) ran during the receive, the fd kept
reporting O_NONBLOCK while its socket blocked again. Receives now switch the mode only
for MSG_DONTWAIT and read the current flags under file_descriptors_mutex at both ends,
and SETFL changes the mode and the stored flags in the same critical section.
OnProxyPacketReceived decompressed each room packet once per matching socket while
holding file_descriptors_mutex, so every bsd call waited for it. It now copies the
distinct sockets under the lock, decompresses once without it and delivers the result.
Also reject fd == MAX_FD in IsFileDescriptorValid and PollImpl, which read past the
table, and guard the ProxySocket blocking and receive timeout setters with
packets_mutex, matching their reader.
Assisted-by: Claude Opus 5.5 (investigation and implementation)
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
bsd runs on three host threads, but its calls kept a raw reference into
the shared descriptor table while they used a socket. A close() on
another thread could then destroy the socket mid-call. Waking a blocked
room recv() on close made this happen every time. Every call now works
on a copy of the descriptor taken under the table lock, poll() keeps its
sockets alive while it waits, and close() resets the slot only if it
still holds the same socket.
accept() picked a free fd before blocking and only locked the write, so
another thread could publish a socket in the same slot. It now picks
and writes the fd in one critical section after Accept() returns. dup()
now re-checks the source fd under the lock.
A duplicated fd shares its socket, so the room packet loop queued each
packet once per fd. Deliver it once per socket.
NIFM: when the selected host adapter is missing, the room still works
and IsNetworkAvailable reports it, but GetCurrentNetworkProfile returned
an empty profile. Report a wired room profile in that case, and put the
room address on the first adapter in EnumerateNetworkInterfaces.
Assisted-by: Claude Opus 5.5 (investigation and implementation)
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
bsd:s, bsd:u and bsd:a share one file descriptor table, but each
service bound its own proxy packet callback, so every room packet was
queued three times on each socket. Bind the callback once.
The room thread walked the descriptor table without a lock while bsd
created and closed sockets, so it could reach a destroyed or not yet
created socket. Guard the table with a mutex, and publish a socket only
after it is created and initialized. Check airplane mode before an fd
is taken, so a refused socket no longer leaks its slot.
ProxySocket now initializes protocol, decompresses packets outside the
packet lock without copying the compressed data first, and keeps a read
offset for partial TCP reads instead of erasing from the front.
Add Network::GetRoomIPv4Address(), set only in the Joined and Moderator
states. NIFM uses it for network availability and for every reported
address, including EnumerateNetworkInterfaces and GetCurrentIpAddress,
so no call reports the room address while another rejects the network.
Assisted-by: Claude Opus 5.5 (investigation and implementation)
|
| |\| | |
|
| | |\ \
| | | |
| | | | |
MKW performance improvements
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Give the implementation-local TLS object one definition so ThinLTO retains its dynamic initializer. The state and its lifetime are unchanged.
Assisted by Codex.
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Adapted bitmap scans from sylvieistaken/selevet-eglantine performance build 4. Keep the wide-priority fallback and fix the first live slot after empty bitmap words. Include randomized lifecycle and ordering checks.
Assisted by Codex.
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
837133792d queues the GMMU maps on the GPU thread (GPU::RunInOrder) so the
service thread never waits for the texture cache. With the GPU split
(Low GPU accuracy) the GPU thread defers queued functions to its back, but
its front reads the command lists: it read the lists submitted after a map
through GPU addresses that weren't mapped yet. Pokopia stopped after its
first frame.
Add GPU::MapInOrder for the GMMU maps and the sparse tile remaps. It runs
in order like RunInOrder, and with the split it runs on the front after
draining the back, before the front reads further command lists. The
service thread still never takes the texture cache lock, and the back is
idle while the map changes the caches. Unmaps and the other queued work
still run on the back.
Assisted-by: Claude Opus 5.5 (bisect, fix, testing and commit message)
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
cce6d44af2 executes each command list entry from a copy of its words taken
at submit. Games submit command lists before writing them: the lists wait
behind a semaphore acquire, and the game writes their commands just before
it releases the acquire (Mario Kart World after present). The copies of
those lists were stale. Pokopia stopped after its first frame on macOS: its
GPU never reached the fence the game spun on (EDEN_NX2_PB_SNAPSHOT=0 made it
run again).
Count each channel's suspensions on an acquire and the resumes after them,
and record the count with each copy. A list copied while its channel was
suspended, or whose channel suspended since, reads guest memory instead.
Lists submitted and run without a wait in between keep the copy.
EDEN_NX2_PB_SNAPSHOT=0 still disables it altogether.
Assisted-by: Claude Sonnet 5.5 (first version); Claude Opus 5.5 (bisect, suspension count, testing and commit message)
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
0f14696044 made PresentClientBuffer also wait for the current frame's
fence whenever the previous frame's wasn't reached. Mario Kart World's
GPU waits on semaphores its CPU releases only after the present returns,
so in that state the current fence can't be reached until the present
returns, and each such present stalled up to the 4 s deadline.
Wait for the current frame by default, but give up after a few ms once a
GPU channel was seen suspended on a semaphore acquire and wait for the
previous frame instead. EDEN_NX2_FRAMES_AHEAD=1 always waits for the
previous frame (with 0f14696044's current-frame wait when the GPU is
behind), =0 always for the current one. The scheduler gains a lock-free
flag so the present thread can see suspended channels.
Assisted-by: Claude Sonnet 5.5 (implementation and commit message)
|
| | |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
4d6a13e3d9 and 3d6156434a added bounds checks to the nx2:gpu 216 sparse
map path, but the region checks still compute gpu_address + size, which
wraps for a guest-controlled size. 3d6156434a only guards size == 0 and
the memory offset on the map path, so an unmap (memory handle 0) with a
huge size matches a region through the wrapped sum and reaches
Nx2SparseTile, whose own check wraps the same way, and then
smmu.Unmap(device, size) with a giant page count.
Reject a request whose end wraps the address space before it is used,
for map and unmap alike, with a warning like the existing unknown-memory
check. Also compare by subtraction in the region lookups here and in
Nx2SparseTile and Nx2BackSparse, so none of them depends on the sum.
Assisted-by: Claude Sonnet 5.5 (implementation and commit message)
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The room host and room moderators are in the Moderator state, not
Joined, so the airplane mode override for joined rooms did not apply to
them and LAN Play still returned them to the menu. Accept both states.
Share the room address override between the NIFM profile and IP config
calls so they cannot drift apart.
recv() on a room TCP socket now waited for the receive timeout, because
Recv goes through RecvFrom. Room TCP sockets have no peer, so keep the
previous immediate end-of-stream result when nothing is queued.
Close() now drops queued packets and wakes a blocked recv, which then
fails with EBADF. The socket state that the room thread reads when it
queues a packet is now guarded by the packet mutex.
Assisted-by: Claude Opus 5.5 (investigation and implementation)
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
LAN Play through public lobby rooms failed in two ways.
With airplane mode on (the default), IRequest::GetResult rejected the
game's network request. Mario Kart World then opened the net-connect
applet and returned to the main menu instead of the LAN browser. A
joined room is the emulated network: its sockets only reach room
members. Count it as an available network for GetResult and
IsAnyInternetRequestAccepted.
With airplane mode off, players could open the browser but never saw
each other. Room fake IPs are spread over 192.168.0.0/16, and some room
servers give members different /24s. NIFM reported the host adapter's
/24 mask with the fake IP, so the games treated each other as off-subnet.
Report 255.255.0.0 in a room instead.
Assisted-by: Claude Opus 5.5 (investigation and implementation)
|
| |/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Connect slept for a second while holding packet_mutex, so the host's
SyncNetwork reply could not be handled until Connect had already
returned success in StationOpened. Players could see each other's
group and enter it, but never actually met.
Wait on a condition variable instead, accept the reply only from the
selected host and session, and fail after five seconds. Check packet
sizes and senders, stop duplicate joins from taking another station,
and seed session IDs so separate networks don't share one.
The SDL frontend never called Network::Init, so its multiplayer
option could not join a room. Initialize and shut down networking
around the core.
Assisted-by: Sol (implementation)
Assisted-by: Claude Opus 5.5 (code review)
|
| |\ \
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Resolved by area:
- audio feature_support.h: nx2's native revision handling.
- fiber.cpp: ours, which also drops the unused rewind stack.
- host_memory.cpp: ours granule bitmap and HintCold, plus nx2's
fallocate hole punching per whole dirty granule on Linux.
- texture_cache.h: nx2's old-age eviction pass, then our Collect().
- kepler_compute.cpp: shared upscale slots, then Fortune's Weave's,
then the Kirby Air Riders scan.
- nx2_gsv.h: ours, plus nx2's GetBufferMaxResolution and graphics
device ids (1-based).
- nvhost_ctrl_gpu.cpp: engine support flag bits 40-44.
- lower_to_maxwell.h: ours as the base, with nx2's seven lowering
commits applied one at a time. Second texture descriptor buffers
are read bindless in TEX, TLD.SCR (level zero) and SUST; FSEL
keeps its operand modifiers; TXD takes any channel mask.
lower_to_maxwell.h lowers 837 Fortune's Weave and 1183 Mario Kart
World shader dumps with the same rejects as nx2 and ours (12 and 0).
Assisted-by: Claude Sonnet 5.5 (conflict analysis and drafting)
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Fire Emblem: Fortune's Weave opens the keyboard with library version
0x160012 and a 0x530-byte config. Read with the Switch 1 layout, the
byte taken as use_utf8 belonged to initial_string_offset, so the name
entry returned UTF-16 and the game kept only its first letter. The
text prefix of the common part keeps its layout; the flags, lengths,
string offsets and dictionary fields move (checked against the game's
nn::swkbd::keyboardConfig2kbdConfig). Version 0x140010 is unchanged.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Command 106 was auto-stubbed, and Fire Emblem: Fortune's Weave treats
its empty reply as mode 0 and picks its 720p tier (rendering at 360p).
Report mode 4 (1440p) docked and 2 (1080p, the screen) handheld; the
game then renders at 720p and 540p and upscales to those.
EDEN_VI2_MAX_RESOLUTION_MODE overrides the mode.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The vi2 session is served by AM's thread on guest core 3, so the host
sleep in PaceToVblank held that core for most of every frame. Game
threads scheduled there only ran between presents: Fire Emblem:
Fortune's Weave's loader got one RomFS read per frame (33 ms apart
instead of about 4 ms), which doubled its load times.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Fire Emblem: Fortune's Weave's movie player queries (428) and maps (426)
each decoder output image, then blits it (RGBA, format 0xd5, block-linear
with 16-GOB blocks) into a texture of its own. The pool memory is process
memory (114) that no GPU mapping covered, so the blit read zeros and the
movies were black.
For decoder images, 426 now maps the image at its own address for the
GPU unless a mapping already covers it, and replies with the address,
the last byte's address and the image descriptor as our Eden tree does.
427 drops the mapping after the last unmap, as do 430 and 112. Images the
client reads on the GPU are written as block-linear RGBA, and the GPU
caches are invalidated after each frame. NV12 images and images read
with 961 keep the pitch-linear layout.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Present word 12 holds (swap interval << 16) | refresh rate. Presents were
always held to the next 60 Hz vblank, so Fire Emblem: Fortune's Weave,
which sends 0x2003c (interval 2) after its boot logos, ran at 60 fps and
double speed instead of 30.
Pace each present by its interval and rate (interval clamped to 1-4, rate
60 if outside 30-240 Hz) and log when the word changes.
EDEN_NX2_SWAP_INTERVAL=<n> forces the interval.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Each address space allocated its own SMMU range for the same memory
outside the heap. The caches key memory by device address, so these were
separate copies, and presentation used whichever range was recorded
last: Fire Emblem: Fortune's Weave drew into one alias while VI showed
another, and the screen stayed black.
Key these ranges by (ASID, CPU address, size) and count references. The
first address space allocates the range, the last release frees it, and
a closed session's entries are dropped so a reused ASID can't inherit
them. EDEN_NX2_PRIVATE_DEVICE_RANGES=1 restores a range per address
space.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
GetHdrStatus returns a u64 output format after the result. The bare
success reply left it to stale reply words, and Fire Emblem: Fortune's
Weave set up HDR output from them: its tone map constants came out NaN
and every frame was black. Report format 1 (SDR) for the "default"
display.
Assisted-by: Claude Opus 5.5 (debugging and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Present word 7 holds the size of the frame drawn into the image's
top-left corner, and image preference word 6 its format (1 RGBA8,
4 RGB10A2). Fire Emblem: Fortune's Weave draws 1280x720 RGB10A2 frames
into 3840x2160 images; showing the whole image as RGBA8 gave a corner
of wrongly decoded pixels.
Assisted-by: Claude Opus 5.5 (debugging, porting and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The Switch 2 SDK filters its class enumeration by flags bits 40..43 (2D,
3D, compute and inline-to-memory) before it picks its context classes.
Without them Fire Emblem: Fortune's Weave tears NVN down at boot
(2162-0001). Bisected against the Eden NS2 tree's characteristics block;
its other differences are not needed.
Assisted-by: Claude Opus 5.5 (bisecting and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The Switch 2 SDK asks for the {gpc, tpc} pair of every virtual SM and
treats a pair left at its 0xc0c0 sentinel as failure; with the ioctl
unimplemented, Fire Emblem: Fortune's Weave tore NVN down at boot
(2162-0001). Fill every pair: one GPC, two SMs per TPC.
Assisted-by: Claude Opus 5.5 (debugging, porting and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Fire Emblem: Fortune's Weave creates a graphics device with gpu 41 and
uses the returned id in later NvRm calls; auto-stubbed, it got id 0 and
NVN setup failed. Hand out ids from 1 and free them with 42.
gpu 202 answered (0, 0) for an empty partition, which the SDK reads as a
one-byte partition at address 0. An empty one is min ~0, max 0.
Assisted-by: Claude Opus 5.5 (debugging, porting and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
GameChat polls nx2:camera command 29 every frame; it was logged as an
unimplemented function (Critical plus Warning), 40,000 times in one
session. Answer 3, 21 and 29 with the same empty success, logging each
once.
Assisted-by: Claude Sonnet 5.5 (code)
(cherry picked from commit 0b7b562898bba137934420b366e3980476ee221f)
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
With the present waiting for the previous frame's fence, the game
refills command memory it already submitted while the GPU thread is
still running that frame, so some frames rendered into the wrong image.
Copy each entry's words at submit and execute the copy. Resumed entries
and ranges the GPU has newer words for still read memory.
EDEN_NX2_PB_SNAPSHOT=0 executes from memory.
Ported from Wael3rd/Eglantine-MKW (bd3119a86f).
Assisted-by: Claude Sonnet 5.5 (porting the fix)
(cherry picked from commit 408bb84d06ae0729697ef9bed2c2ba76ce6dff42)
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Title 1 clears about 1 GB of its sparse regions at boot through the GPU
memory manager. Every block the clear touched got 4 MiB of guest memory,
which the clear itself then committed on the host, and counted as written,
so the texture cache gave the images over it device memory too. A block
nobody wrote reads zero already: when the part of a write that lands on
it is all zero, leave it as it is.
(cherry picked from commit 0d7ff63fd1a373cecff6ba91022c9027e801e53f)
|
| |\ \ \
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
test/linux-all-prs-plus
# Conflicts:
# src/core/hle/service/service.cpp
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Every call to an auto-stubbed command wrote a Critical report, and
Critical flushes the log file. Mario Kart World polls nx2:camera 29 about
47 times a second, so the log flushed that often for the whole session.
Each (service, command) pair is reported once; repeats answer success
silently.
|
| |\ \ \ \
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
test/linux-all-prs-plus
# Conflicts:
# src/core/hle/service/nvdrv/nvdrv.cpp
|
| | | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Mario Kart World runs small command lists (20-byte entries) that its
culling dispatches fill in each frame. Accurate GPU mode reads every
command list through the caches; Fast mode reads guest memory directly
(on the split's front thread too), where those entries were still the
words of an older frame, so the draws behind them were left out: the
trees around the courses vanished in Fast mode only.
The buffer cache now also marks the device pages the GPU writes (shader
stores, copies of GPU-written data) in a bitmap the split's front can
read. A command list on such a page waits for the back to run what was
queued before it and is flushed when its words are still only in host
buffers. In a race that is ~5% of command lists (13,500 a second of
262,000) and ~400 flushes a second.
|
| |\ \ \ \ \
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
test/linux-all-prs-plus
# Conflicts:
# src/common/host_memory.h
|
| | | |/ / /
| |/| | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
The kernel clears every page it hands out, and the backing memory is a
page-file section the host only gives RAM to once a page is touched. So
the clears themselves made every page of a game's heap resident: Mario
Kart World (12 GB layout) had a 12.5 GB working set 20 s after boot.
HostMemory keeps two bits per 64 KiB of backing: used (handed out by the
kernel at least once) and dirty (may hold data). Pages returned to the
kernel mark their granules dirty, and a zero clear only touches dirty
granules; a granule cleared in full is clean again. A new kernel on the
same memory marks everything a previous one used dirty, so leaked
processes can't leak data into the next game. KMemoryManager's
optimized-process fill and KSharedMemory's clear go through the same
path.
Mario Kart World, title screen and attract demo, 180 s: working set 20 s
in 4.7-6.4 GB instead of 12.5 GB, peak 14-17.6 GB instead of 20.1 GB.
|
| |\ \ \ \ \
| | | | | |
| | | | | |
| | | | | | |
test/linux-all-prs
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
vi2 229 carries the size the game drew into the presented image in word
7, ((height - 1) << 16) | (width - 1), from the image's top-left corner:
Kirby Air Riders draws 1920x1080 into 2560x1440 images (0x0437077f) and
Mario Kart World 2560x1440 into 3840x2160 ones (0x059f09ff). Docked,
Kirby's frame sat in the top-left corner with black to the right and
below. Crop to the given size; the handheld 1920x1080 limit still
applies, and Mario Kart World's docked crop stays only for presents that
give none.
|
| |\ \ \ \ \ \
| | | | | | |
| | | | | | |
| | | | | | | |
test/linux-all-prs
|
| | | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
ssl:s 0 CreateContext and 100 CreateContextForSystem return an ISslContext
like ssl's CreateContext, but the placeholders replied without an object,
so callers (Minecraft uses 100) got handle 0. Create the same context ssl
does. GetContextCount and GetThreadCoreMask now reply with their word and
double word.
|
| |\ \ \ \ \ \ \
| | | | | | | |
| | | | | | | |
| | | | | | | | |
test/linux-all-prs
|