From dbfb1cfe20353d30ae3aade2ce1b9e97946c47fd Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sat, 30 Oct 2021 19:11:41 +0100 Subject: [PATCH] Fully implement the nvdrv Host1xChannel::Submit operation This pushes a set of command buffers into the Host1x command FIFO allocated for the channel, returning fence thresholds that can be waited on for completion, --- .../nvdrv/devices/nvhost/host1x_channel.cpp | 32 ++++++++++++++++++- .../nvdrv/devices/nvhost/host1x_channel.h | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/host1x_channel.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/host1x_channel.cpp index cde37b1b..1a5ddf40 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/host1x_channel.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/host1x_channel.cpp @@ -12,7 +12,9 @@ namespace skyline::service::nvdrv::device::nvhost { const SessionContext &ctx, core::ChannelType channelType) : NvDevice(state, driver, core, ctx), - channelType(channelType) {} + channelType(channelType) { + state.soc->host1x.channels[static_cast(channelType)].Start(); + } PosixResult Host1XChannel::SetNvmapFd(In fd) { state.logger->Debug("fd: {}", fd); @@ -25,6 +27,34 @@ namespace skyline::service::nvdrv::device::nvhost { state.logger->Debug("numCmdBufs: {}, numRelocs: {}, numSyncpointIncrs: {}, numFenceThresholds: {}", cmdBufs.size(), relocs.size(), syncpointIncrs.size(), fenceThresholds.size()); + if (fenceThresholds.size() > syncpointIncrs.size()) + return PosixResult::InvalidArgument; + + if (!relocs.empty()) + throw exception("Relocations are unimplemented!"); + + std::scoped_lock lock(channelMutex); + + for (size_t i{}; i < syncpointIncrs.size(); i++) { + const auto &incr{syncpointIncrs[i]}; + + u32 max{core.syncpointManager.IncrementSyncpointMaxExt(incr.syncpointId, incr.numIncrs)}; + if (i < fenceThresholds.size()) + fenceThresholds[i] = max; + } + + for (const auto &cmdBuf : cmdBufs) { + auto handleDesc{core.nvMap.GetHandle(cmdBuf.mem)}; + if (!handleDesc) + throw exception("Invalid handle passed for a command buffer!"); + + u64 gatherAddress{handleDesc->address + cmdBuf.offset}; + state.logger->Debug("Submit gather, CPU address: 0x{:X}, words: 0x{:X}", gatherAddress, cmdBuf.words); + + span gather(reinterpret_cast(gatherAddress), cmdBuf.words); + state.soc->host1x.channels[static_cast(channelType)].Push(gather); + } + return PosixResult::Success; } diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/host1x_channel.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/host1x_channel.h index e48287bd..175d5f0d 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/host1x_channel.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/host1x_channel.h @@ -23,7 +23,7 @@ namespace skyline::service::nvdrv::device::nvhost { */ struct SubmitCmdBuf { core::NvMap::Handle::Id mem; - u32 offset; //!< Offset from the handle of where the gather should start + u32 offset; //!< Offset in bytes from the handle of where the gather should start u32 words; //!< Size for the gather in 4 byte words };