mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 16:08:50 +01:00
[util] Rename NtTimerDuration to TimerDuration
This commit is contained in:
parent
a78aab147e
commit
b885883e06
@ -33,8 +33,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (!m_envOverride) {
|
if (!m_envOverride) {
|
||||||
m_targetInterval = frameRate > 0.0
|
m_targetInterval = frameRate > 0.0
|
||||||
? NtTimerDuration(int64_t(double(NtTimerDuration::period::den) / frameRate))
|
? TimerDuration(int64_t(double(TimerDuration::period::den) / frameRate))
|
||||||
: NtTimerDuration::zero();
|
: TimerDuration::zero();
|
||||||
|
|
||||||
if (isEnabled() && !m_initialized)
|
if (isEnabled() && !m_initialized)
|
||||||
initialize();
|
initialize();
|
||||||
@ -46,8 +46,8 @@ namespace dxvk {
|
|||||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||||
|
|
||||||
m_refreshInterval = refreshRate > 0.0
|
m_refreshInterval = refreshRate > 0.0
|
||||||
? NtTimerDuration(int64_t(double(NtTimerDuration::period::den) / refreshRate))
|
? TimerDuration(int64_t(double(TimerDuration::period::den) / refreshRate))
|
||||||
: NtTimerDuration::zero();
|
: TimerDuration::zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -67,22 +67,22 @@ namespace dxvk {
|
|||||||
auto t0 = m_lastFrame;
|
auto t0 = m_lastFrame;
|
||||||
auto t1 = dxvk::high_resolution_clock::now();
|
auto t1 = dxvk::high_resolution_clock::now();
|
||||||
|
|
||||||
auto frameTime = std::chrono::duration_cast<NtTimerDuration>(t1 - t0);
|
auto frameTime = std::chrono::duration_cast<TimerDuration>(t1 - t0);
|
||||||
|
|
||||||
if (frameTime * 100 > m_targetInterval * 103 - m_deviation * 100) {
|
if (frameTime * 100 > m_targetInterval * 103 - m_deviation * 100) {
|
||||||
// If we have a slow frame, reset the deviation since we
|
// If we have a slow frame, reset the deviation since we
|
||||||
// do not want to compensate for low performance later on
|
// do not want to compensate for low performance later on
|
||||||
m_deviation = NtTimerDuration::zero();
|
m_deviation = TimerDuration::zero();
|
||||||
} else {
|
} else {
|
||||||
// Don't call sleep if the amount of time to sleep is shorter
|
// Don't call sleep if the amount of time to sleep is shorter
|
||||||
// than the time the function calls are likely going to take
|
// than the time the function calls are likely going to take
|
||||||
NtTimerDuration sleepDuration = m_targetInterval - m_deviation - frameTime;
|
TimerDuration sleepDuration = m_targetInterval - m_deviation - frameTime;
|
||||||
t1 = sleep(t1, sleepDuration);
|
t1 = sleep(t1, sleepDuration);
|
||||||
|
|
||||||
// Compensate for any sleep inaccuracies in the next frame, and
|
// Compensate for any sleep inaccuracies in the next frame, and
|
||||||
// limit cumulative deviation in order to avoid stutter in case we
|
// limit cumulative deviation in order to avoid stutter in case we
|
||||||
// have a number of slow frames immediately followed by a fast one.
|
// have a number of slow frames immediately followed by a fast one.
|
||||||
frameTime = std::chrono::duration_cast<NtTimerDuration>(t1 - t0);
|
frameTime = std::chrono::duration_cast<TimerDuration>(t1 - t0);
|
||||||
m_deviation += frameTime - m_targetInterval;
|
m_deviation += frameTime - m_targetInterval;
|
||||||
m_deviation = std::min(m_deviation, m_targetInterval / 16);
|
m_deviation = std::min(m_deviation, m_targetInterval / 16);
|
||||||
}
|
}
|
||||||
@ -91,8 +91,8 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FpsLimiter::TimePoint FpsLimiter::sleep(TimePoint t0, NtTimerDuration duration) {
|
FpsLimiter::TimePoint FpsLimiter::sleep(TimePoint t0, TimerDuration duration) {
|
||||||
if (duration <= NtTimerDuration::zero())
|
if (duration <= TimerDuration::zero())
|
||||||
return t0;
|
return t0;
|
||||||
|
|
||||||
// On wine, we can rely on NtDelayExecution waiting for more or
|
// On wine, we can rely on NtDelayExecution waiting for more or
|
||||||
@ -100,16 +100,16 @@ namespace dxvk {
|
|||||||
// spamming QueryPerformanceCounter for performance reasons.
|
// spamming QueryPerformanceCounter for performance reasons.
|
||||||
// On Windows, we busy-wait for the last couple of milliseconds
|
// On Windows, we busy-wait for the last couple of milliseconds
|
||||||
// since sleeping is highly inaccurate and inconsistent.
|
// since sleeping is highly inaccurate and inconsistent.
|
||||||
NtTimerDuration sleepThreshold = m_sleepThreshold;
|
TimerDuration sleepThreshold = m_sleepThreshold;
|
||||||
|
|
||||||
if (m_sleepGranularity != NtTimerDuration::zero())
|
if (m_sleepGranularity != TimerDuration::zero())
|
||||||
sleepThreshold += duration / 6;
|
sleepThreshold += duration / 6;
|
||||||
|
|
||||||
NtTimerDuration remaining = duration;
|
TimerDuration remaining = duration;
|
||||||
TimePoint t1 = t0;
|
TimePoint t1 = t0;
|
||||||
|
|
||||||
while (remaining > sleepThreshold) {
|
while (remaining > sleepThreshold) {
|
||||||
NtTimerDuration sleepDuration = remaining - sleepThreshold;
|
TimerDuration sleepDuration = remaining - sleepThreshold;
|
||||||
|
|
||||||
if (NtDelayExecution) {
|
if (NtDelayExecution) {
|
||||||
LARGE_INTEGER ticks;
|
LARGE_INTEGER ticks;
|
||||||
@ -121,14 +121,14 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
t1 = dxvk::high_resolution_clock::now();
|
t1 = dxvk::high_resolution_clock::now();
|
||||||
remaining -= std::chrono::duration_cast<NtTimerDuration>(t1 - t0);
|
remaining -= std::chrono::duration_cast<TimerDuration>(t1 - t0);
|
||||||
t0 = t1;
|
t0 = t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Busy-wait until we have slept long enough
|
// Busy-wait until we have slept long enough
|
||||||
while (remaining > NtTimerDuration::zero()) {
|
while (remaining > TimerDuration::zero()) {
|
||||||
t1 = dxvk::high_resolution_clock::now();
|
t1 = dxvk::high_resolution_clock::now();
|
||||||
remaining -= std::chrono::duration_cast<NtTimerDuration>(t1 - t0);
|
remaining -= std::chrono::duration_cast<TimerDuration>(t1 - t0);
|
||||||
t0 = t1;
|
t0 = t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,16 +152,16 @@ namespace dxvk {
|
|||||||
// Wine's implementation of these functions is a stub as of 6.10, which is fine
|
// Wine's implementation of these functions is a stub as of 6.10, which is fine
|
||||||
// since it uses select() in NtDelayExecution. This is only relevant for Windows.
|
// since it uses select() in NtDelayExecution. This is only relevant for Windows.
|
||||||
if (NtQueryTimerResolution && !NtQueryTimerResolution(&min, &max, &cur)) {
|
if (NtQueryTimerResolution && !NtQueryTimerResolution(&min, &max, &cur)) {
|
||||||
m_sleepGranularity = NtTimerDuration(cur);
|
m_sleepGranularity = TimerDuration(cur);
|
||||||
|
|
||||||
if (NtSetTimerResolution && !NtSetTimerResolution(max, TRUE, &cur)) {
|
if (NtSetTimerResolution && !NtSetTimerResolution(max, TRUE, &cur)) {
|
||||||
Logger::info(str::format("Setting timer interval to ", (double(max) / 10.0), " us"));
|
Logger::info(str::format("Setting timer interval to ", (double(max) / 10.0), " us"));
|
||||||
m_sleepGranularity = NtTimerDuration(max);
|
m_sleepGranularity = TimerDuration(max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Assume 1ms sleep granularity by default
|
// Assume 1ms sleep granularity by default
|
||||||
m_sleepGranularity = NtTimerDuration(10000);
|
m_sleepGranularity = TimerDuration(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sleepThreshold = 4 * m_sleepGranularity;
|
m_sleepThreshold = 4 * m_sleepGranularity;
|
||||||
|
@ -53,34 +53,34 @@ namespace dxvk {
|
|||||||
* \returns \c true if the target frame rate is non-zero.
|
* \returns \c true if the target frame rate is non-zero.
|
||||||
*/
|
*/
|
||||||
bool isEnabled() const {
|
bool isEnabled() const {
|
||||||
return m_targetInterval != NtTimerDuration::zero();
|
return m_targetInterval != TimerDuration::zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
using TimePoint = dxvk::high_resolution_clock::time_point;
|
using TimePoint = dxvk::high_resolution_clock::time_point;
|
||||||
|
|
||||||
using NtTimerDuration = std::chrono::duration<int64_t, std::ratio<1, 10000000>>;
|
using TimerDuration = std::chrono::duration<int64_t, std::ratio<1, 10000000>>;
|
||||||
using NtQueryTimerResolutionProc = UINT (WINAPI *) (ULONG*, ULONG*, ULONG*);
|
using NtQueryTimerResolutionProc = UINT (WINAPI *) (ULONG*, ULONG*, ULONG*);
|
||||||
using NtSetTimerResolutionProc = UINT (WINAPI *) (ULONG, BOOL, ULONG*);
|
using NtSetTimerResolutionProc = UINT (WINAPI *) (ULONG, BOOL, ULONG*);
|
||||||
using NtDelayExecutionProc = UINT (WINAPI *) (BOOL, LARGE_INTEGER*);
|
using NtDelayExecutionProc = UINT (WINAPI *) (BOOL, LARGE_INTEGER*);
|
||||||
|
|
||||||
dxvk::mutex m_mutex;
|
dxvk::mutex m_mutex;
|
||||||
|
|
||||||
NtTimerDuration m_targetInterval = NtTimerDuration::zero();
|
TimerDuration m_targetInterval = TimerDuration::zero();
|
||||||
NtTimerDuration m_refreshInterval = NtTimerDuration::zero();
|
TimerDuration m_refreshInterval = TimerDuration::zero();
|
||||||
NtTimerDuration m_deviation = NtTimerDuration::zero();
|
TimerDuration m_deviation = TimerDuration::zero();
|
||||||
TimePoint m_lastFrame;
|
TimePoint m_lastFrame;
|
||||||
|
|
||||||
bool m_initialized = false;
|
bool m_initialized = false;
|
||||||
bool m_envOverride = false;
|
bool m_envOverride = false;
|
||||||
|
|
||||||
NtTimerDuration m_sleepGranularity = NtTimerDuration::zero();
|
TimerDuration m_sleepGranularity = TimerDuration::zero();
|
||||||
NtTimerDuration m_sleepThreshold = NtTimerDuration::zero();
|
TimerDuration m_sleepThreshold = TimerDuration::zero();
|
||||||
|
|
||||||
NtDelayExecutionProc NtDelayExecution = nullptr;
|
NtDelayExecutionProc NtDelayExecution = nullptr;
|
||||||
|
|
||||||
TimePoint sleep(TimePoint t0, NtTimerDuration duration);
|
TimePoint sleep(TimePoint t0, TimerDuration duration);
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user