summaryrefslogtreecommitdiffstats
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/windows/detect.py35
-rw-r--r--platform/windows/os_windows.cpp66
-rw-r--r--platform/windows/os_windows.h1
3 files changed, 100 insertions, 2 deletions
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 11dd4548f1..40a8067000 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -13,6 +13,7 @@ if TYPE_CHECKING:
# To match other platforms
STACK_SIZE = 8388608
+STACK_SIZE_SANITIZERS = 30 * 1024 * 1024
def get_name():
@@ -203,6 +204,7 @@ def get_opts():
BoolVariable("use_llvm", "Use the LLVM compiler", False),
BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True),
BoolVariable("use_asan", "Use address sanitizer (ASAN)", False),
+ BoolVariable("use_ubsan", "Use LLVM compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("debug_crt", "Compile with MSVC's debug CRT (/MDd)", False),
BoolVariable("incremental_link", "Use MSVC incremental linking. May increase or decrease build times.", False),
BoolVariable("silence_msvc", "Silence MSVC's cl/link stdout bloat, redirecting any errors to stderr.", True),
@@ -507,6 +509,7 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config):
if env["use_asan"]:
env.extra_suffix += ".san"
prebuilt_lib_extra_suffix = ".san"
+ env.AppendUnique(CPPDEFINES=["SANITIZERS_ENABLED"])
env.Append(CCFLAGS=["/fsanitize=address"])
env.Append(LINKFLAGS=["/INFERASANLIBS"])
@@ -628,7 +631,11 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config):
env["BUILDERS"]["Program"] = methods.precious_program
env.Append(LINKFLAGS=["/NATVIS:platform\\windows\\godot.natvis"])
- env.AppendUnique(LINKFLAGS=["/STACK:" + str(STACK_SIZE)])
+
+ if env["use_asan"]:
+ env.AppendUnique(LINKFLAGS=["/STACK:" + str(STACK_SIZE_SANITIZERS)])
+ else:
+ env.AppendUnique(LINKFLAGS=["/STACK:" + str(STACK_SIZE)])
def configure_mingw(env: "SConsEnvironment"):
@@ -721,7 +728,10 @@ def configure_mingw(env: "SConsEnvironment"):
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto"])
- env.Append(LINKFLAGS=["-Wl,--stack," + str(STACK_SIZE)])
+ if env["use_asan"]:
+ env.Append(LINKFLAGS=["-Wl,--stack," + str(STACK_SIZE_SANITIZERS)])
+ else:
+ env.Append(LINKFLAGS=["-Wl,--stack," + str(STACK_SIZE)])
## Compile flags
@@ -732,6 +742,27 @@ def configure_mingw(env: "SConsEnvironment"):
if not env["use_llvm"]:
env.Append(CCFLAGS=["-mwindows"])
+ if env["use_asan"] or env["use_ubsan"]:
+ if not env["use_llvm"]:
+ print("GCC does not support sanitizers on Windows.")
+ sys.exit(255)
+ if env["arch"] not in ["x86_32", "x86_64"]:
+ print("Sanitizers are only supported for x86_32 and x86_64.")
+ sys.exit(255)
+
+ env.extra_suffix += ".san"
+ env.AppendUnique(CPPDEFINES=["SANITIZERS_ENABLED"])
+ san_flags = []
+ if env["use_asan"]:
+ san_flags.append("-fsanitize=address")
+ if env["use_ubsan"]:
+ san_flags.append("-fsanitize=undefined")
+ # Disable the vptr check since it gets triggered on any COM interface calls.
+ san_flags.append("-fno-sanitize=vptr")
+ env.Append(CFLAGS=san_flags)
+ env.Append(CCFLAGS=san_flags)
+ env.Append(LINKFLAGS=san_flags)
+
env.Append(CPPDEFINES=["WINDOWS_ENABLED", "WASAPI_ENABLED", "WINMIDI_ENABLED"])
env.Append(
CPPDEFINES=[
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index fb95c69b52..7316992b60 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -616,6 +616,72 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const {
return info;
}
+bool OS_Windows::get_user_prefers_integrated_gpu() const {
+ // On Windows 10, the preferred GPU configured in Windows Settings is
+ // stored in the registry under the key
+ // `HKEY_CURRENT_USER\SOFTWARE\Microsoft\DirectX\UserGpuPreferences`
+ // with the name being the app ID or EXE path. The value is in the form of
+ // `GpuPreference=1;`, with the value being 1 for integrated GPU and 2
+ // for discrete GPU. On Windows 11, there may be more flags, separated
+ // by semicolons.
+
+ // If this is a packaged app, use the "application user model ID".
+ // Otherwise, use the EXE path.
+ WCHAR value_name[32768];
+ bool is_packaged = false;
+ {
+ HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
+ if (kernel32) {
+ using GetCurrentApplicationUserModelIdPtr = LONG(WINAPI *)(UINT32 * length, PWSTR id);
+ GetCurrentApplicationUserModelIdPtr GetCurrentApplicationUserModelId = (GetCurrentApplicationUserModelIdPtr)GetProcAddress(kernel32, "GetCurrentApplicationUserModelId");
+
+ if (GetCurrentApplicationUserModelId) {
+ UINT32 length = sizeof(value_name) / sizeof(value_name[0]);
+ LONG result = GetCurrentApplicationUserModelId(&length, value_name);
+ if (result == ERROR_SUCCESS) {
+ is_packaged = true;
+ }
+ }
+ }
+ }
+ if (!is_packaged && GetModuleFileNameW(nullptr, value_name, sizeof(value_name) / sizeof(value_name[0])) >= sizeof(value_name) / sizeof(value_name[0])) {
+ // Paths should never be longer than 32767, but just in case.
+ return false;
+ }
+
+ LPCWSTR subkey = L"SOFTWARE\\Microsoft\\DirectX\\UserGpuPreferences";
+ HKEY hkey = nullptr;
+ LSTATUS result = RegOpenKeyExW(HKEY_CURRENT_USER, subkey, 0, KEY_READ, &hkey);
+ if (result != ERROR_SUCCESS) {
+ return false;
+ }
+
+ DWORD size = 0;
+ result = RegGetValueW(hkey, nullptr, value_name, RRF_RT_REG_SZ, nullptr, nullptr, &size);
+ if (result != ERROR_SUCCESS || size == 0) {
+ RegCloseKey(hkey);
+ return false;
+ }
+
+ Vector<WCHAR> buffer;
+ buffer.resize(size / sizeof(WCHAR));
+ result = RegGetValueW(hkey, nullptr, value_name, RRF_RT_REG_SZ, nullptr, (LPBYTE)buffer.ptrw(), &size);
+ if (result != ERROR_SUCCESS) {
+ RegCloseKey(hkey);
+ return false;
+ }
+
+ RegCloseKey(hkey);
+ const String flags = String::utf16((const char16_t *)buffer.ptr(), size / sizeof(WCHAR));
+
+ for (const String &flag : flags.split(";", false)) {
+ if (flag == "GpuPreference=1") {
+ return true;
+ }
+ }
+ return false;
+}
+
OS::DateTime OS_Windows::get_datetime(bool p_utc) const {
SYSTEMTIME systemtime;
if (p_utc) {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index b6a21ed42d..9c7b98d7fd 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -172,6 +172,7 @@ public:
virtual String get_version() const override;
virtual Vector<String> get_video_adapter_driver_info() const override;
+ virtual bool get_user_prefers_integrated_gpu() const override;
virtual void initialize_joypads() override {}