diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 61ab1f9062..4c8433e7dd 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -464,11 +464,7 @@ static void EmuThread(std::unique_ptr boot) PanicAlert("Failed to initialize video backend!"); return; } - g_video_backend->Video_Prepare(); - Common::ScopeGuard video_guard{[] { - g_video_backend->Video_Cleanup(); - g_video_backend->Shutdown(); - }}; + Common::ScopeGuard video_guard{[] { g_video_backend->Shutdown(); }}; if (cpu_info.HTT) SConfig::GetInstance().bDSPThread = cpu_info.num_cores > 4; diff --git a/Source/Core/VideoBackends/D3D/VideoBackend.h b/Source/Core/VideoBackends/D3D/VideoBackend.h index 81aa79417b..97870ffdea 100644 --- a/Source/Core/VideoBackends/D3D/VideoBackend.h +++ b/Source/Core/VideoBackends/D3D/VideoBackend.h @@ -17,13 +17,8 @@ class VideoBackend : public VideoBackendBase std::string GetName() const override; std::string GetDisplayName() const override; - void Video_Prepare() override; - void Video_Cleanup() override; - void InitBackendInfo() override; unsigned int PeekMessages() override; - - void* m_window_handle; }; } diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp index 26a8c4dcfd..3f9529d318 100644 --- a/Source/Core/VideoBackends/D3D/main.cpp +++ b/Source/Core/VideoBackends/D3D/main.cpp @@ -145,32 +145,30 @@ bool VideoBackend::Initialize(void* window_handle) InitBackendInfo(); InitializeShared(); - m_window_handle = window_handle; - - return true; -} - -void VideoBackend::Video_Prepare() -{ - if (FAILED(D3D::Create(reinterpret_cast(m_window_handle)))) + if (FAILED(D3D::Create(reinterpret_cast(window_handle)))) + { PanicAlert("Failed to create D3D device."); + return false; + } - // internal interfaces g_renderer = std::make_unique(); g_texture_cache = std::make_unique(); g_vertex_manager = std::make_unique(); g_perf_query = std::make_unique(); + VertexShaderCache::Init(); PixelShaderCache::Init(); GeometryShaderCache::Init(); VertexShaderCache::WaitForBackgroundCompilesToComplete(); D3D::InitUtils(); BBox::Init(); + return true; } void VideoBackend::Shutdown() { - // TODO: should be in Video_Cleanup + g_renderer->Shutdown(); + D3D::ShutdownUtils(); PixelShaderCache::Shutdown(); VertexShaderCache::Shutdown(); @@ -182,13 +180,8 @@ void VideoBackend::Shutdown() g_texture_cache.reset(); g_renderer.reset(); - D3D::Close(); - ShutdownShared(); -} -void VideoBackend::Video_Cleanup() -{ - CleanupShared(); + D3D::Close(); } } diff --git a/Source/Core/VideoBackends/Null/NullBackend.cpp b/Source/Core/VideoBackends/Null/NullBackend.cpp index 4ea460e440..c687c8f2df 100644 --- a/Source/Core/VideoBackends/Null/NullBackend.cpp +++ b/Source/Core/VideoBackends/Null/NullBackend.cpp @@ -58,38 +58,32 @@ bool VideoBackend::Initialize(void* window_handle) InitializeShared(); InitBackendInfo(); - return true; -} - -// This is called after Initialize() from the Core -// Run from the graphics thread -void VideoBackend::Video_Prepare() -{ g_renderer = std::make_unique(); g_vertex_manager = std::make_unique(); g_perf_query = std::make_unique(); g_framebuffer_manager = std::make_unique(); g_texture_cache = std::make_unique(); + VertexShaderCache::s_instance = std::make_unique(); GeometryShaderCache::s_instance = std::make_unique(); PixelShaderCache::s_instance = std::make_unique(); + return true; } void VideoBackend::Shutdown() { - ShutdownShared(); -} + g_renderer->Shutdown(); -void VideoBackend::Video_Cleanup() -{ - CleanupShared(); PixelShaderCache::s_instance.reset(); VertexShaderCache::s_instance.reset(); GeometryShaderCache::s_instance.reset(); + g_texture_cache.reset(); g_perf_query.reset(); g_vertex_manager.reset(); g_framebuffer_manager.reset(); g_renderer.reset(); + + ShutdownShared(); } } diff --git a/Source/Core/VideoBackends/Null/VideoBackend.h b/Source/Core/VideoBackends/Null/VideoBackend.h index 5581d8511a..bb7da23c8d 100644 --- a/Source/Core/VideoBackends/Null/VideoBackend.h +++ b/Source/Core/VideoBackends/Null/VideoBackend.h @@ -15,9 +15,6 @@ class VideoBackend : public VideoBackendBase std::string GetName() const override { return "Null"; } std::string GetDisplayName() const override { return "Null"; } - void Video_Prepare() override; - void Video_Cleanup() override; - void InitBackendInfo() override; unsigned int PeekMessages() override { return 0; } diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index d3cfa4136d..3408d6099c 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -809,6 +809,7 @@ Renderer::~Renderer() = default; void Renderer::Shutdown() { + ::Renderer::Shutdown(); g_framebuffer_manager.reset(); UpdateActiveConfig(); diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index 797e1e0e98..993057b2d9 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -84,7 +84,7 @@ public: ~Renderer() override; void Init(); - void Shutdown(); + void Shutdown() override; std::unique_ptr CreateTexture(const TextureConfig& config) override; std::unique_ptr diff --git a/Source/Core/VideoBackends/OGL/VideoBackend.h b/Source/Core/VideoBackends/OGL/VideoBackend.h index c78c94c4c1..a42fc3cce6 100644 --- a/Source/Core/VideoBackends/OGL/VideoBackend.h +++ b/Source/Core/VideoBackends/OGL/VideoBackend.h @@ -17,9 +17,6 @@ class VideoBackend : public VideoBackendBase std::string GetName() const override; std::string GetDisplayName() const override; - void Video_Prepare() override; - void Video_Cleanup() override; - void InitBackendInfo() override; unsigned int PeekMessages() override; diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index 3b07eb96a7..64aea5f2c5 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -172,23 +172,11 @@ bool VideoBackend::Initialize(void* window_handle) if (!GLInterface->Create(window_handle, g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer)) return false; - return true; -} - -// This is called after Initialize() from the Core -// Run from the graphics thread -void VideoBackend::Video_Prepare() -{ GLInterface->MakeCurrent(); if (!InitializeGLExtensions() || !FillBackendInfo()) - { - // TODO: Handle this better. We'll likely end up crashing anyway, but this method doesn't - // return anything, so we can't inform the caller that startup failed. - return; - } + return false; g_renderer = std::make_unique(); - g_vertex_manager = std::make_unique(); g_perf_query = GetPerfQuery(); ProgramShaderCache::Init(); @@ -197,21 +185,12 @@ void VideoBackend::Video_Prepare() static_cast(g_renderer.get())->Init(); TextureConverter::Init(); BoundingBox::Init(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); + return true; } void VideoBackend::Shutdown() { - GLInterface->Shutdown(); - GLInterface.reset(); - ShutdownShared(); -} - -void VideoBackend::Video_Cleanup() -{ - // The following calls are NOT Thread Safe - // And need to be called from the video thread - CleanupShared(); - static_cast(g_renderer.get())->Shutdown(); + g_renderer->Shutdown(); BoundingBox::Shutdown(); TextureConverter::Shutdown(); g_sampler_cache.reset(); @@ -221,5 +200,8 @@ void VideoBackend::Video_Cleanup() g_vertex_manager.reset(); g_renderer.reset(); GLInterface->ClearCurrent(); + GLInterface->Shutdown(); + GLInterface.reset(); + ShutdownShared(); } } diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp index 4b84655002..28bd57557e 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.cpp +++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp @@ -26,15 +26,6 @@ SWRenderer::SWRenderer() { } -void SWRenderer::Init() -{ -} - -void SWRenderer::Shutdown() -{ - UpdateActiveConfig(); -} - std::unique_ptr SWRenderer::CreateTexture(const TextureConfig& config) { return std::make_unique(config); diff --git a/Source/Core/VideoBackends/Software/SWRenderer.h b/Source/Core/VideoBackends/Software/SWRenderer.h index 312acd1991..ecab73cccc 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.h +++ b/Source/Core/VideoBackends/Software/SWRenderer.h @@ -13,9 +13,6 @@ class SWRenderer : public Renderer public: SWRenderer(); - static void Init(); - static void Shutdown(); - std::unique_ptr CreateTexture(const TextureConfig& config) override; std::unique_ptr CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override; diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 115f9a9509..a79540891f 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -88,38 +88,8 @@ bool VideoSoftware::Initialize(void* window_handle) Clipper::Init(); Rasterizer::Init(); - SWRenderer::Init(); DebugUtil::Init(); - return true; -} - -void VideoSoftware::Shutdown() -{ - SWOGLWindow::Shutdown(); - - ShutdownShared(); -} - -void VideoSoftware::Video_Cleanup() -{ - CleanupShared(); - - SWRenderer::Shutdown(); - DebugUtil::Shutdown(); - // The following calls are NOT Thread Safe - // And need to be called from the video thread - SWRenderer::Shutdown(); - g_framebuffer_manager.reset(); - g_texture_cache.reset(); - g_perf_query.reset(); - g_vertex_manager.reset(); - g_renderer.reset(); -} - -// This is called after Video_Initialize() from the Core -void VideoSoftware::Video_Prepare() -{ GLInterface->MakeCurrent(); SWOGLWindow::s_instance->Prepare(); @@ -127,7 +97,22 @@ void VideoSoftware::Video_Prepare() g_vertex_manager = std::make_unique(); g_perf_query = std::make_unique(); g_texture_cache = std::make_unique(); - SWRenderer::Init(); + return true; +} + +void VideoSoftware::Shutdown() +{ + if (g_renderer) + g_renderer->Shutdown(); + + DebugUtil::Shutdown(); + SWOGLWindow::Shutdown(); + g_framebuffer_manager.reset(); + g_texture_cache.reset(); + g_perf_query.reset(); + g_vertex_manager.reset(); + g_renderer.reset(); + ShutdownShared(); } unsigned int VideoSoftware::PeekMessages() diff --git a/Source/Core/VideoBackends/Software/VideoBackend.h b/Source/Core/VideoBackends/Software/VideoBackend.h index fbc2cbd20d..0221aba9c7 100644 --- a/Source/Core/VideoBackends/Software/VideoBackend.h +++ b/Source/Core/VideoBackends/Software/VideoBackend.h @@ -17,9 +17,6 @@ class VideoSoftware : public VideoBackendBase std::string GetName() const override; std::string GetDisplayName() const override; - void Video_Prepare() override; - void Video_Cleanup() override; - void InitBackendInfo() override; unsigned int PeekMessages() override; diff --git a/Source/Core/VideoBackends/Vulkan/ShaderCache.cpp b/Source/Core/VideoBackends/Vulkan/ShaderCache.cpp index 2c69267dfc..9f77958b0f 100644 --- a/Source/Core/VideoBackends/Vulkan/ShaderCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/ShaderCache.cpp @@ -76,6 +76,9 @@ void ShaderCache::Shutdown() m_async_shader_compiler->StopWorkerThreads(); m_async_shader_compiler->RetrieveWorkItems(); } + + if (g_ActiveConfig.bShaderCache && m_pipeline_cache != VK_NULL_HANDLE) + SavePipelineCache(); } static bool IsStripPrimitiveTopology(VkPrimitiveTopology topology) diff --git a/Source/Core/VideoBackends/Vulkan/VideoBackend.h b/Source/Core/VideoBackends/Vulkan/VideoBackend.h index 4a32ae076b..b38ec28131 100644 --- a/Source/Core/VideoBackends/Vulkan/VideoBackend.h +++ b/Source/Core/VideoBackends/Vulkan/VideoBackend.h @@ -16,9 +16,6 @@ public: std::string GetName() const override { return "Vulkan"; } std::string GetDisplayName() const override { return "Vulkan (experimental)"; } - void Video_Prepare() override; - void Video_Cleanup() override; - void InitBackendInfo() override; unsigned int PeekMessages() override { return 0; } diff --git a/Source/Core/VideoBackends/Vulkan/main.cpp b/Source/Core/VideoBackends/Vulkan/main.cpp index 63b7921442..d8a725845a 100644 --- a/Source/Core/VideoBackends/Vulkan/main.cpp +++ b/Source/Core/VideoBackends/Vulkan/main.cpp @@ -245,22 +245,16 @@ bool VideoBackend::Initialize(void* window_handle) if (g_ActiveConfig.CanPrecompileUberShaders()) g_shader_cache->PrecompileUberShaders(); + // Display the name so the user knows which device was actually created. + INFO_LOG(VIDEO, "Vulkan Device: %s", g_vulkan_context->GetDeviceProperties().deviceName); return true; } -// This is called after Initialize() from the Core -// Run from the graphics thread -void VideoBackend::Video_Prepare() -{ - // Display the name so the user knows which device was actually created - OSD::AddMessage(StringFromFormat("Using physical adapter %s", - g_vulkan_context->GetDeviceProperties().deviceName) - .c_str(), - 5000); -} - void VideoBackend::Shutdown() { + if (g_renderer) + g_renderer->Shutdown(); + if (g_command_buffer_mgr) g_command_buffer_mgr->WaitForGPUIdle(); @@ -279,15 +273,4 @@ void VideoBackend::Shutdown() ShutdownShared(); UnloadVulkanLibrary(); } - -void VideoBackend::Video_Cleanup() -{ - g_command_buffer_mgr->WaitForGPUIdle(); - - // Save all cached pipelines out to disk for next time. - if (g_ActiveConfig.bShaderCache) - g_shader_cache->SavePipelineCache(); - - CleanupShared(); -} } diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp index 4dfb97f84a..fcad23ccbf 100644 --- a/Source/Core/VideoCommon/MainBase.cpp +++ b/Source/Core/VideoCommon/MainBase.cpp @@ -45,15 +45,6 @@ void VideoBackendBase::Video_ExitLoop() s_FifoShuttingDown.Set(); } -void VideoBackendBase::Video_CleanupShared() -{ - // First stop any framedumping, which might need to dump the last xfb frame. This process - // can require additional graphics sub-systems so it needs to be done first - g_renderer->ShutdownFrameDumping(); - - Video_Cleanup(); -} - // Run from the CPU thread (from VideoInterface.cpp) void VideoBackendBase::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, u64 ticks) @@ -211,12 +202,8 @@ void VideoBackendBase::ShutdownShared() m_initialized = false; - Fifo::Shutdown(); -} - -void VideoBackendBase::CleanupShared() -{ VertexLoaderManager::Clear(); + Fifo::Shutdown(); } // Run from the CPU thread diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 410330709f..9e56d20f29 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -101,6 +101,13 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height) Renderer::~Renderer() = default; +void Renderer::Shutdown() +{ + // First stop any framedumping, which might need to dump the last xfb frame. This process + // can require additional graphics sub-systems so it needs to be done first + ShutdownFrameDumping(); +} + void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight, float Gamma) { diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 819d6aae88..423707166b 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -154,7 +154,7 @@ public: virtual void ChangeSurface(void* new_surface_handle) {} bool UseVertexDepthRange() const; - void ShutdownFrameDumping(); + virtual void Shutdown(); protected: std::tuple CalculateTargetScale(int x, int y) const; @@ -243,6 +243,7 @@ private: std::string GetFrameDumpNextImageFileName() const; bool StartFrameDumpToImage(const FrameDumpConfig& config); void DumpFrameToImage(const FrameDumpConfig& config); + void ShutdownFrameDumping(); bool IsFrameDumping(); diff --git a/Source/Core/VideoCommon/VideoBackendBase.h b/Source/Core/VideoCommon/VideoBackendBase.h index b7d6e1faa8..060c52916a 100644 --- a/Source/Core/VideoCommon/VideoBackendBase.h +++ b/Source/Core/VideoCommon/VideoBackendBase.h @@ -45,12 +45,8 @@ public: void ShowConfig(void*); virtual void InitBackendInfo() = 0; - virtual void Video_Prepare() = 0; void Video_ExitLoop(); - void Video_CleanupShared(); // called from gl/d3d thread - virtual void Video_Cleanup() = 0; - void Video_BeginField(u32, u32, u32, u32, u64); u32 Video_AccessEFB(EFBAccessType, u32, u32, u32); @@ -70,7 +66,6 @@ public: protected: void InitializeShared(); void ShutdownShared(); - void CleanupShared(); bool m_initialized = false; bool m_invalid = false;