HostInterface: Add function to switch between sw/hw rendering
This commit is contained in:
parent
f2231d6669
commit
4a3478b360
|
@ -105,6 +105,8 @@ public:
|
|||
GPU();
|
||||
virtual ~GPU();
|
||||
|
||||
virtual bool IsHardwareRenderer() const = 0;
|
||||
|
||||
virtual bool Initialize(HostDisplay* host_display, System* system, DMA* dma,
|
||||
InterruptController* interrupt_controller, Timers* timers);
|
||||
virtual void Reset();
|
||||
|
|
|
@ -15,6 +15,11 @@ GPU_HW::GPU_HW() : GPU()
|
|||
|
||||
GPU_HW::~GPU_HW() = default;
|
||||
|
||||
bool GPU_HW::IsHardwareRenderer() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPU_HW::Initialize(HostDisplay* host_display, System* system, DMA* dma, InterruptController* interrupt_controller,
|
||||
Timers* timers)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,8 @@ public:
|
|||
GPU_HW();
|
||||
virtual ~GPU_HW();
|
||||
|
||||
virtual bool IsHardwareRenderer() const override;
|
||||
|
||||
virtual bool Initialize(HostDisplay* host_display, System* system, DMA* dma,
|
||||
InterruptController* interrupt_controller, Timers* timers) override;
|
||||
virtual void Reset() override;
|
||||
|
|
|
@ -15,6 +15,11 @@ GPU_SW::~GPU_SW()
|
|||
m_host_display->SetDisplayTexture(nullptr, 0, 0, 0, 0, 0, 0, 1.0f);
|
||||
}
|
||||
|
||||
bool GPU_SW::IsHardwareRenderer() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GPU_SW::Initialize(HostDisplay* host_display, System* system, DMA* dma, InterruptController* interrupt_controller,
|
||||
Timers* timers)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@ public:
|
|||
GPU_SW();
|
||||
~GPU_SW() override;
|
||||
|
||||
bool IsHardwareRenderer() const override;
|
||||
|
||||
bool Initialize(HostDisplay* host_display, System* system, DMA* dma, InterruptController* interrupt_controller,
|
||||
Timers* timers) override;
|
||||
void Reset() override;
|
||||
|
|
|
@ -515,7 +515,6 @@ std::string HostInterface::GetGameListDatabaseFileName() const
|
|||
|
||||
void HostInterface::UpdateSettings(const std::function<void()>& apply_callback)
|
||||
{
|
||||
// TODO: Should we move this to the base class?
|
||||
const GPURenderer old_gpu_renderer = m_settings.gpu_renderer;
|
||||
const u32 old_gpu_resolution_scale = m_settings.gpu_resolution_scale;
|
||||
const bool old_gpu_true_color = m_settings.gpu_true_color;
|
||||
|
@ -528,7 +527,6 @@ void HostInterface::UpdateSettings(const std::function<void()>& apply_callback)
|
|||
|
||||
apply_callback();
|
||||
|
||||
// TODO: Fast path for hardware->software switches
|
||||
if (m_settings.gpu_renderer != old_gpu_renderer)
|
||||
SwitchGPURenderer();
|
||||
|
||||
|
@ -549,6 +547,18 @@ void HostInterface::UpdateSettings(const std::function<void()>& apply_callback)
|
|||
m_display->SetDisplayLinearFiltering(m_settings.display_linear_filtering);
|
||||
}
|
||||
|
||||
void HostInterface::ToggleSoftwareRendering()
|
||||
{
|
||||
if (!m_system || m_settings.gpu_renderer == GPURenderer::Software)
|
||||
return;
|
||||
|
||||
const GPURenderer new_renderer =
|
||||
m_system->GetGPU()->IsHardwareRenderer() ? GPURenderer::Software : m_settings.gpu_renderer;
|
||||
|
||||
AddFormattedOSDMessage(2.0f, "Switching to %s renderer...", Settings::GetRendererDisplayName(new_renderer));
|
||||
m_system->RecreateGPU(new_renderer);
|
||||
}
|
||||
|
||||
void HostInterface::RunFrame()
|
||||
{
|
||||
m_frame_timer.Reset();
|
||||
|
|
|
@ -104,8 +104,13 @@ protected:
|
|||
/// Returns the path of the game database cache file.
|
||||
std::string GetGameListDatabaseFileName() const;
|
||||
|
||||
/// Applies new settings, updating internal state as needed. apply_callback should call m_settings.Load() after
|
||||
/// locking any required mutexes.
|
||||
void UpdateSettings(const std::function<void()>& apply_callback);
|
||||
|
||||
/// Quick switch between software and hardware rendering.
|
||||
void ToggleSoftwareRendering();
|
||||
|
||||
void RunFrame();
|
||||
|
||||
/// Throttles the system, i.e. sleeps until it's time to execute the next frame.
|
||||
|
|
|
@ -36,8 +36,8 @@ System::System(HostInterface* host_interface) : m_host_interface(host_interface)
|
|||
m_spu = std::make_unique<SPU>();
|
||||
m_mdec = std::make_unique<MDEC>();
|
||||
m_sio = std::make_unique<SIO>();
|
||||
m_region = host_interface->GetSettings().region;
|
||||
m_cpu_execution_mode = host_interface->GetSettings().cpu_execution_mode;
|
||||
m_region = host_interface->m_settings.region;
|
||||
m_cpu_execution_mode = host_interface->m_settings.cpu_execution_mode;
|
||||
}
|
||||
|
||||
System::~System() = default;
|
||||
|
@ -45,13 +45,13 @@ System::~System() = default;
|
|||
std::unique_ptr<System> System::Create(HostInterface* host_interface)
|
||||
{
|
||||
std::unique_ptr<System> system(new System(host_interface));
|
||||
if (!system->CreateGPU())
|
||||
if (!system->CreateGPU(host_interface->m_settings.gpu_renderer))
|
||||
return {};
|
||||
|
||||
return system;
|
||||
}
|
||||
|
||||
bool System::RecreateGPU()
|
||||
bool System::RecreateGPU(GPURenderer renderer)
|
||||
{
|
||||
// save current state
|
||||
std::unique_ptr<ByteStream> state_stream = ByteStream_CreateGrowableMemoryStream();
|
||||
|
@ -62,7 +62,7 @@ bool System::RecreateGPU()
|
|||
|
||||
// create new renderer
|
||||
m_gpu.reset();
|
||||
if (!CreateGPU())
|
||||
if (!CreateGPU(renderer))
|
||||
{
|
||||
Panic("Failed to recreate GPU");
|
||||
return false;
|
||||
|
@ -193,9 +193,9 @@ void System::InitializeComponents()
|
|||
m_mdec->Initialize(this, m_dma.get());
|
||||
}
|
||||
|
||||
bool System::CreateGPU()
|
||||
bool System::CreateGPU(GPURenderer renderer)
|
||||
{
|
||||
switch (m_host_interface->GetSettings().gpu_renderer)
|
||||
switch (renderer)
|
||||
{
|
||||
case GPURenderer::HardwareOpenGL:
|
||||
m_gpu = m_host_interface->GetDisplay()->GetRenderAPI() == HostDisplay::RenderAPI::OpenGLES ?
|
||||
|
@ -220,7 +220,6 @@ bool System::CreateGPU()
|
|||
{
|
||||
Log_ErrorPrintf("Failed to initialize GPU, falling back to software");
|
||||
m_gpu.reset();
|
||||
m_host_interface->GetSettings().gpu_renderer = GPURenderer::Software;
|
||||
m_gpu = GPU::CreateSoftwareRenderer();
|
||||
if (!m_gpu->Initialize(m_host_interface->GetDisplay(), this, m_dma.get(), m_interrupt_controller.get(),
|
||||
m_timers.get()))
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
bool SaveState(ByteStream* state);
|
||||
|
||||
/// Recreates the GPU component, saving/loading the state so it is preserved. Call when the GPU renderer changes.
|
||||
bool RecreateGPU();
|
||||
bool RecreateGPU(GPURenderer renderer);
|
||||
|
||||
/// Updates GPU settings, without recreating the renderer.
|
||||
void UpdateGPUSettings();
|
||||
|
@ -98,7 +98,7 @@ private:
|
|||
System(HostInterface* host_interface);
|
||||
|
||||
bool DoState(StateWrapper& sw);
|
||||
bool CreateGPU();
|
||||
bool CreateGPU(GPURenderer renderer);
|
||||
|
||||
void InitializeComponents();
|
||||
|
||||
|
|
|
@ -419,7 +419,7 @@ void SDLHostInterface::HandleSDLKeyEvent(const SDL_Event* event)
|
|||
|
||||
case SDL_SCANCODE_END: {
|
||||
if (pressed)
|
||||
DoToggleSoftwareRendering();
|
||||
ToggleSoftwareRendering();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1549,31 +1549,6 @@ void SDLHostInterface::DoFrameStep()
|
|||
m_paused = false;
|
||||
}
|
||||
|
||||
void SDLHostInterface::DoToggleSoftwareRendering()
|
||||
{
|
||||
if (!m_system)
|
||||
return;
|
||||
|
||||
if (m_settings.gpu_renderer != GPURenderer::Software)
|
||||
{
|
||||
m_settings.gpu_renderer = GPURenderer::Software;
|
||||
AddOSDMessage("Switched to software GPU renderer.");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WIN32
|
||||
m_settings.gpu_renderer = m_display->GetRenderAPI() == HostDisplay::RenderAPI::D3D11 ? GPURenderer::HardwareD3D11 :
|
||||
GPURenderer::HardwareOpenGL;
|
||||
#else
|
||||
m_settings.gpu_renderer = GPURenderer::HardwareOpenGL;
|
||||
#endif
|
||||
|
||||
AddOSDMessage("Switched to hardware GPU renderer.");
|
||||
}
|
||||
|
||||
m_system->RecreateGPU();
|
||||
}
|
||||
|
||||
void SDLHostInterface::DoToggleFullscreen()
|
||||
{
|
||||
m_settings.display_fullscreen = !m_settings.display_fullscreen;
|
||||
|
|
|
@ -99,7 +99,6 @@ private:
|
|||
void DoSaveState(u32 index);
|
||||
void DoTogglePause();
|
||||
void DoFrameStep();
|
||||
void DoToggleSoftwareRendering();
|
||||
void DoToggleFullscreen();
|
||||
void DoModifyInternalResolution(s32 increment);
|
||||
|
||||
|
|
Loading…
Reference in New Issue