mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-15 02:44:41 +00:00
GPUDevice: Unload persistent libraries on shutdown
This commit is contained in:
@@ -558,6 +558,8 @@ void System::CoreThreadShutdown()
|
||||
|
||||
Achievements::Shutdown();
|
||||
|
||||
GPUDevice::UnloadDynamicLibraries();
|
||||
|
||||
InputManager::CloseSources();
|
||||
|
||||
s_state.core_thread_handle = {};
|
||||
|
||||
@@ -1394,14 +1394,11 @@ std::unique_ptr<GPUDevice> GPUDevice::CreateDeviceForAPI(RenderAPI api)
|
||||
namespace dyn_libs {
|
||||
static void CloseShaderc();
|
||||
static void CloseSpirvCross();
|
||||
static void CloseAll();
|
||||
|
||||
static std::mutex s_dyn_mutex;
|
||||
static DynamicLibrary s_shaderc_library;
|
||||
static DynamicLibrary s_spirv_cross_library;
|
||||
|
||||
static bool s_close_registered = false;
|
||||
|
||||
shaderc_compiler_t g_shaderc_compiler = nullptr;
|
||||
|
||||
// TODO: Merge all of these into a struct?
|
||||
@@ -1446,17 +1443,17 @@ bool dyn_libs::OpenShaderc(Error* error)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!s_close_registered)
|
||||
{
|
||||
s_close_registered = true;
|
||||
std::atexit(&dyn_libs::CloseAll);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dyn_libs::CloseShaderc()
|
||||
{
|
||||
if (!s_shaderc_library.IsOpen())
|
||||
{
|
||||
DebugAssert(!g_shaderc_compiler);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_shaderc_compiler)
|
||||
{
|
||||
shaderc_compiler_release(g_shaderc_compiler);
|
||||
@@ -1501,17 +1498,14 @@ bool dyn_libs::OpenSpirvCross(Error* error)
|
||||
SPIRV_CROSS_MSL_FUNCTIONS(LOAD_FUNC)
|
||||
#undef LOAD_FUNC
|
||||
|
||||
if (!s_close_registered)
|
||||
{
|
||||
s_close_registered = true;
|
||||
std::atexit(&dyn_libs::CloseAll);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dyn_libs::CloseSpirvCross()
|
||||
{
|
||||
if (!s_spirv_cross_library.IsOpen())
|
||||
return;
|
||||
|
||||
#define UNLOAD_FUNC(F) F = nullptr;
|
||||
SPIRV_CROSS_FUNCTIONS(UNLOAD_FUNC)
|
||||
SPIRV_CROSS_HLSL_FUNCTIONS(UNLOAD_FUNC)
|
||||
@@ -1521,12 +1515,6 @@ void dyn_libs::CloseSpirvCross()
|
||||
s_spirv_cross_library.Close();
|
||||
}
|
||||
|
||||
void dyn_libs::CloseAll()
|
||||
{
|
||||
CloseShaderc();
|
||||
CloseSpirvCross();
|
||||
}
|
||||
|
||||
#undef SPIRV_CROSS_HLSL_FUNCTIONS
|
||||
#undef SPIRV_CROSS_MSL_FUNCTIONS
|
||||
#undef SPIRV_CROSS_FUNCTIONS
|
||||
@@ -2106,3 +2094,15 @@ std::unique_ptr<GPUShader> GPUDevice::TranspileAndCreateShaderFromSource(
|
||||
|
||||
return CreateShaderFromSource(stage, target_language, dest_source, entry_point, out_binary, error);
|
||||
}
|
||||
|
||||
void GPUDevice::UnloadDynamicLibraries()
|
||||
{
|
||||
Assert(!g_gpu_device);
|
||||
|
||||
dyn_libs::CloseSpirvCross();
|
||||
dyn_libs::CloseShaderc();
|
||||
|
||||
#ifdef ENABLE_VULKAN
|
||||
VulkanLoader::DestroyVulkanInstance();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -868,6 +868,9 @@ public:
|
||||
ALWAYS_INLINE static Statistics& GetStatistics() { return s_stats; }
|
||||
static void ResetStatistics();
|
||||
|
||||
/// Releases dynamic libraries and other resources used by the GPU device system.
|
||||
static void UnloadDynamicLibraries();
|
||||
|
||||
protected:
|
||||
virtual bool CreateDeviceAndMainSwapChain(std::string_view adapter, CreateFlags create_flags, const WindowInfo& wi,
|
||||
GPUVSyncMode vsync_mode, bool allow_present_throttle,
|
||||
|
||||
@@ -66,8 +66,6 @@ VKAPI_ATTR static VkBool32 VKAPI_CALL DebugMessengerCallback(VkDebugUtilsMessage
|
||||
namespace {
|
||||
struct Locals
|
||||
{
|
||||
~Locals();
|
||||
|
||||
DynamicLibrary library;
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkDebugUtilsMessengerEXT debug_messenger_callback = VK_NULL_HANDLE;
|
||||
@@ -88,20 +86,6 @@ ALIGN_TO_CACHE_LINE static Locals s_locals;
|
||||
|
||||
} // namespace VulkanLoader
|
||||
|
||||
VulkanLoader::Locals::~Locals()
|
||||
{
|
||||
// Called at process shutdown.
|
||||
if (instance)
|
||||
LockedDestroyVulkanInstance();
|
||||
|
||||
#ifdef ENABLE_SDL
|
||||
if (library_loaded_from_sdl)
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
#endif
|
||||
|
||||
library.Close();
|
||||
}
|
||||
|
||||
bool VulkanLoader::LoadVulkanLibrary(WindowInfoType wtype, Error* error)
|
||||
{
|
||||
#ifdef ENABLE_SDL
|
||||
@@ -655,6 +639,14 @@ void VulkanLoader::ReleaseVulkanInstance()
|
||||
LockedReleaseVulkanInstance();
|
||||
}
|
||||
|
||||
void VulkanLoader::DestroyVulkanInstance()
|
||||
{
|
||||
const std::lock_guard lock(s_locals.mutex);
|
||||
if (s_locals.instance != VK_NULL_HANDLE)
|
||||
LockedDestroyVulkanInstance();
|
||||
UnloadVulkanLibrary();
|
||||
}
|
||||
|
||||
const VulkanLoader::OptionalExtensions& VulkanLoader::GetOptionalExtensions()
|
||||
{
|
||||
return s_locals.optional_extensions;
|
||||
|
||||
@@ -39,6 +39,9 @@ VkInstance GetVulkanInstance();
|
||||
/// Releases the shared Vulkan instance.
|
||||
void ReleaseVulkanInstance();
|
||||
|
||||
/// Destroys the instance, if any, and unloads the Vulkan library.
|
||||
void DestroyVulkanInstance();
|
||||
|
||||
/// Returns optional extensions for the current instance.
|
||||
const OptionalExtensions& GetOptionalExtensions();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user