Closed wolfokami321 closed 5 years ago
I've heard issues like this before, the solution was disabling power-saving mode on your CPU (on windows, set your power profile to High Performance)
Try killing dwm.exe
and see if that has any effect.
@JoaRiski DWM resets itself on Windows 8+
Another option could be to disable Windows Aero, though I'm not sure if it's relevant to this case. I've experienced similar issues with framerate and killing dwm and/or disabling Aero has helped.
ive tried both with no result
I've had this issue as well, however, I use a NVidia GeForce GT 650M, and Scrolling in Google Chrome or having OBS open will either make the framerate or the audio speed back up to 60fps, or both. I made a thread on reddit about it, and none of the suggestions here worked for me.
@Blayer98 Check your power management setting in both the Windows and Nvidia control panel, also make sure Xenia is set to use the dedicated Nvidia GPU and NOT the Intel iGPU.
Changing Windows power management to Performance didn't work, and even when using the NVidia GPU, it doesn't improve the framerate or audio. Setting NVidia to Performance didn't work either. @shadowbrony33
I've had both on as well and that does not work either, there has to be an issue with Xenia...
timeBeginPeriod(0); might fix it. It sets a global windows timer and affects all processes. By default it's set to 10 and chrome may be setting it to 0 for better performance.
Hmm, I could test that but I don't have time unfortunately, I will see if I can build Xenia at home later but no promises...
I actually got a reddit reply from Dark-Star_1337:
"Both Chrome and OBS switch the timer tick interval in Windows to 1ms (the default is around 15ms I think), probably that's what causes Xenia to speed up. Just google "Chrome timer tick rate" or something like that."
Try this: http://www.lucashale.com/timerresolution/TimerResolution.zip
Press 'Maximum' and see if it does anything.
Wouldn't the timeBeginPeriod(0); be a good addition to xenia since it is pretty CPU heavy?
@Margen67 That tool you linked works great! Bejeweled Blitz LIVE still runs slow, but at least the audio is playing at normal speed. I pressed Maximum and the Resolution was set to 0.500 milliseconds. The default for me was 15.625.
Game Room while using the tool plays audio at normal speed as well and the game runs faster.
@Margen67 Is that tool open source?
That tool is not necessary, you only need to set the timer resolution to 0.5 ms through a kernel32 function. I used it for my PSP emulator to get a PSP thread to process audio at 1 ms resolution when it uses very small packets to play audio samples.
ULONG hal::os::Clock::m_old_resolution;
ULONG hal::os::Clock::m_max_resolution;
f64 hal::os::Clock::m_qpc_resolution;
f64 hal::os::Clock::m_qpc_factor;
f64 hal::os::Clock::m_qpc_frequency;
s64 hal::os::Clock::m_tsc_frequency;
hal::os::Clock hal::os::Clock::m_instance(0);
hal::os::Clock::Clock()
{
}
hal::os::Clock::Clock(int)
{
ULONG dummy;
s64 pca, pcb, pcf, tsca, tscb;
f64 interval;
int const times = 16;
int const retries = 5;
// install the fastest timer resolution (should be 0.5 ms)
::NtQueryTimerResolution(&dummy, &m_max_resolution, &m_old_resolution);
::NtSetTimerResolution(m_max_resolution, TRUE, &dummy);
::NtQueryPerformanceCounter((PLARGE_INTEGER)&pca, (PLARGE_INTEGER)&pcf);
m_qpc_frequency = f64(pcf);
m_qpc_factor = 1000000.0 / m_qpc_frequency;
m_qpc_resolution = f64(m_max_resolution) / 10.0;
m_tsc_frequency = 0;
f64 frequency = 0.0;
// try to compute the CPU frequency with the highest thread priority
__ThreadPriority(THREAD_PRIORITY_TIME_CRITICAL)
{
for (int j = 0; j < times; ++j)
{
for (int i = 0; i < retries; ++i)
{
ReadCounters(tsca, pca);
do
{
ReadCounters(tscb, pcb);
interval = f64(pcb - pca) * m_qpc_factor;
}
while (interval < 1000.0);
if (interval < 1001.0)
{
frequency += f64(tscb - tsca) / interval;
break;
}
}
}
}
m_tsc_frequency = s64(frequency / f64(times));
}
hal::os::Clock::~Clock()
{
if (this == &m_instance)
{
ULONG dummy;
// restore the original timer resolution
::NtSetTimerResolution(m_old_resolution, FALSE, &dummy);
}
}
...
struct ScopedThreadPriority
{
/**/ ScopedThreadPriority(int new_priority = THREAD_PRIORITY_TIME_CRITICAL) : old_priority(::GetThreadPriority((HANDLE)0xFFFFFFFEull))
{
::SetThreadPriority((HANDLE)0xFFFFFFFEull, new_priority);
}
/**/ ~ScopedThreadPriority()
{
::SetThreadPriority((HANDLE)0xFFFFFFFEull, old_priority);
}
operator bool() const { return true; }
private:
int old_priority;
};
#define __ThreadPriority(priority) if (::hal::os::ScopedThreadPriority const __stp__ = ::hal::os::ScopedThreadPriority(priority))
Thanks @hlide - I'll look into this.
Not sure if you already got it but this tool is open source. https://github.com/tebjan/TimerTool
Question: Do AAA games use this same hack? This is an internal API call - one thing I'm worried about is that it'll change across versions of Windows.
I had an issue with Sonic The Hedgehog 2006 running well the first time I tried it, then every time I tried to play the game in Xenia after that the sounds would play at the correct speed but everything else would be in slow motion, even though I was already on the Max Performance power setting.
Using the Timer Tool listed by @slx7R4GDZM seems to have fixed this issue for me!
@DrChat, Chrome definitely calls it. I think it is pretty safe to assume it will be around for the long-term; it has been around since at least Windows 2000.
If you are still worried, though, we can use GetProcAddress and then just not do anything if the proc isn't found:
typedef LONG(CALLBACK* NTSETTIMERRESOLUTION)(IN ULONG DesiredTime,
IN BOOLEAN SetResolution,
OUT PULONG ActualTime);
NTSETTIMERRESOLUTION NtSetTimerResolution;
typedef LONG(CALLBACK* NTQUERYTIMERRESOLUTION)(OUT PULONG MaximumTime,
OUT PULONG MinimumTime,
OUT PULONG CurrentTime);
NTQUERYTIMERRESOLUTION NtQueryTimerResolution;
// On startup
ULONG dummy;
ULONG m_old_resolution = -1;
ULONG m_max_resolution;
HMODULE hNtDll = LoadLibrary(L"NtDll.dll");
if (hNtDll) {
NtQueryTimerResolution = (NTQUERYTIMERRESOLUTION)GetProcAddress(hNtDll, "NtQueryTimerResolution");
NtSetTimerResolution = (NTSETTIMERRESOLUTION)GetProcAddress(hNtDll, "NtSetTimerResolution");
if (NtQueryTimerResolution && NtSetTimerResolution) {
NtQueryTimerResolution(&dummy, &m_max_resolution, &m_old_resolution);
NtSetTimerResolution(m_max_resolution, TRUE, &dummy);
}
}
// On exit
if (hNtDll) {
if (m_old_resolution != -1) {
NtSetTimerResolution(m_old_resolution, FALSE, &dummy);
}
FreeLibrary(hNtDll);
}
Or the alternative (without GetProcAddress approach) that hlide gave:
extern "C" NTSYSAPI LONG NTAPI NtSetTimerResolution(
ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
extern "C" NTSYSAPI LONG NTAPI NtQueryTimerResolution(
OUT PULONG MinimumResolution, OUT PULONG MaximumResolution,
OUT PULONG CurrentResolution);
// On startup
::NtQueryTimerResolution(&dummy, &m_max_resolution, &m_old_resolution);
::NtSetTimerResolution(m_max_resolution, TRUE, &dummy);
// On exit
::NtSetTimerResolution(m_old_resolution, FALSE, &dummy);
Both approaches seem to work perfectly. I was wondering why I usually got half framerate on Banjo-Kazooie, and this was the anwer.
It looks like RPCS3 is having a similar issue. https://github.com/RPCS3/rpcs3/pull/4579
Should be fixed as of 6262dd2c3d30cbc13e653b42d6691c5388433ca6.
I experienced what would seem to be this issue on a recent build, but I remembered I was playing with my HPET settings recently to address an unrelated problem.
For anyone else experiencing what seems like this issue: Xenia was running at around half speed when I had the following set in my BCD config:
tscsyncpolicy Enhanced
useplatformclock Yes
disabledynamictick Yes
Setting the values to the following solved the issue:
tscsyncpolicy Default
useplatformclock No
disabledynamictick No
I'm not sure which one in particular fixed it, but at least one of them was making Xenia lag significantly.
Using the timer tool linked above, the min and max times had not changed at all between adjusting these HPET-related settings.
My "QueryPerformanceFrequency" however had dropped from 24.00000 MHz before making the change to 4.10157 MHz afterwards.
HPET has a lot of caveats. But I'm not sure what it would have to do with chrome.
Power-saving settings affects performance in all applications, not just xenia.
How do I make my game run faster... I'm trying to make Dragon Ball Z: Ultimate Tenkaichi run faster but it goes so slow... My power saving setting is turned to best performance its still slow???
@DBZGohan Only by hardcore programming, or maybe we can eventually, but there are no simple switches.
I noticed an odd error, unless I open google chrome, the framerate for xenia is 30fps or lower. This is repeatable. The graphics card I am using is the Nvidia 965m. Specifically youtube or discord speeds up the game for some reason. I'm also using Allancat's xenia build for Sonic 2006