skyline/app/src/main/cpp/skyline/soc/host1x/command_fifo.h

63 lines
2.3 KiB
C++

// SPDX-License-Identifier: MPL-2.0
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <common.h>
#include <common/circular_queue.h>
#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<span<u32>> 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> nvDecClass; //!< The THI wrapped NVDEC class for video decoding
TegraHostInterface<VicClass> 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<u32> 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<u32> gather);
};
}