Also use events for config changed

This commit is contained in:
Scott Mansell 2023-01-31 00:49:23 +13:00
parent 0da69055d9
commit 3ae78b8e76
11 changed files with 46 additions and 13 deletions

View File

@ -169,6 +169,8 @@ void Gfx::PresentBackbuffer()
void Gfx::OnConfigChanged(u32 bits)
{
AbstractGfx::OnConfigChanged(bits);
// Quad-buffer changes require swap chain recreation.
if (bits & CONFIG_CHANGE_BIT_STEREO_MODE && m_swap_chain)
m_swap_chain->SetStereo(SwapChain::WantsStereo());

View File

@ -437,6 +437,8 @@ SurfaceInfo Gfx::GetSurfaceInfo() const
void Gfx::OnConfigChanged(u32 bits)
{
AbstractGfx::OnConfigChanged(bits);
// For quad-buffered stereo we need to change the layer count, so recreate the swap chain.
if (m_swap_chain && bits & CONFIG_CHANGE_BIT_STEREO_MODE)
{

View File

@ -273,6 +273,8 @@ void Metal::Gfx::WaitForGPUIdle()
void Metal::Gfx::OnConfigChanged(u32 bits)
{
AbstractGfx::OnConfigChanged(bits);
if (bits & CONFIG_CHANGE_BIT_VSYNC)
[m_layer setDisplaySyncEnabled:g_ActiveConfig.bVSyncActive];

View File

@ -436,6 +436,8 @@ void OGLGfx::PresentBackbuffer()
void OGLGfx::OnConfigChanged(u32 bits)
{
AbstractGfx::OnConfigChanged(bits);
if (bits & CONFIG_CHANGE_BIT_VSYNC && !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC))
m_main_gl_context->SwapInterval(g_ActiveConfig.bVSyncActive);

View File

@ -369,6 +369,8 @@ void VKGfx::CheckForSurfaceResize()
void VKGfx::OnConfigChanged(u32 bits)
{
AbstractGfx::OnConfigChanged(bits);
if (bits & CONFIG_CHANGE_BIT_HOST_CONFIG)
g_object_cache->ReloadPipelineCache();

View File

@ -239,7 +239,7 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
auto perf_query = std::make_unique<PerfQuery>();
auto bounding_box = std::make_unique<VKBoundingBox>();
return !InitializeShared(std::move(gfx), std::move(vertex_manager), std::move(perf_query),
return InitializeShared(std::move(gfx), std::move(vertex_manager), std::move(perf_query),
std::move(bounding_box));
}

View File

@ -16,6 +16,11 @@
std::unique_ptr<AbstractGfx> g_gfx;
AbstractGfx::AbstractGfx()
{
ConfigChangedEvent::Register([this](u32 bits) { OnConfigChanged(bits); }, "AbstractGfx");
}
bool AbstractGfx::IsHeadless() const
{
return true;
@ -132,6 +137,16 @@ std::unique_ptr<VideoCommon::AsyncShaderCompiler> AbstractGfx::CreateAsyncShader
return std::make_unique<VideoCommon::AsyncShaderCompiler>();
}
void AbstractGfx::OnConfigChanged(u32 changed_bits)
{
// If there's any shader changes, wait for the GPU to finish before destroying anything.
if (changed_bits & (CONFIG_CHANGE_BIT_HOST_CONFIG | CONFIG_CHANGE_BIT_MULTISAMPLES))
{
WaitForGPUIdle();
SetPipeline(nullptr);
}
}
bool AbstractGfx::UseGeometryShaderForUI() const
{
// OpenGL doesn't render to a 2-layer backbuffer like D3D/Vulkan for quad-buffered stereo,

View File

@ -42,6 +42,7 @@ using ClearColor = std::array<float, 4>;
class AbstractGfx
{
public:
AbstractGfx();
virtual ~AbstractGfx() = default;
virtual bool IsHeadless() const = 0;
@ -149,7 +150,7 @@ public:
virtual std::unique_ptr<VideoCommon::AsyncShaderCompiler> CreateAsyncShaderCompiler();
// Called when the configuration changes, and backend structures need to be updated.
virtual void OnConfigChanged(u32 bits) {}
virtual void OnConfigChanged(u32 changed_bits);
// Returns true if a layer-expanding geometry shader should be used when rendering the user
// interface and final XFB.

View File

@ -65,6 +65,9 @@ Renderer::Renderer()
UpdateActiveConfig();
CalculateTargetSize();
UpdateWidescreen();
m_config_changed_handle = ConfigChangedEvent::Register([this](u32 bits) { OnConfigChanged(bits); }, "Renderer");
// VertexManager doesn't maintain statistics in Wii mode.
if (!SConfig::GetInstance().bWii)
m_update_widescreen_handle = AfterFrameEvent::Register([this] { UpdateWidescreenHeuristic(); }, "WideScreen Heuristic");

View File

@ -256,6 +256,9 @@ void CheckForConfigChanges()
const u32 old_game_mod_changes =
g_ActiveConfig.graphics_mod_config ? g_ActiveConfig.graphics_mod_config->GetChangeCount() : 0;
const bool old_graphics_mods_enabled = g_ActiveConfig.bGraphicMods;
const AspectMode old_suggested_aspect_mode = g_ActiveConfig.suggested_aspect_mode;
const bool old_widescreen_hack = g_ActiveConfig.bWidescreenHack;
const auto old_post_processing_shader = g_ActiveConfig.sPostProcessingShader;
UpdateActiveConfig();
FreeLook::UpdateActiveConfig();
@ -301,22 +304,21 @@ void CheckForConfigChanges()
changed_bits |= CONFIG_CHANGE_BIT_BBOX;
if (g_renderer->CalculateTargetSize())
changed_bits |= CONFIG_CHANGE_BIT_TARGET_SIZE;
g_presenter->CheckForConfigChanges(changed_bits);
if (old_suggested_aspect_mode != g_ActiveConfig.suggested_aspect_mode)
changed_bits |= CONFIG_CHANGE_BIT_ASPECT_RATIO;
if (old_widescreen_hack != g_ActiveConfig.bWidescreenHack)
changed_bits |= CONFIG_CHANGE_BIT_ASPECT_RATIO;
if (old_post_processing_shader != g_ActiveConfig.sPostProcessingShader)
changed_bits |= CONFIG_CHANGE_BIT_POST_PROCESSING_SHADER;
// No changes?
if (changed_bits == 0)
return;
// Notify the backend of the changes, if any.
g_gfx->OnConfigChanged(changed_bits);
// Notify all listeners
ConfigChangedEvent::Trigger(changed_bits);
// If there's any shader changes, wait for the GPU to finish before destroying anything.
if (changed_bits & (CONFIG_CHANGE_BIT_HOST_CONFIG | CONFIG_CHANGE_BIT_MULTISAMPLES))
{
g_gfx->WaitForGPUIdle();
g_gfx->SetPipeline(nullptr);
}
// TODO: Move everything else to the ConfigChanged event
// Framebuffer changed?
if (changed_bits & (CONFIG_CHANGE_BIT_MULTISAMPLES | CONFIG_CHANGE_BIT_STEREO_MODE |

View File

@ -70,7 +70,9 @@ enum ConfigChangeBits : u32
CONFIG_CHANGE_BIT_ANISOTROPY = (1 << 4),
CONFIG_CHANGE_BIT_FORCE_TEXTURE_FILTERING = (1 << 5),
CONFIG_CHANGE_BIT_VSYNC = (1 << 6),
CONFIG_CHANGE_BIT_BBOX = (1 << 7)
CONFIG_CHANGE_BIT_BBOX = (1 << 7),
CONFIG_CHANGE_BIT_ASPECT_RATIO = (1 << 8),
CONFIG_CHANGE_BIT_POST_PROCESSING_SHADER = (1 << 9),
};
// NEVER inherit from this class.