mirror of https://github.com/PCSX2/pcsx2.git
GS: Set vsync based on host decision
Fixes bug where after changing settings in the big picture UI, if you didn't have a game running, it would turn off vsync, making GPU go brr. Also cleans up HostDisplay a bit, removing redundant parameters.
This commit is contained in:
parent
6a1eb231dd
commit
44c8974aba
|
@ -1828,8 +1828,7 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
|
||||||
|
|
||||||
g_emu_thread->connectDisplaySignals(m_display_widget);
|
g_emu_thread->connectDisplaySignals(m_display_widget);
|
||||||
|
|
||||||
if (!g_host_display->CreateRenderDevice(wi.value(), Host::GetStringSettingValue("EmuCore/GS", "Adapter", ""), EmuConfig.GetEffectiveVsyncMode(),
|
if (!g_host_display->CreateDevice(wi.value()))
|
||||||
Host::GetBoolSettingValue("EmuCore/GS", "ThreadedPresentation", false), Host::GetBoolSettingValue("EmuCore/GS", "UseDebugDevice", false)))
|
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Failed to create host display device context."));
|
QMessageBox::critical(this, tr("Error"), tr("Failed to create host display device context."));
|
||||||
destroyDisplayWidget(true);
|
destroyDisplayWidget(true);
|
||||||
|
@ -1852,7 +1851,7 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
|
||||||
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused);
|
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused);
|
||||||
m_display_widget->setFocus();
|
m_display_widget->setFocus();
|
||||||
|
|
||||||
g_host_display->DoneRenderContextCurrent();
|
g_host_display->DoneCurrent();
|
||||||
return m_display_widget;
|
return m_display_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1904,7 +1903,7 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
|
||||||
return m_display_widget;
|
return m_display_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_host_display->DestroyRenderSurface();
|
g_host_display->DestroySurface();
|
||||||
|
|
||||||
destroyDisplayWidget(surfaceless);
|
destroyDisplayWidget(surfaceless);
|
||||||
|
|
||||||
|
@ -1924,7 +1923,7 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main, b
|
||||||
|
|
||||||
g_emu_thread->connectDisplaySignals(m_display_widget);
|
g_emu_thread->connectDisplaySignals(m_display_widget);
|
||||||
|
|
||||||
if (!g_host_display->ChangeRenderWindow(wi.value()))
|
if (!g_host_display->ChangeWindow(wi.value()))
|
||||||
pxFailRel("Failed to recreate surface on new widget.");
|
pxFailRel("Failed to recreate surface on new widget.");
|
||||||
|
|
||||||
if (is_exclusive_fullscreen)
|
if (is_exclusive_fullscreen)
|
||||||
|
|
|
@ -832,24 +832,24 @@ void EmuThread::updateDisplay()
|
||||||
pxAssertRel(!isOnEmuThread(), "Not on emu thread");
|
pxAssertRel(!isOnEmuThread(), "Not on emu thread");
|
||||||
|
|
||||||
// finished with the display for now
|
// finished with the display for now
|
||||||
g_host_display->DoneRenderContextCurrent();
|
g_host_display->DoneCurrent();
|
||||||
|
|
||||||
// but we should get it back after this call
|
// but we should get it back after this call
|
||||||
onUpdateDisplayRequested(m_is_fullscreen, !m_is_fullscreen && m_is_rendering_to_main, m_is_surfaceless);
|
onUpdateDisplayRequested(m_is_fullscreen, !m_is_fullscreen && m_is_rendering_to_main, m_is_surfaceless);
|
||||||
if (!g_host_display->MakeRenderContextCurrent())
|
if (!g_host_display->MakeCurrent())
|
||||||
{
|
{
|
||||||
pxFailRel("Failed to recreate context after updating");
|
pxFailRel("Failed to recreate context after updating");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmuThread::acquireHostDisplay(HostDisplay::RenderAPI api)
|
bool EmuThread::acquireHostDisplay(RenderAPI api)
|
||||||
{
|
{
|
||||||
pxAssertRel(!g_host_display, "Host display does not exist on create");
|
pxAssertRel(!g_host_display, "Host display does not exist on create");
|
||||||
m_is_rendering_to_main = shouldRenderToMain();
|
m_is_rendering_to_main = shouldRenderToMain();
|
||||||
m_is_surfaceless = false;
|
m_is_surfaceless = false;
|
||||||
|
|
||||||
g_host_display = HostDisplay::CreateDisplayForAPI(api);
|
g_host_display = HostDisplay::CreateForAPI(api);
|
||||||
if (!g_host_display)
|
if (!g_host_display)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -862,15 +862,14 @@ bool EmuThread::acquireHostDisplay(HostDisplay::RenderAPI api)
|
||||||
|
|
||||||
connectDisplaySignals(widget);
|
connectDisplaySignals(widget);
|
||||||
|
|
||||||
if (!g_host_display->MakeRenderContextCurrent())
|
if (!g_host_display->MakeCurrent())
|
||||||
{
|
{
|
||||||
Console.Error("Failed to make render context current");
|
Console.Error("Failed to make render context current");
|
||||||
releaseHostDisplay();
|
releaseHostDisplay();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_host_display->InitializeRenderDevice(EmuFolders::Cache, false) ||
|
if (!g_host_display->SetupDevice() || !ImGuiManager::Initialize())
|
||||||
!ImGuiManager::Initialize())
|
|
||||||
{
|
{
|
||||||
Console.Error("Failed to initialize device/imgui");
|
Console.Error("Failed to initialize device/imgui");
|
||||||
releaseHostDisplay();
|
releaseHostDisplay();
|
||||||
|
@ -899,7 +898,7 @@ void EmuThread::releaseHostDisplay()
|
||||||
emit onDestroyDisplayRequested();
|
emit onDestroyDisplayRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host::AcquireHostDisplay(HostDisplay::RenderAPI api)
|
bool Host::AcquireHostDisplay(RenderAPI api)
|
||||||
{
|
{
|
||||||
return g_emu_thread->acquireHostDisplay(api);
|
return g_emu_thread->acquireHostDisplay(api);
|
||||||
}
|
}
|
||||||
|
@ -909,6 +908,24 @@ void Host::ReleaseHostDisplay()
|
||||||
g_emu_thread->releaseHostDisplay();
|
g_emu_thread->releaseHostDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VsyncMode Host::GetEffectiveVSyncMode()
|
||||||
|
{
|
||||||
|
// Force vsync on when running big picture UI, and paused or no VM.
|
||||||
|
if (g_emu_thread->isRunningFullscreenUI())
|
||||||
|
{
|
||||||
|
const VMState state = VMManager::GetState();
|
||||||
|
if (state == VMState::Shutdown || state == VMState::Paused)
|
||||||
|
return VsyncMode::On;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force vsync off when not running at 100% speed.
|
||||||
|
if (EmuConfig.GS.LimitScalar != 1.0f)
|
||||||
|
return VsyncMode::Off;
|
||||||
|
|
||||||
|
// Otherwise use the config setting.
|
||||||
|
return EmuConfig.GS.VsyncEnable;
|
||||||
|
}
|
||||||
|
|
||||||
bool Host::BeginPresentFrame(bool frame_skip)
|
bool Host::BeginPresentFrame(bool frame_skip)
|
||||||
{
|
{
|
||||||
if (!g_host_display->BeginPresent(frame_skip))
|
if (!g_host_display->BeginPresent(frame_skip))
|
||||||
|
@ -935,7 +952,7 @@ void Host::EndPresentFrame()
|
||||||
|
|
||||||
void Host::ResizeHostDisplay(u32 new_window_width, u32 new_window_height, float new_window_scale)
|
void Host::ResizeHostDisplay(u32 new_window_width, u32 new_window_height, float new_window_scale)
|
||||||
{
|
{
|
||||||
g_host_display->ResizeRenderWindow(new_window_width, new_window_height, new_window_scale);
|
g_host_display->ResizeWindow(new_window_width, new_window_height, new_window_scale);
|
||||||
ImGuiManager::WindowResized();
|
ImGuiManager::WindowResized();
|
||||||
|
|
||||||
// if we're paused, re-present the current frame at the new window size.
|
// if we're paused, re-present the current frame at the new window size.
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
bool shouldRenderToMain() const;
|
bool shouldRenderToMain() const;
|
||||||
|
|
||||||
/// Called back from the GS thread when the display state changes (e.g. fullscreen, render to main).
|
/// Called back from the GS thread when the display state changes (e.g. fullscreen, render to main).
|
||||||
bool acquireHostDisplay(HostDisplay::RenderAPI api);
|
bool acquireHostDisplay(RenderAPI api);
|
||||||
void connectDisplaySignals(DisplayWidget* widget);
|
void connectDisplaySignals(DisplayWidget* widget);
|
||||||
void releaseHostDisplay();
|
void releaseHostDisplay();
|
||||||
void updateDisplay();
|
void updateDisplay();
|
||||||
|
|
|
@ -1089,8 +1089,6 @@ struct Pcsx2Config
|
||||||
|
|
||||||
bool MultitapEnabled(uint port) const;
|
bool MultitapEnabled(uint port) const;
|
||||||
|
|
||||||
VsyncMode GetEffectiveVsyncMode() const;
|
|
||||||
|
|
||||||
bool operator==(const Pcsx2Config& right) const;
|
bool operator==(const Pcsx2Config& right) const;
|
||||||
bool operator!=(const Pcsx2Config& right) const
|
bool operator!=(const Pcsx2Config& right) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Frontend/InputManager.h"
|
#include "Frontend/InputManager.h"
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
|
#include "HostDisplay.h"
|
||||||
#include "IconsFontAwesome5.h"
|
#include "IconsFontAwesome5.h"
|
||||||
#include "Recording/InputRecordingControls.h"
|
#include "Recording/InputRecordingControls.h"
|
||||||
#include "VMManager.h"
|
#include "VMManager.h"
|
||||||
|
@ -45,7 +46,7 @@ static void HotkeyAdjustTargetSpeed(double delta)
|
||||||
EmuConfig.Framerate.NominalScalar = std::max(min_speed, EmuConfig.GS.LimitScalar + delta);
|
EmuConfig.Framerate.NominalScalar = std::max(min_speed, EmuConfig.GS.LimitScalar + delta);
|
||||||
VMManager::SetLimiterMode(LimiterModeType::Nominal);
|
VMManager::SetLimiterMode(LimiterModeType::Nominal);
|
||||||
gsUpdateFrequency(EmuConfig);
|
gsUpdateFrequency(EmuConfig);
|
||||||
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
GetMTGS().UpdateVSyncMode();
|
||||||
Host::AddIconOSDMessage("SpeedChanged", ICON_FA_CLOCK,
|
Host::AddIconOSDMessage("SpeedChanged", ICON_FA_CLOCK,
|
||||||
fmt::format("Target speed set to {:.0f}%.", std::round(EmuConfig.Framerate.NominalScalar * 100.0)), 5.0f);
|
fmt::format("Target speed set to {:.0f}%.", std::round(EmuConfig.Framerate.NominalScalar * 100.0)), 5.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,37 +95,37 @@ D3D11HostDisplay::D3D11HostDisplay() = default;
|
||||||
|
|
||||||
D3D11HostDisplay::~D3D11HostDisplay()
|
D3D11HostDisplay::~D3D11HostDisplay()
|
||||||
{
|
{
|
||||||
D3D11HostDisplay::DestroyRenderSurface();
|
D3D11HostDisplay::DestroySurface();
|
||||||
m_context.reset();
|
m_context.reset();
|
||||||
m_device.reset();
|
m_device.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
HostDisplay::RenderAPI D3D11HostDisplay::GetRenderAPI() const
|
RenderAPI D3D11HostDisplay::GetRenderAPI() const
|
||||||
{
|
{
|
||||||
return HostDisplay::RenderAPI::D3D11;
|
return RenderAPI::D3D11;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* D3D11HostDisplay::GetRenderDevice() const
|
void* D3D11HostDisplay::GetDevice() const
|
||||||
{
|
{
|
||||||
return m_device.get();
|
return m_device.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* D3D11HostDisplay::GetRenderContext() const
|
void* D3D11HostDisplay::GetContext() const
|
||||||
{
|
{
|
||||||
return m_context.get();
|
return m_context.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* D3D11HostDisplay::GetRenderSurface() const
|
void* D3D11HostDisplay::GetSurface() const
|
||||||
{
|
{
|
||||||
return m_swap_chain.get();
|
return m_swap_chain.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D11HostDisplay::HasRenderDevice() const
|
bool D3D11HostDisplay::HasDevice() const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(m_device);
|
return static_cast<bool>(m_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D11HostDisplay::HasRenderSurface() const
|
bool D3D11HostDisplay::HasSurface() const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(m_swap_chain);
|
return static_cast<bool>(m_swap_chain);
|
||||||
}
|
}
|
||||||
|
@ -210,10 +210,10 @@ void D3D11HostDisplay::SetVSync(VsyncMode mode)
|
||||||
m_vsync_mode = mode;
|
m_vsync_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device)
|
bool D3D11HostDisplay::CreateDevice(const WindowInfo& wi)
|
||||||
{
|
{
|
||||||
UINT create_flags = 0;
|
UINT create_flags = 0;
|
||||||
if (debug_device)
|
if (EmuConfig.GS.UseDebugDevice)
|
||||||
create_flags |= D3D11_CREATE_DEVICE_DEBUG;
|
create_flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||||
|
|
||||||
ComPtr<IDXGIFactory> temp_dxgi_factory;
|
ComPtr<IDXGIFactory> temp_dxgi_factory;
|
||||||
|
@ -225,17 +225,17 @@ bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 adapter_index;
|
u32 adapter_index;
|
||||||
if (!adapter_name.empty())
|
if (!EmuConfig.GS.Adapter.empty())
|
||||||
{
|
{
|
||||||
AdapterAndModeList adapter_info(GetAdapterAndModeList(temp_dxgi_factory.get()));
|
AdapterAndModeList adapter_info(GetAdapterAndModeList(temp_dxgi_factory.get()));
|
||||||
for (adapter_index = 0; adapter_index < static_cast<u32>(adapter_info.adapter_names.size()); adapter_index++)
|
for (adapter_index = 0; adapter_index < static_cast<u32>(adapter_info.adapter_names.size()); adapter_index++)
|
||||||
{
|
{
|
||||||
if (adapter_name == adapter_info.adapter_names[adapter_index])
|
if (EmuConfig.GS.Adapter == adapter_info.adapter_names[adapter_index])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (adapter_index == static_cast<u32>(adapter_info.adapter_names.size()))
|
if (adapter_index == static_cast<u32>(adapter_info.adapter_names.size()))
|
||||||
{
|
{
|
||||||
Console.Warning("Could not find adapter '%s', using first (%s)", std::string(adapter_name).c_str(),
|
Console.Warning("Could not find adapter '%s', using first (%s)", EmuConfig.GS.Adapter.c_str(),
|
||||||
adapter_info.adapter_names[0].c_str());
|
adapter_info.adapter_names[0].c_str());
|
||||||
adapter_index = 0;
|
adapter_index = 0;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_device && IsDebuggerPresent())
|
if (EmuConfig.GS.UseDebugDevice && IsDebuggerPresent())
|
||||||
{
|
{
|
||||||
ComPtr<ID3D11InfoQueue> info;
|
ComPtr<ID3D11InfoQueue> info;
|
||||||
if (m_device.try_query_to(&info))
|
if (m_device.try_query_to(&info))
|
||||||
|
@ -314,7 +314,7 @@ bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
}
|
}
|
||||||
|
|
||||||
m_window_info = wi;
|
m_window_info = wi;
|
||||||
m_vsync_mode = vsync;
|
m_vsync_mode = Host::GetEffectiveVSyncMode();
|
||||||
|
|
||||||
if (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateSwapChain(nullptr))
|
if (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateSwapChain(nullptr))
|
||||||
return false;
|
return false;
|
||||||
|
@ -322,17 +322,17 @@ bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D11HostDisplay::InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device)
|
bool D3D11HostDisplay::SetupDevice()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D11HostDisplay::MakeRenderContextCurrent()
|
bool D3D11HostDisplay::MakeCurrent()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D11HostDisplay::DoneRenderContextCurrent()
|
bool D3D11HostDisplay::DoneCurrent()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -450,15 +450,15 @@ bool D3D11HostDisplay::CreateSwapChainRTV()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D11HostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
bool D3D11HostDisplay::ChangeWindow(const WindowInfo& new_wi)
|
||||||
{
|
{
|
||||||
DestroyRenderSurface();
|
DestroySurface();
|
||||||
|
|
||||||
m_window_info = new_wi;
|
m_window_info = new_wi;
|
||||||
return CreateSwapChain(nullptr);
|
return CreateSwapChain(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11HostDisplay::DestroyRenderSurface()
|
void D3D11HostDisplay::DestroySurface()
|
||||||
{
|
{
|
||||||
if (IsFullscreen())
|
if (IsFullscreen())
|
||||||
SetFullscreen(false, 0, 0, 0.0f);
|
SetFullscreen(false, 0, 0, 0.0f);
|
||||||
|
@ -559,7 +559,7 @@ std::string D3D11HostDisplay::GetDriverInfo() const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11HostDisplay::ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
void D3D11HostDisplay::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
||||||
{
|
{
|
||||||
if (!m_swap_chain)
|
if (!m_swap_chain)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -36,26 +36,26 @@ public:
|
||||||
~D3D11HostDisplay();
|
~D3D11HostDisplay();
|
||||||
|
|
||||||
RenderAPI GetRenderAPI() const override;
|
RenderAPI GetRenderAPI() const override;
|
||||||
void* GetRenderDevice() const override;
|
void* GetDevice() const override;
|
||||||
void* GetRenderContext() const override;
|
void* GetContext() const override;
|
||||||
void* GetRenderSurface() const override;
|
void* GetSurface() const override;
|
||||||
|
|
||||||
bool HasRenderDevice() const override;
|
bool HasDevice() const override;
|
||||||
bool HasRenderSurface() const override;
|
bool HasSurface() const override;
|
||||||
|
|
||||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) override;
|
bool CreateDevice(const WindowInfo& wi) override;
|
||||||
bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) override;
|
bool SetupDevice() override;
|
||||||
|
|
||||||
bool MakeRenderContextCurrent() override;
|
bool MakeCurrent() override;
|
||||||
bool DoneRenderContextCurrent() override;
|
bool DoneCurrent() override;
|
||||||
|
|
||||||
bool ChangeRenderWindow(const WindowInfo& new_wi) override;
|
bool ChangeWindow(const WindowInfo& new_wi) override;
|
||||||
void ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
||||||
bool SupportsFullscreen() const override;
|
bool SupportsFullscreen() const override;
|
||||||
bool IsFullscreen() override;
|
bool IsFullscreen() override;
|
||||||
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
||||||
AdapterAndModeList GetAdapterAndModeList() override;
|
AdapterAndModeList GetAdapterAndModeList() override;
|
||||||
void DestroyRenderSurface() override;
|
void DestroySurface() override;
|
||||||
std::string GetDriverInfo() const override;
|
std::string GetDriverInfo() const override;
|
||||||
|
|
||||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) override;
|
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) override;
|
||||||
|
|
|
@ -54,37 +54,37 @@ D3D12HostDisplay::~D3D12HostDisplay()
|
||||||
if (g_d3d12_context)
|
if (g_d3d12_context)
|
||||||
{
|
{
|
||||||
g_d3d12_context->WaitForGPUIdle();
|
g_d3d12_context->WaitForGPUIdle();
|
||||||
D3D12HostDisplay::DestroyRenderSurface();
|
D3D12HostDisplay::DestroySurface();
|
||||||
g_d3d12_context->Destroy();
|
g_d3d12_context->Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostDisplay::RenderAPI D3D12HostDisplay::GetRenderAPI() const
|
RenderAPI D3D12HostDisplay::GetRenderAPI() const
|
||||||
{
|
{
|
||||||
return HostDisplay::RenderAPI::D3D12;
|
return RenderAPI::D3D12;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* D3D12HostDisplay::GetRenderDevice() const
|
void* D3D12HostDisplay::GetDevice() const
|
||||||
{
|
{
|
||||||
return g_d3d12_context->GetDevice();
|
return g_d3d12_context->GetDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* D3D12HostDisplay::GetRenderContext() const
|
void* D3D12HostDisplay::GetContext() const
|
||||||
{
|
{
|
||||||
return g_d3d12_context.get();
|
return g_d3d12_context.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* D3D12HostDisplay::GetRenderSurface() const
|
void* D3D12HostDisplay::GetSurface() const
|
||||||
{
|
{
|
||||||
return m_swap_chain.get();
|
return m_swap_chain.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12HostDisplay::HasRenderDevice() const
|
bool D3D12HostDisplay::HasDevice() const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(g_d3d12_context);
|
return static_cast<bool>(g_d3d12_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12HostDisplay::HasRenderSurface() const
|
bool D3D12HostDisplay::HasSurface() const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(m_swap_chain);
|
return static_cast<bool>(m_swap_chain);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ void D3D12HostDisplay::SetVSync(VsyncMode mode)
|
||||||
m_vsync_mode = mode;
|
m_vsync_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device)
|
bool D3D12HostDisplay::CreateDevice(const WindowInfo& wi)
|
||||||
{
|
{
|
||||||
ComPtr<IDXGIFactory> temp_dxgi_factory;
|
ComPtr<IDXGIFactory> temp_dxgi_factory;
|
||||||
HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(temp_dxgi_factory.put()));
|
HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(temp_dxgi_factory.put()));
|
||||||
|
@ -147,18 +147,17 @@ bool D3D12HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 adapter_index;
|
u32 adapter_index;
|
||||||
if (!adapter_name.empty())
|
if (!EmuConfig.GS.Adapter.empty())
|
||||||
{
|
{
|
||||||
AdapterAndModeList adapter_info(GetAdapterAndModeList(temp_dxgi_factory.get()));
|
AdapterAndModeList adapter_info(GetAdapterAndModeList(temp_dxgi_factory.get()));
|
||||||
for (adapter_index = 0; adapter_index < static_cast<u32>(adapter_info.adapter_names.size()); adapter_index++)
|
for (adapter_index = 0; adapter_index < static_cast<u32>(adapter_info.adapter_names.size()); adapter_index++)
|
||||||
{
|
{
|
||||||
if (adapter_name == adapter_info.adapter_names[adapter_index])
|
if (EmuConfig.GS.Adapter == adapter_info.adapter_names[adapter_index])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (adapter_index == static_cast<u32>(adapter_info.adapter_names.size()))
|
if (adapter_index == static_cast<u32>(adapter_info.adapter_names.size()))
|
||||||
{
|
{
|
||||||
Console.Warning("Could not find adapter '%*s', using first (%s)", static_cast<int>(adapter_name.size()),
|
Console.Warning("Could not find adapter '%s', using first (%s)", EmuConfig.GS.Adapter.c_str(), adapter_info.adapter_names[0].c_str());
|
||||||
adapter_name.data(), adapter_info.adapter_names[0].c_str());
|
|
||||||
adapter_index = 0;
|
adapter_index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +167,7 @@ bool D3D12HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
adapter_index = 0;
|
adapter_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!D3D12::Context::Create(temp_dxgi_factory.get(), adapter_index, debug_device))
|
if (!D3D12::Context::Create(temp_dxgi_factory.get(), adapter_index, EmuConfig.GS.UseDebugDevice))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -198,17 +197,17 @@ bool D3D12HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12HostDisplay::InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device)
|
bool D3D12HostDisplay::SetupDevice()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12HostDisplay::MakeRenderContextCurrent()
|
bool D3D12HostDisplay::MakeCurrent()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12HostDisplay::DoneRenderContextCurrent()
|
bool D3D12HostDisplay::DoneCurrent()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -323,15 +322,15 @@ void D3D12HostDisplay::DestroySwapChainRTVs()
|
||||||
m_current_swap_chain_buffer = 0;
|
m_current_swap_chain_buffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12HostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
bool D3D12HostDisplay::ChangeWindow(const WindowInfo& new_wi)
|
||||||
{
|
{
|
||||||
DestroyRenderSurface();
|
DestroySurface();
|
||||||
|
|
||||||
m_window_info = new_wi;
|
m_window_info = new_wi;
|
||||||
return CreateSwapChain(nullptr);
|
return CreateSwapChain(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12HostDisplay::DestroyRenderSurface()
|
void D3D12HostDisplay::DestroySurface()
|
||||||
{
|
{
|
||||||
// For some reason if we don't execute the command list here, the swap chain is in use.. not sure where.
|
// For some reason if we don't execute the command list here, the swap chain is in use.. not sure where.
|
||||||
g_d3d12_context->ExecuteCommandList(true);
|
g_d3d12_context->ExecuteCommandList(true);
|
||||||
|
@ -428,7 +427,7 @@ std::string D3D12HostDisplay::GetDriverInfo() const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12HostDisplay::ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
void D3D12HostDisplay::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
||||||
{
|
{
|
||||||
if (!m_swap_chain)
|
if (!m_swap_chain)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -42,26 +42,26 @@ public:
|
||||||
~D3D12HostDisplay();
|
~D3D12HostDisplay();
|
||||||
|
|
||||||
RenderAPI GetRenderAPI() const override;
|
RenderAPI GetRenderAPI() const override;
|
||||||
void* GetRenderDevice() const override;
|
void* GetDevice() const override;
|
||||||
void* GetRenderContext() const override;
|
void* GetContext() const override;
|
||||||
void* GetRenderSurface() const override;
|
void* GetSurface() const override;
|
||||||
|
|
||||||
bool HasRenderDevice() const override;
|
bool HasDevice() const override;
|
||||||
bool HasRenderSurface() const override;
|
bool HasSurface() const override;
|
||||||
|
|
||||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) override;
|
bool CreateDevice(const WindowInfo& wi) override;
|
||||||
bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) override;
|
bool SetupDevice() override;
|
||||||
|
|
||||||
bool MakeRenderContextCurrent() override;
|
bool MakeCurrent() override;
|
||||||
bool DoneRenderContextCurrent() override;
|
bool DoneCurrent() override;
|
||||||
|
|
||||||
bool ChangeRenderWindow(const WindowInfo& new_wi) override;
|
bool ChangeWindow(const WindowInfo& new_wi) override;
|
||||||
void ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
||||||
bool SupportsFullscreen() const override;
|
bool SupportsFullscreen() const override;
|
||||||
bool IsFullscreen() override;
|
bool IsFullscreen() override;
|
||||||
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
||||||
AdapterAndModeList GetAdapterAndModeList() override;
|
AdapterAndModeList GetAdapterAndModeList() override;
|
||||||
void DestroyRenderSurface() override;
|
void DestroySurface() override;
|
||||||
std::string GetDriverInfo() const override;
|
std::string GetDriverInfo() const override;
|
||||||
|
|
||||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) override;
|
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) override;
|
||||||
|
|
|
@ -202,7 +202,6 @@ namespace FullscreenUI
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Main
|
// Main
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
static void UpdateForcedVsync(bool should_force);
|
|
||||||
static void UpdateGameDetails(std::string path, std::string serial, std::string title, u32 crc);
|
static void UpdateGameDetails(std::string path, std::string serial, std::string title, u32 crc);
|
||||||
static void ToggleTheme();
|
static void ToggleTheme();
|
||||||
static void PauseForMenuOpen();
|
static void PauseForMenuOpen();
|
||||||
|
@ -567,10 +566,6 @@ bool FullscreenUI::Initialize()
|
||||||
SwitchToLanding();
|
SwitchToLanding();
|
||||||
}
|
}
|
||||||
|
|
||||||
// force vsync on so we don't run at thousands of fps
|
|
||||||
// Initialize is called on the GS thread, so we can access the display directly.
|
|
||||||
UpdateForcedVsync(VMManager::GetState() != VMState::Running);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,15 +580,6 @@ bool FullscreenUI::HasActiveWindow()
|
||||||
ImGuiFullscreen::IsFileSelectorOpen();
|
ImGuiFullscreen::IsFileSelectorOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::UpdateForcedVsync(bool should_force)
|
|
||||||
{
|
|
||||||
// force vsync on so we don't run at thousands of fps
|
|
||||||
const VsyncMode mode = EmuConfig.GetEffectiveVsyncMode();
|
|
||||||
|
|
||||||
// toss it through regardless of the mode, because options can change it
|
|
||||||
g_host_display->SetVSync((should_force && mode == VsyncMode::Off) ? VsyncMode::On : mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FullscreenUI::CheckForConfigChanges(const Pcsx2Config& old_config)
|
void FullscreenUI::CheckForConfigChanges(const Pcsx2Config& old_config)
|
||||||
{
|
{
|
||||||
if (!IsInitialized())
|
if (!IsInitialized())
|
||||||
|
@ -635,12 +621,8 @@ void FullscreenUI::OnVMPaused()
|
||||||
if (!IsInitialized())
|
if (!IsInitialized())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GetMTGS().RunOnGSThread([]() {
|
// Force vsync on.
|
||||||
if (!IsInitialized())
|
GetMTGS().UpdateVSyncMode();
|
||||||
return;
|
|
||||||
|
|
||||||
UpdateForcedVsync(true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::OnVMResumed()
|
void FullscreenUI::OnVMResumed()
|
||||||
|
@ -648,12 +630,8 @@ void FullscreenUI::OnVMResumed()
|
||||||
if (!IsInitialized())
|
if (!IsInitialized())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GetMTGS().RunOnGSThread([]() {
|
// Restore game vsync.
|
||||||
if (!IsInitialized())
|
GetMTGS().UpdateVSyncMode();
|
||||||
return;
|
|
||||||
|
|
||||||
UpdateForcedVsync(false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::OnVMDestroyed()
|
void FullscreenUI::OnVMDestroyed()
|
||||||
|
@ -667,7 +645,7 @@ void FullscreenUI::OnVMDestroyed()
|
||||||
|
|
||||||
s_pause_menu_was_open = false;
|
s_pause_menu_was_open = false;
|
||||||
SwitchToLanding();
|
SwitchToLanding();
|
||||||
UpdateForcedVsync(true);
|
GetMTGS().UpdateVSyncMode();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,25 +51,25 @@ public:
|
||||||
MetalHostDisplay();
|
MetalHostDisplay();
|
||||||
~MetalHostDisplay();
|
~MetalHostDisplay();
|
||||||
RenderAPI GetRenderAPI() const override;
|
RenderAPI GetRenderAPI() const override;
|
||||||
void* GetRenderDevice() const override;
|
void* GetDevice() const override;
|
||||||
void* GetRenderContext() const override;
|
void* GetContext() const override;
|
||||||
void* GetRenderSurface() const override;
|
void* GetSurface() const override;
|
||||||
|
|
||||||
bool HasRenderDevice() const override;
|
bool HasDevice() const override;
|
||||||
bool HasRenderSurface() const override;
|
bool HasSurface() const override;
|
||||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) override;
|
bool CreateDevice(const WindowInfo& wi) override;
|
||||||
bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) override;
|
bool SetupDevice() override;
|
||||||
bool MakeRenderContextCurrent() override;
|
bool MakeCurrent() override;
|
||||||
bool DoneRenderContextCurrent() override;
|
bool DoneCurrent() override;
|
||||||
void DestroyRenderSurface() override;
|
void DestroySurface() override;
|
||||||
bool ChangeRenderWindow(const WindowInfo& wi) override;
|
bool ChangeWindow(const WindowInfo& wi) override;
|
||||||
bool SupportsFullscreen() const override;
|
bool SupportsFullscreen() const override;
|
||||||
bool IsFullscreen() override;
|
bool IsFullscreen() override;
|
||||||
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
||||||
AdapterAndModeList GetAdapterAndModeList() override;
|
AdapterAndModeList GetAdapterAndModeList() override;
|
||||||
std::string GetDriverInfo() const override;
|
std::string GetDriverInfo() const override;
|
||||||
|
|
||||||
void ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
||||||
|
|
||||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) override;
|
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) override;
|
||||||
void UpdateTexture(id<MTLTexture> texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride);
|
void UpdateTexture(id<MTLTexture> texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride);
|
||||||
|
|
|
@ -49,7 +49,7 @@ MetalHostDisplay::MetalHostDisplay()
|
||||||
|
|
||||||
MetalHostDisplay::~MetalHostDisplay()
|
MetalHostDisplay::~MetalHostDisplay()
|
||||||
{
|
{
|
||||||
MetalHostDisplay::DestroyRenderSurface();
|
MetalHostDisplay::DestroySurface();
|
||||||
m_queue = nullptr;
|
m_queue = nullptr;
|
||||||
m_dev.Reset();
|
m_dev.Reset();
|
||||||
}
|
}
|
||||||
|
@ -72,16 +72,16 @@ static void OnMainThread(Fn&& fn)
|
||||||
dispatch_sync(dispatch_get_main_queue(), fn);
|
dispatch_sync(dispatch_get_main_queue(), fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
HostDisplay::RenderAPI MetalHostDisplay::GetRenderAPI() const
|
RenderAPI MetalHostDisplay::GetRenderAPI() const
|
||||||
{
|
{
|
||||||
return RenderAPI::Metal;
|
return RenderAPI::Metal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* MetalHostDisplay::GetRenderDevice() const { return const_cast<void*>(static_cast<const void*>(&m_dev)); }
|
void* MetalHostDisplay::GetDevice() const { return const_cast<void*>(static_cast<const void*>(&m_dev)); }
|
||||||
void* MetalHostDisplay::GetRenderContext() const { return (__bridge void*)m_queue; }
|
void* MetalHostDisplay::GetContext() const { return (__bridge void*)m_queue; }
|
||||||
void* MetalHostDisplay::GetRenderSurface() const { return (__bridge void*)m_layer; }
|
void* MetalHostDisplay::GetSurface() const { return (__bridge void*)m_layer; }
|
||||||
bool MetalHostDisplay::HasRenderDevice() const { return m_dev.IsOk(); }
|
bool MetalHostDisplay::HasDevice() const { return m_dev.IsOk(); }
|
||||||
bool MetalHostDisplay::HasRenderSurface() const { return static_cast<bool>(m_layer);}
|
bool MetalHostDisplay::HasSurface() const { return static_cast<bool>(m_layer);}
|
||||||
|
|
||||||
void MetalHostDisplay::AttachSurfaceOnMainThread()
|
void MetalHostDisplay::AttachSurfaceOnMainThread()
|
||||||
{
|
{
|
||||||
|
@ -103,12 +103,11 @@ void MetalHostDisplay::DetachSurfaceOnMainThread()
|
||||||
m_layer = nullptr;
|
m_layer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetalHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device)
|
bool MetalHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||||
{ @autoreleasepool {
|
{ @autoreleasepool {
|
||||||
m_window_info = wi;
|
m_window_info = wi;
|
||||||
pxAssertRel(!m_dev.dev, "Device already created!");
|
pxAssertRel(!m_dev.dev, "Device already created!");
|
||||||
std::string null_terminated_adapter_name(adapter_name);
|
NSString* ns_adapter_name = [NSString stringWithUTF8String:EmuConfig.GS.Adapter.c_str()];
|
||||||
NSString* ns_adapter_name = [NSString stringWithUTF8String:null_terminated_adapter_name.c_str()];
|
|
||||||
auto devs = MRCTransfer(MTLCopyAllDevices());
|
auto devs = MRCTransfer(MTLCopyAllDevices());
|
||||||
for (id<MTLDevice> dev in devs.Get())
|
for (id<MTLDevice> dev in devs.Get())
|
||||||
{
|
{
|
||||||
|
@ -117,8 +116,8 @@ bool MetalHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
}
|
}
|
||||||
if (!m_dev.dev)
|
if (!m_dev.dev)
|
||||||
{
|
{
|
||||||
if (!adapter_name.empty())
|
if (!EmuConfig.GS.Adapter.empty())
|
||||||
Console.Warning("Metal: Couldn't find adapter %s, using default", null_terminated_adapter_name.c_str());
|
Console.Warning("Metal: Couldn't find adapter %s, using default", EmuConfig.GS.Adapter.c_str());
|
||||||
m_dev = GSMTLDevice(MRCTransfer(MTLCreateSystemDefaultDevice()));
|
m_dev = GSMTLDevice(MRCTransfer(MTLCreateSystemDefaultDevice()));
|
||||||
if (!m_dev.dev)
|
if (!m_dev.dev)
|
||||||
Host::ReportErrorAsync("No Metal Devices Available", "No Metal-supporting GPUs were found. PCSX2 requires a Metal GPU (available on all macs from 2012 onwards).");
|
Host::ReportErrorAsync("No Metal Devices Available", "No Metal-supporting GPUs were found. PCSX2 requires a Metal GPU (available on all macs from 2012 onwards).");
|
||||||
|
@ -146,22 +145,22 @@ bool MetalHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
|
||||||
{
|
{
|
||||||
AttachSurfaceOnMainThread();
|
AttachSurfaceOnMainThread();
|
||||||
});
|
});
|
||||||
SetVSync(vsync);
|
SetVSync(Host::GetEffectiveVSyncMode());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
bool MetalHostDisplay::InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device)
|
bool MetalHostDisplay::SetupDevice()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetalHostDisplay::MakeRenderContextCurrent() { return true; }
|
bool MetalHostDisplay::MakeCurrent() { return true; }
|
||||||
bool MetalHostDisplay::DoneRenderContextCurrent() { return true; }
|
bool MetalHostDisplay::DoneCurrent() { return true; }
|
||||||
|
|
||||||
void MetalHostDisplay::DestroyRenderSurface()
|
void MetalHostDisplay::DestroySurface()
|
||||||
{
|
{
|
||||||
if (!m_layer)
|
if (!m_layer)
|
||||||
return;
|
return;
|
||||||
|
@ -169,7 +168,7 @@ void MetalHostDisplay::DestroyRenderSurface()
|
||||||
m_layer = nullptr;
|
m_layer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetalHostDisplay::ChangeRenderWindow(const WindowInfo& wi)
|
bool MetalHostDisplay::ChangeWindow(const WindowInfo& wi)
|
||||||
{
|
{
|
||||||
OnMainThread([this, &wi]
|
OnMainThread([this, &wi]
|
||||||
{
|
{
|
||||||
|
@ -201,7 +200,7 @@ std::string MetalHostDisplay::GetDriverInfo() const
|
||||||
return desc;
|
return desc;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
void MetalHostDisplay::ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
void MetalHostDisplay::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
||||||
{
|
{
|
||||||
m_window_info.surface_scale = new_window_scale;
|
m_window_info.surface_scale = new_window_scale;
|
||||||
if (m_window_info.surface_width == static_cast<u32>(new_window_width) && m_window_info.surface_height == static_cast<u32>(new_window_height))
|
if (m_window_info.surface_width == static_cast<u32>(new_window_width) && m_window_info.surface_height == static_cast<u32>(new_window_height))
|
||||||
|
|
|
@ -60,22 +60,22 @@ OpenGLHostDisplay::~OpenGLHostDisplay()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostDisplay::RenderAPI OpenGLHostDisplay::GetRenderAPI() const
|
RenderAPI OpenGLHostDisplay::GetRenderAPI() const
|
||||||
{
|
{
|
||||||
return m_gl_context->IsGLES() ? RenderAPI::OpenGLES : RenderAPI::OpenGL;
|
return m_gl_context->IsGLES() ? RenderAPI::OpenGLES : RenderAPI::OpenGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* OpenGLHostDisplay::GetRenderDevice() const
|
void* OpenGLHostDisplay::GetDevice() const
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* OpenGLHostDisplay::GetRenderContext() const
|
void* OpenGLHostDisplay::GetContext() const
|
||||||
{
|
{
|
||||||
return m_gl_context.get();
|
return m_gl_context.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* OpenGLHostDisplay::GetRenderSurface() const
|
void* OpenGLHostDisplay::GetSurface() const
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -188,17 +188,17 @@ std::string OpenGLHostDisplay::GetGLSLVersionHeader() const
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLHostDisplay::HasRenderDevice() const
|
bool OpenGLHostDisplay::HasDevice() const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(m_gl_context);
|
return static_cast<bool>(m_gl_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLHostDisplay::HasRenderSurface() const
|
bool OpenGLHostDisplay::HasSurface() const
|
||||||
{
|
{
|
||||||
return m_window_info.type != WindowInfo::Type::Surfaceless;
|
return m_window_info.type != WindowInfo::Type::Surfaceless;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device)
|
bool OpenGLHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||||
{
|
{
|
||||||
m_gl_context = GL::Context::Create(wi);
|
m_gl_context = GL::Context::Create(wi);
|
||||||
if (!m_gl_context)
|
if (!m_gl_context)
|
||||||
|
@ -209,11 +209,11 @@ bool OpenGLHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_vie
|
||||||
}
|
}
|
||||||
|
|
||||||
m_window_info = m_gl_context->GetWindowInfo();
|
m_window_info = m_gl_context->GetWindowInfo();
|
||||||
m_vsync_mode = vsync;
|
m_vsync_mode = Host::GetEffectiveVSyncMode();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLHostDisplay::InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device)
|
bool OpenGLHostDisplay::SetupDevice()
|
||||||
{
|
{
|
||||||
SetSwapInterval();
|
SetSwapInterval();
|
||||||
GL::Program::ResetLastProgram();
|
GL::Program::ResetLastProgram();
|
||||||
|
@ -226,7 +226,7 @@ void OpenGLHostDisplay::SetSwapInterval()
|
||||||
m_gl_context->SetSwapInterval(interval);
|
m_gl_context->SetSwapInterval(interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLHostDisplay::MakeRenderContextCurrent()
|
bool OpenGLHostDisplay::MakeCurrent()
|
||||||
{
|
{
|
||||||
if (!m_gl_context->MakeCurrent())
|
if (!m_gl_context->MakeCurrent())
|
||||||
{
|
{
|
||||||
|
@ -238,12 +238,12 @@ bool OpenGLHostDisplay::MakeRenderContextCurrent()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLHostDisplay::DoneRenderContextCurrent()
|
bool OpenGLHostDisplay::DoneCurrent()
|
||||||
{
|
{
|
||||||
return m_gl_context->DoneCurrent();
|
return m_gl_context->DoneCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
bool OpenGLHostDisplay::ChangeWindow(const WindowInfo& new_wi)
|
||||||
{
|
{
|
||||||
pxAssert(m_gl_context);
|
pxAssert(m_gl_context);
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ bool OpenGLHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLHostDisplay::ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
void OpenGLHostDisplay::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
||||||
{
|
{
|
||||||
if (!m_gl_context)
|
if (!m_gl_context)
|
||||||
return;
|
return;
|
||||||
|
@ -309,7 +309,7 @@ HostDisplay::AdapterAndModeList OpenGLHostDisplay::GetAdapterAndModeList()
|
||||||
return aml;
|
return aml;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLHostDisplay::DestroyRenderSurface()
|
void OpenGLHostDisplay::DestroySurface()
|
||||||
{
|
{
|
||||||
if (!m_gl_context)
|
if (!m_gl_context)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -31,26 +31,26 @@ public:
|
||||||
~OpenGLHostDisplay();
|
~OpenGLHostDisplay();
|
||||||
|
|
||||||
RenderAPI GetRenderAPI() const override;
|
RenderAPI GetRenderAPI() const override;
|
||||||
void* GetRenderDevice() const override;
|
void* GetDevice() const override;
|
||||||
void* GetRenderContext() const override;
|
void* GetContext() const override;
|
||||||
void* GetRenderSurface() const override;
|
void* GetSurface() const override;
|
||||||
|
|
||||||
bool HasRenderDevice() const override;
|
bool HasDevice() const override;
|
||||||
bool HasRenderSurface() const override;
|
bool HasSurface() const override;
|
||||||
|
|
||||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) override;
|
bool CreateDevice(const WindowInfo& wi) override;
|
||||||
bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) override;
|
bool SetupDevice() override;
|
||||||
|
|
||||||
bool MakeRenderContextCurrent() override;
|
bool MakeCurrent() override;
|
||||||
bool DoneRenderContextCurrent() override;
|
bool DoneCurrent() override;
|
||||||
|
|
||||||
bool ChangeRenderWindow(const WindowInfo& new_wi) override;
|
bool ChangeWindow(const WindowInfo& new_wi) override;
|
||||||
void ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
||||||
bool SupportsFullscreen() const override;
|
bool SupportsFullscreen() const override;
|
||||||
bool IsFullscreen() override;
|
bool IsFullscreen() override;
|
||||||
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
||||||
AdapterAndModeList GetAdapterAndModeList() override;
|
AdapterAndModeList GetAdapterAndModeList() override;
|
||||||
void DestroyRenderSurface() override;
|
void DestroySurface() override;
|
||||||
std::string GetDriverInfo() const override;
|
std::string GetDriverInfo() const override;
|
||||||
|
|
||||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic) override;
|
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic) override;
|
||||||
|
|
|
@ -61,27 +61,27 @@ VulkanHostDisplay::~VulkanHostDisplay()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostDisplay::RenderAPI VulkanHostDisplay::GetRenderAPI() const
|
RenderAPI VulkanHostDisplay::GetRenderAPI() const
|
||||||
{
|
{
|
||||||
return HostDisplay::RenderAPI::Vulkan;
|
return RenderAPI::Vulkan;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* VulkanHostDisplay::GetRenderDevice() const
|
void* VulkanHostDisplay::GetDevice() const
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* VulkanHostDisplay::GetRenderContext() const
|
void* VulkanHostDisplay::GetContext() const
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* VulkanHostDisplay::GetRenderSurface() const
|
void* VulkanHostDisplay::GetSurface() const
|
||||||
{
|
{
|
||||||
return m_swap_chain.get();
|
return m_swap_chain.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
bool VulkanHostDisplay::ChangeWindow(const WindowInfo& new_wi)
|
||||||
{
|
{
|
||||||
g_vulkan_context->WaitForGPUIdle();
|
g_vulkan_context->WaitForGPUIdle();
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ bool VulkanHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHostDisplay::ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
void VulkanHostDisplay::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
||||||
{
|
{
|
||||||
if (m_swap_chain->GetWidth() == static_cast<u32>(new_window_width) && m_swap_chain->GetHeight() == static_cast<u32>(new_window_height))
|
if (m_swap_chain->GetWidth() == static_cast<u32>(new_window_width) && m_swap_chain->GetHeight() == static_cast<u32>(new_window_height))
|
||||||
{
|
{
|
||||||
|
@ -167,7 +167,7 @@ HostDisplay::AdapterAndModeList VulkanHostDisplay::GetAdapterAndModeList()
|
||||||
return StaticGetAdapterAndModeList(m_window_info.type != WindowInfo::Type::Surfaceless ? &m_window_info : nullptr);
|
return StaticGetAdapterAndModeList(m_window_info.type != WindowInfo::Type::Surfaceless ? &m_window_info : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHostDisplay::DestroyRenderSurface()
|
void VulkanHostDisplay::DestroySurface()
|
||||||
{
|
{
|
||||||
g_vulkan_context->WaitForGPUIdle();
|
g_vulkan_context->WaitForGPUIdle();
|
||||||
m_swap_chain.reset();
|
m_swap_chain.reset();
|
||||||
|
@ -275,14 +275,13 @@ void VulkanHostDisplay::SetVSync(VsyncMode mode)
|
||||||
m_vsync_mode = mode;
|
m_vsync_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::CreateRenderDevice(
|
bool VulkanHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||||
const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device)
|
|
||||||
{
|
{
|
||||||
// debug_device = true;
|
|
||||||
|
|
||||||
WindowInfo local_wi(wi);
|
WindowInfo local_wi(wi);
|
||||||
if (!Vulkan::Context::Create(adapter_name, &local_wi, &m_swap_chain, GetPreferredPresentModeForVsyncMode(vsync), threaded_presentation,
|
const VsyncMode vsync = Host::GetEffectiveVSyncMode();
|
||||||
debug_device, debug_device))
|
const bool debug_device = EmuConfig.GS.UseDebugDevice;
|
||||||
|
if (!Vulkan::Context::Create(EmuConfig.GS.Adapter, &local_wi, &m_swap_chain, GetPreferredPresentModeForVsyncMode(vsync),
|
||||||
|
EmuConfig.GS.ThreadedPresentation, debug_device, debug_device))
|
||||||
{
|
{
|
||||||
Console.Error("Failed to create Vulkan context");
|
Console.Error("Failed to create Vulkan context");
|
||||||
m_window_info = {};
|
m_window_info = {};
|
||||||
|
@ -295,18 +294,18 @@ bool VulkanHostDisplay::CreateRenderDevice(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device)
|
bool VulkanHostDisplay::SetupDevice()
|
||||||
{
|
{
|
||||||
Vulkan::ShaderCache::Create(shader_cache_directory, SHADER_CACHE_VERSION, debug_device);
|
Vulkan::ShaderCache::Create(EmuFolders::Cache, SHADER_CACHE_VERSION, EmuConfig.GS.UseDebugDevice);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::HasRenderDevice() const
|
bool VulkanHostDisplay::HasDevice() const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(g_vulkan_context);
|
return static_cast<bool>(g_vulkan_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::HasRenderSurface() const
|
bool VulkanHostDisplay::HasSurface() const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(m_swap_chain);
|
return static_cast<bool>(m_swap_chain);
|
||||||
}
|
}
|
||||||
|
@ -327,12 +326,12 @@ bool VulkanHostDisplay::UpdateImGuiFontTexture()
|
||||||
return ImGui_ImplVulkan_CreateFontsTexture();
|
return ImGui_ImplVulkan_CreateFontsTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::MakeRenderContextCurrent()
|
bool VulkanHostDisplay::MakeCurrent()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::DoneRenderContextCurrent()
|
bool VulkanHostDisplay::DoneCurrent()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +352,7 @@ bool VulkanHostDisplay::BeginPresent(bool frame_skip)
|
||||||
{
|
{
|
||||||
if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR)
|
if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
{
|
{
|
||||||
ResizeRenderWindow(0, 0, m_window_info.surface_scale);
|
ResizeWindow(0, 0, m_window_info.surface_scale);
|
||||||
res = m_swap_chain->AcquireNextImage();
|
res = m_swap_chain->AcquireNextImage();
|
||||||
}
|
}
|
||||||
else if (res == VK_ERROR_SURFACE_LOST_KHR)
|
else if (res == VK_ERROR_SURFACE_LOST_KHR)
|
||||||
|
|
|
@ -20,26 +20,26 @@ public:
|
||||||
~VulkanHostDisplay();
|
~VulkanHostDisplay();
|
||||||
|
|
||||||
RenderAPI GetRenderAPI() const override;
|
RenderAPI GetRenderAPI() const override;
|
||||||
void* GetRenderDevice() const override;
|
void* GetDevice() const override;
|
||||||
void* GetRenderContext() const override;
|
void* GetContext() const override;
|
||||||
void* GetRenderSurface() const override;
|
void* GetSurface() const override;
|
||||||
|
|
||||||
bool HasRenderDevice() const override;
|
bool HasDevice() const override;
|
||||||
bool HasRenderSurface() const override;
|
bool HasSurface() const override;
|
||||||
|
|
||||||
bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) override;
|
bool CreateDevice(const WindowInfo& wi) override;
|
||||||
bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) override;
|
bool SetupDevice() override;
|
||||||
|
|
||||||
bool MakeRenderContextCurrent() override;
|
bool MakeCurrent() override;
|
||||||
bool DoneRenderContextCurrent() override;
|
bool DoneCurrent() override;
|
||||||
|
|
||||||
bool ChangeRenderWindow(const WindowInfo& new_wi) override;
|
bool ChangeWindow(const WindowInfo& new_wi) override;
|
||||||
void ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) override;
|
||||||
bool SupportsFullscreen() const override;
|
bool SupportsFullscreen() const override;
|
||||||
bool IsFullscreen() override;
|
bool IsFullscreen() override;
|
||||||
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
||||||
AdapterAndModeList GetAdapterAndModeList() override;
|
AdapterAndModeList GetAdapterAndModeList() override;
|
||||||
void DestroyRenderSurface() override;
|
void DestroySurface() override;
|
||||||
std::string GetDriverInfo() const override;
|
std::string GetDriverInfo() const override;
|
||||||
|
|
||||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) override;
|
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) override;
|
||||||
|
|
|
@ -413,7 +413,8 @@ public:
|
||||||
void ApplySettings();
|
void ApplySettings();
|
||||||
void ResizeDisplayWindow(int width, int height, float scale);
|
void ResizeDisplayWindow(int width, int height, float scale);
|
||||||
void UpdateDisplayWindow();
|
void UpdateDisplayWindow();
|
||||||
void SetVSync(VsyncMode mode);
|
void SetVSyncMode(VsyncMode mode);
|
||||||
|
void UpdateVSyncMode();
|
||||||
void SwitchRenderer(GSRendererType renderer, bool display_message = true);
|
void SwitchRenderer(GSRendererType renderer, bool display_message = true);
|
||||||
void SetSoftwareRendering(bool software, bool display_message = true);
|
void SetSoftwareRendering(bool software, bool display_message = true);
|
||||||
void ToggleSoftwareRendering();
|
void ToggleSoftwareRendering();
|
||||||
|
|
|
@ -76,7 +76,7 @@ static HRESULT s_hr = E_FAIL;
|
||||||
|
|
||||||
Pcsx2Config::GSOptions GSConfig;
|
Pcsx2Config::GSOptions GSConfig;
|
||||||
|
|
||||||
static HostDisplay::RenderAPI s_render_api;
|
static RenderAPI s_render_api;
|
||||||
|
|
||||||
int GSinit()
|
int GSinit()
|
||||||
{
|
{
|
||||||
|
@ -164,45 +164,45 @@ void GSclose()
|
||||||
Host::ReleaseHostDisplay();
|
Host::ReleaseHostDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
static HostDisplay::RenderAPI GetAPIForRenderer(GSRendererType renderer)
|
static RenderAPI GetAPIForRenderer(GSRendererType renderer)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// On Windows, we use DX11 for software, since it's always available.
|
// On Windows, we use DX11 for software, since it's always available.
|
||||||
constexpr HostDisplay::RenderAPI default_api = HostDisplay::RenderAPI::D3D11;
|
constexpr RenderAPI default_api = RenderAPI::D3D11;
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
// For Macs, default to Metal.
|
// For Macs, default to Metal.
|
||||||
constexpr HostDisplay::RenderAPI default_api = HostDisplay::RenderAPI::Metal;
|
constexpr RenderAPI default_api = RenderAPI::Metal;
|
||||||
#else
|
#else
|
||||||
// For Linux, default to OpenGL (because of hardware compatibility), if we
|
// For Linux, default to OpenGL (because of hardware compatibility), if we
|
||||||
// have it, otherwise Vulkan (if we have it).
|
// have it, otherwise Vulkan (if we have it).
|
||||||
#if defined(ENABLE_OPENGL)
|
#if defined(ENABLE_OPENGL)
|
||||||
constexpr HostDisplay::RenderAPI default_api = HostDisplay::RenderAPI::OpenGL;
|
constexpr RenderAPI default_api = RenderAPI::OpenGL;
|
||||||
#elif defined(ENABLE_VULKAN)
|
#elif defined(ENABLE_VULKAN)
|
||||||
constexpr HostDisplay::RenderAPI default_api = HostDisplay::RenderAPI::Vulkan;
|
constexpr RenderAPI default_api = RenderAPI::Vulkan;
|
||||||
#else
|
#else
|
||||||
constexpr HostDisplay::RenderAPI default_api = HostDisplay::RenderAPI::None;
|
constexpr RenderAPI default_api = RenderAPI::None;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (renderer)
|
switch (renderer)
|
||||||
{
|
{
|
||||||
case GSRendererType::OGL:
|
case GSRendererType::OGL:
|
||||||
return HostDisplay::RenderAPI::OpenGL;
|
return RenderAPI::OpenGL;
|
||||||
|
|
||||||
case GSRendererType::VK:
|
case GSRendererType::VK:
|
||||||
return HostDisplay::RenderAPI::Vulkan;
|
return RenderAPI::Vulkan;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
case GSRendererType::DX11:
|
case GSRendererType::DX11:
|
||||||
return HostDisplay::RenderAPI::D3D11;
|
return RenderAPI::D3D11;
|
||||||
|
|
||||||
case GSRendererType::DX12:
|
case GSRendererType::DX12:
|
||||||
return HostDisplay::RenderAPI::D3D12;
|
return RenderAPI::D3D12;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
case GSRendererType::Metal:
|
case GSRendererType::Metal:
|
||||||
return HostDisplay::RenderAPI::Metal;
|
return RenderAPI::Metal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -217,27 +217,27 @@ static bool DoGSOpen(GSRendererType renderer, u8* basemem)
|
||||||
switch (g_host_display->GetRenderAPI())
|
switch (g_host_display->GetRenderAPI())
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
case HostDisplay::RenderAPI::D3D11:
|
case RenderAPI::D3D11:
|
||||||
g_gs_device = std::make_unique<GSDevice11>();
|
g_gs_device = std::make_unique<GSDevice11>();
|
||||||
break;
|
break;
|
||||||
case HostDisplay::RenderAPI::D3D12:
|
case RenderAPI::D3D12:
|
||||||
g_gs_device = std::make_unique<GSDevice12>();
|
g_gs_device = std::make_unique<GSDevice12>();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
case HostDisplay::RenderAPI::Metal:
|
case RenderAPI::Metal:
|
||||||
g_gs_device = std::unique_ptr<GSDevice>(MakeGSDeviceMTL());
|
g_gs_device = std::unique_ptr<GSDevice>(MakeGSDeviceMTL());
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_OPENGL
|
#ifdef ENABLE_OPENGL
|
||||||
case HostDisplay::RenderAPI::OpenGL:
|
case RenderAPI::OpenGL:
|
||||||
case HostDisplay::RenderAPI::OpenGLES:
|
case RenderAPI::OpenGLES:
|
||||||
g_gs_device = std::make_unique<GSDeviceOGL>();
|
g_gs_device = std::make_unique<GSDeviceOGL>();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_VULKAN
|
#ifdef ENABLE_VULKAN
|
||||||
case HostDisplay::RenderAPI::Vulkan:
|
case RenderAPI::Vulkan:
|
||||||
g_gs_device = std::make_unique<GSDeviceVK>();
|
g_gs_device = std::make_unique<GSDeviceVK>();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -279,13 +279,6 @@ static bool DoGSOpen(GSRendererType renderer, u8* basemem)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCSX2_CORE
|
|
||||||
// Don't override the fullscreen UI's vsync choice.
|
|
||||||
if (!FullscreenUI::IsInitialized())
|
|
||||||
g_host_display->SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
|
||||||
#else
|
|
||||||
g_host_display->SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
|
||||||
#endif
|
|
||||||
GSConfig.OsdShowGPU = EmuConfig.GS.OsdShowGPU && g_host_display->SetGPUTimingEnabled(true);
|
GSConfig.OsdShowGPU = EmuConfig.GS.OsdShowGPU && g_host_display->SetGPUTimingEnabled(true);
|
||||||
|
|
||||||
g_gs_renderer->SetRegsMem(basemem);
|
g_gs_renderer->SetRegsMem(basemem);
|
||||||
|
@ -774,9 +767,9 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
||||||
// Options which need a full teardown/recreate.
|
// Options which need a full teardown/recreate.
|
||||||
if (!GSConfig.RestartOptionsAreEqual(old_config))
|
if (!GSConfig.RestartOptionsAreEqual(old_config))
|
||||||
{
|
{
|
||||||
HostDisplay::RenderAPI existing_api = g_host_display->GetRenderAPI();
|
RenderAPI existing_api = g_host_display->GetRenderAPI();
|
||||||
if (existing_api == HostDisplay::RenderAPI::OpenGLES)
|
if (existing_api == RenderAPI::OpenGLES)
|
||||||
existing_api = HostDisplay::RenderAPI::OpenGL;
|
existing_api = RenderAPI::OpenGL;
|
||||||
|
|
||||||
const bool do_full_restart = (
|
const bool do_full_restart = (
|
||||||
existing_api != GetAPIForRenderer(GSConfig.Renderer) ||
|
existing_api != GetAPIForRenderer(GSConfig.Renderer) ||
|
||||||
|
@ -877,9 +870,9 @@ void GSSwitchRenderer(GSRendererType new_renderer)
|
||||||
if (!g_gs_renderer || GSConfig.Renderer == new_renderer)
|
if (!g_gs_renderer || GSConfig.Renderer == new_renderer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
HostDisplay::RenderAPI existing_api = g_host_display->GetRenderAPI();
|
RenderAPI existing_api = g_host_display->GetRenderAPI();
|
||||||
if (existing_api == HostDisplay::RenderAPI::OpenGLES)
|
if (existing_api == RenderAPI::OpenGLES)
|
||||||
existing_api = HostDisplay::RenderAPI::OpenGL;
|
existing_api = RenderAPI::OpenGL;
|
||||||
|
|
||||||
const bool is_software_switch = (new_renderer == GSRendererType::SW || GSConfig.Renderer == GSRendererType::SW);
|
const bool is_software_switch = (new_renderer == GSRendererType::SW || GSConfig.Renderer == GSRendererType::SW);
|
||||||
const bool recreate_display = (!is_software_switch && existing_api != GetAPIForRenderer(new_renderer));
|
const bool recreate_display = (!is_software_switch && existing_api != GetAPIForRenderer(new_renderer));
|
||||||
|
|
|
@ -79,14 +79,14 @@ bool GSDevice11::Create()
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL level;
|
D3D_FEATURE_LEVEL level;
|
||||||
|
|
||||||
if (g_host_display->GetRenderAPI() != HostDisplay::RenderAPI::D3D11)
|
if (g_host_display->GetRenderAPI() != RenderAPI::D3D11)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Render API is incompatible with D3D11\n");
|
Console.Error("Render API is incompatible with D3D11");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dev = static_cast<ID3D11Device*>(g_host_display->GetRenderDevice());
|
m_dev = static_cast<ID3D11Device*>(g_host_display->GetDevice());
|
||||||
m_ctx = static_cast<ID3D11DeviceContext*>(g_host_display->GetRenderContext());
|
m_ctx = static_cast<ID3D11DeviceContext*>(g_host_display->GetContext());
|
||||||
level = m_dev->GetFeatureLevel();
|
level = m_dev->GetFeatureLevel();
|
||||||
|
|
||||||
if (!GSConfig.DisableShaderCache)
|
if (!GSConfig.DisableShaderCache)
|
||||||
|
|
|
@ -581,14 +581,14 @@ bool GSDeviceMTL::Create()
|
||||||
if (!GSDevice::Create())
|
if (!GSDevice::Create())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (g_host_display->GetRenderAPI() != HostDisplay::RenderAPI::Metal)
|
if (g_host_display->GetRenderAPI() != RenderAPI::Metal)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!g_host_display->HasRenderDevice() || !g_host_display->HasRenderSurface())
|
if (!g_host_display->HasDevice() || !g_host_display->HasSurface())
|
||||||
return false;
|
return false;
|
||||||
m_dev = *static_cast<const GSMTLDevice*>(g_host_display->GetRenderDevice());
|
m_dev = *static_cast<const GSMTLDevice*>(g_host_display->GetDevice());
|
||||||
m_queue = MRCRetain((__bridge id<MTLCommandQueue>)g_host_display->GetRenderContext());
|
m_queue = MRCRetain((__bridge id<MTLCommandQueue>)g_host_display->GetContext());
|
||||||
MTLPixelFormat layer_px_fmt = [(__bridge CAMetalLayer*)g_host_display->GetRenderSurface() pixelFormat];
|
MTLPixelFormat layer_px_fmt = [(__bridge CAMetalLayer*)g_host_display->GetSurface() pixelFormat];
|
||||||
|
|
||||||
m_features.broken_point_sampler = [[m_dev.dev name] containsString:@"AMD"];
|
m_features.broken_point_sampler = [[m_dev.dev name] containsString:@"AMD"];
|
||||||
m_features.geometry_shader = false;
|
m_features.geometry_shader = false;
|
||||||
|
|
|
@ -196,7 +196,7 @@ bool GSDeviceOGL::Create()
|
||||||
if (!GSDevice::Create())
|
if (!GSDevice::Create())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (g_host_display->GetRenderAPI() != HostDisplay::RenderAPI::OpenGL)
|
if (g_host_display->GetRenderAPI() != RenderAPI::OpenGL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check openGL requirement as soon as possible so we can switch to another
|
// Check openGL requirement as soon as possible so we can switch to another
|
||||||
|
|
|
@ -1308,7 +1308,7 @@ bool GSDeviceVK::CreateRenderPasses()
|
||||||
bool GSDeviceVK::CompileConvertPipelines()
|
bool GSDeviceVK::CompileConvertPipelines()
|
||||||
{
|
{
|
||||||
// we may not have a swap chain if running in headless mode.
|
// we may not have a swap chain if running in headless mode.
|
||||||
Vulkan::SwapChain* swapchain = static_cast<Vulkan::SwapChain*>(g_host_display->GetRenderSurface());
|
Vulkan::SwapChain* swapchain = static_cast<Vulkan::SwapChain*>(g_host_display->GetSurface());
|
||||||
if (swapchain)
|
if (swapchain)
|
||||||
{
|
{
|
||||||
m_swap_chain_render_pass =
|
m_swap_chain_render_pass =
|
||||||
|
@ -1506,7 +1506,7 @@ bool GSDeviceVK::CompileConvertPipelines()
|
||||||
bool GSDeviceVK::CompilePresentPipelines()
|
bool GSDeviceVK::CompilePresentPipelines()
|
||||||
{
|
{
|
||||||
// we may not have a swap chain if running in headless mode.
|
// we may not have a swap chain if running in headless mode.
|
||||||
Vulkan::SwapChain* swapchain = static_cast<Vulkan::SwapChain*>(g_host_display->GetRenderSurface());
|
Vulkan::SwapChain* swapchain = static_cast<Vulkan::SwapChain*>(g_host_display->GetSurface());
|
||||||
if (swapchain)
|
if (swapchain)
|
||||||
{
|
{
|
||||||
m_swap_chain_render_pass =
|
m_swap_chain_render_pass =
|
||||||
|
|
|
@ -142,7 +142,7 @@ std::string HostDisplay::GetFullscreenModeString(u32 width, u32 height, float re
|
||||||
#endif
|
#endif
|
||||||
#include "GS/Renderers/Metal/GSMetalCPPAccessible.h"
|
#include "GS/Renderers/Metal/GSMetalCPPAccessible.h"
|
||||||
|
|
||||||
std::unique_ptr<HostDisplay> HostDisplay::CreateDisplayForAPI(RenderAPI api)
|
std::unique_ptr<HostDisplay> HostDisplay::CreateForAPI(RenderAPI api)
|
||||||
{
|
{
|
||||||
switch (api)
|
switch (api)
|
||||||
{
|
{
|
||||||
|
@ -153,7 +153,7 @@ std::unique_ptr<HostDisplay> HostDisplay::CreateDisplayForAPI(RenderAPI api)
|
||||||
return std::make_unique<D3D12HostDisplay>();
|
return std::make_unique<D3D12HostDisplay>();
|
||||||
#endif
|
#endif
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
case HostDisplay::RenderAPI::Metal:
|
case RenderAPI::Metal:
|
||||||
return std::unique_ptr<HostDisplay>(MakeMetalHostDisplay());
|
return std::unique_ptr<HostDisplay>(MakeMetalHostDisplay());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,17 @@
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
|
enum class RenderAPI
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
D3D11,
|
||||||
|
Metal,
|
||||||
|
D3D12,
|
||||||
|
Vulkan,
|
||||||
|
OpenGL,
|
||||||
|
OpenGLES
|
||||||
|
};
|
||||||
|
|
||||||
/// An abstracted RGBA8 texture.
|
/// An abstracted RGBA8 texture.
|
||||||
class HostDisplayTexture
|
class HostDisplayTexture
|
||||||
{
|
{
|
||||||
|
@ -42,17 +53,6 @@ public:
|
||||||
class HostDisplay
|
class HostDisplay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class RenderAPI
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
D3D11,
|
|
||||||
Metal,
|
|
||||||
D3D12,
|
|
||||||
Vulkan,
|
|
||||||
OpenGL,
|
|
||||||
OpenGLES
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class Alignment
|
enum class Alignment
|
||||||
{
|
{
|
||||||
LeftOrTop,
|
LeftOrTop,
|
||||||
|
@ -72,7 +72,7 @@ public:
|
||||||
static const char* RenderAPIToString(RenderAPI api);
|
static const char* RenderAPIToString(RenderAPI api);
|
||||||
|
|
||||||
/// Creates a display for the specified API.
|
/// Creates a display for the specified API.
|
||||||
static std::unique_ptr<HostDisplay> CreateDisplayForAPI(RenderAPI api);
|
static std::unique_ptr<HostDisplay> CreateForAPI(RenderAPI api);
|
||||||
|
|
||||||
/// Parses a fullscreen mode into its components (width * height @ refresh hz)
|
/// Parses a fullscreen mode into its components (width * height @ refresh hz)
|
||||||
static bool ParseFullscreenMode(const std::string_view& mode, u32* width, u32* height, float* refresh_rate);
|
static bool ParseFullscreenMode(const std::string_view& mode, u32* width, u32* height, float* refresh_rate);
|
||||||
|
@ -90,27 +90,45 @@ public:
|
||||||
__fi void SetDisplayAlignment(Alignment alignment) { m_display_alignment = alignment; }
|
__fi void SetDisplayAlignment(Alignment alignment) { m_display_alignment = alignment; }
|
||||||
|
|
||||||
virtual RenderAPI GetRenderAPI() const = 0;
|
virtual RenderAPI GetRenderAPI() const = 0;
|
||||||
virtual void* GetRenderDevice() const = 0;
|
virtual void* GetDevice() const = 0;
|
||||||
virtual void* GetRenderContext() const = 0;
|
virtual void* GetContext() const = 0;
|
||||||
virtual void* GetRenderSurface() const = 0;
|
virtual void* GetSurface() const = 0;
|
||||||
|
|
||||||
virtual bool HasRenderDevice() const = 0;
|
virtual bool HasDevice() const = 0;
|
||||||
virtual bool HasRenderSurface() const = 0;
|
virtual bool HasSurface() const = 0;
|
||||||
|
|
||||||
virtual bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, VsyncMode vsync, bool threaded_presentation, bool debug_device) = 0;
|
/// Creates the rendering/GPU device. This should be called on the thread which owns the window.
|
||||||
virtual bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) = 0;
|
virtual bool CreateDevice(const WindowInfo& wi) = 0;
|
||||||
virtual bool MakeRenderContextCurrent() = 0;
|
|
||||||
virtual bool DoneRenderContextCurrent() = 0;
|
/// Fully initializes the rendering device. This should be called on the GS thread.
|
||||||
virtual void DestroyRenderSurface() = 0;
|
virtual bool SetupDevice() = 0;
|
||||||
virtual bool ChangeRenderWindow(const WindowInfo& wi) = 0;
|
|
||||||
virtual bool SupportsFullscreen() const = 0;
|
/// Sets the device for the current thread. Only needed for OpenGL.
|
||||||
virtual bool IsFullscreen() = 0;
|
virtual bool MakeCurrent() = 0;
|
||||||
virtual bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) = 0;
|
|
||||||
virtual AdapterAndModeList GetAdapterAndModeList() = 0;
|
/// Clears the device for the current thread. Only needed for OpenGL.
|
||||||
virtual std::string GetDriverInfo() const = 0;
|
virtual bool DoneCurrent() = 0;
|
||||||
|
|
||||||
|
/// Destroys the surface we're currently drawing to.
|
||||||
|
virtual void DestroySurface() = 0;
|
||||||
|
|
||||||
|
/// Switches to a new window/surface.
|
||||||
|
virtual bool ChangeWindow(const WindowInfo& wi) = 0;
|
||||||
|
|
||||||
/// Call when the window size changes externally to recreate any resources.
|
/// Call when the window size changes externally to recreate any resources.
|
||||||
virtual void ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) = 0;
|
virtual void ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) = 0;
|
||||||
|
|
||||||
|
/// Returns true if exclusive fullscreen is supported.
|
||||||
|
virtual bool SupportsFullscreen() const = 0;
|
||||||
|
|
||||||
|
/// Returns true if exclusive fullscreen is active.
|
||||||
|
virtual bool IsFullscreen() = 0;
|
||||||
|
|
||||||
|
/// Attempts to switch to the specified mode in exclusive fullscreen.
|
||||||
|
virtual bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) = 0;
|
||||||
|
|
||||||
|
virtual AdapterAndModeList GetAdapterAndModeList() = 0;
|
||||||
|
virtual std::string GetDriverInfo() const = 0;
|
||||||
|
|
||||||
/// Creates an abstracted RGBA8 texture. If dynamic, the texture can be updated with UpdateTexture() below.
|
/// Creates an abstracted RGBA8 texture. If dynamic, the texture can be updated with UpdateTexture() below.
|
||||||
virtual std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) = 0;
|
virtual std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) = 0;
|
||||||
|
@ -155,11 +173,14 @@ extern std::unique_ptr<HostDisplay> g_host_display;
|
||||||
namespace Host
|
namespace Host
|
||||||
{
|
{
|
||||||
/// Creates the host display. This may create a new window. The API used depends on the current configuration.
|
/// Creates the host display. This may create a new window. The API used depends on the current configuration.
|
||||||
bool AcquireHostDisplay(HostDisplay::RenderAPI api);
|
bool AcquireHostDisplay(RenderAPI api);
|
||||||
|
|
||||||
/// Destroys the host display. This may close the display window.
|
/// Destroys the host display. This may close the display window.
|
||||||
void ReleaseHostDisplay();
|
void ReleaseHostDisplay();
|
||||||
|
|
||||||
|
/// Returns the desired vsync mode, depending on the runtime environment.
|
||||||
|
VsyncMode GetEffectiveVSyncMode();
|
||||||
|
|
||||||
/// Returns false if the window was completely occluded. If frame_skip is set, the frame won't be
|
/// Returns false if the window was completely occluded. If frame_skip is set, the frame won't be
|
||||||
/// displayed, but the GPU command queue will still be flushed.
|
/// displayed, but the GPU command queue will still be flushed.
|
||||||
bool BeginPresentFrame(bool frame_skip);
|
bool BeginPresentFrame(bool frame_skip);
|
||||||
|
|
|
@ -935,6 +935,7 @@ void SysMtgsThread::ApplySettings()
|
||||||
|
|
||||||
RunOnGSThread([opts = EmuConfig.GS]() {
|
RunOnGSThread([opts = EmuConfig.GS]() {
|
||||||
GSUpdateConfig(opts);
|
GSUpdateConfig(opts);
|
||||||
|
g_host_display->SetVSync(Host::GetEffectiveVSyncMode());
|
||||||
});
|
});
|
||||||
|
|
||||||
// We need to synchronize the thread when changing any settings when the download mode
|
// We need to synchronize the thread when changing any settings when the download mode
|
||||||
|
@ -964,15 +965,21 @@ void SysMtgsThread::UpdateDisplayWindow()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysMtgsThread::SetVSync(VsyncMode mode)
|
void SysMtgsThread::SetVSyncMode(VsyncMode mode)
|
||||||
{
|
{
|
||||||
pxAssertRel(IsOpen(), "MTGS is running");
|
pxAssertRel(IsOpen(), "MTGS is running");
|
||||||
|
|
||||||
RunOnGSThread([mode]() {
|
RunOnGSThread([mode]() {
|
||||||
|
Console.WriteLn("Vsync is %s", mode == VsyncMode::Off ? "OFF" : (mode == VsyncMode::Adaptive ? "ADAPTIVE" : "ON"));
|
||||||
g_host_display->SetVSync(mode);
|
g_host_display->SetVSync(mode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SysMtgsThread::UpdateVSyncMode()
|
||||||
|
{
|
||||||
|
SetVSyncMode(Host::GetEffectiveVSyncMode());
|
||||||
|
}
|
||||||
|
|
||||||
void SysMtgsThread::SwitchRenderer(GSRendererType renderer, bool display_message /* = true */)
|
void SysMtgsThread::SwitchRenderer(GSRendererType renderer, bool display_message /* = true */)
|
||||||
{
|
{
|
||||||
pxAssertRel(IsOpen(), "MTGS is running");
|
pxAssertRel(IsOpen(), "MTGS is running");
|
||||||
|
|
|
@ -678,18 +678,6 @@ bool Pcsx2Config::GSOptions::UseHardwareRenderer() const
|
||||||
return (Renderer != GSRendererType::Null && Renderer != GSRendererType::SW);
|
return (Renderer != GSRendererType::Null && Renderer != GSRendererType::SW);
|
||||||
}
|
}
|
||||||
|
|
||||||
VsyncMode Pcsx2Config::GetEffectiveVsyncMode() const
|
|
||||||
{
|
|
||||||
if (GS.LimitScalar != 1.0f)
|
|
||||||
{
|
|
||||||
Console.WriteLn("Vsync is OFF");
|
|
||||||
return VsyncMode::Off;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLn("Vsync is %s", GS.VsyncEnable == VsyncMode::Off ? "OFF" : (GS.VsyncEnable == VsyncMode::Adaptive ? "ADAPTIVE" : "ON"));
|
|
||||||
return GS.VsyncEnable;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pcsx2Config::SPU2Options::SPU2Options()
|
Pcsx2Config::SPU2Options::SPU2Options()
|
||||||
{
|
{
|
||||||
bitset = 0;
|
bitset = 0;
|
||||||
|
|
|
@ -1377,7 +1377,7 @@ void VMManager::SetLimiterMode(LimiterModeType type)
|
||||||
|
|
||||||
EmuConfig.LimiterMode = type;
|
EmuConfig.LimiterMode = type;
|
||||||
gsUpdateFrequency(EmuConfig);
|
gsUpdateFrequency(EmuConfig);
|
||||||
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
GetMTGS().UpdateVSyncMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMManager::FrameAdvance(u32 num_frames /*= 1*/)
|
void VMManager::FrameAdvance(u32 num_frames /*= 1*/)
|
||||||
|
@ -1586,7 +1586,6 @@ void VMManager::CheckForGSConfigChanges(const Pcsx2Config& old_config)
|
||||||
UpdateVSyncRate();
|
UpdateVSyncRate();
|
||||||
frameLimitReset();
|
frameLimitReset();
|
||||||
GetMTGS().ApplySettings();
|
GetMTGS().ApplySettings();
|
||||||
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMManager::CheckForFramerateConfigChanges(const Pcsx2Config& old_config)
|
void VMManager::CheckForFramerateConfigChanges(const Pcsx2Config& old_config)
|
||||||
|
@ -1598,7 +1597,7 @@ void VMManager::CheckForFramerateConfigChanges(const Pcsx2Config& old_config)
|
||||||
gsUpdateFrequency(EmuConfig);
|
gsUpdateFrequency(EmuConfig);
|
||||||
UpdateVSyncRate();
|
UpdateVSyncRate();
|
||||||
frameLimitReset();
|
frameLimitReset();
|
||||||
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
GetMTGS().UpdateVSyncMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMManager::CheckForPatchConfigChanges(const Pcsx2Config& old_config)
|
void VMManager::CheckForPatchConfigChanges(const Pcsx2Config& old_config)
|
||||||
|
|
|
@ -117,7 +117,7 @@ bool Host::ConfirmMessage(const std::string_view& title, const std::string_view&
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host::AcquireHostDisplay(HostDisplay::RenderAPI api)
|
bool Host::AcquireHostDisplay(RenderAPI api)
|
||||||
{
|
{
|
||||||
sApp.OpenGsPanel();
|
sApp.OpenGsPanel();
|
||||||
|
|
||||||
|
@ -125,14 +125,11 @@ bool Host::AcquireHostDisplay(HostDisplay::RenderAPI api)
|
||||||
if (g_gs_window_info.type == WindowInfo::Type::Surfaceless)
|
if (g_gs_window_info.type == WindowInfo::Type::Surfaceless)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
g_host_display = HostDisplay::CreateDisplayForAPI(api);
|
g_host_display = HostDisplay::CreateForAPI(api);
|
||||||
if (!g_host_display)
|
if (!g_host_display)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!g_host_display->CreateRenderDevice(g_gs_window_info, GSConfig.Adapter, EmuConfig.GetEffectiveVsyncMode(),
|
if (!g_host_display->CreateDevice(g_gs_window_info) || !g_host_display->SetupDevice() || !ImGuiManager::Initialize())
|
||||||
GSConfig.ThreadedPresentation, GSConfig.UseDebugDevice) ||
|
|
||||||
!g_host_display->InitializeRenderDevice(EmuFolders::Cache, GSConfig.UseDebugDevice) ||
|
|
||||||
!ImGuiManager::Initialize())
|
|
||||||
{
|
{
|
||||||
g_host_display.reset();
|
g_host_display.reset();
|
||||||
return false;
|
return false;
|
||||||
|
@ -154,6 +151,16 @@ void Host::ReleaseHostDisplay()
|
||||||
sApp.CloseGsPanel();
|
sApp.CloseGsPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VsyncMode Host::GetEffectiveVSyncMode()
|
||||||
|
{
|
||||||
|
// Force vsync off when not running at 100% speed.
|
||||||
|
if (EmuConfig.GS.LimitScalar != 1.0f)
|
||||||
|
return VsyncMode::Off;
|
||||||
|
|
||||||
|
// Otherwise use the config setting.
|
||||||
|
return EmuConfig.GS.VsyncEnable;
|
||||||
|
}
|
||||||
|
|
||||||
bool Host::BeginPresentFrame(bool frame_skip)
|
bool Host::BeginPresentFrame(bool frame_skip)
|
||||||
{
|
{
|
||||||
CheckForGSWindowResize();
|
CheckForGSWindowResize();
|
||||||
|
@ -221,7 +228,7 @@ void Host::CheckForGSWindowResize()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GSResetAPIState();
|
GSResetAPIState();
|
||||||
g_host_display->ResizeRenderWindow(width, height, scale);
|
g_host_display->ResizeWindow(width, height, scale);
|
||||||
GSRestoreAPIState();
|
GSRestoreAPIState();
|
||||||
ImGuiManager::WindowResized();
|
ImGuiManager::WindowResized();
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ void SysCoreThread::ApplySettings(const Pcsx2Config& src)
|
||||||
{
|
{
|
||||||
Console.WriteLn("Applying GS settings...");
|
Console.WriteLn("Applying GS settings...");
|
||||||
GetMTGS().ApplySettings();
|
GetMTGS().ApplySettings();
|
||||||
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
GetMTGS().UpdateVSyncMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ void SysCoreThread::_reset_stuff_as_needed()
|
||||||
|
|
||||||
if (m_resetVsyncTimers)
|
if (m_resetVsyncTimers)
|
||||||
{
|
{
|
||||||
GetMTGS().SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
GetMTGS().UpdateVSyncMode();
|
||||||
UpdateVSyncRate();
|
UpdateVSyncRate();
|
||||||
frameLimitReset();
|
frameLimitReset();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue