// SPDX-License-Identifier: MPL-2.0 // Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/) #pragma once #include #include #include "syncpoint.h" #include "classes/class.h" #include "classes/host1x.h" #include "classes/nvdec.h" #include "classes/vic.h" #include "tegra_host_interface.h" namespace skyline::soc::host1x { /** * @brief Represents the command FIFO block of the Host1x controller, with one per each channel allowing them to run asynchronously * @note A "gather" is equivalent to a GpEntry except we don't need to emulate them directly as they will always be contiguous across CPU memory, hence a regular span is sufficient */ class ChannelCommandFifo { private: const DeviceState &state; static constexpr size_t GatherQueueSize{0x1000}; //!< Maximum size of the gather queue, this value is arbritary CircularQueue> gatherQueue; std::thread thread; //!< The thread that manages processing of pushbuffers within gathers std::mutex threadStartMutex; //!< Protects the thread from being started multiple times Host1xClass host1XClass; //!< The internal Host1x class, used for performing syncpoint waits and other general operations TegraHostInterface nvDecClass; //!< The THI wrapped NVDEC class for video decoding TegraHostInterface vicClass; //!< The THI wrapped VIC class for acceleration of image operations /** * @brief Sends a method call to the target class */ void Send(ClassId targetClass, u32 method, u32 argument); /** * @brief Processes the pushbuffer contained within the given gather, calling methods as needed */ void Process(span gather); /** * @brief Executes all pending gathers in the FIFO and polls for more */ void Run(); public: ChannelCommandFifo(const DeviceState &state, SyncpointSet &syncpoints); ~ChannelCommandFifo(); /** * @brief Starts the pushbuffer processing thread if it hasn't already been started */ void Start(); /** * @brief Pushes a single gather into the FIFO to be processed asynchronously */ void Push(span gather); }; }