diff options
| author | duck912 <350528965+Duck912@users.noreply.github.com> | 2026-10-31 01:46:15 -0400 |
|---|---|---|
| committer | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 14:58:36 -0500 |
| commit | 210fb0cb690318e8ff65a042cfecb8dc345a66ab (patch) | |
| tree | 0aa0f814c02e554e9e31d2afd429605fcb0e42b9 /src/core/hle | |
| parent | 5f0325e2b4e72c3d10c44c7445bf73bc63e0ea32 (diff) | |
nvhost_ctrl_gpu: implement VSMS_MAPPING
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>
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 5998940afa..c13ad4fbff 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -113,12 +113,22 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> case 0x6: return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetTPCMasks3, input, output, inline_output); - case 0x13: - LOG_DEBUG(Service_NVDRV, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return NvResult::NotImplemented; + case 0x13: { + // NVGPU_GPU_IOCTL_VSMS_MAPPING: an 8-byte argument struct plus a buffer of + // {gpc_index, tpc_index} byte pairs, one per virtual SM. The SDK treats a pair left at + // its 0xc0c0 sentinel as failure, so fill every pair: one GPC, two SMs per TPC. + if (command.raw != 0xc0084713 || input.size() != 8 || output.size() != 8 || + inline_output.size() < 2) { + return NvResult::BadParameter; + } + std::memcpy(output.data(), input.data(), output.size()); + for (size_t i = 0; i + 1 < inline_output.size(); i += 2) { + inline_output[i] = 0; // gpc_index + inline_output[i + 1] = static_cast<u8>(i / 4); // tpc_index + } + LOG_DEBUG(Service_NVDRV, "VSMS mapping for {} SMs", inline_output.size() / 2); + return NvResult::Success; + } default: break; } |
