diff options
| author | 2019-02-08 23:21:53 -0500 | |
|---|---|---|
| committer | 2019-03-06 21:48:57 -0500 | |
| commit | aaa373585cd55bd03fcc589d2ad9f749e2cb99d4 (patch) | |
| tree | 1da617fd05d84d59910d585a6b01af2c89f3ed36 | |
| parent | gpu: Move command processing to another thread. (diff) | |
| download | yuzu-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.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 48 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 26 | ||||
| -rw-r--r-- | src/video_core/gpu_asynch.cpp | 37 | ||||
| -rw-r--r-- | src/video_core/gpu_asynch.h | 37 | ||||
| -rw-r--r-- | src/video_core/gpu_synch.cpp | 37 | ||||
| -rw-r--r-- | src/video_core/gpu_synch.h | 29 |
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 | ||
| 19 | namespace Tegra { | 17 | namespace 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 | ||
| 48 | GPU::~GPU() = default; | 42 | GPU::~GPU() = default; |
| @@ -71,48 +65,6 @@ const DmaPusher& GPU::DmaPusher() const { | |||
| 71 | return *dma_pusher; | 65 | return *dma_pusher; |
| 72 | } | 66 | } |
| 73 | 67 | ||
| 74 | void 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 | |||
| 83 | void 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 | |||
| 92 | void 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 | |||
| 100 | void 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 | |||
| 108 | void 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 | |||
| 116 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { | 68 | u32 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 { | |||
| 19 | class RendererBase; | 19 | class RendererBase; |
| 20 | } // namespace VideoCore | 20 | } // namespace VideoCore |
| 21 | 21 | ||
| 22 | namespace VideoCommon::GPUThread { | ||
| 23 | class ThreadManager; | ||
| 24 | } // namespace VideoCommon::GPUThread | ||
| 25 | |||
| 26 | namespace Tegra { | 22 | namespace Tegra { |
| 27 | 23 | ||
| 28 | enum class RenderTargetFormat : u32 { | 24 | enum 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 | ||
| 126 | class GPU final { | 122 | class GPU { |
| 127 | public: | 123 | public: |
| 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 | ||
| 224 | private: | 220 | private: |
| 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 | ||
| 239 | private: | 235 | protected: |
| 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 | ||
| 239 | private: | ||
| 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 | |||
| 9 | namespace VideoCommon { | ||
| 10 | |||
| 11 | GPUAsynch::GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer) | ||
| 12 | : Tegra::GPU(system, renderer), gpu_thread{renderer, *dma_pusher} {} | ||
| 13 | |||
| 14 | GPUAsynch::~GPUAsynch() = default; | ||
| 15 | |||
| 16 | void GPUAsynch::PushGPUEntries(Tegra::CommandList&& entries) { | ||
| 17 | gpu_thread.SubmitList(std::move(entries)); | ||
| 18 | } | ||
| 19 | |||
| 20 | void GPUAsynch::SwapBuffers( | ||
| 21 | std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) { | ||
| 22 | gpu_thread.SwapBuffers(std::move(framebuffer)); | ||
| 23 | } | ||
| 24 | |||
| 25 | void GPUAsynch::FlushRegion(VAddr addr, u64 size) { | ||
| 26 | gpu_thread.FlushRegion(addr, size); | ||
| 27 | } | ||
| 28 | |||
| 29 | void GPUAsynch::InvalidateRegion(VAddr addr, u64 size) { | ||
| 30 | gpu_thread.InvalidateRegion(addr, size); | ||
| 31 | } | ||
| 32 | |||
| 33 | void 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 | |||
| 10 | namespace VideoCore { | ||
| 11 | class RendererBase; | ||
| 12 | } // namespace VideoCore | ||
| 13 | |||
| 14 | namespace VideoCommon { | ||
| 15 | |||
| 16 | namespace GPUThread { | ||
| 17 | class ThreadManager; | ||
| 18 | } // namespace GPUThread | ||
| 19 | |||
| 20 | /// Implementation of GPU interface that runs the GPU asynchronously | ||
| 21 | class GPUAsynch : public Tegra::GPU { | ||
| 22 | public: | ||
| 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 | |||
| 33 | private: | ||
| 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 | |||
| 8 | namespace VideoCommon { | ||
| 9 | |||
| 10 | GPUSynch::GPUSynch(Core::System& system, VideoCore::RendererBase& renderer) | ||
| 11 | : Tegra::GPU(system, renderer) {} | ||
| 12 | |||
| 13 | GPUSynch::~GPUSynch() = default; | ||
| 14 | |||
| 15 | void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) { | ||
| 16 | dma_pusher->Push(std::move(entries)); | ||
| 17 | dma_pusher->DispatchCalls(); | ||
| 18 | } | ||
| 19 | |||
| 20 | void GPUSynch::SwapBuffers( | ||
| 21 | std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) { | ||
| 22 | renderer.SwapBuffers(std::move(framebuffer)); | ||
| 23 | } | ||
| 24 | |||
| 25 | void GPUSynch::FlushRegion(VAddr addr, u64 size) { | ||
| 26 | renderer.Rasterizer().FlushRegion(addr, size); | ||
| 27 | } | ||
| 28 | |||
| 29 | void GPUSynch::InvalidateRegion(VAddr addr, u64 size) { | ||
| 30 | renderer.Rasterizer().InvalidateRegion(addr, size); | ||
| 31 | } | ||
| 32 | |||
| 33 | void 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 | |||
| 9 | namespace VideoCore { | ||
| 10 | class RendererBase; | ||
| 11 | } // namespace VideoCore | ||
| 12 | |||
| 13 | namespace VideoCommon { | ||
| 14 | |||
| 15 | /// Implementation of GPU interface that runs the GPU synchronously | ||
| 16 | class GPUSynch : public Tegra::GPU { | ||
| 17 | public: | ||
| 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 | ||