[nvdrv] Add AllocGPFIFOEX1 + modify GPFIFOEXs (#115)
Some checks failed
eden-build / windows (msvc) (push) Waiting to run
eden-build / linux (push) Waiting to run
eden-build / android (push) Waiting to run
eden-build / source (push) Has been cancelled

I noticed that AllocGPFIFOEX was missing from eden.
It is the same as GPFIFOEX2, but is called separately, even on the real console.
I updated the struct to match closely the one seen on switchbrew, and changed the STUBS, because according to sources they seem to be complete.
My guess is that the STUBS were remained due to the unknowns back then.

Reviewed-on: #115
Co-authored-by: SDK-Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK-Chan <sdkchan@eden-emu.dev>
This commit is contained in:
SDK-Chan 2025-07-24 16:57:53 +02:00 committed by crueter
parent 46ddbea71c
commit 03ab350bc6
Signed by: crueter
GPG key ID: 425ACD2D4830EBC6
2 changed files with 36 additions and 24 deletions

View file

@ -78,6 +78,8 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
return WrapFixed(this, &nvhost_gpu::SetErrorNotifier, input, output);
case 0xd:
return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output);
case 0x18:
return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx, input, output, fd);
case 0x1a:
return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output, fd);
case 0x1b:
@ -170,12 +172,35 @@ NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) {
return NvResult::Success;
}
NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd) {
LOG_WARNING(Service_NVDRV,
"(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, "
"unk1={:X}, unk2={:X}, unk3={:X}",
params.num_entries, params.flags, params.unk0, params.unk1, params.unk2,
params.unk3);
NvResult nvhost_gpu::AllocGPFIFOEx(IoctlAllocGpfifoEx& params, DeviceFD fd) {
LOG_DEBUG(Service_NVDRV, "called, num_entries={:X}, flags={:X}, reserved1={:X}, "
"reserved2={:X}, reserved3={:X}",
params.num_entries, params.flags, params.reserved[0], params.reserved[1],
params.reserved[2]);
if (channel_state->initialized) {
LOG_CRITICAL(Service_NVDRV, "Already allocated!");
return NvResult::AlreadyAllocated;
}
u64 program_id{};
if (auto* const session = core.GetSession(sessions[fd]); session != nullptr) {
program_id = session->process->GetProgramId();
}
system.GPU().InitChannel(*channel_state, program_id);
params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint);
return NvResult::Success;
}
NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx& params, DeviceFD fd) {
LOG_DEBUG(Service_NVDRV,
"called, num_entries={:X}, flags={:X}, reserved1={:X}, "
"reserved2={:X}, reserved3={:X}",
params.num_entries, params.flags, params.reserved[0], params.reserved[1],
params.reserved[2]);
if (channel_state->initialized) {
LOG_CRITICAL(Service_NVDRV, "Already allocated!");

View file

@ -131,27 +131,13 @@ private:
static_assert(sizeof(NvFence) == 8, "Fence is incorrect size");
struct IoctlAllocGpfifoEx {
u32_le num_entries{};
u32_le flags{};
u32_le unk0{};
u32_le unk1{};
u32_le unk2{};
u32_le unk3{};
u32_le unk4{};
u32_le unk5{};
};
static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx is incorrect size");
struct IoctlAllocGpfifoEx2 {
u32_le num_entries{}; // in
u32_le num_jobs{}; // in
u32_le flags{}; // in
u32_le unk0{}; // in (1 works)
NvFence fence_out{}; // out
u32_le unk1{}; // in
u32_le unk2{}; // in
u32_le unk3{}; // in
std::array<u32_le, 3> reserved{}; // in and ingored (for now) according to switch brew
};
static_assert(sizeof(IoctlAllocGpfifoEx2) == 32, "IoctlAllocGpfifoEx2 is incorrect size");
static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx2 is incorrect size");
struct IoctlAllocObjCtx {
u32_le class_num{}; // 0x902D=2d, 0xB197=3d, 0xB1C0=compute, 0xA140=kepler, 0xB0B5=DMA,
@ -196,7 +182,8 @@ private:
NvResult ZCullBind(IoctlZCullBind& params);
NvResult SetErrorNotifier(IoctlSetErrorNotifier& params);
NvResult SetChannelPriority(IoctlChannelSetPriority& params);
NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd);
NvResult AllocGPFIFOEx(IoctlAllocGpfifoEx& params, DeviceFD fd);
NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx& params, DeviceFD fd);
NvResult AllocateObjectContext(IoctlAllocObjCtx& params);
NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries);