summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2019-02-08 23:21:53 -0500
committerGravatar bunnei2019-03-06 21:48:57 -0500
commitaaa373585cd55bd03fcc589d2ad9f749e2cb99d4 (patch)
tree1da617fd05d84d59910d585a6b01af2c89f3ed36
parentgpu: Move command processing to another thread. (diff)
downloadyuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.tar.gz
yuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.tar.xz
yuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.zip
gpu: Refactor a/synchronous implementations into their own classes.
-rw-r--r--src/core/core.cpp9
-rw-r--r--src/video_core/CMakeLists.txt4
-rw-r--r--src/video_core/gpu.cpp48
-rw-r--r--src/video_core/gpu.h26
-rw-r--r--src/video_core/gpu_asynch.cpp37
-rw-r--r--src/video_core/gpu_asynch.h37
-rw-r--r--src/video_core/gpu_synch.cpp37
-rw-r--r--src/video_core/gpu_synch.h29
8 files changed, 162 insertions, 65 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 9e5d167c3..1d83e9e11 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -36,7 +36,8 @@
36#include "frontend/applets/software_keyboard.h" 36#include "frontend/applets/software_keyboard.h"
37#include "frontend/applets/web_browser.h" 37#include "frontend/applets/web_browser.h"
38#include "video_core/debug_utils/debug_utils.h" 38#include "video_core/debug_utils/debug_utils.h"
39#include "video_core/gpu.h" 39#include "video_core/gpu_asynch.h"
40#include "video_core/gpu_synch.h"
40#include "video_core/renderer_base.h" 41#include "video_core/renderer_base.h"
41#include "video_core/video_core.h" 42#include "video_core/video_core.h"
42 43
@@ -131,7 +132,11 @@ struct System::Impl {
131 132
132 is_powered_on = true; 133 is_powered_on = true;
133 134
134 gpu_core = std::make_unique<Tegra::GPU>(system, *renderer); 135 if (Settings::values.use_asynchronous_gpu_emulation) {
136 gpu_core = std::make_unique<VideoCommon::GPUAsynch>(system, *renderer);
137 } else {
138 gpu_core = std::make_unique<VideoCommon::GPUSynch>(system, *renderer);
139 }
135 140
136 cpu_core_manager.Initialize(system); 141 cpu_core_manager.Initialize(system);
137 142
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 3bb5d0ed7..a4cb33c17 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -17,6 +17,10 @@ add_library(video_core STATIC
17 engines/shader_header.h 17 engines/shader_header.h
18 gpu.cpp 18 gpu.cpp
19 gpu.h 19 gpu.h
20 gpu_asynch.cpp
21 gpu_asynch.h
22 gpu_synch.cpp
23 gpu_synch.h
20 gpu_thread.cpp 24 gpu_thread.cpp
21 gpu_thread.h 25 gpu_thread.h
22 macro_interpreter.cpp 26 macro_interpreter.cpp
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 0d7a052dd..08abf8ac9 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -6,14 +6,12 @@
6#include "core/core.h" 6#include "core/core.h"
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/memory.h" 8#include "core/memory.h"
9#include "core/settings.h"
10#include "video_core/engines/fermi_2d.h" 9#include "video_core/engines/fermi_2d.h"
11#include "video_core/engines/kepler_compute.h" 10#include "video_core/engines/kepler_compute.h"
12#include "video_core/engines/kepler_memory.h" 11#include "video_core/engines/kepler_memory.h"
13#include "video_core/engines/maxwell_3d.h" 12#include "video_core/engines/maxwell_3d.h"
14#include "video_core/engines/maxwell_dma.h" 13#include "video_core/engines/maxwell_dma.h"
15#include "video_core/gpu.h" 14#include "video_core/gpu.h"
16#include "video_core/gpu_thread.h"
17#include "video_core/renderer_base.h" 15#include "video_core/renderer_base.h"
18 16
19namespace Tegra { 17namespace Tegra {
@@ -39,10 +37,6 @@ GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) : renderer{ren
39 kepler_compute = std::make_unique<Engines::KeplerCompute>(*memory_manager); 37 kepler_compute = std::make_unique<Engines::KeplerCompute>(*memory_manager);
40 maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, rasterizer, *memory_manager); 38 maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, rasterizer, *memory_manager);
41 kepler_memory = std::make_unique<Engines::KeplerMemory>(system, rasterizer, *memory_manager); 39 kepler_memory = std::make_unique<Engines::KeplerMemory>(system, rasterizer, *memory_manager);
42
43 if (Settings::values.use_asynchronous_gpu_emulation) {
44 gpu_thread = std::make_unique<VideoCommon::GPUThread::ThreadManager>(renderer, *dma_pusher);
45 }
46} 40}
47 41
48GPU::~GPU() = default; 42GPU::~GPU() = default;
@@ -71,48 +65,6 @@ const DmaPusher& GPU::DmaPusher() const {
71 return *dma_pusher; 65 return *dma_pusher;
72} 66}
73 67
74void GPU::PushGPUEntries(Tegra::CommandList&& entries) {
75 if (Settings::values.use_asynchronous_gpu_emulation) {
76 gpu_thread->SubmitList(std::move(entries));
77 } else {
78 dma_pusher->Push(std::move(entries));
79 dma_pusher->DispatchCalls();
80 }
81}
82
83void GPU::SwapBuffers(
84 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
85 if (Settings::values.use_asynchronous_gpu_emulation) {
86 gpu_thread->SwapBuffers(std::move(framebuffer));
87 } else {
88 renderer.SwapBuffers(std::move(framebuffer));
89 }
90}
91
92void GPU::FlushRegion(VAddr addr, u64 size) {
93 if (Settings::values.use_asynchronous_gpu_emulation) {
94 gpu_thread->FlushRegion(addr, size);
95 } else {
96 renderer.Rasterizer().FlushRegion(addr, size);
97 }
98}
99
100void GPU::InvalidateRegion(VAddr addr, u64 size) {
101 if (Settings::values.use_asynchronous_gpu_emulation) {
102 gpu_thread->InvalidateRegion(addr, size);
103 } else {
104 renderer.Rasterizer().InvalidateRegion(addr, size);
105 }
106}
107
108void GPU::FlushAndInvalidateRegion(VAddr addr, u64 size) {
109 if (Settings::values.use_asynchronous_gpu_emulation) {
110 gpu_thread->FlushAndInvalidateRegion(addr, size);
111 } else {
112 renderer.Rasterizer().FlushAndInvalidateRegion(addr, size);
113 }
114}
115
116u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { 68u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
117 ASSERT(format != RenderTargetFormat::NONE); 69 ASSERT(format != RenderTargetFormat::NONE);
118 70
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 3f3098bf1..14a421cc1 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -19,10 +19,6 @@ namespace VideoCore {
19class RendererBase; 19class RendererBase;
20} // namespace VideoCore 20} // namespace VideoCore
21 21
22namespace VideoCommon::GPUThread {
23class ThreadManager;
24} // namespace VideoCommon::GPUThread
25
26namespace Tegra { 22namespace Tegra {
27 23
28enum class RenderTargetFormat : u32 { 24enum class RenderTargetFormat : u32 {
@@ -123,7 +119,7 @@ enum class EngineID {
123 MAXWELL_DMA_COPY_A = 0xB0B5, 119 MAXWELL_DMA_COPY_A = 0xB0B5,
124}; 120};
125 121
126class GPU final { 122class GPU {
127public: 123public:
128 explicit GPU(Core::System& system, VideoCore::RendererBase& renderer); 124 explicit GPU(Core::System& system, VideoCore::RendererBase& renderer);
129 125
@@ -206,20 +202,20 @@ public:
206 } regs{}; 202 } regs{};
207 203
208 /// Push GPU command entries to be processed 204 /// Push GPU command entries to be processed
209 void PushGPUEntries(Tegra::CommandList&& entries); 205 virtual void PushGPUEntries(Tegra::CommandList&& entries) = 0;
210 206
211 /// Swap buffers (render frame) 207 /// Swap buffers (render frame)
212 void SwapBuffers( 208 virtual void SwapBuffers(
213 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer); 209 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) = 0;
214 210
215 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory 211 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
216 void FlushRegion(VAddr addr, u64 size); 212 virtual void FlushRegion(VAddr addr, u64 size) = 0;
217 213
218 /// Notify rasterizer that any caches of the specified region should be invalidated 214 /// Notify rasterizer that any caches of the specified region should be invalidated
219 void InvalidateRegion(VAddr addr, u64 size); 215 virtual void InvalidateRegion(VAddr addr, u64 size) = 0;
220 216
221 /// Notify rasterizer that any caches of the specified region should be flushed and invalidated 217 /// Notify rasterizer that any caches of the specified region should be flushed and invalidated
222 void FlushAndInvalidateRegion(VAddr addr, u64 size); 218 virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0;
223 219
224private: 220private:
225 void ProcessBindMethod(const MethodCall& method_call); 221 void ProcessBindMethod(const MethodCall& method_call);
@@ -236,13 +232,13 @@ private:
236 /// Determines where the method should be executed. 232 /// Determines where the method should be executed.
237 bool ExecuteMethodOnEngine(const MethodCall& method_call); 233 bool ExecuteMethodOnEngine(const MethodCall& method_call);
238 234
239private: 235protected:
240 std::unique_ptr<Tegra::DmaPusher> dma_pusher; 236 std::unique_ptr<Tegra::DmaPusher> dma_pusher;
241 std::unique_ptr<Tegra::MemoryManager> memory_manager;
242 std::unique_ptr<VideoCommon::GPUThread::ThreadManager> gpu_thread;
243
244 VideoCore::RendererBase& renderer; 237 VideoCore::RendererBase& renderer;
245 238
239private:
240 std::unique_ptr<Tegra::MemoryManager> memory_manager;
241
246 /// Mapping of command subchannels to their bound engine ids. 242 /// Mapping of command subchannels to their bound engine ids.
247 std::array<EngineID, 8> bound_engines = {}; 243 std::array<EngineID, 8> bound_engines = {};
248 244
diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp
new file mode 100644
index 000000000..ad0a747e3
--- /dev/null
+++ b/src/video_core/gpu_asynch.cpp
@@ -0,0 +1,37 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "video_core/gpu_asynch.h"
6#include "video_core/gpu_thread.h"
7#include "video_core/renderer_base.h"
8
9namespace VideoCommon {
10
11GPUAsynch::GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer)
12 : Tegra::GPU(system, renderer), gpu_thread{renderer, *dma_pusher} {}
13
14GPUAsynch::~GPUAsynch() = default;
15
16void GPUAsynch::PushGPUEntries(Tegra::CommandList&& entries) {
17 gpu_thread.SubmitList(std::move(entries));
18}
19
20void GPUAsynch::SwapBuffers(
21 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
22 gpu_thread.SwapBuffers(std::move(framebuffer));
23}
24
25void GPUAsynch::FlushRegion(VAddr addr, u64 size) {
26 gpu_thread.FlushRegion(addr, size);
27}
28
29void GPUAsynch::InvalidateRegion(VAddr addr, u64 size) {
30 gpu_thread.InvalidateRegion(addr, size);
31}
32
33void GPUAsynch::FlushAndInvalidateRegion(VAddr addr, u64 size) {
34 gpu_thread.FlushAndInvalidateRegion(addr, size);
35}
36
37} // namespace VideoCommon
diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h
new file mode 100644
index 000000000..58046f3e9
--- /dev/null
+++ b/src/video_core/gpu_asynch.h
@@ -0,0 +1,37 @@
1// Copyright 2019 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 "video_core/gpu.h"
8#include "video_core/gpu_thread.h"
9
10namespace VideoCore {
11class RendererBase;
12} // namespace VideoCore
13
14namespace VideoCommon {
15
16namespace GPUThread {
17class ThreadManager;
18} // namespace GPUThread
19
20/// Implementation of GPU interface that runs the GPU asynchronously
21class GPUAsynch : public Tegra::GPU {
22public:
23 explicit GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer);
24 ~GPUAsynch();
25
26 void PushGPUEntries(Tegra::CommandList&& entries) override;
27 void SwapBuffers(
28 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override;
29 void FlushRegion(VAddr addr, u64 size) override;
30 void InvalidateRegion(VAddr addr, u64 size) override;
31 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
32
33private:
34 GPUThread::ThreadManager gpu_thread;
35};
36
37} // namespace VideoCommon
diff --git a/src/video_core/gpu_synch.cpp b/src/video_core/gpu_synch.cpp
new file mode 100644
index 000000000..4c00b96c7
--- /dev/null
+++ b/src/video_core/gpu_synch.cpp
@@ -0,0 +1,37 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "video_core/gpu_synch.h"
6#include "video_core/renderer_base.h"
7
8namespace VideoCommon {
9
10GPUSynch::GPUSynch(Core::System& system, VideoCore::RendererBase& renderer)
11 : Tegra::GPU(system, renderer) {}
12
13GPUSynch::~GPUSynch() = default;
14
15void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) {
16 dma_pusher->Push(std::move(entries));
17 dma_pusher->DispatchCalls();
18}
19
20void GPUSynch::SwapBuffers(
21 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
22 renderer.SwapBuffers(std::move(framebuffer));
23}
24
25void GPUSynch::FlushRegion(VAddr addr, u64 size) {
26 renderer.Rasterizer().FlushRegion(addr, size);
27}
28
29void GPUSynch::InvalidateRegion(VAddr addr, u64 size) {
30 renderer.Rasterizer().InvalidateRegion(addr, size);
31}
32
33void GPUSynch::FlushAndInvalidateRegion(VAddr addr, u64 size) {
34 renderer.Rasterizer().FlushAndInvalidateRegion(addr, size);
35}
36
37} // namespace VideoCommon
diff --git a/src/video_core/gpu_synch.h b/src/video_core/gpu_synch.h
new file mode 100644
index 000000000..658f683e2
--- /dev/null
+++ b/src/video_core/gpu_synch.h
@@ -0,0 +1,29 @@
1// Copyright 2019 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 "video_core/gpu.h"
8
9namespace VideoCore {
10class RendererBase;
11} // namespace VideoCore
12
13namespace VideoCommon {
14
15/// Implementation of GPU interface that runs the GPU synchronously
16class GPUSynch : public Tegra::GPU {
17public:
18 explicit GPUSynch(Core::System& system, VideoCore::RendererBase& renderer);
19 ~GPUSynch();
20
21 void PushGPUEntries(Tegra::CommandList&& entries) override;
22 void SwapBuffers(
23 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override;
24 void FlushRegion(VAddr addr, u64 size) override;
25 void InvalidateRegion(VAddr addr, u64 size) override;
26 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
27};
28
29} // namespace VideoCommon