gpu: Refactor a/synchronous implementations into their own classes.
This commit is contained in:
parent
7b574f406b
commit
aaa373585c
8 changed files with 162 additions and 65 deletions
|
@ -36,7 +36,8 @@
|
||||||
#include "frontend/applets/software_keyboard.h"
|
#include "frontend/applets/software_keyboard.h"
|
||||||
#include "frontend/applets/web_browser.h"
|
#include "frontend/applets/web_browser.h"
|
||||||
#include "video_core/debug_utils/debug_utils.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/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
|
@ -131,7 +132,11 @@ struct System::Impl {
|
||||||
|
|
||||||
is_powered_on = true;
|
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);
|
cpu_core_manager.Initialize(system);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ add_library(video_core STATIC
|
||||||
engines/shader_header.h
|
engines/shader_header.h
|
||||||
gpu.cpp
|
gpu.cpp
|
||||||
gpu.h
|
gpu.h
|
||||||
|
gpu_asynch.cpp
|
||||||
|
gpu_asynch.h
|
||||||
|
gpu_synch.cpp
|
||||||
|
gpu_synch.h
|
||||||
gpu_thread.cpp
|
gpu_thread.cpp
|
||||||
gpu_thread.h
|
gpu_thread.h
|
||||||
macro_interpreter.cpp
|
macro_interpreter.cpp
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "video_core/engines/fermi_2d.h"
|
#include "video_core/engines/fermi_2d.h"
|
||||||
#include "video_core/engines/kepler_compute.h"
|
#include "video_core/engines/kepler_compute.h"
|
||||||
#include "video_core/engines/kepler_memory.h"
|
#include "video_core/engines/kepler_memory.h"
|
||||||
#include "video_core/engines/maxwell_3d.h"
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
#include "video_core/engines/maxwell_dma.h"
|
#include "video_core/engines/maxwell_dma.h"
|
||||||
#include "video_core/gpu.h"
|
#include "video_core/gpu.h"
|
||||||
#include "video_core/gpu_thread.h"
|
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
|
||||||
namespace Tegra {
|
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);
|
kepler_compute = std::make_unique<Engines::KeplerCompute>(*memory_manager);
|
||||||
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, rasterizer, *memory_manager);
|
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, rasterizer, *memory_manager);
|
||||||
kepler_memory = std::make_unique<Engines::KeplerMemory>(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;
|
GPU::~GPU() = default;
|
||||||
|
@ -71,48 +65,6 @@ const DmaPusher& GPU::DmaPusher() const {
|
||||||
return *dma_pusher;
|
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) {
|
u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
|
||||||
ASSERT(format != RenderTargetFormat::NONE);
|
ASSERT(format != RenderTargetFormat::NONE);
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,6 @@ namespace VideoCore {
|
||||||
class RendererBase;
|
class RendererBase;
|
||||||
} // namespace VideoCore
|
} // namespace VideoCore
|
||||||
|
|
||||||
namespace VideoCommon::GPUThread {
|
|
||||||
class ThreadManager;
|
|
||||||
} // namespace VideoCommon::GPUThread
|
|
||||||
|
|
||||||
namespace Tegra {
|
namespace Tegra {
|
||||||
|
|
||||||
enum class RenderTargetFormat : u32 {
|
enum class RenderTargetFormat : u32 {
|
||||||
|
@ -123,7 +119,7 @@ enum class EngineID {
|
||||||
MAXWELL_DMA_COPY_A = 0xB0B5,
|
MAXWELL_DMA_COPY_A = 0xB0B5,
|
||||||
};
|
};
|
||||||
|
|
||||||
class GPU final {
|
class GPU {
|
||||||
public:
|
public:
|
||||||
explicit GPU(Core::System& system, VideoCore::RendererBase& renderer);
|
explicit GPU(Core::System& system, VideoCore::RendererBase& renderer);
|
||||||
|
|
||||||
|
@ -206,20 +202,20 @@ public:
|
||||||
} regs{};
|
} regs{};
|
||||||
|
|
||||||
/// Push GPU command entries to be processed
|
/// Push GPU command entries to be processed
|
||||||
void PushGPUEntries(Tegra::CommandList&& entries);
|
virtual void PushGPUEntries(Tegra::CommandList&& entries) = 0;
|
||||||
|
|
||||||
/// Swap buffers (render frame)
|
/// Swap buffers (render frame)
|
||||||
void SwapBuffers(
|
virtual void SwapBuffers(
|
||||||
std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer);
|
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
|
/// 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
|
/// 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
|
/// 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:
|
private:
|
||||||
void ProcessBindMethod(const MethodCall& method_call);
|
void ProcessBindMethod(const MethodCall& method_call);
|
||||||
|
@ -236,13 +232,13 @@ private:
|
||||||
/// Determines where the method should be executed.
|
/// Determines where the method should be executed.
|
||||||
bool ExecuteMethodOnEngine(const MethodCall& method_call);
|
bool ExecuteMethodOnEngine(const MethodCall& method_call);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
std::unique_ptr<Tegra::DmaPusher> dma_pusher;
|
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;
|
VideoCore::RendererBase& renderer;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Tegra::MemoryManager> memory_manager;
|
||||||
|
|
||||||
/// Mapping of command subchannels to their bound engine ids.
|
/// Mapping of command subchannels to their bound engine ids.
|
||||||
std::array<EngineID, 8> bound_engines = {};
|
std::array<EngineID, 8> bound_engines = {};
|
||||||
|
|
||||||
|
|
37
src/video_core/gpu_asynch.cpp
Normal file
37
src/video_core/gpu_asynch.cpp
Normal file
|
@ -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
|
37
src/video_core/gpu_asynch.h
Normal file
37
src/video_core/gpu_asynch.h
Normal file
|
@ -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
|
37
src/video_core/gpu_synch.cpp
Normal file
37
src/video_core/gpu_synch.cpp
Normal file
|
@ -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
|
29
src/video_core/gpu_synch.h
Normal file
29
src/video_core/gpu_synch.h
Normal file
|
@ -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
|
Loading…
Reference in a new issue