// SPDX-License-Identifier: MIT OR MPL-2.0 // Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/) #pragma once #include #include #include namespace skyline::service::nvdrv::device::nvhost { /** * @brief nvhost::Host1xChannel is used by applications to interface with host1x channels, such as VIC and NVDEC * @url https://switchbrew.org/wiki/NV_services#Channels */ class Host1xChannel : public NvDevice { private: core::ChannelType channelType; //!< The specific host1x channel that this instance refers to std::mutex channelMutex; //!< Synchronises submit operations public: /** * @brief Describes how a gather for a submit should be generated from a given handle */ struct SubmitCmdBuf { core::NvMap::Handle::Id mem; u32 offset; //!< Offset in bytes from the handle of where the gather should start u32 words; //!< Size for the gather in 4 byte words }; /** * @brief Describes a single memory relocation that can be applied to a pinned handle before command submission * @note These are used like: patchMem[patchOffset] = pinMem.iova + pinOffset */ struct SubmitReloc { core::NvMap::Handle::Id patchMem; u32 patchOffset; core::NvMap::Handle::Id pinMem; u32 pinOffset; }; /** * @brief Describes how the command buffers supplied with the submit will affect a given syncpoint */ struct SubmitSyncpointIncr { u32 syncpointId; u32 numIncrs; std::array _res_; }; /** * @brief A buffer descriptor used for MapBuffer and UnmapBuffer */ struct BufferHandle { core::NvMap::Handle::Id handle; //!< Handle to be (un)pinned u32 address; //!< The output IOVA that the handle was pinned too }; Host1xChannel(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx, core::ChannelType channelType); /** * @brief Sets the nvmap client to be used for channel submits * @url https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD */ PosixResult SetNvmapFd(In id); /** * @brief Submits the specified command buffer data to the channel and returns fences that can be waited on * @url https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CHANNEL_SUBMIT */ PosixResult Submit(span cmdBufs, span relocs, span relocShifts, span syncpointIncrs, span fenceThresholds); /** * @brief Returns the syncpoint ID that is located at the given index in this channel's syncpoint array * @url https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CHANNEL_GET_SYNCPOINT */ PosixResult GetSyncpoint(In channelSyncpointIdx, Out syncpointId); /** * @brief Stubbed in modern nvdrv to return 0 * @url https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CHANNEL_GET_WAITBASE */ PosixResult GetWaitBase(In pChannelType, Out waitBase); /** * @brief Sets the timeout for channel submits * @url https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CHANNEL_SET_SUBMIT_TIMEOUT */ PosixResult SetSubmitTimeout(In timeout); /** * @brief Pins a set of nvmap handles into the channel address space for use in submitted command buffers * @url https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CHANNEL_MAP_CMD_BUFFER */ PosixResult MapBuffer(u8 compressed, span handles); /** * @brief Unpins a set of nvmap handles into the channel address space * @url https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CHANNEL_UNMAP_CMD_BUFFER */ PosixResult UnmapBuffer(u8 compressed, span handles); PosixResult Ioctl(IoctlDescriptor cmd, span buffer) override; }; }