summaryrefslogtreecommitdiff
path: root/src/video_core/engines/puller.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/engines/puller.h')
-rw-r--r--src/video_core/engines/puller.h179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/video_core/engines/puller.h b/src/video_core/engines/puller.h
new file mode 100644
index 000000000..d948ec790
--- /dev/null
+++ b/src/video_core/engines/puller.h
@@ -0,0 +1,179 @@
1// Copyright 2021 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 <array>
8#include <cstddef>
9#include <vector>
10#include "common/bit_field.h"
11#include "common/common_funcs.h"
12#include "common/common_types.h"
13#include "video_core/engines/engine_interface.h"
14
15namespace Core {
16class System;
17}
18
19namespace Tegra {
20class MemoryManager;
21class DmaPusher;
22
23enum class EngineID {
24 FERMI_TWOD_A = 0x902D, // 2D Engine
25 MAXWELL_B = 0xB197, // 3D Engine
26 KEPLER_COMPUTE_B = 0xB1C0,
27 KEPLER_INLINE_TO_MEMORY_B = 0xA140,
28 MAXWELL_DMA_COPY_A = 0xB0B5,
29};
30
31namespace Control {
32struct ChannelState;
33}
34} // namespace Tegra
35
36namespace VideoCore {
37class RasterizerInterface;
38}
39
40namespace Tegra::Engines {
41
42class Puller final {
43public:
44 struct MethodCall {
45 u32 method{};
46 u32 argument{};
47 u32 subchannel{};
48 u32 method_count{};
49
50 explicit MethodCall(u32 method_, u32 argument_, u32 subchannel_ = 0, u32 method_count_ = 0)
51 : method(method_), argument(argument_), subchannel(subchannel_),
52 method_count(method_count_) {}
53
54 [[nodiscard]] bool IsLastCall() const {
55 return method_count <= 1;
56 }
57 };
58
59 enum class FenceOperation : u32 {
60 Acquire = 0,
61 Increment = 1,
62 };
63
64 union FenceAction {
65 u32 raw;
66 BitField<0, 1, FenceOperation> op;
67 BitField<8, 24, u32> syncpoint_id;
68 };
69
70 explicit Puller(GPU& gpu_, MemoryManager& memory_manager_, DmaPusher& dma_pusher,
71 Control::ChannelState& channel_state);
72 ~Puller();
73
74 void CallMethod(const MethodCall& method_call);
75
76 void CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
77 u32 methods_pending);
78
79 void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
80
81 void CallPullerMethod(const MethodCall& method_call);
82
83 void CallEngineMethod(const MethodCall& method_call);
84
85 void CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
86 u32 methods_pending);
87
88private:
89 Tegra::GPU& gpu;
90
91 MemoryManager& memory_manager;
92 DmaPusher& dma_pusher;
93 Control::ChannelState& channel_state;
94 VideoCore::RasterizerInterface* rasterizer = nullptr;
95
96 static constexpr std::size_t NUM_REGS = 0x800;
97 struct Regs {
98 static constexpr size_t NUM_REGS = 0x40;
99
100 union {
101 struct {
102 INSERT_PADDING_WORDS_NOINIT(0x4);
103 struct {
104 u32 address_high;
105 u32 address_low;
106
107 [[nodiscard]] GPUVAddr SemaphoreAddress() const {
108 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
109 address_low);
110 }
111 } semaphore_address;
112
113 u32 semaphore_sequence;
114 u32 semaphore_trigger;
115 INSERT_PADDING_WORDS_NOINIT(0xC);
116
117 // The pusher and the puller share the reference counter, the pusher only has read
118 // access
119 u32 reference_count;
120 INSERT_PADDING_WORDS_NOINIT(0x5);
121
122 u32 semaphore_acquire;
123 u32 semaphore_release;
124 u32 fence_value;
125 FenceAction fence_action;
126 INSERT_PADDING_WORDS_NOINIT(0xE2);
127
128 // Puller state
129 u32 acquire_mode;
130 u32 acquire_source;
131 u32 acquire_active;
132 u32 acquire_timeout;
133 u32 acquire_value;
134 };
135 std::array<u32, NUM_REGS> reg_array;
136 };
137 } regs{};
138
139 void ProcessBindMethod(const MethodCall& method_call);
140 void ProcessFenceActionMethod();
141 void ProcessSemaphoreAcquire();
142 void ProcessSemaphoreRelease();
143 void ProcessSemaphoreTriggerMethod();
144 void ProcessWaitForInterruptMethod();
145 [[nodiscard]] bool ExecuteMethodOnEngine(u32 method);
146
147 /// Mapping of command subchannels to their bound engine ids
148 std::array<EngineID, 8> bound_engines{};
149
150 enum class GpuSemaphoreOperation {
151 AcquireEqual = 0x1,
152 WriteLong = 0x2,
153 AcquireGequal = 0x4,
154 AcquireMask = 0x8,
155 };
156
157#define ASSERT_REG_POSITION(field_name, position) \
158 static_assert(offsetof(Regs, field_name) == position * 4, \
159 "Field " #field_name " has invalid position")
160
161 ASSERT_REG_POSITION(semaphore_address, 0x4);
162 ASSERT_REG_POSITION(semaphore_sequence, 0x6);
163 ASSERT_REG_POSITION(semaphore_trigger, 0x7);
164 ASSERT_REG_POSITION(reference_count, 0x14);
165 ASSERT_REG_POSITION(semaphore_acquire, 0x1A);
166 ASSERT_REG_POSITION(semaphore_release, 0x1B);
167 ASSERT_REG_POSITION(fence_value, 0x1C);
168 ASSERT_REG_POSITION(fence_action, 0x1D);
169
170 ASSERT_REG_POSITION(acquire_mode, 0x100);
171 ASSERT_REG_POSITION(acquire_source, 0x101);
172 ASSERT_REG_POSITION(acquire_active, 0x102);
173 ASSERT_REG_POSITION(acquire_timeout, 0x103);
174 ASSERT_REG_POSITION(acquire_value, 0x104);
175
176#undef ASSERT_REG_POSITION
177};
178
179} // namespace Tegra::Engines