@@ -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<Renderer>();
g_vertex_manager = std::make_unique<VertexManager>();
g_perf_query = std::make_unique<PerfQuery>();
g_framebuffer_manager = std::make_unique<FramebufferManagerBase>();
g_texture_cache = std::make_unique<TextureCache>();

VertexShaderCache::s_instance = std::make_unique<VertexShaderCache>();
GeometryShaderCache::s_instance = std::make_unique<GeometryShaderCache>();
PixelShaderCache::s_instance = std::make_unique<PixelShaderCache>();
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();
}
}
@@ -15,11 +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; }
};
}
@@ -809,6 +809,7 @@ Renderer::~Renderer() = default;

void Renderer::Shutdown()
{
::Renderer::Shutdown();
g_framebuffer_manager.reset();

UpdateActiveConfig();
@@ -84,7 +84,7 @@ class Renderer : public ::Renderer
~Renderer() override;

void Init();
void Shutdown();
void Shutdown() override;

std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
std::unique_ptr<AbstractStagingTexture>
@@ -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;

private:
bool InitializeGLExtensions();
bool FillBackendInfo();
@@ -58,12 +58,6 @@ Make AA apply instantly during gameplay if possible

namespace OGL
{
// Draw messages on top of the screen
unsigned int VideoBackend::PeekMessages()
{
return GLInterface->PeekMessages();
}

std::string VideoBackend::GetName() const
{
return "OGL";
@@ -172,23 +166,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<Renderer>();

g_vertex_manager = std::make_unique<VertexManager>();
g_perf_query = GetPerfQuery();
ProgramShaderCache::Init();
@@ -197,21 +179,12 @@ void VideoBackend::Video_Prepare()
static_cast<Renderer*>(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<Renderer*>(g_renderer.get())->Shutdown();
g_renderer->Shutdown();
BoundingBox::Shutdown();
TextureConverter::Shutdown();
g_sampler_cache.reset();
@@ -221,5 +194,8 @@ void VideoBackend::Video_Cleanup()
g_vertex_manager.reset();
g_renderer.reset();
GLInterface->ClearCurrent();
GLInterface->Shutdown();
GLInterface.reset();
ShutdownShared();
}
}
@@ -26,15 +26,6 @@ SWRenderer::SWRenderer()
{
}

void SWRenderer::Init()
{
}

void SWRenderer::Shutdown()
{
UpdateActiveConfig();
}

std::unique_ptr<AbstractTexture> SWRenderer::CreateTexture(const TextureConfig& config)
{
return std::make_unique<SW::SWTexture>(config);
@@ -13,9 +13,6 @@ class SWRenderer : public Renderer
public:
SWRenderer();

static void Init();
static void Shutdown();

std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
std::unique_ptr<AbstractStagingTexture>
CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override;
@@ -88,50 +88,30 @@ bool VideoSoftware::Initialize(void* window_handle)

Clipper::Init();
Rasterizer::Init();
SWRenderer::Init();
DebugUtil::Init();

GLInterface->MakeCurrent();
SWOGLWindow::s_instance->Prepare();

g_renderer = std::make_unique<SWRenderer>();
g_vertex_manager = std::make_unique<SWVertexLoader>();
g_perf_query = std::make_unique<PerfQuery>();
g_texture_cache = std::make_unique<TextureCache>();
return true;
}

void VideoSoftware::Shutdown()
{
SWOGLWindow::Shutdown();

ShutdownShared();
}
if (g_renderer)
g_renderer->Shutdown();

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();
SWOGLWindow::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();

g_renderer = std::make_unique<SWRenderer>();
g_vertex_manager = std::make_unique<SWVertexLoader>();
g_perf_query = std::make_unique<PerfQuery>();
g_texture_cache = std::make_unique<TextureCache>();
SWRenderer::Init();
}

unsigned int VideoSoftware::PeekMessages()
{
return SWOGLWindow::s_instance->PeekMessages();
ShutdownShared();
}
}
@@ -17,11 +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;
};
}
@@ -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)
@@ -16,11 +16,6 @@ class VideoBackend : public VideoBackendBase

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; }
};
}
@@ -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();
}
}
@@ -299,8 +299,6 @@ void RunGpuLoop()
[] {
const SConfig& param = SConfig::GetInstance();

g_video_backend->PeekMessages();

// Do nothing while paused
if (!s_emu_running_state.IsSet())
return;
@@ -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
@@ -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)
{
@@ -154,7 +154,7 @@ class Renderer
virtual void ChangeSurface(void* new_surface_handle) {}
bool UseVertexDepthRange() const;

void ShutdownFrameDumping();
virtual void Shutdown();

protected:
std::tuple<int, int> CalculateTargetScale(int x, int y) const;
@@ -243,6 +243,7 @@ class Renderer
std::string GetFrameDumpNextImageFileName() const;
bool StartFrameDumpToImage(const FrameDumpConfig& config);
void DumpFrameToImage(const FrameDumpConfig& config);
void ShutdownFrameDumping();

bool IsFrameDumping();

@@ -35,8 +35,6 @@ class VideoBackendBase
{
public:
virtual ~VideoBackendBase() {}
virtual unsigned int PeekMessages() = 0;

virtual bool Initialize(void* window_handle) = 0;
virtual void Shutdown() = 0;

@@ -45,12 +43,8 @@ class VideoBackendBase
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 +64,6 @@ class VideoBackendBase
protected:
void InitializeShared();
void ShutdownShared();
void CleanupShared();

bool m_initialized = false;
bool m_invalid = false;