| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- // Copyright 2020 yuzu Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #pragma once
- #include <memory>
- #include <unordered_map>
- #include <vector>
- #include <queue>
- #include "common/bit_field.h"
- #include "common/common_types.h"
- #include "video_core/command_classes/sync_manager.h"
- namespace Tegra {
- class GPU;
- class Nvdec;
- class Vic;
- class Host1x;
- enum class ChSubmissionMode : u32 {
- SetClass = 0,
- Incrementing = 1,
- NonIncrementing = 2,
- Mask = 3,
- Immediate = 4,
- Restart = 5,
- Gather = 6,
- };
- enum class ChClassId : u32 {
- NoClass = 0x0,
- Host1x = 0x1,
- VideoEncodeMpeg = 0x20,
- VideoEncodeNvEnc = 0x21,
- VideoStreamingVi = 0x30,
- VideoStreamingIsp = 0x32,
- VideoStreamingIspB = 0x34,
- VideoStreamingViI2c = 0x36,
- GraphicsVic = 0x5d,
- Graphics3D = 0x60,
- GraphicsGpu = 0x61,
- Tsec = 0xe0,
- TsecB = 0xe1,
- NvJpg = 0xc0,
- NvDec = 0xf0
- };
- enum class ChMethod : u32 {
- Empty = 0,
- SetMethod = 0x10,
- SetData = 0x11,
- };
- union ChCommandHeader {
- u32 raw;
- BitField<0, 16, u32> value;
- BitField<16, 12, ChMethod> method_offset;
- BitField<28, 4, ChSubmissionMode> submission_mode;
- };
- static_assert(sizeof(ChCommandHeader) == sizeof(u32), "ChCommand header is an invalid size");
- struct ChCommand {
- ChClassId class_id{};
- int method_offset{};
- std::vector<u32> arguments;
- };
- using ChCommandHeaderList = std::vector<ChCommandHeader>;
- using ChCommandList = std::vector<ChCommand>;
- struct ThiRegisters {
- u32_le increment_syncpt{};
- INSERT_PADDING_WORDS(1);
- u32_le increment_syncpt_error{};
- u32_le ctx_switch_incremement_syncpt{};
- INSERT_PADDING_WORDS(4);
- u32_le ctx_switch{};
- INSERT_PADDING_WORDS(1);
- u32_le ctx_syncpt_eof{};
- INSERT_PADDING_WORDS(5);
- u32_le method_0{};
- u32_le method_1{};
- INSERT_PADDING_WORDS(12);
- u32_le int_status{};
- u32_le int_mask{};
- };
- enum class ThiMethod : u32 {
- IncSyncpt = offsetof(ThiRegisters, increment_syncpt) / sizeof(u32),
- SetMethod0 = offsetof(ThiRegisters, method_0) / sizeof(u32),
- SetMethod1 = offsetof(ThiRegisters, method_1) / sizeof(u32),
- };
- class CDmaPusher {
- public:
- explicit CDmaPusher(GPU& gpu_);
- ~CDmaPusher();
- /// Push NVDEC command buffer entries into queue
- void Push(ChCommandHeaderList&& entries);
- /// Process queued command buffer entries
- void DispatchCalls();
- /// Process one queue element
- void Step();
- /// Invoke command class devices to execute the command based on the current state
- void ExecuteCommand(u32 state_offset, u32 data);
- private:
- /// Write arguments value to the ThiRegisters member at the specified offset
- void ThiStateWrite(ThiRegisters& state, u32 state_offset, const std::vector<u32>& arguments);
- GPU& gpu;
- std::shared_ptr<Tegra::Nvdec> nvdec_processor;
- std::unique_ptr<Tegra::Vic> vic_processor;
- std::unique_ptr<Tegra::Host1x> host1x_processor;
- std::unique_ptr<SyncptIncrManager> sync_manager;
- ChClassId current_class{};
- ThiRegisters vic_thi_state{};
- ThiRegisters nvdec_thi_state{};
- s32 count{};
- s32 offset{};
- u32 mask{};
- bool incrementing{};
- // Queue of command lists to be processed
- std::queue<ChCommandHeaderList> cdma_queue;
- };
- } // namespace Tegra
|