From e44ab5f0049301c4a348ca102e26bd294f6309b8 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Wed, 19 Feb 2020 01:03:51 +0700 Subject: [PATCH] nvhost_nvdec: implement IocChannelGetSyncPoint and ChannelSubmit --- .../service/nvdrv/devices/nvhost_nvdec.cpp | 78 +++++++++++++++++-- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 4127dc55a2..7a7c9cf7a4 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -9,10 +9,12 @@ #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" namespace Service::Nvidia::Devices { - + constexpr u32 NVHOST_IOCTL_MAGIC(0x0); constexpr u32 NVHOST_IOCTL_CHANNEL_MAP_CMD_BUFFER(0x9); - +constexpr u32 NVHOST_IOCTL_CHANNEL_MAP_CMD_BUFFER_EX(0x25); +constexpr u32 NVHOST_IOCTL_CHANNEL_SUBMIT(0x1); + nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {} nvhost_nvdec::~nvhost_nvdec() = default; @@ -27,11 +29,15 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector& input, const std:: return SetNVMAPfd(input, output); case IoctlCommand::IocChannelGetWaitBase: return ChannelGetWaitBase(input, output); + case IoctlCommand::IocChannelGetSyncPoint: + return ChannelGetSyncPoint(input, output); } - + if (command.group == NVHOST_IOCTL_MAGIC) { if (command.cmd == NVHOST_IOCTL_CHANNEL_MAP_CMD_BUFFER) { return ChannelMapCmdBuffer(input, output); + } else if (command.cmd == NVHOST_IOCTL_CHANNEL_SUBMIT) { + return ChannelSubmit(input, output); } } @@ -39,6 +45,7 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector& input, const std:: return 0; } + u32 nvhost_nvdec::SetNVMAPfd(const std::vector& input, std::vector& output) { IoctlSetNvmapFD params{}; std::memcpy(¶ms, input.data(), input.size()); @@ -47,7 +54,68 @@ u32 nvhost_nvdec::SetNVMAPfd(const std::vector& input, std::vector& outp nvmap_fd = params.nvmap_fd; return 0; } - + +u32 nvhost_nvdec::ChannelSubmit(const std::vector& input, std::vector& output) { + u32 startPt = 16; + + IoctlSubmit params{}; + std::memcpy(¶ms, input.data(), startPt); + + std::vector cmdBufs(params.num_cmdbufs); + std::memcpy(cmdBufs.data(), input.data() + startPt, + sizeof(IoctlCmdBuf) * params.num_cmdbufs); + startPt += sizeof(IoctlCmdBuf) * params.num_cmdbufs; + // TODO(namkazt): what to do with this? + + std::vector relocs(params.num_relocs); + std::memcpy(relocs.data(), input.data() + startPt, sizeof(IoctlReloc) * params.num_relocs); + startPt += sizeof(IoctlReloc) * params.num_relocs; + // TODO(namkazt): what to do with this? + + std::vector relocShifts(params.num_relocs); + std::memcpy(relocShifts.data(), input.data() + startPt, + sizeof(IoctlRelocShift) * params.num_relocs); + startPt += sizeof(IoctlRelocShift) * params.num_relocs; + //TODO(namkazt): what to do with this? + + std::vector syncPtIncrs(params.num_syncpt_incrs); + std::memcpy(syncPtIncrs.data(), input.data() + startPt, + sizeof(IoctlSyncPtIncr) * params.num_syncpt_incrs); + startPt += sizeof(IoctlSyncPtIncr) * params.num_syncpt_incrs; + // apply increment to sync points and create new one if not existed + for (auto syncIncr : syncPtIncrs) { + auto itr = syncPtValues.find(syncIncr.syncpt_id); + if (itr == syncPtValues.end()) { + syncPtValues[syncIncr.syncpt_id] = syncIncr.syncpt_incrs; + } else { + syncPtValues[syncIncr.syncpt_id] += syncIncr.syncpt_incrs; + } + } + + LOG_WARNING(Service_NVDRV, + "(STUBBED) called, num_cmdbufs: {}, num_relocs: {}, num_syncpt_incrs: {}, num_fences: {}", + params.num_cmdbufs, params.num_relocs, params.num_syncpt_incrs, params.num_fences); + + std::memcpy(output.data(), ¶ms, 16); + return 0; +} + +u32 nvhost_nvdec::ChannelGetSyncPoint(const std::vector& input, std::vector& output) { + IoctChannelSyncPoint params{}; + std::memcpy(¶ms, input.data(), input.size()); + LOG_WARNING(Service_NVDRV, "called, module_id: {}", params.syncpt_id); + + auto itr = syncPtValues.find(params.syncpt_id); + if (itr == syncPtValues.end()) { + params.syncpt_value = 0; + } else { + params.syncpt_value = itr->second; + } + + std::memcpy(output.data(), ¶ms, output.size()); + return 0; +} + u32 nvhost_nvdec::ChannelGetWaitBase(const std::vector& input, std::vector& output) { IoctChannelWaitBase params{}; std::memcpy(¶ms, input.data(), input.size()); @@ -77,5 +145,5 @@ u32 nvhost_nvdec::ChannelMapCmdBuffer(const std::vector& input, std::vector< sizeof(IoctlHandleMapBuffer) * params.num_handles); return 0; } - + } // namespace Service::Nvidia::Devices