diff --git a/libretro/LibretroD3D11Context.cpp b/libretro/LibretroD3D11Context.cpp index c6bcfe459e..062e18dfe1 100644 --- a/libretro/LibretroD3D11Context.cpp +++ b/libretro/LibretroD3D11Context.cpp @@ -9,7 +9,7 @@ #endif bool LibretroD3D11Context::Init() { - if (!LibretroHWRenderContext::Init()) + if (!LibretroHWRenderContext::Init(true)) return false; g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11; @@ -43,15 +43,6 @@ void LibretroD3D11Context::DestroyDrawContext() { d3d11_ = nullptr; } -void LibretroD3D11Context::ContextDestroy() -{ - LibretroHWRenderContext::ContextDestroy(); -#if 0 - // this should be enabled once DeviceLost/DeviceRestore can fully switch to a new draw context. - DestroyDrawContext(); -#endif -} - void LibretroD3D11Context::GotBackbuffer() { D3D11_TEXTURE2D_DESC desc{}; desc.Width = PSP_CoreParameter().pixelWidth; diff --git a/libretro/LibretroD3D11Context.h b/libretro/LibretroD3D11Context.h index 435c11b4aa..733772ca0a 100644 --- a/libretro/LibretroD3D11Context.h +++ b/libretro/LibretroD3D11Context.h @@ -15,8 +15,6 @@ class LibretroD3D11Context : public LibretroHWRenderContext { void CreateDrawContext() override; void DestroyDrawContext() override; - void ContextDestroy() override; - GPUCore GetGPUCore() override { return GPUCORE_DIRECTX11; } const char *Ident() override { return "DirectX 11"; } private: diff --git a/libretro/LibretroGLContext.cpp b/libretro/LibretroGLContext.cpp index 2da61ce3a9..15f3b98f63 100644 --- a/libretro/LibretroGLContext.cpp +++ b/libretro/LibretroGLContext.cpp @@ -8,21 +8,13 @@ bool LibretroGLContext::Init() { - if (!LibretroHWRenderContext::Init()) + if (!LibretroHWRenderContext::Init(true)) return false; - libretro_get_proc_address = hw_render_.get_proc_address; - g_Config.iGPUBackend = (int)GPUBackend::OPENGL; return true; } -void LibretroGLContext::Shutdown() -{ - LibretroGraphicsContext::Shutdown(); - libretro_get_proc_address = nullptr; -} - void LibretroGLContext::CreateDrawContext() { if (!glewInitDone) @@ -40,6 +32,7 @@ void LibretroGLContext::CreateDrawContext() draw_ = Draw::T3DCreateGLContext(); renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); } + void LibretroGLContext::DestroyDrawContext() { LibretroHWRenderContext::DestroyDrawContext(); diff --git a/libretro/LibretroGLContext.h b/libretro/LibretroGLContext.h index 93ec05a618..f059041faa 100644 --- a/libretro/LibretroGLContext.h +++ b/libretro/LibretroGLContext.h @@ -20,7 +20,6 @@ class LibretroGLContext : public LibretroHWRenderContext { } bool Init() override; - void Shutdown() override; void CreateDrawContext() override; void DestroyDrawContext() override; void SetRenderTarget() override diff --git a/libretro/LibretroGraphicsContext.cpp b/libretro/LibretroGraphicsContext.cpp index 8245febb81..438e6ad448 100644 --- a/libretro/LibretroGraphicsContext.cpp +++ b/libretro/LibretroGraphicsContext.cpp @@ -1,7 +1,7 @@ -#include "libretro/libretro.h" #include "libretro/LibretroGraphicsContext.h" #include "libretro/LibretroGLContext.h" +#include "libretro/libretro.h" #ifndef NO_VULKAN #include "libretro/LibretroVulkanContext.h" #endif @@ -15,13 +15,15 @@ #include "GPU/GPUInterface.h" retro_video_refresh_t LibretroGraphicsContext::video_cb; -retro_hw_get_proc_address_t libretro_get_proc_address; void retro_set_video_refresh(retro_video_refresh_t cb) { LibretroGraphicsContext::video_cb = cb; } static void context_reset() { ((LibretroHWRenderContext *)Libretro::ctx)->ContextReset(); } static void context_destroy() { ((LibretroHWRenderContext *)Libretro::ctx)->ContextDestroy(); } -bool LibretroHWRenderContext::Init() { return Libretro::environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render_); } +bool LibretroHWRenderContext::Init(bool cache_context) { + hw_render_.cache_context = cache_context; + return Libretro::environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render_); +} LibretroHWRenderContext::LibretroHWRenderContext(retro_hw_context_type context_type, unsigned version_major, unsigned version_minor) { @@ -39,7 +41,7 @@ void LibretroHWRenderContext::ContextReset() // needed to restart the thread // TODO: find a way to move this to ContextDestroy. - if (Libretro::useEmuThread && draw_ && Libretro::emuThreadState != Libretro::EmuThreadState::PAUSED) + if (!hw_render_.cache_context && Libretro::useEmuThread && draw_ && Libretro::emuThreadState != Libretro::EmuThreadState::PAUSED) DestroyDrawContext(); if (!draw_) @@ -70,7 +72,11 @@ void LibretroHWRenderContext::ContextDestroy() } LostBackbuffer(); + gpu->DeviceLost(); + + if(!hw_render_.cache_context && !Libretro::useEmuThread) + Shutdown(); } void LibretroGraphicsContext::GotBackbuffer() diff --git a/libretro/LibretroGraphicsContext.h b/libretro/LibretroGraphicsContext.h index 413643c008..b0c2025e54 100644 --- a/libretro/LibretroGraphicsContext.h +++ b/libretro/LibretroGraphicsContext.h @@ -50,7 +50,7 @@ class LibretroGraphicsContext : public GraphicsContext { class LibretroHWRenderContext : public LibretroGraphicsContext { public: LibretroHWRenderContext(retro_hw_context_type context_type, unsigned version_major = 0, unsigned version_minor = 0); - bool Init() override; + bool Init(bool cache_context); void SetRenderTarget() override {} void SwapBuffers() override { @@ -66,8 +66,6 @@ class LibretroHWRenderContext : public LibretroGraphicsContext { retro_hw_render_callback hw_render_ = {}; }; -extern "C" retro_hw_get_proc_address_t libretro_get_proc_address; - #ifdef _WIN32 class LibretroD3D9Context : public LibretroHWRenderContext { public: diff --git a/libretro/LibretroVulkanContext.cpp b/libretro/LibretroVulkanContext.cpp index b058bec3f5..b9f0f97aa6 100644 --- a/libretro/LibretroVulkanContext.cpp +++ b/libretro/LibretroVulkanContext.cpp @@ -19,6 +19,9 @@ void vk_libretro_shutdown(); void vk_libretro_set_hwrender_interface(retro_hw_render_interface *hw_render_interface); void vk_libretro_wait_for_presentation(); +LibretroVulkanContext::LibretroVulkanContext() + : LibretroHWRenderContext(RETRO_HW_CONTEXT_VULKAN, VK_MAKE_VERSION(1, 0, 18)) {} + void LibretroVulkanContext::SwapBuffers() { vk_libretro_wait_for_presentation(); @@ -76,22 +79,6 @@ static bool create_device(retro_vulkan_context *context, VkInstance instance, Vk return true; } -static void destroy_device(void) -{ - if (!vk) - return; - - PSP_CoreParameter().graphicsContext->Shutdown(); -} - -void LibretroVulkanContext::ContextDestroy() -{ - LibretroHWRenderContext::ContextDestroy(); - - // temporary workaround, destroy_device is currently being called too late/never - destroy_device(); -} - static const VkApplicationInfo *GetApplicationInfo(void) { static VkApplicationInfo app_info{ VK_STRUCTURE_TYPE_APPLICATION_INFO }; @@ -105,7 +92,7 @@ static const VkApplicationInfo *GetApplicationInfo(void) bool LibretroVulkanContext::Init() { - if (!LibretroHWRenderContext::Init()) + if (!LibretroHWRenderContext::Init(false)) return false; static const struct retro_hw_render_context_negotiation_interface_vulkan iface = { RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN, RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION, GetApplicationInfo, create_device, nullptr }; @@ -119,6 +106,9 @@ void LibretroVulkanContext::Shutdown() { LibretroHWRenderContext::Shutdown(); + if (!vk) + return; + vk->WaitUntilQueueIdle(); vk->DestroyObjects(); diff --git a/libretro/LibretroVulkanContext.h b/libretro/LibretroVulkanContext.h index 94c1df8fef..93188e764d 100644 --- a/libretro/LibretroVulkanContext.h +++ b/libretro/LibretroVulkanContext.h @@ -1,16 +1,14 @@ #pragma once -#include "Common/Vulkan/VulkanLoader.h" #include "libretro/LibretroGraphicsContext.h" class LibretroVulkanContext : public LibretroHWRenderContext { public: - LibretroVulkanContext() : LibretroHWRenderContext(RETRO_HW_CONTEXT_VULKAN, VK_MAKE_VERSION(1, 0, 18)) {} + LibretroVulkanContext(); ~LibretroVulkanContext() override {} bool Init() override; void Shutdown() override; void SwapBuffers() override; - void ContextDestroy() override; void *GetAPIContext() override; void CreateDrawContext() override;