forked from lutris/buildbot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
10eede4
commit 9ead2ff
Showing
109 changed files
with
8,407 additions
and
29,013 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -978,3 +978,229 @@ index 2253591f6fa..07fb6decb62 100644 | |
{ | ||
struct object *root; | ||
struct mapping *mapping; | ||
From 3b066b60d21e0fa03ee713a5c11ecfc5252de53c Mon Sep 17 00:00:00 2001 | ||
From: Arkadiusz Hiler <[email protected]> | ||
Date: Thu, 3 Jun 2021 22:56:08 +0300 | ||
Subject: [PATCH] wineboot: Check if the kernel trusts TSC before using it for | ||
Qpc. | ||
|
||
Even if the bits are claiming that TSC meets our requirements the | ||
hardware implementation may still be broken. | ||
|
||
The Linux kernel does a lot of quality testing before deciding to use as | ||
the clock source. If it (or the user, through an override) does not trust | ||
the TSC we should not trust it either. | ||
|
||
CW-Bug-Id: #18918 | ||
CW-Bug-Id: #18958 | ||
--- | ||
programs/wineboot/wineboot.c | 31 +++++++++++++++++++++++++++++++ | ||
1 file changed, 31 insertions(+) | ||
|
||
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c | ||
index 9bebededa4f..79a4bda4d67 100644 | ||
--- a/programs/wineboot/wineboot.c | ||
+++ b/programs/wineboot/wineboot.c | ||
@@ -315,6 +315,30 @@ static UINT64 read_tsc_frequency(void) | ||
return freq; | ||
} | ||
|
||
+static BOOL is_tsc_trusted_by_the_kernel(void) | ||
+{ | ||
+ char buf[4] = {}; | ||
+ DWORD num_read; | ||
+ HANDLE handle; | ||
+ BOOL ret = TRUE; | ||
+ | ||
+ handle = CreateFileA( "\\??\\unix\\sys\\bus\\clocksource\\devices\\clocksource0\\current_clocksource", | ||
+ GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); | ||
+ | ||
+ if (handle == INVALID_HANDLE_VALUE) | ||
+ return TRUE; | ||
+ | ||
+ if (ReadFile( handle, buf, sizeof(buf)-1, &num_read, NULL )) | ||
+ { | ||
+ if (!!strcmp( "tsc", buf )) | ||
+ ret = FALSE; | ||
+ } | ||
+ | ||
+ CloseHandle( handle ); | ||
+ | ||
+ return ret; | ||
+} | ||
+ | ||
static void initialize_qpc_features(struct _KUSER_SHARED_DATA *data) | ||
{ | ||
int regs[4]; | ||
@@ -346,6 +370,13 @@ static void initialize_qpc_features(struct _KUSER_SHARED_DATA *data) | ||
WARN("No invariant TSC, disabling QpcBypass\n"); | ||
return; | ||
} | ||
+ | ||
+ if (!is_tsc_trusted_by_the_kernel()) | ||
+ { | ||
+ WARN("TSC is not trusted by the kernel, disabling QpcBypass.\n"); | ||
+ return; | ||
+ } | ||
+ | ||
data->QpcBypassEnabled |= SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED; | ||
|
||
/* check for rdtscp support bit */ | ||
From 69f2470f937f46ae362d0ba5c144f170f5850a8e Mon Sep 17 00:00:00 2001 | ||
From: Joshua Ashton <[email protected]> | ||
Date: Thu, 3 Jun 2021 20:27:49 +0100 | ||
Subject: [PATCH] wineboot: Return TSC frequency in ~Mhz | ||
|
||
Some games such as Horizon Zero Dawn use this registry value to correlate values from rtdsc -> real time. | ||
|
||
In my testing across a few devices, Windows always returns the tsc frequency in this entry, not the current/maximum frequency of the processor. | ||
|
||
Returning the nominal/maximum cpu frequency here causes the game to run in slow motion as it may not match the tsc frequency of the processor. | ||
|
||
Ideally we'd not have to measure this and the kernel would return tsc_khz to userspace, but this is a good enough stop-gap until https://lkml.org/lkml/2020/12/31/72 or something similar is merged. | ||
|
||
Fixes: #4125 (Slow motion bug) | ||
|
||
Signed-off-by: Joshua Ashton <[email protected]> | ||
--- | ||
programs/wineboot/wineboot.c | 5 ++++- | ||
1 file changed, 4 insertions(+), 1 deletion(-) | ||
|
||
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c | ||
index 79a4bda4d67..0662feac9ce 100644 | ||
--- a/programs/wineboot/wineboot.c | ||
+++ b/programs/wineboot/wineboot.c | ||
@@ -969,12 +969,15 @@ static void create_hardware_registry_keys(void) | ||
if (!RegCreateKeyExW( cpu_key, numW, 0, NULL, REG_OPTION_VOLATILE, | ||
KEY_ALL_ACCESS, NULL, &hkey, NULL )) | ||
{ | ||
+ UINT64 tsc_freq = read_tsc_frequency(); /* Hz */ | ||
+ DWORD tsc_freq_mhz = (DWORD)(tsc_freq / 1000000ull); | ||
+ | ||
RegSetValueExW( hkey, L"FeatureSet", 0, REG_DWORD, (BYTE *)&sci.ProcessorFeatureBits, sizeof(DWORD) ); | ||
set_reg_value( hkey, L"Identifier", id ); | ||
/* TODO: report ARM properly */ | ||
set_reg_value( hkey, L"ProcessorNameString", namestr ); | ||
set_reg_value( hkey, L"VendorIdentifier", vendorid ); | ||
- RegSetValueExW( hkey, L"~MHz", 0, REG_DWORD, (BYTE *)&power_info[i].MaxMhz, sizeof(DWORD) ); | ||
+ RegSetValueExW( hkey, L"~MHz", 0, REG_DWORD, (BYTE *)&tsc_freq_mhz, sizeof(DWORD) ); | ||
RegCloseKey( hkey ); | ||
} | ||
if (sci.ProcessorArchitecture != PROCESSOR_ARCHITECTURE_ARM && | ||
From 2bde7d53b3874dfc6f3066819e00da142443a48f Mon Sep 17 00:00:00 2001 | ||
From: Joshua Ashton <[email protected]> | ||
Date: Fri, 4 Jun 2021 10:20:51 +0200 | ||
Subject: [PATCH] wineboot: Calculate TSC frequency once at the start | ||
|
||
This calculates the TSC frequency once at the very start of wineboot. | ||
|
||
This avoids needing to calculate this multiple times which can lead to stalls. | ||
|
||
Signed-off-by: Joshua Ashton <[email protected]> | ||
--- | ||
programs/wineboot/wineboot.c | 26 ++++++++++++++------------ | ||
1 file changed, 14 insertions(+), 12 deletions(-) | ||
|
||
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c | ||
index 0662feac9ce..dc0e645dd09 100644 | ||
--- a/programs/wineboot/wineboot.c | ||
+++ b/programs/wineboot/wineboot.c | ||
@@ -339,7 +339,7 @@ static BOOL is_tsc_trusted_by_the_kernel(void) | ||
return ret; | ||
} | ||
|
||
-static void initialize_qpc_features(struct _KUSER_SHARED_DATA *data) | ||
+static void initialize_qpc_features(struct _KUSER_SHARED_DATA *data, UINT64 tsc_frequency) | ||
{ | ||
int regs[4]; | ||
|
||
@@ -388,7 +388,7 @@ static void initialize_qpc_features(struct _KUSER_SHARED_DATA *data) | ||
else | ||
data->QpcBypassEnabled |= SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_MFENCE; | ||
|
||
- if ((data->QpcFrequency = (read_tsc_frequency() >> 10))) | ||
+ if ((data->QpcFrequency = (tsc_frequency >> 10))) | ||
{ | ||
data->QpcShift = 10; | ||
data->QpcBias = 0; | ||
@@ -433,7 +433,7 @@ static UINT64 muldiv_tsc(UINT64 a, UINT64 b, UINT64 c) | ||
return ka * kb * c + kb * ra + ka * rb + (ra * rb + c / 2) / c; | ||
} | ||
|
||
-static void create_hypervisor_shared_data(void) | ||
+static void create_hypervisor_shared_data(UINT64 tsc_frequency) | ||
{ | ||
struct _KUSER_SHARED_DATA *user_shared_data = (void *)0x7ffe0000; | ||
struct hypervisor_shared_data *hypervisor_shared_data; | ||
@@ -480,7 +480,7 @@ static void create_hypervisor_shared_data(void) | ||
|
||
if (user_shared_data->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED) | ||
{ | ||
- hypervisor_shared_data->QpcMultiplier = muldiv_tsc((UINT64)5000 << 32, (UINT64)2000 << 32, read_tsc_frequency()); | ||
+ hypervisor_shared_data->QpcMultiplier = muldiv_tsc((UINT64)5000 << 32, (UINT64)2000 << 32, tsc_frequency); | ||
user_shared_data->QpcBypassEnabled |= SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_HV_PAGE; | ||
user_shared_data->QpcInterruptTimeIncrement = (ULONGLONG)1 << 63; | ||
user_shared_data->QpcInterruptTimeIncrementShift = 1; | ||
@@ -495,7 +495,7 @@ static void create_hypervisor_shared_data(void) | ||
UnmapViewOfFile( hypervisor_shared_data ); | ||
} | ||
|
||
-static void create_user_shared_data(void) | ||
+static void create_user_shared_data(UINT64 tsc_frequency) | ||
{ | ||
struct _KUSER_SHARED_DATA *data; | ||
RTL_OSVERSIONINFOEXW version; | ||
@@ -582,7 +582,7 @@ static void create_user_shared_data(void) | ||
data->ActiveGroupCount = 1; | ||
|
||
initialize_xstate_features( data ); | ||
- initialize_qpc_features( data ); | ||
+ initialize_qpc_features( data, tsc_frequency ); | ||
|
||
UnmapViewOfFile( data ); | ||
} | ||
@@ -894,7 +894,7 @@ static void create_bios_key( HKEY system_key ) | ||
} | ||
|
||
/* create the volatile hardware registry keys */ | ||
-static void create_hardware_registry_keys(void) | ||
+static void create_hardware_registry_keys(UINT64 tsc_frequency) | ||
{ | ||
unsigned int i; | ||
HKEY hkey, system_key, cpu_key, fpu_key; | ||
@@ -969,8 +969,7 @@ static void create_hardware_registry_keys(void) | ||
if (!RegCreateKeyExW( cpu_key, numW, 0, NULL, REG_OPTION_VOLATILE, | ||
KEY_ALL_ACCESS, NULL, &hkey, NULL )) | ||
{ | ||
- UINT64 tsc_freq = read_tsc_frequency(); /* Hz */ | ||
- DWORD tsc_freq_mhz = (DWORD)(tsc_freq / 1000000ull); | ||
+ DWORD tsc_freq_mhz = (DWORD)(tsc_frequency / 1000000ull); /* Hz -> Mhz */ | ||
|
||
RegSetValueExW( hkey, L"FeatureSet", 0, REG_DWORD, (BYTE *)&sci.FeatureSet, sizeof(DWORD) ); | ||
set_reg_value( hkey, L"Identifier", id ); | ||
@@ -1896,9 +1895,12 @@ int __cdecl main( int argc, char *argv[] ) | ||
BOOL end_session, force, init, kill, restart, shutdown, update; | ||
HANDLE event; | ||
OBJECT_ATTRIBUTES attr; | ||
+ UINT64 tsc_frequency; | ||
UNICODE_STRING nameW; | ||
BOOL is_wow64; | ||
|
||
+ tsc_frequency = read_tsc_frequency(); | ||
+ | ||
end_session = force = init = kill = restart = shutdown = update = FALSE; | ||
GetWindowsDirectoryW( windowsdir, MAX_PATH ); | ||
if( !SetCurrentDirectoryW( windowsdir ) ) | ||
@@ -1981,9 +1983,9 @@ int __cdecl main( int argc, char *argv[] ) | ||
|
||
ResetEvent( event ); /* in case this is a restart */ | ||
|
||
- create_user_shared_data(); | ||
- create_hypervisor_shared_data(); | ||
- create_hardware_registry_keys(); | ||
+ create_user_shared_data(tsc_frequency); | ||
+ create_hypervisor_shared_data(tsc_frequency); | ||
+ create_hardware_registry_keys(tsc_frequency); | ||
create_dynamic_registry_keys(); | ||
create_environment_registry_keys(); | ||
create_computer_name_keys(); |
53 changes: 53 additions & 0 deletions
53
runners/wine/build-preparation/fshack-patches/1-mfplat-godfall-hotfix.mypatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
From 99d2e546fb21ae93114834142692518ce4730ee5 Mon Sep 17 00:00:00 2001 | ||
From: Thomas Crider <[email protected]> | ||
Date: Wed, 30 Jun 2021 19:57:23 -0600 | ||
Subject: [PATCH] winegstreamer: adjust GetSlowestRate and GetFastestRate | ||
values | ||
|
||
Per the docs, 0 would not render additional frames: | ||
|
||
https://docs.microsoft.com/en-us/windows/win32/medfound/about-rate-control | ||
A rate of zero causes one frame to be rendered; after that, the presentation | ||
clock does not advance. To get another frame at the rate of zero, the | ||
application must seek to a new position. | ||
|
||
Having this set to 0 causes Godfall's new character intro video to | ||
black screen, seemingly because it only renders one frame. | ||
|
||
Based on the current GetFastestRate value attempt, if we approach the logic on | ||
numerical positive/negative values, the fastest forward rate would be | ||
1e6f (1000000f) and slowest 1.0f, while in reverse the fastest would | ||
be -1.0f and slowest -1e6f (-1000000f). | ||
|
||
This fixes Godfall's new character intro video playback and does not | ||
appear to break other tested games. | ||
|
||
Signed-off-by: Thomas Crider <[email protected]> | ||
--- | ||
dlls/winegstreamer/media_source.c | 4 ++-- | ||
1 file changed, 2 insertions(+), 2 deletions(-) | ||
|
||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c | ||
index eaf4b9b6815..79e51ca3977 100644 | ||
--- a/dlls/winegstreamer/media_source.c | ||
+++ b/dlls/winegstreamer/media_source.c | ||
@@ -936,7 +936,7 @@ static HRESULT WINAPI media_source_rate_support_GetSlowestRate(IMFRateSupport *i | ||
{ | ||
TRACE("%p, %d, %d, %p.\n", iface, direction, thin, rate); | ||
|
||
- *rate = 0.0f; | ||
+ *rate = direction == MFRATE_FORWARD ? 1.0f : -1e6f; | ||
|
||
return S_OK; | ||
} | ||
@@ -945,7 +945,7 @@ static HRESULT WINAPI media_source_rate_support_GetFastestRate(IMFRateSupport *i | ||
{ | ||
TRACE("%p, %d, %d, %p.\n", iface, direction, thin, rate); | ||
|
||
- *rate = direction == MFRATE_FORWARD ? 1e6f : -1e6f; | ||
+ *rate = direction == MFRATE_FORWARD ? 1e6f : -1.0f; | ||
|
||
return S_OK; | ||
} | ||
-- | ||
2.31.1 |
Oops, something went wrong.