Merge pull request #12659 from unknownbrackets/vsync

Support vsync in all hardware backends, support runtime update
This commit is contained in:
Henrik Rydgård 2020-03-01 09:52:14 +01:00 committed by GitHub
commit 2ec82951a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 87 additions and 91 deletions

View File

@ -949,20 +949,17 @@ bool VulkanContext::InitSwapchain() {
ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i])); ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i]));
} }
for (size_t i = 0; i < presentModeCount; i++) { for (size_t i = 0; i < presentModeCount; i++) {
if (swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) { bool match = false;
// Default to the first present mode from the list. match = match || ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_FIFO_RELAXED) && presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_FIFO) && presentModes[i] == VK_PRESENT_MODE_FIFO_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_IMMEDIATE) && presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR);
// Default to the first present mode from the list.
if (match || swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
swapchainPresentMode = presentModes[i]; swapchainPresentMode = presentModes[i];
} }
if ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) { if (match) {
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
if ((flags_ & VULKAN_FLAG_PRESENT_FIFO_RELAXED) && presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
break;
}
if ((flags_ & VULKAN_FLAG_PRESENT_IMMEDIATE) && presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
break; break;
} }
} }

View File

@ -13,6 +13,7 @@ enum {
VULKAN_FLAG_PRESENT_MAILBOX = 2, VULKAN_FLAG_PRESENT_MAILBOX = 2,
VULKAN_FLAG_PRESENT_IMMEDIATE = 4, VULKAN_FLAG_PRESENT_IMMEDIATE = 4,
VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8, VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8,
VULKAN_FLAG_PRESENT_FIFO = 16,
}; };
enum { enum {
@ -136,6 +137,7 @@ public:
VkDevice GetDevice() const { return device_; } VkDevice GetDevice() const { return device_; }
VkInstance GetInstance() const { return instance_; } VkInstance GetInstance() const { return instance_; }
uint32_t GetFlags() const { return flags_; } uint32_t GetFlags() const { return flags_; }
void UpdateFlags(uint32_t flags) { flags_ = flags; }
VulkanDeleteList &Delete() { return globalDeleteList_; } VulkanDeleteList &Delete() { return globalDeleteList_; }

View File

@ -556,7 +556,12 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
// we have nothing to do here. // we have nothing to do here.
bool doFrameSkip = g_Config.iFrameSkip != 0; bool doFrameSkip = g_Config.iFrameSkip != 0;
if (!throttle && g_Config.bFrameSkipUnthrottle) { bool unthrottleNeedsSkip = g_Config.bFrameSkipUnthrottle;
if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) {
// Vulkan doesn't support the interval setting, so we force frameskip.
unthrottleNeedsSkip = true;
}
if (!throttle && unthrottleNeedsSkip) {
doFrameSkip = true; doFrameSkip = true;
skipFrame = true; skipFrame = true;
if (numSkippedFrames >= 7) { if (numSkippedFrames >= 7) {

View File

@ -73,7 +73,6 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE); device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT); context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
D3D_FEATURE_LEVEL featureLevel = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL); D3D_FEATURE_LEVEL featureLevel = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
lastVsync_ = g_Config.bVSync ? 1 : 0;
stockD3D11.Create(device_); stockD3D11.Create(device_);

View File

@ -81,6 +81,4 @@ private:
DepalShaderCacheD3D11 *depalShaderCache_; DepalShaderCacheD3D11 *depalShaderCache_;
DrawEngineD3D11 drawEngine_; DrawEngineD3D11 drawEngine_;
ShaderManagerD3D11 *shaderManagerD3D11_; ShaderManagerD3D11 *shaderManagerD3D11_;
int lastVsync_;
}; };

View File

@ -58,8 +58,6 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
drawEngine_(draw) { drawEngine_(draw) {
device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE);
deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX); deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX);
lastVsync_ = g_Config.bVSync ? 1 : 0;
dxstate.SetVSyncInterval(g_Config.bVSync);
shaderManagerDX9_ = new ShaderManagerDX9(draw, device_); shaderManagerDX9_ = new ShaderManagerDX9(draw, device_);
framebufferManagerDX9_ = new FramebufferManagerDX9(draw); framebufferManagerDX9_ = new FramebufferManagerDX9(draw);
@ -285,15 +283,6 @@ void GPU_DX9::ReapplyGfxState() {
} }
void GPU_DX9::BeginFrame() { void GPU_DX9::BeginFrame() {
// Turn off vsync when unthrottled
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
if (PSP_CoreParameter().unthrottle || PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL)
desiredVSyncInterval = 0;
if (desiredVSyncInterval != lastVsync_) {
dxstate.SetVSyncInterval(desiredVSyncInterval);
lastVsync_ = desiredVSyncInterval;
}
textureCacheDX9_->StartFrame(); textureCacheDX9_->StartFrame();
drawEngine_.DecimateTrackedVertexArrays(); drawEngine_.DecimateTrackedVertexArrays();
depalShaderCache_.Decimate(); depalShaderCache_.Decimate();

View File

@ -80,8 +80,6 @@ private:
DepalShaderCacheDX9 depalShaderCache_; DepalShaderCacheDX9 depalShaderCache_;
DrawEngineDX9 drawEngine_; DrawEngineDX9 drawEngine_;
ShaderManagerDX9 *shaderManagerDX9_; ShaderManagerDX9 *shaderManagerDX9_;
int lastVsync_;
}; };
} // namespace DX9 } // namespace DX9

View File

@ -360,6 +360,7 @@ void GPU_GLES::BeginHostFrame() {
drawEngine_.Resized(); drawEngine_.Resized();
shaderManagerGL_->DirtyShader(); shaderManagerGL_->DirtyShader();
textureCacheGL_->NotifyConfigChanged(); textureCacheGL_->NotifyConfigChanged();
resized_ = false;
} }
drawEngine_.BeginFrame(); drawEngine_.BeginFrame();
@ -369,42 +370,11 @@ void GPU_GLES::EndHostFrame() {
drawEngine_.EndFrame(); drawEngine_.EndFrame();
} }
inline void GPU_GLES::UpdateVsyncInterval(bool force) {
#ifdef _WIN32
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
if (PSP_CoreParameter().unthrottle) {
desiredVSyncInterval = 0;
}
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
int limit = PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2;
// For an alternative speed that is a clean factor of 60, the user probably still wants vsync.
if (limit == 0 || (limit >= 0 && limit != 15 && limit != 30 && limit != 60)) {
desiredVSyncInterval = 0;
}
}
if (desiredVSyncInterval != lastVsync_ || force) {
// Disabled EXT_swap_control_tear for now, it never seems to settle at the correct timing
// so it just keeps tearing. Not what I hoped for...
//if (gl_extensions.EXT_swap_control_tear) {
// // See http://developer.download.nvidia.com/opengl/specs/WGL_EXT_swap_control_tear.txt
// glstate.SetVSyncInterval(-desiredVSyncInterval);
//} else {
gfxCtx_->SwapInterval(desiredVSyncInterval);
//}
lastVsync_ = desiredVSyncInterval;
}
#endif
}
void GPU_GLES::ReapplyGfxState() { void GPU_GLES::ReapplyGfxState() {
GPUCommon::ReapplyGfxState(); GPUCommon::ReapplyGfxState();
} }
void GPU_GLES::BeginFrame() { void GPU_GLES::BeginFrame() {
UpdateVsyncInterval(resized_);
resized_ = false;
textureCacheGL_->StartFrame(); textureCacheGL_->StartFrame();
drawEngine_.DecimateTrackedVertexArrays(); drawEngine_.DecimateTrackedVertexArrays();
depalShaderCache_.Decimate(); depalShaderCache_.Decimate();

View File

@ -79,8 +79,6 @@ private:
void CopyDisplayToOutput() override; void CopyDisplayToOutput() override;
void Reinitialize() override; void Reinitialize() override;
inline void UpdateVsyncInterval(bool force);
FramebufferManagerGLES *framebufferManagerGL_; FramebufferManagerGLES *framebufferManagerGL_;
TextureCacheGLES *textureCacheGL_; TextureCacheGLES *textureCacheGL_;
DepalShaderCacheGLES depalShaderCache_; DepalShaderCacheGLES depalShaderCache_;
@ -89,8 +87,4 @@ private:
ShaderManagerGLES *shaderManagerGL_; ShaderManagerGLES *shaderManagerGL_;
std::string shaderCachePath_; std::string shaderCachePath_;
#ifdef _WIN32
int lastVsync_;
#endif
}; };

View File

@ -6,6 +6,7 @@
#include "profiler/profiler.h" #include "profiler/profiler.h"
#include "Common/ColorConv.h" #include "Common/ColorConv.h"
#include "Common/GraphicsContext.h"
#include "Core/Reporting.h" #include "Core/Reporting.h"
#include "GPU/GeDisasm.h" #include "GPU/GeDisasm.h"
#include "GPU/GPU.h" #include "GPU/GPU.h"
@ -408,6 +409,7 @@ GPUCommon::GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw) :
} }
UpdateCmdInfo(); UpdateCmdInfo();
UpdateVsyncInterval(true);
} }
GPUCommon::~GPUCommon() { GPUCommon::~GPUCommon() {
@ -432,6 +434,7 @@ void GPUCommon::UpdateCmdInfo() {
} }
void GPUCommon::BeginHostFrame() { void GPUCommon::BeginHostFrame() {
UpdateVsyncInterval(resized_);
ReapplyGfxState(); ReapplyGfxState();
// TODO: Assume config may have changed - maybe move to resize. // TODO: Assume config may have changed - maybe move to resize.
@ -458,6 +461,30 @@ void GPUCommon::Reinitialize() {
interruptsEnabled_ = true; interruptsEnabled_ = true;
} }
void GPUCommon::UpdateVsyncInterval(bool force) {
#ifdef _WIN32
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
if (PSP_CoreParameter().unthrottle) {
desiredVSyncInterval = 0;
}
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
int limit = PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2;
// For an alternative speed that is a clean factor of 60, the user probably still wants vsync.
if (limit == 0 || (limit >= 0 && limit != 15 && limit != 30 && limit != 60)) {
desiredVSyncInterval = 0;
}
}
if (desiredVSyncInterval != lastVsync_ || force) {
// Disabled EXT_swap_control_tear for now, it never seems to settle at the correct timing
// so it just keeps tearing. Not what I hoped for... (gl_extensions.EXT_swap_control_tear)
// See http://developer.download.nvidia.com/opengl/specs/WGL_EXT_swap_control_tear.txt
gfxCtx_->SwapInterval(desiredVSyncInterval);
lastVsync_ = desiredVSyncInterval;
}
#endif
}
int GPUCommon::EstimatePerVertexCost() { int GPUCommon::EstimatePerVertexCost() {
// TODO: This is transform cost, also account for rasterization cost somehow... although it probably // TODO: This is transform cost, also account for rasterization cost somehow... although it probably
// runs in parallel with transform. // runs in parallel with transform.

View File

@ -276,6 +276,7 @@ protected:
} }
void BeginFrame() override; void BeginFrame() override;
void UpdateVsyncInterval(bool force);
virtual void FastRunLoop(DisplayList &list); virtual void FastRunLoop(DisplayList &list);
@ -362,6 +363,10 @@ private:
// Debug stats. // Debug stats.
double timeSteppingStarted_; double timeSteppingStarted_;
double timeSpentStepping_; double timeSpentStepping_;
#ifdef _WIN32
int lastVsync_;
#endif
}; };
struct CommonCommandTableEntry { struct CommonCommandTableEntry {

View File

@ -57,7 +57,6 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
drawEngine_(vulkan_, draw), drawEngine_(vulkan_, draw),
depalShaderCache_(draw, vulkan_), depalShaderCache_(draw, vulkan_),
vulkan2D_(vulkan_) { vulkan2D_(vulkan_) {
UpdateVsyncInterval(true);
CheckGPUFeatures(); CheckGPUFeatures();
shaderManagerVulkan_ = new ShaderManagerVulkan(draw, vulkan_); shaderManagerVulkan_ = new ShaderManagerVulkan(draw, vulkan_);
@ -419,10 +418,6 @@ void GPU_Vulkan::InitClear() {
} }
} }
void GPU_Vulkan::UpdateVsyncInterval(bool force) {
// TODO
}
void GPU_Vulkan::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) { void GPU_Vulkan::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {
GPUDebug::NotifyDisplay(framebuf, stride, format); GPUDebug::NotifyDisplay(framebuf, stride, format);
framebufferManager_->SetDisplayFramebuffer(framebuf, stride, format); framebufferManager_->SetDisplayFramebuffer(framebuf, stride, format);

View File

@ -80,7 +80,6 @@ private:
void InitClear() override; void InitClear() override;
void CopyDisplayToOutput() override; void CopyDisplayToOutput() override;
void Reinitialize() override; void Reinitialize() override;
inline void UpdateVsyncInterval(bool force);
void InitDeviceObjects(); void InitDeviceObjects();
void DestroyDeviceObjects(); void DestroyDeviceObjects();

View File

@ -342,7 +342,11 @@ void GameSettingsScreen::CreateViews() {
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync"))); CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync")));
vSync->OnClick.Add([=](EventParams &e) {
NativeResized();
return UI::EVENT_CONTINUE;
});
#endif #endif
CheckBox *hwTransform = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTransform, gr->T("Hardware Transform"))); CheckBox *hwTransform = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTransform, gr->T("Hardware Transform")));

View File

@ -42,12 +42,12 @@ D3D11Context::~D3D11Context() {
} }
void D3D11Context::SwapBuffers() { void D3D11Context::SwapBuffers() {
swapChain_->Present(0, 0); swapChain_->Present(swapInterval_, 0);
draw_->HandleEvent(Draw::Event::PRESENTED, 0, 0, nullptr, nullptr); draw_->HandleEvent(Draw::Event::PRESENTED, 0, 0, nullptr, nullptr);
} }
void D3D11Context::SwapInterval(int interval) { void D3D11Context::SwapInterval(int interval) {
// Dummy swapInterval_ = interval;
} }
HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) { HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) {

View File

@ -67,4 +67,5 @@ private:
HMODULE hD3D11; HMODULE hD3D11;
int width; int width;
int height; int height;
int swapInterval_ = 0;
}; };

View File

@ -56,7 +56,7 @@ static void GetRes(HWND hWnd, int &xres, int &yres) {
} }
void D3D9Context::SwapInterval(int interval) { void D3D9Context::SwapInterval(int interval) {
// Dummy swapInterval_ = interval;
} }
bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
@ -159,7 +159,7 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
presentParams_.hDeviceWindow = wnd; presentParams_.hDeviceWindow = wnd;
presentParams_.EnableAutoDepthStencil = true; presentParams_.EnableAutoDepthStencil = true;
presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8; presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
presentParams_.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; presentParams_.PresentationInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
if (has9Ex_) { if (has9Ex_) {
if (windowed && IsWin7OrLater()) { if (windowed && IsWin7OrLater()) {
@ -205,16 +205,19 @@ void D3D9Context::Resize() {
// This should only be called from the emu thread. // This should only be called from the emu thread.
int xres, yres; int xres, yres;
GetRes(hWnd_, xres, yres); GetRes(hWnd_, xres, yres);
uint32_t newInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;;
bool w_changed = presentParams_.BackBufferWidth != xres; bool w_changed = presentParams_.BackBufferWidth != xres;
bool h_changed = presentParams_.BackBufferHeight != yres; bool h_changed = presentParams_.BackBufferHeight != yres;
bool i_changed = presentParams_.PresentationInterval != newInterval;
if (device_ && (w_changed || h_changed)) { if (device_ && (w_changed || h_changed || i_changed)) {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr); draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr);
presentParams_.BackBufferWidth = xres; presentParams_.BackBufferWidth = xres;
presentParams_.BackBufferHeight = yres; presentParams_.BackBufferHeight = yres;
presentParams_.PresentationInterval = newInterval;
HRESULT hr = device_->Reset(&presentParams_); HRESULT hr = device_->Reset(&presentParams_);
if (FAILED(hr)) { if (FAILED(hr)) {
// Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015. // Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015.
PanicAlert("Unable to reset D3D9 device"); PanicAlert("Unable to reset D3D9 device");
} }
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr);

View File

@ -53,5 +53,6 @@ private:
HWND hWnd_; // Holds Our Window Handle HWND hWnd_; // Holds Our Window Handle
HMODULE hD3D9_; HMODULE hD3D9_;
D3DPRESENT_PARAMETERS presentParams_; D3DPRESENT_PARAMETERS presentParams_;
int swapInterval_ = 0;
}; };

View File

@ -74,6 +74,15 @@ static VulkanContext *g_Vulkan;
static VulkanLogOptions g_LogOptions; static VulkanLogOptions g_LogOptions;
static uint32_t FlagsFromConfig() {
uint32_t flags = 0;
flags = g_Config.bVSync ? VULKAN_FLAG_PRESENT_FIFO : VULKAN_FLAG_PRESENT_MAILBOX;
if (g_validate_) {
flags |= VULKAN_FLAG_VALIDATE;
}
return flags;
}
bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_message) { bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_message) {
*error_message = "N/A"; *error_message = "N/A";
@ -100,10 +109,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
VulkanContext::CreateInfo info{}; VulkanContext::CreateInfo info{};
info.app_name = "PPSSPP"; info.app_name = "PPSSPP";
info.app_ver = gitVer.ToInteger(); info.app_ver = gitVer.ToInteger();
info.flags = VULKAN_FLAG_PRESENT_MAILBOX; info.flags = FlagsFromConfig();
if (g_validate_) {
info.flags |= VULKAN_FLAG_VALIDATE;
}
if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) { if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) {
*error_message = g_Vulkan->InitError(); *error_message = g_Vulkan->InitError();
delete g_Vulkan; delete g_Vulkan;
@ -184,6 +190,7 @@ void WindowsVulkanContext::Resize() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
g_Vulkan->DestroyObjects(); g_Vulkan->DestroyObjects();
g_Vulkan->UpdateFlags(FlagsFromConfig());
g_Vulkan->ReinitSurface(); g_Vulkan->ReinitSurface();
g_Vulkan->InitObjects(); g_Vulkan->InitObjects();

View File

@ -739,6 +739,7 @@ namespace MainWindow {
case ID_OPTIONS_VSYNC: case ID_OPTIONS_VSYNC:
g_Config.bVSync = !g_Config.bVSync; g_Config.bVSync = !g_Config.bVSync;
NativeResized();
break; break;
case ID_OPTIONS_FRAMESKIP_AUTO: case ID_OPTIONS_FRAMESKIP_AUTO:

View File

@ -81,6 +81,13 @@ AndroidVulkanContext::~AndroidVulkanContext() {
g_Vulkan = nullptr; g_Vulkan = nullptr;
} }
static uint32_t FlagsFromConfig() {
if (g_Config.bVSync) {
return VULKAN_FLAG_PRESENT_FIFO;
}
return VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED;
}
bool AndroidVulkanContext::InitAPI() { bool AndroidVulkanContext::InitAPI() {
ILOG("AndroidVulkanContext::Init"); ILOG("AndroidVulkanContext::Init");
init_glslang(); init_glslang();
@ -105,7 +112,7 @@ bool AndroidVulkanContext::InitAPI() {
VulkanContext::CreateInfo info{}; VulkanContext::CreateInfo info{};
info.app_name = "PPSSPP"; info.app_name = "PPSSPP";
info.app_ver = gitVer.ToInteger(); info.app_ver = gitVer.ToInteger();
info.flags = VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED; info.flags = FlagsFromConfig();
VkResult res = g_Vulkan->CreateInstance(info); VkResult res = g_Vulkan->CreateInstance(info);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str()); ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str());
@ -216,7 +223,7 @@ void AndroidVulkanContext::Resize() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
g_Vulkan->DestroyObjects(); g_Vulkan->DestroyObjects();
// backbufferResize updated these values. TODO: Notify another way? g_Vulkan->UpdateFlags(FlagsFromConfig());
g_Vulkan->ReinitSurface(); g_Vulkan->ReinitSurface();
g_Vulkan->InitObjects(); g_Vulkan->InitObjects();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());

View File

@ -73,9 +73,6 @@ void CheckGLExtensions() {
memset(&gl_extensions, 0, sizeof(gl_extensions)); memset(&gl_extensions, 0, sizeof(gl_extensions));
} }
void DirectXState::SetVSyncInterval(int interval) {
}
} // namespace DX9 } // namespace DX9
#endif // _MSC_VER #endif // _MSC_VER

View File

@ -484,9 +484,6 @@ public:
DxSampler0State1<D3DSAMP_MAXMIPLEVEL, 0> texMaxMipLevel; DxSampler0State1<D3DSAMP_MAXMIPLEVEL, 0> texMaxMipLevel;
DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU; DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU;
DxSampler0State1<D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP> texAddressV; DxSampler0State1<D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP> texAddressV;
// Only works on Win32, all other platforms are "force-vsync"
void SetVSyncInterval(int interval); // one of the above VSYNC, or a higher number for multi-frame waits (could be useful for 30hz games)
}; };
#undef STATE1 #undef STATE1