summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2019-02-09 05:21:53 +0100
committerbunnei <bunneidev@gmail.com>2019-03-07 03:48:57 +0100
commitaaa373585cd55bd03fcc589d2ad9f749e2cb99d4 (patch)
tree1da617fd05d84d59910d585a6b01af2c89f3ed36 /src
parentgpu: Move command processing to another thread. (diff)
downloadyuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.tar
yuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.tar.gz
yuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.tar.bz2
yuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.tar.lz
yuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.tar.xz
yuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.tar.zst
yuzu-aaa373585cd55bd03fcc589d2ad9f749e2cb99d4.zip
Diffstat (limited to 'src')
-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 @@
#include "frontend/applets/software_keyboard.h"
#include "frontend/applets/web_browser.h"
#include "video_core/debug_utils/debug_utils.h"
-#include "video_core/gpu.h"
+#include "video_core/gpu_asynch.h"
+#include "video_core/gpu_synch.h"
#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
@@ -131,7 +132,11 @@ struct System::Impl {
is_powered_on = true;
- gpu_core = std::make_unique<Tegra::GPU>(system, *renderer);
+ if (Settings::values.use_asynchronous_gpu_emulation) {
+ gpu_core = std::make_unique<VideoCommon::GPUAsynch>(system, *renderer);
+ } else {
+ gpu_core = std::make_unique<VideoCommon::GPUSynch>(system, *renderer);
+ }
cpu_core_manager.Initialize(system);
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
engines/shader_header.h
gpu.cpp
gpu.h
+ gpu_asynch.cpp
+ gpu_asynch.h
+ gpu_synch.cpp
+ gpu_synch.h
gpu_thread.cpp
gpu_thread.h
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 @@
#include "core/core.h"
#include "core/core_timing.h"
#include "core/memory.h"
-#include "core/settings.h"
#include "video_core/engines/fermi_2d.h"
#include "video_core/engines/kepler_compute.h"
#include "video_core/engines/kepler_memory.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/engines/maxwell_dma.h"
#include "video_core/gpu.h"
-#include "video_core/gpu_thread.h"
#include "video_core/renderer_base.h"
namespace Tegra {
@@ -39,10 +37,6 @@ GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) : renderer{ren
kepler_compute = std::make_unique<Engines::KeplerCompute>(*memory_manager);
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, rasterizer, *memory_manager);
kepler_memory = std::make_unique<Engines::KeplerMemory>(system, rasterizer, *memory_manager);
-
- if (Settings::values.use_asynchronous_gpu_emulation) {
- gpu_thread = std::make_unique<VideoCommon::GPUThread::ThreadManager>(renderer, *dma_pusher);
- }
}
GPU::~GPU() = default;
@@ -71,48 +65,6 @@ const DmaPusher& GPU::DmaPusher() const {
return *dma_pusher;
}
-void GPU::PushGPUEntries(Tegra::CommandList&& entries) {
- if (Settings::values.use_asynchronous_gpu_emulation) {
- gpu_thread->SubmitList(std::move(entries));
- } else {
- dma_pusher->Push(std::move(entries));
- dma_pusher->DispatchCalls();
- }
-}
-
-void GPU::SwapBuffers(
- std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
- if (Settings::values.use_asynchronous_gpu_emulation) {
- gpu_thread->SwapBuffers(std::move(framebuffer));
- } else {
- renderer.SwapBuffers(std::move(framebuffer));
- }
-}
-
-void GPU::FlushRegion(VAddr addr, u64 size) {
- if (Settings::values.use_asynchronous_gpu_emulation) {
- gpu_thread->FlushRegion(addr, size);
- } else {
- renderer.Rasterizer().FlushRegion(addr, size);
- }
-}
-
-void GPU::InvalidateRegion(VAddr addr, u64 size) {
- if (Settings::values.use_asynchronous_gpu_emulation) {
- gpu_thread->InvalidateRegion(addr, size);
- } else {
- renderer.Rasterizer().InvalidateRegion(addr, size);
- }
-}
-
-void GPU::FlushAndInvalidateRegion(VAddr addr, u64 size) {
- if (Settings::values.use_asynchronous_gpu_emulation) {
- gpu_thread->FlushAndInvalidateRegion(addr, size);
- } else {
- renderer.Rasterizer().FlushAndInvalidateRegion(addr, size);
- }
-}
-
u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
ASSERT(format != RenderTargetFormat::NONE);
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 {
class RendererBase;
} // namespace VideoCore
-namespace VideoCommon::GPUThread {
-class ThreadManager;
-} // namespace VideoCommon::GPUThread
-
namespace Tegra {
enum class RenderTargetFormat : u32 {
@@ -123,7 +119,7 @@ enum class EngineID {
MAXWELL_DMA_COPY_A = 0xB0B5,
};
-class GPU final {
+class GPU {
public:
explicit GPU(Core::System& system, VideoCore::RendererBase& renderer);
@@ -206,20 +202,20 @@ public:
} regs{};
/// Push GPU command entries to be processed
- void PushGPUEntries(Tegra::CommandList&& entries);
+ virtual void PushGPUEntries(Tegra::CommandList&& entries) = 0;
/// Swap buffers (render frame)
- void SwapBuffers(
- std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer);
+ virtual void SwapBuffers(
+ std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) = 0;
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
- void FlushRegion(VAddr addr, u64 size);
+ virtual void FlushRegion(VAddr addr, u64 size) = 0;
/// Notify rasterizer that any caches of the specified region should be invalidated
- void InvalidateRegion(VAddr addr, u64 size);
+ virtual void InvalidateRegion(VAddr addr, u64 size) = 0;
/// Notify rasterizer that any caches of the specified region should be flushed and invalidated
- void FlushAndInvalidateRegion(VAddr addr, u64 size);
+ virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0;
private:
void ProcessBindMethod(const MethodCall& method_call);
@@ -236,13 +232,13 @@ private:
/// Determines where the method should be executed.
bool ExecuteMethodOnEngine(const MethodCall& method_call);
-private:
+protected:
std::unique_ptr<Tegra::DmaPusher> dma_pusher;
- std::unique_ptr<Tegra::MemoryManager> memory_manager;
- std::unique_ptr<VideoCommon::GPUThread::ThreadManager> gpu_thread;
-
VideoCore::RendererBase& renderer;
+private:
+ std::unique_ptr<Tegra::MemoryManager> memory_manager;
+
/// Mapping of command subchannels to their bound engine ids.
std::array<EngineID, 8> bound_engines = {};
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 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "video_core/gpu_asynch.h"
+#include "video_core/gpu_thread.h"
+#include "video_core/renderer_base.h"
+
+namespace VideoCommon {
+
+GPUAsynch::GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer)
+ : Tegra::GPU(system, renderer), gpu_thread{renderer, *dma_pusher} {}
+
+GPUAsynch::~GPUAsynch() = default;
+
+void GPUAsynch::PushGPUEntries(Tegra::CommandList&& entries) {
+ gpu_thread.SubmitList(std::move(entries));
+}
+
+void GPUAsynch::SwapBuffers(
+ std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
+ gpu_thread.SwapBuffers(std::move(framebuffer));
+}
+
+void GPUAsynch::FlushRegion(VAddr addr, u64 size) {
+ gpu_thread.FlushRegion(addr, size);
+}
+
+void GPUAsynch::InvalidateRegion(VAddr addr, u64 size) {
+ gpu_thread.InvalidateRegion(addr, size);
+}
+
+void GPUAsynch::FlushAndInvalidateRegion(VAddr addr, u64 size) {
+ gpu_thread.FlushAndInvalidateRegion(addr, size);
+}
+
+} // 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 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "video_core/gpu.h"
+#include "video_core/gpu_thread.h"
+
+namespace VideoCore {
+class RendererBase;
+} // namespace VideoCore
+
+namespace VideoCommon {
+
+namespace GPUThread {
+class ThreadManager;
+} // namespace GPUThread
+
+/// Implementation of GPU interface that runs the GPU asynchronously
+class GPUAsynch : public Tegra::GPU {
+public:
+ explicit GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer);
+ ~GPUAsynch();
+
+ void PushGPUEntries(Tegra::CommandList&& entries) override;
+ void SwapBuffers(
+ std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override;
+ void FlushRegion(VAddr addr, u64 size) override;
+ void InvalidateRegion(VAddr addr, u64 size) override;
+ void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
+
+private:
+ GPUThread::ThreadManager gpu_thread;
+};
+
+} // 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 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "video_core/gpu_synch.h"
+#include "video_core/renderer_base.h"
+
+namespace VideoCommon {
+
+GPUSynch::GPUSynch(Core::System& system, VideoCore::RendererBase& renderer)
+ : Tegra::GPU(system, renderer) {}
+
+GPUSynch::~GPUSynch() = default;
+
+void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) {
+ dma_pusher->Push(std::move(entries));
+ dma_pusher->DispatchCalls();
+}
+
+void GPUSynch::SwapBuffers(
+ std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
+ renderer.SwapBuffers(std::move(framebuffer));
+}
+
+void GPUSynch::FlushRegion(VAddr addr, u64 size) {
+ renderer.Rasterizer().FlushRegion(addr, size);
+}
+
+void GPUSynch::InvalidateRegion(VAddr addr, u64 size) {
+ renderer.Rasterizer().InvalidateRegion(addr, size);
+}
+
+void GPUSynch::FlushAndInvalidateRegion(VAddr addr, u64 size) {
+ renderer.Rasterizer().FlushAndInvalidateRegion(addr, size);
+}
+
+} // 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 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "video_core/gpu.h"
+
+namespace VideoCore {
+class RendererBase;
+} // namespace VideoCore
+
+namespace VideoCommon {
+
+/// Implementation of GPU interface that runs the GPU synchronously
+class GPUSynch : public Tegra::GPU {
+public:
+ explicit GPUSynch(Core::System& system, VideoCore::RendererBase& renderer);
+ ~GPUSynch();
+
+ void PushGPUEntries(Tegra::CommandList&& entries) override;
+ void SwapBuffers(
+ std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override;
+ void FlushRegion(VAddr addr, u64 size) override;
+ void InvalidateRegion(VAddr addr, u64 size) override;
+ void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
+};
+
+} // namespace VideoCommon