nvhost_nvdec: implement IocChannelGetSyncPoint and ChannelSubmit

This commit is contained in:
Nguyen Dac Nam
2020-02-19 01:03:51 +07:00
committed by GitHub
parent 5479b9b50d
commit e44ab5f004

View File

@@ -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<u8>& 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<u8>& input, const std::
return 0;
}
u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlSetNvmapFD params{};
std::memcpy(&params, input.data(), input.size());
@@ -47,7 +54,68 @@ u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& outp
nvmap_fd = params.nvmap_fd;
return 0;
}
u32 nvhost_nvdec::ChannelSubmit(const std::vector<u8>& input, std::vector<u8>& output) {
u32 startPt = 16;
IoctlSubmit params{};
std::memcpy(&params, input.data(), startPt);
std::vector<IoctlCmdBuf> 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<IoctlReloc> 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<IoctlRelocShift> 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<IoctlSyncPtIncr> 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(), &params, 16);
return 0;
}
u32 nvhost_nvdec::ChannelGetSyncPoint(const std::vector<u8>& input, std::vector<u8>& output) {
IoctChannelSyncPoint params{};
std::memcpy(&params, 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(), &params, output.size());
return 0;
}
u32 nvhost_nvdec::ChannelGetWaitBase(const std::vector<u8>& input, std::vector<u8>& output) {
IoctChannelWaitBase params{};
std::memcpy(&params, input.data(), input.size());
@@ -77,5 +145,5 @@ u32 nvhost_nvdec::ChannelMapCmdBuffer(const std::vector<u8>& input, std::vector<
sizeof(IoctlHandleMapBuffer) * params.num_handles);
return 0;
}
} // namespace Service::Nvidia::Devices