summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/core.cpp15
-rw-r--r--src/video_core/gpu.h5
-rw-r--r--src/video_core/gpu_asynch.cpp6
-rw-r--r--src/video_core/gpu_asynch.h5
-rw-r--r--src/video_core/gpu_synch.cpp4
-rw-r--r--src/video_core/gpu_synch.h1
-rw-r--r--src/video_core/gpu_thread.cpp17
-rw-r--r--src/video_core/gpu_thread.h6
-rw-r--r--src/video_core/video_core.cpp10
-rw-r--r--src/video_core/video_core.h7
10 files changed, 51 insertions, 25 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 2b8ec3ca7..eb300eef7 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -3,9 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <array> 5#include <array>
6#include <map>
7#include <memory> 6#include <memory>
8#include <thread>
9#include <utility> 7#include <utility>
10 8
11#include "common/file_util.h" 9#include "common/file_util.h"
@@ -38,8 +36,6 @@
38#include "frontend/applets/software_keyboard.h" 36#include "frontend/applets/software_keyboard.h"
39#include "frontend/applets/web_browser.h" 37#include "frontend/applets/web_browser.h"
40#include "video_core/debug_utils/debug_utils.h" 38#include "video_core/debug_utils/debug_utils.h"
41#include "video_core/gpu_asynch.h"
42#include "video_core/gpu_synch.h"
43#include "video_core/renderer_base.h" 39#include "video_core/renderer_base.h"
44#include "video_core/video_core.h" 40#include "video_core/video_core.h"
45 41
@@ -135,13 +131,9 @@ struct System::Impl {
135 return ResultStatus::ErrorVideoCore; 131 return ResultStatus::ErrorVideoCore;
136 } 132 }
137 133
138 is_powered_on = true; 134 gpu_core = VideoCore::CreateGPU(system);
139 135
140 if (Settings::values.use_asynchronous_gpu_emulation) { 136 is_powered_on = true;
141 gpu_core = std::make_unique<VideoCommon::GPUAsynch>(system, *renderer);
142 } else {
143 gpu_core = std::make_unique<VideoCommon::GPUSynch>(system, *renderer);
144 }
145 137
146 LOG_DEBUG(Core, "Initialized OK"); 138 LOG_DEBUG(Core, "Initialized OK");
147 139
@@ -188,7 +180,8 @@ struct System::Impl {
188 } 180 }
189 181
190 // Main process has been loaded and been made current. 182 // Main process has been loaded and been made current.
191 // Begin CPU execution. 183 // Begin GPU and CPU execution.
184 gpu_core->Start();
192 cpu_core_manager.StartThreads(); 185 cpu_core_manager.StartThreads();
193 186
194 status = ResultStatus::Success; 187 status = ResultStatus::Success;
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index de30ea354..fe6628923 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -207,6 +207,11 @@ public:
207 }; 207 };
208 } regs{}; 208 } regs{};
209 209
210 /// Performs any additional setup necessary in order to begin GPU emulation.
211 /// This can be used to launch any necessary threads and register any necessary
212 /// core timing events.
213 virtual void Start() = 0;
214
210 /// Push GPU command entries to be processed 215 /// Push GPU command entries to be processed
211 virtual void PushGPUEntries(Tegra::CommandList&& entries) = 0; 216 virtual void PushGPUEntries(Tegra::CommandList&& entries) = 0;
212 217
diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp
index db507cf04..d4e2553a9 100644
--- a/src/video_core/gpu_asynch.cpp
+++ b/src/video_core/gpu_asynch.cpp
@@ -9,10 +9,14 @@
9namespace VideoCommon { 9namespace VideoCommon {
10 10
11GPUAsynch::GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer) 11GPUAsynch::GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer)
12 : Tegra::GPU(system, renderer), gpu_thread{system, renderer, *dma_pusher} {} 12 : GPU(system, renderer), gpu_thread{system} {}
13 13
14GPUAsynch::~GPUAsynch() = default; 14GPUAsynch::~GPUAsynch() = default;
15 15
16void GPUAsynch::Start() {
17 gpu_thread.StartThread(renderer, *dma_pusher);
18}
19
16void GPUAsynch::PushGPUEntries(Tegra::CommandList&& entries) { 20void GPUAsynch::PushGPUEntries(Tegra::CommandList&& entries) {
17 gpu_thread.SubmitList(std::move(entries)); 21 gpu_thread.SubmitList(std::move(entries));
18} 22}
diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h
index 1dcc61a6c..30be74cba 100644
--- a/src/video_core/gpu_asynch.h
+++ b/src/video_core/gpu_asynch.h
@@ -13,16 +13,13 @@ class RendererBase;
13 13
14namespace VideoCommon { 14namespace VideoCommon {
15 15
16namespace GPUThread {
17class ThreadManager;
18} // namespace GPUThread
19
20/// Implementation of GPU interface that runs the GPU asynchronously 16/// Implementation of GPU interface that runs the GPU asynchronously
21class GPUAsynch : public Tegra::GPU { 17class GPUAsynch : public Tegra::GPU {
22public: 18public:
23 explicit GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer); 19 explicit GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer);
24 ~GPUAsynch() override; 20 ~GPUAsynch() override;
25 21
22 void Start() override;
26 void PushGPUEntries(Tegra::CommandList&& entries) override; 23 void PushGPUEntries(Tegra::CommandList&& entries) override;
27 void SwapBuffers( 24 void SwapBuffers(
28 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override; 25 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override;
diff --git a/src/video_core/gpu_synch.cpp b/src/video_core/gpu_synch.cpp
index 2cfc900ed..45e43b1dc 100644
--- a/src/video_core/gpu_synch.cpp
+++ b/src/video_core/gpu_synch.cpp
@@ -8,10 +8,12 @@
8namespace VideoCommon { 8namespace VideoCommon {
9 9
10GPUSynch::GPUSynch(Core::System& system, VideoCore::RendererBase& renderer) 10GPUSynch::GPUSynch(Core::System& system, VideoCore::RendererBase& renderer)
11 : Tegra::GPU(system, renderer) {} 11 : GPU(system, renderer) {}
12 12
13GPUSynch::~GPUSynch() = default; 13GPUSynch::~GPUSynch() = default;
14 14
15void GPUSynch::Start() {}
16
15void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) { 17void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) {
16 dma_pusher->Push(std::move(entries)); 18 dma_pusher->Push(std::move(entries));
17 dma_pusher->DispatchCalls(); 19 dma_pusher->DispatchCalls();
diff --git a/src/video_core/gpu_synch.h b/src/video_core/gpu_synch.h
index 766b5631c..3031fcf72 100644
--- a/src/video_core/gpu_synch.h
+++ b/src/video_core/gpu_synch.h
@@ -18,6 +18,7 @@ public:
18 explicit GPUSynch(Core::System& system, VideoCore::RendererBase& renderer); 18 explicit GPUSynch(Core::System& system, VideoCore::RendererBase& renderer);
19 ~GPUSynch() override; 19 ~GPUSynch() override;
20 20
21 void Start() override;
21 void PushGPUEntries(Tegra::CommandList&& entries) override; 22 void PushGPUEntries(Tegra::CommandList&& entries) override;
22 void SwapBuffers( 23 void SwapBuffers(
23 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override; 24 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override;
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index cc56cf467..c9a2077de 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -55,19 +55,24 @@ static void RunThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_p
55 } 55 }
56} 56}
57 57
58ThreadManager::ThreadManager(Core::System& system, VideoCore::RendererBase& renderer, 58ThreadManager::ThreadManager(Core::System& system) : system{system} {}
59 Tegra::DmaPusher& dma_pusher)
60 : system{system}, thread{RunThread, std::ref(renderer), std::ref(dma_pusher), std::ref(state)} {
61 synchronization_event = system.CoreTiming().RegisterEvent(
62 "GPUThreadSynch", [this](u64 fence, s64) { state.WaitForSynchronization(fence); });
63}
64 59
65ThreadManager::~ThreadManager() { 60ThreadManager::~ThreadManager() {
61 if (!thread.joinable()) {
62 return;
63 }
64
66 // Notify GPU thread that a shutdown is pending 65 // Notify GPU thread that a shutdown is pending
67 PushCommand(EndProcessingCommand()); 66 PushCommand(EndProcessingCommand());
68 thread.join(); 67 thread.join();
69} 68}
70 69
70void ThreadManager::StartThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_pusher) {
71 thread = std::thread{RunThread, std::ref(renderer), std::ref(dma_pusher), std::ref(state)};
72 synchronization_event = system.CoreTiming().RegisterEvent(
73 "GPUThreadSynch", [this](u64 fence, s64) { state.WaitForSynchronization(fence); });
74}
75
71void ThreadManager::SubmitList(Tegra::CommandList&& entries) { 76void ThreadManager::SubmitList(Tegra::CommandList&& entries) {
72 const u64 fence{PushCommand(SubmitListCommand(std::move(entries)))}; 77 const u64 fence{PushCommand(SubmitListCommand(std::move(entries)))};
73 const s64 synchronization_ticks{Core::Timing::usToCycles(9000)}; 78 const s64 synchronization_ticks{Core::Timing::usToCycles(9000)};
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h
index 62bcea5bb..cc14527c7 100644
--- a/src/video_core/gpu_thread.h
+++ b/src/video_core/gpu_thread.h
@@ -138,10 +138,12 @@ struct SynchState final {
138/// Class used to manage the GPU thread 138/// Class used to manage the GPU thread
139class ThreadManager final { 139class ThreadManager final {
140public: 140public:
141 explicit ThreadManager(Core::System& system, VideoCore::RendererBase& renderer, 141 explicit ThreadManager(Core::System& system);
142 Tegra::DmaPusher& dma_pusher);
143 ~ThreadManager(); 142 ~ThreadManager();
144 143
144 /// Creates and starts the GPU thread.
145 void StartThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_pusher);
146
145 /// Push GPU command entries to be processed 147 /// Push GPU command entries to be processed
146 void SubmitList(Tegra::CommandList&& entries); 148 void SubmitList(Tegra::CommandList&& entries);
147 149
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index cb82ecf3f..60cda0ca3 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -5,6 +5,8 @@
5#include <memory> 5#include <memory>
6#include "core/core.h" 6#include "core/core.h"
7#include "core/settings.h" 7#include "core/settings.h"
8#include "video_core/gpu_asynch.h"
9#include "video_core/gpu_synch.h"
8#include "video_core/renderer_base.h" 10#include "video_core/renderer_base.h"
9#include "video_core/renderer_opengl/renderer_opengl.h" 11#include "video_core/renderer_opengl/renderer_opengl.h"
10#include "video_core/video_core.h" 12#include "video_core/video_core.h"
@@ -16,6 +18,14 @@ std::unique_ptr<RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_wind
16 return std::make_unique<OpenGL::RendererOpenGL>(emu_window, system); 18 return std::make_unique<OpenGL::RendererOpenGL>(emu_window, system);
17} 19}
18 20
21std::unique_ptr<Tegra::GPU> CreateGPU(Core::System& system) {
22 if (Settings::values.use_asynchronous_gpu_emulation) {
23 return std::make_unique<VideoCommon::GPUAsynch>(system, system.Renderer());
24 }
25
26 return std::make_unique<VideoCommon::GPUSynch>(system, system.Renderer());
27}
28
19u16 GetResolutionScaleFactor(const RendererBase& renderer) { 29u16 GetResolutionScaleFactor(const RendererBase& renderer) {
20 return static_cast<u16>( 30 return static_cast<u16>(
21 Settings::values.resolution_factor 31 Settings::values.resolution_factor
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h
index 3c583f195..b8e0ac372 100644
--- a/src/video_core/video_core.h
+++ b/src/video_core/video_core.h
@@ -14,6 +14,10 @@ namespace Core::Frontend {
14class EmuWindow; 14class EmuWindow;
15} 15}
16 16
17namespace Tegra {
18class GPU;
19}
20
17namespace VideoCore { 21namespace VideoCore {
18 22
19class RendererBase; 23class RendererBase;
@@ -27,6 +31,9 @@ class RendererBase;
27std::unique_ptr<RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window, 31std::unique_ptr<RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window,
28 Core::System& system); 32 Core::System& system);
29 33
34/// Creates an emulated GPU instance using the given system context.
35std::unique_ptr<Tegra::GPU> CreateGPU(Core::System& system);
36
30u16 GetResolutionScaleFactor(const RendererBase& renderer); 37u16 GetResolutionScaleFactor(const RendererBase& renderer);
31 38
32} // namespace VideoCore 39} // namespace VideoCore