From fca1122cefdeb3754f25aa338bcc537470030218 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 7 Jan 2019 21:42:32 -0500 Subject: core: Set is_powered_on before GPU is initialized. --- src/core/core.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/core/core.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index 6dda20faa7..11094a87a5 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -129,10 +129,12 @@ struct System::Impl { return ResultStatus::ErrorVideoCore; } + is_powered_on = true; + gpu_core = std::make_unique(system, renderer->Rasterizer()); cpu_core_manager.Initialize(system); - is_powered_on = true; + LOG_DEBUG(Core, "Initialized OK"); // Reset counters and set time origin to current frame -- cgit v1.2.3 From 1e27162275b1e69114457b03151a67d24be57838 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 7 Jan 2019 23:32:02 -0500 Subject: gpu: Refactor to take RendererBase instead of RasterizerInterface. --- src/core/core.cpp | 2 +- src/video_core/gpu.cpp | 5 +++-- src/video_core/gpu.h | 34 +++++++++++++++++++--------------- 3 files changed, 23 insertions(+), 18 deletions(-) (limited to 'src/core/core.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index 11094a87a5..9e5d167c34 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -131,7 +131,7 @@ struct System::Impl { is_powered_on = true; - gpu_core = std::make_unique(system, renderer->Rasterizer()); + gpu_core = std::make_unique(system, *renderer); cpu_core_manager.Initialize(system); diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index ac30d1a89c..08abf8ac9d 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -12,7 +12,7 @@ #include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_dma.h" #include "video_core/gpu.h" -#include "video_core/rasterizer_interface.h" +#include "video_core/renderer_base.h" namespace Tegra { @@ -28,7 +28,8 @@ u32 FramebufferConfig::BytesPerPixel(PixelFormat format) { UNREACHABLE(); } -GPU::GPU(Core::System& system, VideoCore::RasterizerInterface& rasterizer) { +GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) : renderer{renderer} { + auto& rasterizer{renderer.Rasterizer()}; memory_manager = std::make_unique(); dma_pusher = std::make_unique(*this); maxwell_3d = std::make_unique(system, rasterizer, *memory_manager); diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 6313702f27..ac7aec6a43 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -16,8 +16,8 @@ class System; } namespace VideoCore { -class RasterizerInterface; -} +class RendererBase; +} // namespace VideoCore namespace Tegra { @@ -121,7 +121,8 @@ enum class EngineID { class GPU final { public: - explicit GPU(Core::System& system, VideoCore::RasterizerInterface& rasterizer); + explicit GPU(Core::System& system, VideoCore::RendererBase& renderer); + ~GPU(); struct MethodCall { @@ -200,9 +201,24 @@ public: }; } regs{}; +private: + void ProcessBindMethod(const MethodCall& method_call); + void ProcessSemaphoreTriggerMethod(); + void ProcessSemaphoreRelease(); + void ProcessSemaphoreAcquire(); + + // Calls a GPU puller method. + void CallPullerMethod(const MethodCall& method_call); + // Calls a GPU engine method. + void CallEngineMethod(const MethodCall& method_call); + // Determines where the method should be executed. + bool ExecuteMethodOnEngine(const MethodCall& method_call); + private: std::unique_ptr dma_pusher; std::unique_ptr memory_manager; + + VideoCore::RendererBase& renderer; /// Mapping of command subchannels to their bound engine ids. std::array bound_engines = {}; @@ -217,18 +233,6 @@ private: std::unique_ptr maxwell_dma; /// Inline memory engine std::unique_ptr kepler_memory; - - void ProcessBindMethod(const MethodCall& method_call); - void ProcessSemaphoreTriggerMethod(); - void ProcessSemaphoreRelease(); - void ProcessSemaphoreAcquire(); - - // Calls a GPU puller method. - void CallPullerMethod(const MethodCall& method_call); - // Calls a GPU engine method. - void CallEngineMethod(const MethodCall& method_call); - // Determines where the method should be executed. - bool ExecuteMethodOnEngine(const MethodCall& method_call); }; #define ASSERT_REG_POSITION(field_name, position) \ -- cgit v1.2.3 From 83079031b3a65948be2a702402be21c19e912672 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 8 Feb 2019 23:21:53 -0500 Subject: gpu: Refactor a/synchronous implementations into their own classes. --- src/core/core.cpp | 9 ++++++-- src/video_core/CMakeLists.txt | 4 ++++ src/video_core/gpu.cpp | 48 ------------------------------------------- src/video_core/gpu.h | 26 ++++++++++------------- src/video_core/gpu_asynch.cpp | 37 +++++++++++++++++++++++++++++++++ src/video_core/gpu_asynch.h | 37 +++++++++++++++++++++++++++++++++ src/video_core/gpu_synch.cpp | 37 +++++++++++++++++++++++++++++++++ src/video_core/gpu_synch.h | 29 ++++++++++++++++++++++++++ 8 files changed, 162 insertions(+), 65 deletions(-) create mode 100644 src/video_core/gpu_asynch.cpp create mode 100644 src/video_core/gpu_asynch.h create mode 100644 src/video_core/gpu_synch.cpp create mode 100644 src/video_core/gpu_synch.h (limited to 'src/core/core.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index 9e5d167c34..1d83e9e118 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(system, *renderer); + if (Settings::values.use_asynchronous_gpu_emulation) { + gpu_core = std::make_unique(system, *renderer); + } else { + gpu_core = std::make_unique(system, *renderer); + } cpu_core_manager.Initialize(system); diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 3bb5d0ed7a..a4cb33c171 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 0d7a052ddd..08abf8ac9d 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(*memory_manager); maxwell_dma = std::make_unique(system, rasterizer, *memory_manager); kepler_memory = std::make_unique(system, rasterizer, *memory_manager); - - if (Settings::values.use_asynchronous_gpu_emulation) { - gpu_thread = std::make_unique(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> 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 3f3098bf16..14a421cc1e 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> framebuffer); + virtual void SwapBuffers( + std::optional> 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 dma_pusher; - std::unique_ptr memory_manager; - std::unique_ptr gpu_thread; - VideoCore::RendererBase& renderer; +private: + std::unique_ptr memory_manager; + /// Mapping of command subchannels to their bound engine ids. std::array bound_engines = {}; diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp new file mode 100644 index 0000000000..ad0a747e3b --- /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> 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 0000000000..58046f3e96 --- /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> 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 0000000000..4c00b96c71 --- /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> 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 0000000000..658f683e2b --- /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> 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 -- cgit v1.2.3