VideoBackends: Combine Initialize/Prepare and Cleanup/Shutdown methods

Also allows the work previously done in Prepare to return a failure
status.
This commit is contained in:
Stenzek 2018-01-26 15:09:07 +10:00
parent 04027a7da7
commit d96e8c9d76
20 changed files with 58 additions and 160 deletions

View file

@ -464,11 +464,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
PanicAlert("Failed to initialize video backend!"); PanicAlert("Failed to initialize video backend!");
return; return;
} }
g_video_backend->Video_Prepare(); Common::ScopeGuard video_guard{[] { g_video_backend->Shutdown(); }};
Common::ScopeGuard video_guard{[] {
g_video_backend->Video_Cleanup();
g_video_backend->Shutdown();
}};
if (cpu_info.HTT) if (cpu_info.HTT)
SConfig::GetInstance().bDSPThread = cpu_info.num_cores > 4; SConfig::GetInstance().bDSPThread = cpu_info.num_cores > 4;

View file

@ -17,13 +17,8 @@ class VideoBackend : public VideoBackendBase
std::string GetName() const override; std::string GetName() const override;
std::string GetDisplayName() const override; std::string GetDisplayName() const override;
void Video_Prepare() override;
void Video_Cleanup() override;
void InitBackendInfo() override; void InitBackendInfo() override;
unsigned int PeekMessages() override; unsigned int PeekMessages() override;
void* m_window_handle;
}; };
} }

View file

@ -145,32 +145,30 @@ bool VideoBackend::Initialize(void* window_handle)
InitBackendInfo(); InitBackendInfo();
InitializeShared(); InitializeShared();
m_window_handle = window_handle; if (FAILED(D3D::Create(reinterpret_cast<HWND>(window_handle))))
{
return true;
}
void VideoBackend::Video_Prepare()
{
if (FAILED(D3D::Create(reinterpret_cast<HWND>(m_window_handle))))
PanicAlert("Failed to create D3D device."); PanicAlert("Failed to create D3D device.");
return false;
}
// internal interfaces
g_renderer = std::make_unique<Renderer>(); g_renderer = std::make_unique<Renderer>();
g_texture_cache = std::make_unique<TextureCache>(); g_texture_cache = std::make_unique<TextureCache>();
g_vertex_manager = std::make_unique<VertexManager>(); g_vertex_manager = std::make_unique<VertexManager>();
g_perf_query = std::make_unique<PerfQuery>(); g_perf_query = std::make_unique<PerfQuery>();
VertexShaderCache::Init(); VertexShaderCache::Init();
PixelShaderCache::Init(); PixelShaderCache::Init();
GeometryShaderCache::Init(); GeometryShaderCache::Init();
VertexShaderCache::WaitForBackgroundCompilesToComplete(); VertexShaderCache::WaitForBackgroundCompilesToComplete();
D3D::InitUtils(); D3D::InitUtils();
BBox::Init(); BBox::Init();
return true;
} }
void VideoBackend::Shutdown() void VideoBackend::Shutdown()
{ {
// TODO: should be in Video_Cleanup g_renderer->Shutdown();
D3D::ShutdownUtils(); D3D::ShutdownUtils();
PixelShaderCache::Shutdown(); PixelShaderCache::Shutdown();
VertexShaderCache::Shutdown(); VertexShaderCache::Shutdown();
@ -182,13 +180,8 @@ void VideoBackend::Shutdown()
g_texture_cache.reset(); g_texture_cache.reset();
g_renderer.reset(); g_renderer.reset();
D3D::Close();
ShutdownShared(); ShutdownShared();
}
void VideoBackend::Video_Cleanup() D3D::Close();
{
CleanupShared();
} }
} }

View file

@ -58,38 +58,32 @@ bool VideoBackend::Initialize(void* window_handle)
InitializeShared(); InitializeShared();
InitBackendInfo(); 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<Renderer>(); g_renderer = std::make_unique<Renderer>();
g_vertex_manager = std::make_unique<VertexManager>(); g_vertex_manager = std::make_unique<VertexManager>();
g_perf_query = std::make_unique<PerfQuery>(); g_perf_query = std::make_unique<PerfQuery>();
g_framebuffer_manager = std::make_unique<FramebufferManagerBase>(); g_framebuffer_manager = std::make_unique<FramebufferManagerBase>();
g_texture_cache = std::make_unique<TextureCache>(); g_texture_cache = std::make_unique<TextureCache>();
VertexShaderCache::s_instance = std::make_unique<VertexShaderCache>(); VertexShaderCache::s_instance = std::make_unique<VertexShaderCache>();
GeometryShaderCache::s_instance = std::make_unique<GeometryShaderCache>(); GeometryShaderCache::s_instance = std::make_unique<GeometryShaderCache>();
PixelShaderCache::s_instance = std::make_unique<PixelShaderCache>(); PixelShaderCache::s_instance = std::make_unique<PixelShaderCache>();
return true;
} }
void VideoBackend::Shutdown() void VideoBackend::Shutdown()
{ {
ShutdownShared(); g_renderer->Shutdown();
}
void VideoBackend::Video_Cleanup()
{
CleanupShared();
PixelShaderCache::s_instance.reset(); PixelShaderCache::s_instance.reset();
VertexShaderCache::s_instance.reset(); VertexShaderCache::s_instance.reset();
GeometryShaderCache::s_instance.reset(); GeometryShaderCache::s_instance.reset();
g_texture_cache.reset(); g_texture_cache.reset();
g_perf_query.reset(); g_perf_query.reset();
g_vertex_manager.reset(); g_vertex_manager.reset();
g_framebuffer_manager.reset(); g_framebuffer_manager.reset();
g_renderer.reset(); g_renderer.reset();
ShutdownShared();
} }
} }

View file

@ -15,9 +15,6 @@ class VideoBackend : public VideoBackendBase
std::string GetName() const override { return "Null"; } std::string GetName() const override { return "Null"; }
std::string GetDisplayName() const override { return "Null"; } std::string GetDisplayName() const override { return "Null"; }
void Video_Prepare() override;
void Video_Cleanup() override;
void InitBackendInfo() override; void InitBackendInfo() override;
unsigned int PeekMessages() override { return 0; } unsigned int PeekMessages() override { return 0; }

View file

@ -809,6 +809,7 @@ Renderer::~Renderer() = default;
void Renderer::Shutdown() void Renderer::Shutdown()
{ {
::Renderer::Shutdown();
g_framebuffer_manager.reset(); g_framebuffer_manager.reset();
UpdateActiveConfig(); UpdateActiveConfig();

View file

@ -84,7 +84,7 @@ public:
~Renderer() override; ~Renderer() override;
void Init(); void Init();
void Shutdown(); void Shutdown() override;
std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override; std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
std::unique_ptr<AbstractStagingTexture> std::unique_ptr<AbstractStagingTexture>

View file

@ -17,9 +17,6 @@ class VideoBackend : public VideoBackendBase
std::string GetName() const override; std::string GetName() const override;
std::string GetDisplayName() const override; std::string GetDisplayName() const override;
void Video_Prepare() override;
void Video_Cleanup() override;
void InitBackendInfo() override; void InitBackendInfo() override;
unsigned int PeekMessages() override; unsigned int PeekMessages() override;

View file

@ -172,23 +172,11 @@ bool VideoBackend::Initialize(void* window_handle)
if (!GLInterface->Create(window_handle, g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer)) if (!GLInterface->Create(window_handle, g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer))
return false; return false;
return true;
}
// This is called after Initialize() from the Core
// Run from the graphics thread
void VideoBackend::Video_Prepare()
{
GLInterface->MakeCurrent(); GLInterface->MakeCurrent();
if (!InitializeGLExtensions() || !FillBackendInfo()) if (!InitializeGLExtensions() || !FillBackendInfo())
{ return false;
// 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;
}
g_renderer = std::make_unique<Renderer>(); g_renderer = std::make_unique<Renderer>();
g_vertex_manager = std::make_unique<VertexManager>(); g_vertex_manager = std::make_unique<VertexManager>();
g_perf_query = GetPerfQuery(); g_perf_query = GetPerfQuery();
ProgramShaderCache::Init(); ProgramShaderCache::Init();
@ -197,21 +185,12 @@ void VideoBackend::Video_Prepare()
static_cast<Renderer*>(g_renderer.get())->Init(); static_cast<Renderer*>(g_renderer.get())->Init();
TextureConverter::Init(); TextureConverter::Init();
BoundingBox::Init(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); BoundingBox::Init(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight());
return true;
} }
void VideoBackend::Shutdown() void VideoBackend::Shutdown()
{ {
GLInterface->Shutdown(); g_renderer->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<Renderer*>(g_renderer.get())->Shutdown();
BoundingBox::Shutdown(); BoundingBox::Shutdown();
TextureConverter::Shutdown(); TextureConverter::Shutdown();
g_sampler_cache.reset(); g_sampler_cache.reset();
@ -221,5 +200,8 @@ void VideoBackend::Video_Cleanup()
g_vertex_manager.reset(); g_vertex_manager.reset();
g_renderer.reset(); g_renderer.reset();
GLInterface->ClearCurrent(); GLInterface->ClearCurrent();
GLInterface->Shutdown();
GLInterface.reset();
ShutdownShared();
} }
} }

View file

@ -26,15 +26,6 @@ SWRenderer::SWRenderer()
{ {
} }
void SWRenderer::Init()
{
}
void SWRenderer::Shutdown()
{
UpdateActiveConfig();
}
std::unique_ptr<AbstractTexture> SWRenderer::CreateTexture(const TextureConfig& config) std::unique_ptr<AbstractTexture> SWRenderer::CreateTexture(const TextureConfig& config)
{ {
return std::make_unique<SW::SWTexture>(config); return std::make_unique<SW::SWTexture>(config);

View file

@ -13,9 +13,6 @@ class SWRenderer : public Renderer
public: public:
SWRenderer(); SWRenderer();
static void Init();
static void Shutdown();
std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override; std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
std::unique_ptr<AbstractStagingTexture> std::unique_ptr<AbstractStagingTexture>
CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override; CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override;

View file

@ -88,38 +88,8 @@ bool VideoSoftware::Initialize(void* window_handle)
Clipper::Init(); Clipper::Init();
Rasterizer::Init(); Rasterizer::Init();
SWRenderer::Init();
DebugUtil::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(); GLInterface->MakeCurrent();
SWOGLWindow::s_instance->Prepare(); SWOGLWindow::s_instance->Prepare();
@ -127,7 +97,22 @@ void VideoSoftware::Video_Prepare()
g_vertex_manager = std::make_unique<SWVertexLoader>(); g_vertex_manager = std::make_unique<SWVertexLoader>();
g_perf_query = std::make_unique<PerfQuery>(); g_perf_query = std::make_unique<PerfQuery>();
g_texture_cache = std::make_unique<TextureCache>(); g_texture_cache = std::make_unique<TextureCache>();
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() unsigned int VideoSoftware::PeekMessages()

View file

@ -17,9 +17,6 @@ class VideoSoftware : public VideoBackendBase
std::string GetName() const override; std::string GetName() const override;
std::string GetDisplayName() const override; std::string GetDisplayName() const override;
void Video_Prepare() override;
void Video_Cleanup() override;
void InitBackendInfo() override; void InitBackendInfo() override;
unsigned int PeekMessages() override; unsigned int PeekMessages() override;

View file

@ -76,6 +76,9 @@ void ShaderCache::Shutdown()
m_async_shader_compiler->StopWorkerThreads(); m_async_shader_compiler->StopWorkerThreads();
m_async_shader_compiler->RetrieveWorkItems(); m_async_shader_compiler->RetrieveWorkItems();
} }
if (g_ActiveConfig.bShaderCache && m_pipeline_cache != VK_NULL_HANDLE)
SavePipelineCache();
} }
static bool IsStripPrimitiveTopology(VkPrimitiveTopology topology) static bool IsStripPrimitiveTopology(VkPrimitiveTopology topology)

View file

@ -16,9 +16,6 @@ public:
std::string GetName() const override { return "Vulkan"; } std::string GetName() const override { return "Vulkan"; }
std::string GetDisplayName() const override { return "Vulkan (experimental)"; } std::string GetDisplayName() const override { return "Vulkan (experimental)"; }
void Video_Prepare() override;
void Video_Cleanup() override;
void InitBackendInfo() override; void InitBackendInfo() override;
unsigned int PeekMessages() override { return 0; } unsigned int PeekMessages() override { return 0; }

View file

@ -245,22 +245,16 @@ bool VideoBackend::Initialize(void* window_handle)
if (g_ActiveConfig.CanPrecompileUberShaders()) if (g_ActiveConfig.CanPrecompileUberShaders())
g_shader_cache->PrecompileUberShaders(); 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; 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() void VideoBackend::Shutdown()
{ {
if (g_renderer)
g_renderer->Shutdown();
if (g_command_buffer_mgr) if (g_command_buffer_mgr)
g_command_buffer_mgr->WaitForGPUIdle(); g_command_buffer_mgr->WaitForGPUIdle();
@ -279,15 +273,4 @@ void VideoBackend::Shutdown()
ShutdownShared(); ShutdownShared();
UnloadVulkanLibrary(); 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();
}
} }

View file

@ -45,15 +45,6 @@ void VideoBackendBase::Video_ExitLoop()
s_FifoShuttingDown.Set(); 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) // Run from the CPU thread (from VideoInterface.cpp)
void VideoBackendBase::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, void VideoBackendBase::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
u64 ticks) u64 ticks)
@ -211,12 +202,8 @@ void VideoBackendBase::ShutdownShared()
m_initialized = false; m_initialized = false;
Fifo::Shutdown();
}
void VideoBackendBase::CleanupShared()
{
VertexLoaderManager::Clear(); VertexLoaderManager::Clear();
Fifo::Shutdown();
} }
// Run from the CPU thread // Run from the CPU thread

View file

@ -101,6 +101,13 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height)
Renderer::~Renderer() = default; 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, void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight,
float Gamma) float Gamma)
{ {

View file

@ -154,7 +154,7 @@ public:
virtual void ChangeSurface(void* new_surface_handle) {} virtual void ChangeSurface(void* new_surface_handle) {}
bool UseVertexDepthRange() const; bool UseVertexDepthRange() const;
void ShutdownFrameDumping(); virtual void Shutdown();
protected: protected:
std::tuple<int, int> CalculateTargetScale(int x, int y) const; std::tuple<int, int> CalculateTargetScale(int x, int y) const;
@ -243,6 +243,7 @@ private:
std::string GetFrameDumpNextImageFileName() const; std::string GetFrameDumpNextImageFileName() const;
bool StartFrameDumpToImage(const FrameDumpConfig& config); bool StartFrameDumpToImage(const FrameDumpConfig& config);
void DumpFrameToImage(const FrameDumpConfig& config); void DumpFrameToImage(const FrameDumpConfig& config);
void ShutdownFrameDumping();
bool IsFrameDumping(); bool IsFrameDumping();

View file

@ -45,12 +45,8 @@ public:
void ShowConfig(void*); void ShowConfig(void*);
virtual void InitBackendInfo() = 0; virtual void InitBackendInfo() = 0;
virtual void Video_Prepare() = 0;
void Video_ExitLoop(); void Video_ExitLoop();
void Video_CleanupShared(); // called from gl/d3d thread
virtual void Video_Cleanup() = 0;
void Video_BeginField(u32, u32, u32, u32, u64); void Video_BeginField(u32, u32, u32, u32, u64);
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32); u32 Video_AccessEFB(EFBAccessType, u32, u32, u32);
@ -70,7 +66,6 @@ public:
protected: protected:
void InitializeShared(); void InitializeShared();
void ShutdownShared(); void ShutdownShared();
void CleanupShared();
bool m_initialized = false; bool m_initialized = false;
bool m_invalid = false; bool m_invalid = false;