mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-23 14:25:37 +00:00
libretro: Better handle resolution changes
This commit is contained in:
parent
e15fafe428
commit
343e3ba3b7
|
@ -50,7 +50,15 @@ static void LibretroLogCallback(void* pUserParam, const char* channelName, const
|
||||||
|
|
||||||
LibretroHostInterface::LibretroHostInterface() = default;
|
LibretroHostInterface::LibretroHostInterface() = default;
|
||||||
|
|
||||||
LibretroHostInterface::~LibretroHostInterface() = default;
|
LibretroHostInterface::~LibretroHostInterface()
|
||||||
|
{
|
||||||
|
// should be cleaned up by the context destroy, but just in case
|
||||||
|
if (m_hw_render_display)
|
||||||
|
{
|
||||||
|
m_hw_render_display->DestroyRenderDevice();
|
||||||
|
m_hw_render_display.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LibretroHostInterface::InitLogging()
|
void LibretroHostInterface::InitLogging()
|
||||||
{
|
{
|
||||||
|
@ -682,6 +690,27 @@ static std::optional<GPURenderer> RetroHwContextToRenderer(retro_hw_context_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::optional<GPURenderer> RenderAPIToRenderer(HostDisplay::RenderAPI api)
|
||||||
|
{
|
||||||
|
switch (api)
|
||||||
|
{
|
||||||
|
case HostDisplay::RenderAPI::OpenGL:
|
||||||
|
case HostDisplay::RenderAPI::OpenGLES:
|
||||||
|
return GPURenderer::HardwareOpenGL;
|
||||||
|
|
||||||
|
case HostDisplay::RenderAPI::Vulkan:
|
||||||
|
return GPURenderer::HardwareVulkan;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
case HostDisplay::RenderAPI::D3D11:
|
||||||
|
return GPURenderer::HardwareD3D11;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool LibretroHostInterface::RequestHardwareRendererContext()
|
bool LibretroHostInterface::RequestHardwareRendererContext()
|
||||||
{
|
{
|
||||||
GPURenderer renderer = Settings::DEFAULT_GPU_RENDERER;
|
GPURenderer renderer = Settings::DEFAULT_GPU_RENDERER;
|
||||||
|
@ -757,14 +786,23 @@ void LibretroHostInterface::HardwareRendererContextReset()
|
||||||
|
|
||||||
void LibretroHostInterface::SwitchToHardwareRenderer()
|
void LibretroHostInterface::SwitchToHardwareRenderer()
|
||||||
{
|
{
|
||||||
std::optional<GPURenderer> renderer = RetroHwContextToRenderer(m_hw_render_callback.context_type);
|
// use the existing device if we just resized the window
|
||||||
|
std::optional<GPURenderer> renderer;
|
||||||
|
std::unique_ptr<HostDisplay> display = std::move(m_hw_render_display);
|
||||||
|
if (display)
|
||||||
|
{
|
||||||
|
Log_InfoPrintf("Using existing hardware display");
|
||||||
|
renderer = RenderAPIToRenderer(display->GetRenderAPI());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
renderer = RetroHwContextToRenderer(m_hw_render_callback.context_type);
|
||||||
if (!renderer.has_value())
|
if (!renderer.has_value())
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Unknown context type %u", static_cast<unsigned>(m_hw_render_callback.context_type));
|
Log_ErrorPrintf("Unknown context type %u", static_cast<unsigned>(m_hw_render_callback.context_type));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HostDisplay> display = nullptr;
|
|
||||||
switch (renderer.value())
|
switch (renderer.value())
|
||||||
{
|
{
|
||||||
case GPURenderer::HardwareOpenGL:
|
case GPURenderer::HardwareOpenGL:
|
||||||
|
@ -801,6 +839,7 @@ void LibretroHostInterface::SwitchToHardwareRenderer()
|
||||||
Log_ErrorPrintf("Failed to create hardware host display");
|
Log_ErrorPrintf("Failed to create hardware host display");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::swap(display, g_libretro_host_interface.m_display);
|
std::swap(display, g_libretro_host_interface.m_display);
|
||||||
g_libretro_host_interface.m_system->RecreateGPU(renderer.value());
|
g_libretro_host_interface.m_system->RecreateGPU(renderer.value());
|
||||||
|
@ -810,21 +849,31 @@ void LibretroHostInterface::SwitchToHardwareRenderer()
|
||||||
|
|
||||||
void LibretroHostInterface::HardwareRendererContextDestroy()
|
void LibretroHostInterface::HardwareRendererContextDestroy()
|
||||||
{
|
{
|
||||||
g_libretro_host_interface.m_hw_render_callback_valid = false;
|
|
||||||
|
|
||||||
// switch back to software
|
// switch back to software
|
||||||
if (g_libretro_host_interface.m_using_hardware_renderer)
|
if (g_libretro_host_interface.m_using_hardware_renderer)
|
||||||
{
|
{
|
||||||
Log_InfoPrintf("Lost hardware renderer context, switching to software renderer");
|
Log_InfoPrintf("Lost hardware renderer context, switching to software renderer");
|
||||||
g_libretro_host_interface.SwitchToSoftwareRenderer();
|
g_libretro_host_interface.SwitchToSoftwareRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_libretro_host_interface.m_hw_render_display)
|
||||||
|
{
|
||||||
|
g_libretro_host_interface.m_hw_render_display->DestroyRenderDevice();
|
||||||
|
g_libretro_host_interface.m_hw_render_display.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
g_libretro_host_interface.m_hw_render_callback_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibretroHostInterface::SwitchToSoftwareRenderer()
|
void LibretroHostInterface::SwitchToSoftwareRenderer()
|
||||||
{
|
{
|
||||||
std::unique_ptr<HostDisplay> display = std::make_unique<LibretroHostDisplay>();
|
// keep the hw renderer around in case we need it later
|
||||||
std::swap(display, g_libretro_host_interface.m_display);
|
if (m_using_hardware_renderer)
|
||||||
g_libretro_host_interface.m_system->RecreateGPU(GPURenderer::Software);
|
{
|
||||||
display->DestroyRenderDevice();
|
m_hw_render_display = std::move(m_display);
|
||||||
m_using_hardware_renderer = false;
|
m_using_hardware_renderer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_display = std::make_unique<LibretroHostDisplay>();
|
||||||
|
m_system->RecreateGPU(GPURenderer::Software);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ private:
|
||||||
static void HardwareRendererContextDestroy();
|
static void HardwareRendererContextDestroy();
|
||||||
|
|
||||||
retro_hw_render_callback m_hw_render_callback = {};
|
retro_hw_render_callback m_hw_render_callback = {};
|
||||||
|
std::unique_ptr<HostDisplay> m_hw_render_display;
|
||||||
bool m_hw_render_callback_valid = false;
|
bool m_hw_render_callback_valid = false;
|
||||||
bool m_using_hardware_renderer = false;
|
bool m_using_hardware_renderer = false;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue