yuzu qt: Add option to disable startup Vulkan check

The startup check apparently confuses other programs when yuzu launches
2 processes and then quickly closes one of them. Though this isn't
really our issues it's also not a big deal for me to add an option to
work around that issue.
master
lat9nq 2022-09-19 14:46:12 +07:00
parent 3a5f9409c8
commit 89af4bfba8
7 changed files with 61 additions and 40 deletions

@ -531,6 +531,7 @@ struct Values {
Setting<bool> use_auto_stub{false, "use_auto_stub"}; Setting<bool> use_auto_stub{false, "use_auto_stub"};
Setting<bool> enable_all_controllers{false, "enable_all_controllers"}; Setting<bool> enable_all_controllers{false, "enable_all_controllers"};
Setting<bool> create_crash_dumps{false, "create_crash_dumps"}; Setting<bool> create_crash_dumps{false, "create_crash_dumps"};
Setting<bool> perform_vulkan_check{true, "perform_vulkan_check"};
// Miscellaneous // Miscellaneous
Setting<std::string> log_filter{"*:Info", "log_filter"}; Setting<std::string> log_filter{"*:Info", "log_filter"};

@ -546,6 +546,7 @@ void Config::ReadDebuggingValues() {
ReadBasicSetting(Settings::values.use_auto_stub); ReadBasicSetting(Settings::values.use_auto_stub);
ReadBasicSetting(Settings::values.enable_all_controllers); ReadBasicSetting(Settings::values.enable_all_controllers);
ReadBasicSetting(Settings::values.create_crash_dumps); ReadBasicSetting(Settings::values.create_crash_dumps);
ReadBasicSetting(Settings::values.perform_vulkan_check);
qt_config->endGroup(); qt_config->endGroup();
} }
@ -1162,6 +1163,7 @@ void Config::SaveDebuggingValues() {
WriteBasicSetting(Settings::values.disable_macro_jit); WriteBasicSetting(Settings::values.disable_macro_jit);
WriteBasicSetting(Settings::values.enable_all_controllers); WriteBasicSetting(Settings::values.enable_all_controllers);
WriteBasicSetting(Settings::values.create_crash_dumps); WriteBasicSetting(Settings::values.create_crash_dumps);
WriteBasicSetting(Settings::values.perform_vulkan_check);
qt_config->endGroup(); qt_config->endGroup();
} }

@ -77,6 +77,7 @@ void ConfigureDebug::SetConfiguration() {
ui->disable_loop_safety_checks->setChecked( ui->disable_loop_safety_checks->setChecked(
Settings::values.disable_shader_loop_safety_checks.GetValue()); Settings::values.disable_shader_loop_safety_checks.GetValue());
ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue()); ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue());
ui->perform_vulkan_check->setChecked(Settings::values.perform_vulkan_check.GetValue());
#ifdef YUZU_USE_QT_WEB_ENGINE #ifdef YUZU_USE_QT_WEB_ENGINE
ui->disable_web_applet->setChecked(UISettings::values.disable_web_applet.GetValue()); ui->disable_web_applet->setChecked(UISettings::values.disable_web_applet.GetValue());
@ -117,6 +118,7 @@ void ConfigureDebug::ApplyConfiguration() {
ui->disable_loop_safety_checks->isChecked(); ui->disable_loop_safety_checks->isChecked();
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
Settings::values.extended_logging = ui->extended_logging->isChecked(); Settings::values.extended_logging = ui->extended_logging->isChecked();
Settings::values.perform_vulkan_check = ui->perform_vulkan_check->isChecked();
UISettings::values.disable_web_applet = ui->disable_web_applet->isChecked(); UISettings::values.disable_web_applet = ui->disable_web_applet->isChecked();
Debugger::ToggleConsole(); Debugger::ToggleConsole();
Common::Log::Filter filter; Common::Log::Filter filter;

@ -313,6 +313,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0">
<widget class="QCheckBox" name="perform_vulkan_check">
<property name="toolTip">
<string>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</string>
</property>
<property name="text">
<string>Perform Startup Vulkan Check</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

@ -4086,7 +4086,8 @@ int main(int argc, char* argv[]) {
} }
#endif #endif
if (StartupChecks(argv[0], &has_broken_vulkan)) { if (StartupChecks(argv[0], &has_broken_vulkan,
Settings::values.perform_vulkan_check.GetValue())) {
return 0; return 0;
} }

@ -57,7 +57,7 @@ bool CheckEnvVars(bool* is_child) {
return false; return false;
} }
bool StartupChecks(const char* arg0, bool* has_broken_vulkan) { bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulkan_check) {
#ifdef _WIN32 #ifdef _WIN32
// Set the startup variable for child processes // Set the startup variable for child processes
const bool env_var_set = SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, ENV_VAR_ENABLED_TEXT); const bool env_var_set = SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, ENV_VAR_ENABLED_TEXT);
@ -67,29 +67,32 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan) {
return false; return false;
} }
PROCESS_INFORMATION process_info; if (perform_vulkan_check) {
std::memset(&process_info, '\0', sizeof(process_info)); // Spawn child process that performs Vulkan check
PROCESS_INFORMATION process_info;
std::memset(&process_info, '\0', sizeof(process_info));
if (!SpawnChild(arg0, &process_info, 0)) { if (!SpawnChild(arg0, &process_info, 0)) {
return false; return false;
} }
// Wait until the processs exits and get exit code from it // Wait until the processs exits and get exit code from it
WaitForSingleObject(process_info.hProcess, INFINITE); WaitForSingleObject(process_info.hProcess, INFINITE);
DWORD exit_code = STILL_ACTIVE; DWORD exit_code = STILL_ACTIVE;
const int err = GetExitCodeProcess(process_info.hProcess, &exit_code); const int err = GetExitCodeProcess(process_info.hProcess, &exit_code);
if (err == 0) { if (err == 0) {
std::fprintf(stderr, "GetExitCodeProcess failed with error %d\n", GetLastError()); std::fprintf(stderr, "GetExitCodeProcess failed with error %d\n", GetLastError());
} }
// Vulkan is broken if the child crashed (return value is not zero) // Vulkan is broken if the child crashed (return value is not zero)
*has_broken_vulkan = (exit_code != 0); *has_broken_vulkan = (exit_code != 0);
if (CloseHandle(process_info.hProcess) == 0) { if (CloseHandle(process_info.hProcess) == 0) {
std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError()); std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
} }
if (CloseHandle(process_info.hThread) == 0) { if (CloseHandle(process_info.hThread) == 0) {
std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError()); std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
}
} }
if (!SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, nullptr)) { if (!SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, nullptr)) {
@ -98,26 +101,28 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan) {
} }
#elif defined(YUZU_UNIX) #elif defined(YUZU_UNIX)
const pid_t pid = fork(); if (perform_vulkan_check) {
if (pid == 0) { const pid_t pid = fork();
CheckVulkan(); if (pid == 0) {
return true; CheckVulkan();
} else if (pid == -1) { return true;
const int err = errno; } else if (pid == -1) {
std::fprintf(stderr, "fork failed with error %d\n", err); const int err = errno;
return false; std::fprintf(stderr, "fork failed with error %d\n", err);
} return false;
}
// Get exit code from child process // Get exit code from child process
int status; int status;
const int r_val = wait(&status); const int r_val = wait(&status);
if (r_val == -1) { if (r_val == -1) {
const int err = errno; const int err = errno;
std::fprintf(stderr, "wait failed with error %d\n", err); std::fprintf(stderr, "wait failed with error %d\n", err);
return false; return false;
}
// Vulkan is broken if the child crashed (return value is not zero)
*has_broken_vulkan = (status != 0);
} }
// Vulkan is broken if the child crashed (return value is not zero)
*has_broken_vulkan = (status != 0);
#endif #endif
return false; return false;
} }

@ -13,7 +13,7 @@ constexpr char ENV_VAR_ENABLED_TEXT[] = "ON";
void CheckVulkan(); void CheckVulkan();
bool CheckEnvVars(bool* is_child); bool CheckEnvVars(bool* is_child);
bool StartupChecks(const char* arg0, bool* has_broken_vulkan); bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulkan_check);
#ifdef _WIN32 #ifdef _WIN32
bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags); bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags);