1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Added VSync=wait setting

This commit is contained in:
narzoul 2024-08-23 23:17:35 +02:00
parent 76dfc38645
commit 16b062d17d
5 changed files with 65 additions and 28 deletions

View File

@ -8,13 +8,13 @@ namespace Config
namespace Settings namespace Settings
{ {
VSync::VSync() VSync::VSync()
: EnumSetting("VSync", "app", { "app", "off", "on" }) : EnumSetting("VSync", "app", { "app", "off", "on", "wait"})
{ {
} }
Setting::ParamInfo VSync::getParamInfo() const Setting::ParamInfo VSync::getParamInfo() const
{ {
if (ON == m_value) if (ON == m_value || WAIT == m_value)
{ {
return { "Interval", 1, 16, 1 }; return { "Interval", 1, 16, 1 };
} }

View File

@ -9,7 +9,7 @@ namespace Config
class VSync : public EnumSetting class VSync : public EnumSetting
{ {
public: public:
enum Values { APP, OFF, ON }; enum Values { APP, OFF, ON, WAIT };
VSync(); VSync();

View File

@ -99,10 +99,13 @@ namespace
UINT getFlipInterval(DWORD flags) UINT getFlipInterval(DWORD flags)
{ {
auto vSync = Config::vSync.get(); switch (Config::vSync.get())
if (Config::Settings::VSync::APP != vSync)
{ {
return Config::Settings::VSync::OFF == vSync ? 0 : Config::vSync.getParam(); case Config::Settings::VSync::OFF:
case Config::Settings::VSync::WAIT:
return 0;
case Config::Settings::VSync::ON:
return Config::vSync.getParam();
} }
if (flags & DDFLIP_NOVSYNC) if (flags & DDFLIP_NOVSYNC)
@ -734,12 +737,17 @@ namespace DDraw
return true; return true;
} }
bool isUpdateReady = g_isUpdateReady;
auto qpcStart = Time::queryPerformanceCounter(); auto qpcStart = Time::queryPerformanceCounter();
auto vsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter(); auto vsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter();
while (static_cast<int>(vsyncCount - g_flipEndVsyncCount) < 0) while (static_cast<int>(vsyncCount - g_flipEndVsyncCount) < 0)
{ {
++vsyncCount; ++vsyncCount;
D3dDdi::KernelModeThunks::waitForVsyncCounter(vsyncCount); D3dDdi::KernelModeThunks::waitForVsyncCounter(vsyncCount);
if (isUpdateReady)
{
flush();
}
} }
Compat::ScopedCriticalSection lock(g_presentCs); Compat::ScopedCriticalSection lock(g_presentCs);
@ -764,10 +772,10 @@ namespace DDraw
g_qpcPrevWaitEnd = qpcWaitEnd; g_qpcPrevWaitEnd = qpcWaitEnd;
Compat::ScopedThreadPriority prio(THREAD_PRIORITY_TIME_CRITICAL); Compat::ScopedThreadPriority prio(THREAD_PRIORITY_TIME_CRITICAL);
auto qpcStart = Time::queryPerformanceCounter();
while (Time::qpcToMs(qpcWaitEnd - qpcNow) > 0) while (Time::qpcToMs(qpcWaitEnd - qpcNow) > 0)
{ {
Time::waitForNextTick(); Time::waitForNextTick();
flush();
qpcNow = Time::queryPerformanceCounter(); qpcNow = Time::queryPerformanceCounter();
} }
@ -775,12 +783,5 @@ namespace DDraw
{ {
qpcNow = Time::queryPerformanceCounter(); qpcNow = Time::queryPerformanceCounter();
} }
Compat::ScopedCriticalSection lock(g_presentCs);
auto qpcEnd = Time::queryPerformanceCounter();
if (g_isUpdatePending)
{
g_qpcUpdateStart += qpcEnd - qpcStart;
}
} }
} }

View File

@ -1,5 +1,6 @@
#include <Common/CompatPtr.h> #include <Common/CompatPtr.h>
#include <Config/Settings/FpsLimiter.h> #include <Config/Settings/FpsLimiter.h>
#include <Config/Settings/VSync.h>
#include <D3dDdi/KernelModeThunks.h> #include <D3dDdi/KernelModeThunks.h>
#include <D3dDdi/ScopedCriticalSection.h> #include <D3dDdi/ScopedCriticalSection.h>
#include <DDraw/DirectDrawClipper.h> #include <DDraw/DirectDrawClipper.h>
@ -177,18 +178,22 @@ namespace DDraw
caps.dwCaps = DDSCAPS_BACKBUFFER; caps.dwCaps = DDSCAPS_BACKBUFFER;
getOrigVtable(This).GetAttachedSurface(This, &caps, &surfaceTargetOverride.getRef()); getOrigVtable(This).GetAttachedSurface(This, &caps, &surfaceTargetOverride.getRef());
} }
HRESULT result = Blt(This, nullptr, surfaceTargetOverride.get(), nullptr, DDBLT_WAIT, nullptr);
if (SUCCEEDED(result) && Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get())
{
RealPrimarySurface::waitForFlipFpsLimit();
}
return result;
}
HRESULT result = SurfaceImpl::Flip(This, surfaceTargetOverride, DDFLIP_WAIT); HRESULT result = SurfaceImpl::Blt(This, nullptr, surfaceTargetOverride.get(), nullptr, DDBLT_WAIT, nullptr);
if (FAILED(result)) if (FAILED(result))
{
return result;
}
dwFlags = DDFLIP_NOVSYNC;
}
else
{ {
return result; HRESULT result = SurfaceImpl::Flip(This, surfaceTargetOverride, DDFLIP_WAIT);
if (FAILED(result))
{
return result;
}
} }
auto statsWindow = Gdi::GuiThread::getStatsWindow(); auto statsWindow = Gdi::GuiThread::getStatsWindow();
@ -199,10 +204,37 @@ namespace DDraw
PrimarySurface::updateFrontResource(); PrimarySurface::updateFrontResource();
RealPrimarySurface::flip(surfaceTargetOverride, dwFlags); RealPrimarySurface::flip(surfaceTargetOverride, dwFlags);
PrimarySurface::waitForIdle();
if (Config::Settings::VSync::WAIT == Config::vSync.get())
{
static UINT lastFlipEnd = 0;
lastFlipEnd += Config::vSync.getParam();
UINT vsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter();
if (static_cast<INT>(vsyncCount - lastFlipEnd) > 0)
{
lastFlipEnd = vsyncCount;
}
RealPrimarySurface::setUpdateReady();
if (0 != RealPrimarySurface::flush())
{
PrimarySurface::waitForIdle();
}
while (static_cast<INT>(vsyncCount - lastFlipEnd) < 0)
{
++vsyncCount;
D3dDdi::KernelModeThunks::waitForVsyncCounter(vsyncCount);
RealPrimarySurface::flush();
}
}
else
{
PrimarySurface::waitForIdle();
}
if (Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get()) if (Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get())
{ {
DDraw::RealPrimarySurface::waitForFlip(m_data->getDDS());
RealPrimarySurface::waitForFlipFpsLimit(); RealPrimarySurface::waitForFlipFpsLimit();
} }
return DD_OK; return DD_OK;

View File

@ -22,10 +22,11 @@
# ForceD3D9On12 = off # ForceD3D9On12 = off
# FpsLimiter = off # FpsLimiter = off
# FullscreenMode = borderless # FullscreenMode = borderless
# GdiStretchBltMode = app
# LogLevel = info # LogLevel = info
# PalettizedTextures = off # PalettizedTextures = off
# RemoveBorders = off # RemoveBorders = off
# RenderColorDepth = appd8 # RenderColorDepth = 32
# ResolutionScale = app(1) # ResolutionScale = app(1)
# ResolutionScaleFilter = point # ResolutionScaleFilter = point
# SoftwareDevice = rgb # SoftwareDevice = rgb
@ -37,15 +38,18 @@
# StatsHotKey = shift+f12 # StatsHotKey = shift+f12
# StatsPosX = right # StatsPosX = right
# StatsPosY = top # StatsPosY = top
# StatsRows = label, presentrate, fliprate, blitcount, lockcount, ddiusage # StatsRows = label, presentrate, fliprate, blitcount, lockcount
# StatsTransparency = alpha(75) # StatsTransparency = alpha(75)
# StatsUpdateRate = 5 # StatsUpdateRate = 5
# SupportedDepthFormats = all # SupportedDepthFormats = all
# SupportedResolutions = native, 640x480, 800x600, 1024x768 # SupportedResolutions = native, 640x480, 800x600, 1024x768
# SupportedTextureFormats = all # SupportedTextureFormats = all
# SurfacePatches = none
# TerminateHotKey = ctrl+alt+end # TerminateHotKey = ctrl+alt+end
# TextureFilter = app # TextureFilter = app
# ThreadPriorityBoost = off # ThreadPriorityBoost = off
# VSync = app # VSync = app
# VertexBufferMemoryType = sysmem # VertexBufferMemoryType = sysmem
# VertexFixup = gpu
# ViewportEdgeFix = off
# WinVersionLie = off # WinVersionLie = off