Repository navigation
Switch 2 SDK calls whose service the host does not serve are answered (refresh rates, the 120 Hz capability, GL / GR, native memory), and the acceleration-structure size query writes its sizes - #2246
Conversation
…: Nintendo Switch 2 Welcome Tour stops at start-up on nn::vi::InitializeWithVrrLfcEnabled and nn::gs::sdk::QueryApplicationGpuTimeSpan (a null read in nn::os::SdkMutexType::Lock, sdk+0x151fb0), on hid calls that abort in sf (0xe15, sdk+0x65cfdc), and on a refresh-rate answer of two 64-bit words that overwrote its caller's saved frame pointer (main+0x5e3e20). hle_vi.c: InitializeWithVrrLfcEnabled does nothing and returns a Result of 0 (void or Result, 0 is safe either way); QueryDisplayCurrentRefreshRate answers 60 Hz, the display's own, as one 32-bit Hz word and a bool; QueryDisplayAvailableRefreshRates lists 60 Hz alone; SetDisplay120HzRefreshRateCapability is logged. hle_hid.c: GetGlGrButtonConfigState answers no GL / GR assigned; SetSceneIdForPrivateApp returns a Result of 0. hle_oe.c: QueryApplicationGpuTimeSpan answers a fixed 8 ms, which keeps the game's dynamic resolution at full size, and the host's measured GPU time of its newest completed frame (mtl_gpu_ms, up to 8 frames back) only with DM_DYNAMIC_RESOLUTION=1, since the host's GPU time held Ocarina of Time's controller at its floor (frame-rate.md); gs::sdk::CreateNativeMemory gives the range's address as its handle and DestroyNativeMemory nothing, both only seen as imports and never called, so the 8-byte handle is not checked yet. Weak stand-ins of mtl_gpu_ms and dm_nvn_frame_count keep host unit tests without a graphics backend linking. From DeathKhan/nx2android cbeb5ccd6 and eea4efef9, as reviewed into DroidPlay Core (enjoyerofslop/droidplay-core#158); services.md entry, the DM_DYNAMIC_RESOLUTION row and a line in frame-rate.md Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…three sizes: the call writes the size of an acceleration structure, of its build scratch and of its update scratch through three pointers, which Nintendo Switch 2 Welcome Tour sums into the memory pool it makes for its acceleration structures (query at main+0x6130cc, pool from the sum at main+0xfc2cc / +0x11bf1c) without zeroing them first. The red stub wrote nothing, so the sum was stack garbage: on an Android host 0xffffffff + 1 + 1, a 4 GB pool committed before the first frame, and the game ran out of memory in its loader 16 frames in. The host builds no acceleration structure and traces no ray, so it answers 64 KB for each, with a red line once: small sizes in the pool's 4 KB granule keep every later offset the game takes valid. From DeathKhan/nx2android 87772ede9 (its hle_nvn.c hunk), as taken into DroidPlay Core (enjoyerofslop/droidplay-core#157); nvn-objects.md entry Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s a fixed 8 ms without DM_DYNAMIC_RESOLUTION=1, and CreateNativeMemorys handle is the ranges address (55 checks, 0 failed on an Apple-silicon Mac) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tionGpuTimeSpan are left to seedds#1425, which takes them over with the same C names: with both, the second to land would not build (a redefinition, or a duplicate in the forced-takeover list). Their code, the GPU time's weak stand-ins, the frame-rate.md line and the DM_DYNAMIC_RESOLUTION row's addition go, and t_oe keeps only its native memory check; the services.md entry keeps the refresh rates, the 120 Hz capability, GL / GR and native memory (only seen as imports, never called) and names seedds#1425 for the rest. As DroidPlay Core's review asked of enjoyerofslop/droidplay-core#158 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Updated in 3cf027f, a new commit on the same branch:
Checked, re-run on an Apple-silicon Mac from this branch:
Not run: the full |
One conflict, in dm/host/tests/t_oe.c: both sides added checks at the end of main(); both are kept. Co-Authored-By: Claude <noreply@anthropic.com>
hle_hid.c: the GL / GR answer stays beside the npad IMU calls main added at the same place Co-Authored-By: Claude <noreply@anthropic.com>
|
The one failing check ( Same line in both jobs (Host unit tests, Sanitizers) of this PR's run 43218207071 and of main's run https://github.com/seedds/nxnative/actions/runs/43326823244 (8d44aaf, 2026-11-12); everything else in the conflict report is as expected ( |
|
The host and sanitizer failures here are main's own |
What and why
Nintendo Switch 2 Welcome Tour (
040057C02159A000, SDK 20.5.29) stops at start-up on SDK calls that talk to a system service whose session the host never opens, and on a red stub that leaves a size query unanswered. #1425 (its profile) takes over three of those calls:vi::InitializeWithVrrLfcEnabled,hid::SetSceneIdForPrivateAppandoe::QueryApplicationGpuTimeSpan. This PR has the others, with no overlap with #1425.They come from DeathKhan/nx2android (cbeb5ccd6, eea4efef9, 87772ede9), an Android port of nxnative, as reviewed into DroidPlay Core: enjoyerofslop/droidplay-core#158 and #157. Its maintainer asked for this matching PR, since these files are shared.
The system calls (
hle_vi.c,hle_hid.c,hle_oe.c):vi::QueryDisplayCurrentRefreshRate: answers 60 Hz, the display's own, as one 32-bit Hz word and a bool. An answer of two 64-bit words overwrote the caller's saved frame pointer (main+0x5e3e20).vi::QueryDisplayAvailableRefreshRates: lists 60 Hz alone.vi::SetDisplay120HzRefreshRateCapability: is logged.hid::GetGlGrButtonConfigState: answers no GL / GR assigned. Its SDK body aborts insf(0xe15,sdk+0x65cfdc).gs::sdk::CreateNativeMemory/DestroyNativeMemory: the handle is the range's address, and nothing is registered. Both are only seen as imports so far, never called, so the 8-byte handle isn't checked yet.nvnDeviceCalculateAccelerationStructureMemoryRequirementswrites its three sizes:main+0x6130cc, the sum atmain+0xfc2cc/+0x11bf1c), and doesn't zero them first. The red stub wrote nothing, so on the Android host the sum was stack garbage: a 4 GB pool, and the game ran out of memory in its loader 16 frames in. On the Mac the result depends on what the stack holds.Tests:
t_oechecks the native memory handle.History: an earlier version also took over #1425's three calls. They were dropped in 3cf027f, so the two PRs don't collide.
Checked
0100606026F12000:t_oe: 54 checks, 0 failed.t_hid: 209 checks, 0 failed.dm/hostand the game's profile. Not run: the wholemake -C dm/host/tests run.hle_vi.c,hle_hid.candhle_oe.cpassclang -fsyntax-only -Wall -Wextra.hle_nvn.c's only warnings are existing ones on other lines.dm/tools/teststest_docs,test_env_switches,test_lint_candtest_architecturepass.docs_symptoms.pywas run.regress.py check: not run. These hooks are reached only by Switch 2 games that call them.Docs
docs/reference/services.mdanddocs/reference/nvn-objects.mdentries, andpython3 dm/tools/docs_symptoms.pywas run🤖 Generated with Claude Code