summaryrefslogtreecommitdiff
path: root/src/video_core/cdma_pusher.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/cdma_pusher.h')
-rw-r--r--src/video_core/cdma_pusher.h138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/video_core/cdma_pusher.h b/src/video_core/cdma_pusher.h
new file mode 100644
index 000000000..982f309c5
--- /dev/null
+++ b/src/video_core/cdma_pusher.h
@@ -0,0 +1,138 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <unordered_map>
9#include <vector>
10#include <queue>
11
12#include "common/bit_field.h"
13#include "common/common_types.h"
14#include "video_core/command_classes/sync_manager.h"
15
16namespace Tegra {
17
18class GPU;
19class Nvdec;
20class Vic;
21class Host1x;
22
23enum class ChSubmissionMode : u32 {
24 SetClass = 0,
25 Incrementing = 1,
26 NonIncrementing = 2,
27 Mask = 3,
28 Immediate = 4,
29 Restart = 5,
30 Gather = 6,
31};
32
33enum class ChClassId : u32 {
34 NoClass = 0x0,
35 Host1x = 0x1,
36 VideoEncodeMpeg = 0x20,
37 VideoEncodeNvEnc = 0x21,
38 VideoStreamingVi = 0x30,
39 VideoStreamingIsp = 0x32,
40 VideoStreamingIspB = 0x34,
41 VideoStreamingViI2c = 0x36,
42 GraphicsVic = 0x5d,
43 Graphics3D = 0x60,
44 GraphicsGpu = 0x61,
45 Tsec = 0xe0,
46 TsecB = 0xe1,
47 NvJpg = 0xc0,
48 NvDec = 0xf0
49};
50
51enum class ChMethod : u32 {
52 Empty = 0,
53 SetMethod = 0x10,
54 SetData = 0x11,
55};
56
57union ChCommandHeader {
58 u32 raw;
59 BitField<0, 16, u32> value;
60 BitField<16, 12, ChMethod> method_offset;
61 BitField<28, 4, ChSubmissionMode> submission_mode;
62};
63static_assert(sizeof(ChCommandHeader) == sizeof(u32), "ChCommand header is an invalid size");
64
65struct ChCommand {
66 ChClassId class_id{};
67 int method_offset{};
68 std::vector<u32> arguments;
69};
70
71using ChCommandHeaderList = std::vector<Tegra::ChCommandHeader>;
72using ChCommandList = std::vector<Tegra::ChCommand>;
73
74struct ThiRegisters {
75 u32_le increment_syncpt{};
76 INSERT_PADDING_WORDS(1);
77 u32_le increment_syncpt_error{};
78 u32_le ctx_switch_incremement_syncpt{};
79 INSERT_PADDING_WORDS(4);
80 u32_le ctx_switch{};
81 INSERT_PADDING_WORDS(1);
82 u32_le ctx_syncpt_eof{};
83 INSERT_PADDING_WORDS(5);
84 u32_le method_0{};
85 u32_le method_1{};
86 INSERT_PADDING_WORDS(12);
87 u32_le int_status{};
88 u32_le int_mask{};
89};
90
91enum class ThiMethod : u32 {
92 IncSyncpt = offsetof(ThiRegisters, increment_syncpt) / sizeof(u32),
93 SetMethod0 = offsetof(ThiRegisters, method_0) / sizeof(u32),
94 SetMethod1 = offsetof(ThiRegisters, method_1) / sizeof(u32),
95};
96
97class CDmaPusher {
98public:
99 explicit CDmaPusher(GPU& gpu);
100 ~CDmaPusher();
101
102 /// Push NVDEC command buffer entries into queue
103 void Push(ChCommandHeaderList&& entries);
104
105 /// Process queued command buffer entries
106 void DispatchCalls();
107
108 /// Process one queue element
109 void Step();
110
111 /// Invoke command class devices to execute the command based on the current state
112 void ExecuteCommand(u32 offset, u32 data);
113
114private:
115 /// Write arguments value to the ThiRegisters member at the specified offset
116 void ThiStateWrite(ThiRegisters& state, u32 offset, const std::vector<u32>& arguments);
117
118 GPU& gpu;
119
120 std::shared_ptr<Tegra::Nvdec> nvdec_processor;
121 std::unique_ptr<Tegra::Vic> vic_processor;
122 std::unique_ptr<Tegra::Host1x> host1x_processor;
123 std::unique_ptr<SyncptIncrManager> nvdec_sync;
124 std::unique_ptr<SyncptIncrManager> vic_sync;
125 ChClassId current_class{};
126 ThiRegisters vic_thi_state{};
127 ThiRegisters nvdec_thi_state{};
128
129 s32 count{};
130 s32 offset{};
131 s32 mask{};
132 bool incrementing{};
133
134 // Queue of command lists to be processed
135 std::queue<ChCommandHeaderList> cdma_queue;
136};
137
138} // namespace Tegra