diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-27 14:00:36 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-27 14:00:36 -0400 |
| commit | f387e8e20bfb98913c2f55422d249dbd37cc4d71 (patch) | |
| tree | ffe4b72ab5769d09e84acb97f4922df5d62fa565 /src/core | |
| parent | 360ea914c7eecc1b211f1362bd593c61b76d289c (diff) | |
service: Switch 2 vi2 placeholder session (gsv 305)
gsv 305 returns the session nn::vi2::sdk::Initialize keeps. Reply shapes
read from the SDK: TIPC 1 -> u32 < 0x400, 3 -> u32 < 8, 11/31/32 -> one
handle then result (events here). With this nn::vi::Initialize returns and
the title opens the default display and starts creating a layer.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/nx2_gsv.h | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/core/hle/service/nx2_gsv.h b/src/core/hle/service/nx2_gsv.h index 7619f56d71..44b5bdc673 100644 --- a/src/core/hle/service/nx2_gsv.h +++ b/src/core/hle/service/nx2_gsv.h @@ -3,6 +3,9 @@ #pragma once +#include <array> +#include <vector> + #include "core/core.h" #include "core/hle/kernel/k_client_session.h" #include "core/hle/kernel/k_process.h" @@ -151,6 +154,51 @@ private: std::array<Kernel::KEvent*, NumIds> m_events{}; }; +// Placeholder for the Switch 2 display session (nn::vi2::sdk), handed out by gsv 305. Reply +// shapes read from the SDK: TIPC 1 -> u32 < 0x400, TIPC 3 -> u32 < 8, TIPC 11/31(u32) and +// 32(handle, u32) -> one handle at word 3 then the result. Handles returned here are events (a +// guess); everything else is auto-stubbed through the nx2: prefix. +class INx2Vi2Session final : public ServiceFramework<INx2Vi2Session> { +public: + explicit INx2Vi2Session(Core::System& system_) + : ServiceFramework{system_, "nx2:vi2"}, m_context{system_, "nx2:vi2"} { + RegisterHandlersTipc({ + {1, &INx2Vi2Session::ReturnOne, "Unknown1"}, + {3, &INx2Vi2Session::ReturnOne, "GetDisplayCount (guessed)"}, + {11, &INx2Vi2Session::ReturnEvent, "Unknown11"}, + {31, &INx2Vi2Session::ReturnEvent, "Unknown31"}, + {32, &INx2Vi2Session::ReturnEvent, "Unknown32"}, + }); + } + + ~INx2Vi2Session() override { + for (auto* event : m_events) { + m_context.CloseEvent(event); + } + } + +private: + void ReturnOne(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) nx2:vi2 TIPC {}, returning 1", ctx.GetCommand()); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push<u32>(1); + } + + void ReturnEvent(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) nx2:vi2 TIPC {} [2]={:#x} [3]={:#x}, returning an event", + ctx.GetCommand(), ctx.CommandBuffer()[2], ctx.CommandBuffer()[3]); + auto* event = m_context.CreateEvent(fmt::format("nx2:vi2:Event{}", m_events.size())); + m_events.push_back(event); + IPC::ResponseBuilder rb{ctx, 2, 1, 0}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(ctx, event->GetReadableEvent()); + } + + KernelHelpers::ServiceContext m_context; + std::vector<Kernel::KEvent*> m_events; +}; + // Placeholder for the Switch 2 graphics-system server that nn::gsv::BootWithRemoteMemory talks // to over TIPC. Nothing behind it is emulated: commands succeed and are logged, so boot can show // what comes next. Commands 202 and 1402 hand out the syncpt and nvsrv sessions the SDK uses. @@ -164,6 +212,7 @@ public: {101, &INx2GraphicsSystemSession::Stub, "Unknown101"}, {202, &INx2GraphicsSystemSession::OpenSyncptSession, "OpenSyncptSession (guessed)"}, {204, &INx2GraphicsSystemSession::AttachSyncptMemory, "AttachSyncptMemory (guessed)"}, + {305, &INx2GraphicsSystemSession::OpenViSession, "OpenViSession (guessed)"}, {497, &INx2GraphicsSystemSession::OpenGpuSession, "OpenGpuSession (guessed)"}, {1402, &INx2GraphicsSystemSession::OpenNvsrvSession, "OpenNvsrvSession (guessed)"}, }); @@ -234,6 +283,16 @@ private: m_syncpt_events[1]->GetReadableEvent()); } + void OpenViSession(HLERequestContext& ctx) { + // Used by nn::vi2::sdk::Initialize; takes one u64, returns a session (handle at word 3, + // result at word 4). + const auto* cmd_buf = ctx.CommandBuffer(); + const size_t data = TipcDataOffset(cmd_buf); + LOG_WARNING(Service, "(STUBBED) nx2:gsv TIPC 305 arg={:#x}, returning a nx2:vi2 session", + u64{cmd_buf[data]} | (u64{cmd_buf[data + 1]} << 32)); + ReturnRawSession(system, ctx, std::make_shared<INx2Vi2Session>(system)); + } + void OpenGpuSession(HLERequestContext& ctx) { // Used by nn::gpu::sdk::BootWithRemoteMemory; takes one u64, returns a session (handle at // word 3, result at word 4) that the GPU SDK keeps. |
