diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/audio_core.cpp | 2 | ||||
| -rw-r--r-- | src/audio_core/audio_manager.cpp | 17 | ||||
| -rw-r--r-- | src/audio_core/audio_manager.h | 19 | ||||
| -rw-r--r-- | src/audio_core/renderer/adsp/audio_renderer.cpp | 2 | ||||
| -rw-r--r-- | src/audio_core/renderer/adsp/audio_renderer.h | 2 | ||||
| -rw-r--r-- | src/common/settings.h | 1 | ||||
| -rw-r--r-- | src/core/internal_network/network.cpp | 12 | ||||
| -rw-r--r-- | src/core/internal_network/sockets.h | 11 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_debug.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_debug.ui | 10 | ||||
| -rw-r--r-- | src/yuzu/configuration/input_profiles.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/startup_checks.cpp | 91 | ||||
| -rw-r--r-- | src/yuzu/startup_checks.h | 2 |
15 files changed, 99 insertions, 79 deletions
diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp index c845330cd..07a679c32 100644 --- a/src/audio_core/audio_core.cpp +++ b/src/audio_core/audio_core.cpp | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | namespace AudioCore { | 9 | namespace AudioCore { |
| 10 | 10 | ||
| 11 | AudioCore::AudioCore(Core::System& system) : audio_manager{std::make_unique<AudioManager>(system)} { | 11 | AudioCore::AudioCore(Core::System& system) : audio_manager{std::make_unique<AudioManager>()} { |
| 12 | CreateSinks(); | 12 | CreateSinks(); |
| 13 | // Must be created after the sinks | 13 | // Must be created after the sinks |
| 14 | adsp = std::make_unique<AudioRenderer::ADSP::ADSP>(system, *output_sink); | 14 | adsp = std::make_unique<AudioRenderer::ADSP::ADSP>(system, *output_sink); |
diff --git a/src/audio_core/audio_manager.cpp b/src/audio_core/audio_manager.cpp index 2f1bba9c3..2acde668e 100644 --- a/src/audio_core/audio_manager.cpp +++ b/src/audio_core/audio_manager.cpp | |||
| @@ -1,14 +1,13 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "audio_core/audio_in_manager.h" | ||
| 5 | #include "audio_core/audio_manager.h" | 4 | #include "audio_core/audio_manager.h" |
| 6 | #include "audio_core/audio_out_manager.h" | ||
| 7 | #include "core/core.h" | 5 | #include "core/core.h" |
| 6 | #include "core/hle/service/audio/errors.h" | ||
| 8 | 7 | ||
| 9 | namespace AudioCore { | 8 | namespace AudioCore { |
| 10 | 9 | ||
| 11 | AudioManager::AudioManager(Core::System& system_) : system{system_} { | 10 | AudioManager::AudioManager() { |
| 12 | thread = std::jthread([this]() { ThreadFunc(); }); | 11 | thread = std::jthread([this]() { ThreadFunc(); }); |
| 13 | } | 12 | } |
| 14 | 13 | ||
| @@ -27,7 +26,7 @@ Result AudioManager::SetOutManager(BufferEventFunc buffer_func) { | |||
| 27 | 26 | ||
| 28 | const auto index{events.GetManagerIndex(Event::Type::AudioOutManager)}; | 27 | const auto index{events.GetManagerIndex(Event::Type::AudioOutManager)}; |
| 29 | if (buffer_events[index] == nullptr) { | 28 | if (buffer_events[index] == nullptr) { |
| 30 | buffer_events[index] = buffer_func; | 29 | buffer_events[index] = std::move(buffer_func); |
| 31 | needs_update = true; | 30 | needs_update = true; |
| 32 | events.SetAudioEvent(Event::Type::AudioOutManager, true); | 31 | events.SetAudioEvent(Event::Type::AudioOutManager, true); |
| 33 | } | 32 | } |
| @@ -43,7 +42,7 @@ Result AudioManager::SetInManager(BufferEventFunc buffer_func) { | |||
| 43 | 42 | ||
| 44 | const auto index{events.GetManagerIndex(Event::Type::AudioInManager)}; | 43 | const auto index{events.GetManagerIndex(Event::Type::AudioInManager)}; |
| 45 | if (buffer_events[index] == nullptr) { | 44 | if (buffer_events[index] == nullptr) { |
| 46 | buffer_events[index] = buffer_func; | 45 | buffer_events[index] = std::move(buffer_func); |
| 47 | needs_update = true; | 46 | needs_update = true; |
| 48 | events.SetAudioEvent(Event::Type::AudioInManager, true); | 47 | events.SetAudioEvent(Event::Type::AudioInManager, true); |
| 49 | } | 48 | } |
| @@ -60,19 +59,21 @@ void AudioManager::ThreadFunc() { | |||
| 60 | running = true; | 59 | running = true; |
| 61 | 60 | ||
| 62 | while (running) { | 61 | while (running) { |
| 63 | auto timed_out{events.Wait(l, std::chrono::seconds(2))}; | 62 | const auto timed_out{events.Wait(l, std::chrono::seconds(2))}; |
| 64 | 63 | ||
| 65 | if (events.CheckAudioEventSet(Event::Type::Max)) { | 64 | if (events.CheckAudioEventSet(Event::Type::Max)) { |
| 66 | break; | 65 | break; |
| 67 | } | 66 | } |
| 68 | 67 | ||
| 69 | for (size_t i = 0; i < buffer_events.size(); i++) { | 68 | for (size_t i = 0; i < buffer_events.size(); i++) { |
| 70 | if (events.CheckAudioEventSet(Event::Type(i)) || timed_out) { | 69 | const auto event_type = static_cast<Event::Type>(i); |
| 70 | |||
| 71 | if (events.CheckAudioEventSet(event_type) || timed_out) { | ||
| 71 | if (buffer_events[i]) { | 72 | if (buffer_events[i]) { |
| 72 | buffer_events[i](); | 73 | buffer_events[i](); |
| 73 | } | 74 | } |
| 74 | } | 75 | } |
| 75 | events.SetAudioEvent(Event::Type(i), false); | 76 | events.SetAudioEvent(event_type, false); |
| 76 | } | 77 | } |
| 77 | } | 78 | } |
| 78 | } | 79 | } |
diff --git a/src/audio_core/audio_manager.h b/src/audio_core/audio_manager.h index 8cbd95e22..abf077de4 100644 --- a/src/audio_core/audio_manager.h +++ b/src/audio_core/audio_manager.h | |||
| @@ -10,22 +10,11 @@ | |||
| 10 | #include <thread> | 10 | #include <thread> |
| 11 | 11 | ||
| 12 | #include "audio_core/audio_event.h" | 12 | #include "audio_core/audio_event.h" |
| 13 | #include "core/hle/service/audio/errors.h" | ||
| 14 | 13 | ||
| 15 | namespace Core { | 14 | union Result; |
| 16 | class System; | ||
| 17 | } | ||
| 18 | 15 | ||
| 19 | namespace AudioCore { | 16 | namespace AudioCore { |
| 20 | 17 | ||
| 21 | namespace AudioOut { | ||
| 22 | class Manager; | ||
| 23 | } | ||
| 24 | |||
| 25 | namespace AudioIn { | ||
| 26 | class Manager; | ||
| 27 | } | ||
| 28 | |||
| 29 | /** | 18 | /** |
| 30 | * The AudioManager's main purpose is to wait for buffer events for the audio in and out managers, | 19 | * The AudioManager's main purpose is to wait for buffer events for the audio in and out managers, |
| 31 | * and call an associated callback to release buffers. | 20 | * and call an associated callback to release buffers. |
| @@ -43,7 +32,7 @@ class AudioManager { | |||
| 43 | using BufferEventFunc = std::function<void()>; | 32 | using BufferEventFunc = std::function<void()>; |
| 44 | 33 | ||
| 45 | public: | 34 | public: |
| 46 | explicit AudioManager(Core::System& system); | 35 | explicit AudioManager(); |
| 47 | 36 | ||
| 48 | /** | 37 | /** |
| 49 | * Shutdown the audio manager. | 38 | * Shutdown the audio manager. |
| @@ -80,10 +69,6 @@ private: | |||
| 80 | */ | 69 | */ |
| 81 | void ThreadFunc(); | 70 | void ThreadFunc(); |
| 82 | 71 | ||
| 83 | /// Core system | ||
| 84 | Core::System& system; | ||
| 85 | /// Have sessions started palying? | ||
| 86 | bool sessions_started{}; | ||
| 87 | /// Is the main thread running? | 72 | /// Is the main thread running? |
| 88 | std::atomic<bool> running{}; | 73 | std::atomic<bool> running{}; |
| 89 | /// Unused | 74 | /// Unused |
diff --git a/src/audio_core/renderer/adsp/audio_renderer.cpp b/src/audio_core/renderer/adsp/audio_renderer.cpp index bafe4822a..ab2257bd8 100644 --- a/src/audio_core/renderer/adsp/audio_renderer.cpp +++ b/src/audio_core/renderer/adsp/audio_renderer.cpp | |||
| @@ -47,7 +47,7 @@ RenderMessage AudioRenderer_Mailbox::ADSPWaitMessage() { | |||
| 47 | return msg; | 47 | return msg; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | CommandBuffer& AudioRenderer_Mailbox::GetCommandBuffer(const s32 session_id) { | 50 | CommandBuffer& AudioRenderer_Mailbox::GetCommandBuffer(const u32 session_id) { |
| 51 | return command_buffers[session_id]; | 51 | return command_buffers[session_id]; |
| 52 | } | 52 | } |
| 53 | 53 | ||
diff --git a/src/audio_core/renderer/adsp/audio_renderer.h b/src/audio_core/renderer/adsp/audio_renderer.h index 02e923c84..151f38c1b 100644 --- a/src/audio_core/renderer/adsp/audio_renderer.h +++ b/src/audio_core/renderer/adsp/audio_renderer.h | |||
| @@ -83,7 +83,7 @@ public: | |||
| 83 | * @param session_id - The session id to get (0 or 1). | 83 | * @param session_id - The session id to get (0 or 1). |
| 84 | * @return The command buffer. | 84 | * @return The command buffer. |
| 85 | */ | 85 | */ |
| 86 | CommandBuffer& GetCommandBuffer(s32 session_id); | 86 | CommandBuffer& GetCommandBuffer(u32 session_id); |
| 87 | 87 | ||
| 88 | /** | 88 | /** |
| 89 | * Set the command buffer with the given session id (0 or 1). | 89 | * Set the command buffer with the given session id (0 or 1). |
diff --git a/src/common/settings.h b/src/common/settings.h index 851812f28..d2452c93b 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -531,6 +531,7 @@ struct Values { | |||
| 531 | Setting<bool> use_auto_stub{false, "use_auto_stub"}; | 531 | Setting<bool> use_auto_stub{false, "use_auto_stub"}; |
| 532 | Setting<bool> enable_all_controllers{false, "enable_all_controllers"}; | 532 | Setting<bool> enable_all_controllers{false, "enable_all_controllers"}; |
| 533 | Setting<bool> create_crash_dumps{false, "create_crash_dumps"}; | 533 | Setting<bool> create_crash_dumps{false, "create_crash_dumps"}; |
| 534 | Setting<bool> perform_vulkan_check{true, "perform_vulkan_check"}; | ||
| 534 | 535 | ||
| 535 | // Miscellaneous | 536 | // Miscellaneous |
| 536 | Setting<std::string> log_filter{"*:Info", "log_filter"}; | 537 | Setting<std::string> log_filter{"*:Info", "log_filter"}; |
diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index cdf38a2a4..447fbffaa 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp | |||
| @@ -364,7 +364,7 @@ std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) { | |||
| 364 | std::vector<WSAPOLLFD> host_pollfds(pollfds.size()); | 364 | std::vector<WSAPOLLFD> host_pollfds(pollfds.size()); |
| 365 | std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](PollFD fd) { | 365 | std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](PollFD fd) { |
| 366 | WSAPOLLFD result; | 366 | WSAPOLLFD result; |
| 367 | result.fd = fd.socket->fd; | 367 | result.fd = fd.socket->GetFD(); |
| 368 | result.events = TranslatePollEvents(fd.events); | 368 | result.events = TranslatePollEvents(fd.events); |
| 369 | result.revents = 0; | 369 | result.revents = 0; |
| 370 | return result; | 370 | return result; |
| @@ -430,12 +430,12 @@ std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() { | |||
| 430 | return {AcceptResult{}, GetAndLogLastError()}; | 430 | return {AcceptResult{}, GetAndLogLastError()}; |
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | AcceptResult result; | ||
| 434 | result.socket = std::make_unique<Socket>(); | ||
| 435 | result.socket->fd = new_socket; | ||
| 436 | |||
| 437 | ASSERT(addrlen == sizeof(sockaddr_in)); | 433 | ASSERT(addrlen == sizeof(sockaddr_in)); |
| 438 | result.sockaddr_in = TranslateToSockAddrIn(addr); | 434 | |
| 435 | AcceptResult result{ | ||
| 436 | .socket = std::make_unique<Socket>(new_socket), | ||
| 437 | .sockaddr_in = TranslateToSockAddrIn(addr), | ||
| 438 | }; | ||
| 439 | 439 | ||
| 440 | return {std::move(result), Errno::SUCCESS}; | 440 | return {std::move(result), Errno::SUCCESS}; |
| 441 | } | 441 | } |
diff --git a/src/core/internal_network/sockets.h b/src/core/internal_network/sockets.h index a70429b19..2e328c645 100644 --- a/src/core/internal_network/sockets.h +++ b/src/core/internal_network/sockets.h | |||
| @@ -32,6 +32,10 @@ public: | |||
| 32 | std::unique_ptr<SocketBase> socket; | 32 | std::unique_ptr<SocketBase> socket; |
| 33 | SockAddrIn sockaddr_in; | 33 | SockAddrIn sockaddr_in; |
| 34 | }; | 34 | }; |
| 35 | |||
| 36 | SocketBase() = default; | ||
| 37 | explicit SocketBase(SOCKET fd_) : fd{fd_} {} | ||
| 38 | |||
| 35 | virtual ~SocketBase() = default; | 39 | virtual ~SocketBase() = default; |
| 36 | 40 | ||
| 37 | virtual SocketBase& operator=(const SocketBase&) = delete; | 41 | virtual SocketBase& operator=(const SocketBase&) = delete; |
| @@ -89,12 +93,19 @@ public: | |||
| 89 | 93 | ||
| 90 | virtual void HandleProxyPacket(const ProxyPacket& packet) = 0; | 94 | virtual void HandleProxyPacket(const ProxyPacket& packet) = 0; |
| 91 | 95 | ||
| 96 | [[nodiscard]] SOCKET GetFD() const { | ||
| 97 | return fd; | ||
| 98 | } | ||
| 99 | |||
| 100 | protected: | ||
| 92 | SOCKET fd = INVALID_SOCKET; | 101 | SOCKET fd = INVALID_SOCKET; |
| 93 | }; | 102 | }; |
| 94 | 103 | ||
| 95 | class Socket : public SocketBase { | 104 | class Socket : public SocketBase { |
| 96 | public: | 105 | public: |
| 97 | Socket() = default; | 106 | Socket() = default; |
| 107 | explicit Socket(SOCKET fd_) : SocketBase{fd_} {} | ||
| 108 | |||
| 98 | ~Socket() override; | 109 | ~Socket() override; |
| 99 | 110 | ||
| 100 | Socket(const Socket&) = delete; | 111 | Socket(const Socket&) = delete; |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index a4ed68422..195074bf2 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -546,6 +546,7 @@ void Config::ReadDebuggingValues() { | |||
| 546 | ReadBasicSetting(Settings::values.use_auto_stub); | 546 | ReadBasicSetting(Settings::values.use_auto_stub); |
| 547 | ReadBasicSetting(Settings::values.enable_all_controllers); | 547 | ReadBasicSetting(Settings::values.enable_all_controllers); |
| 548 | ReadBasicSetting(Settings::values.create_crash_dumps); | 548 | ReadBasicSetting(Settings::values.create_crash_dumps); |
| 549 | ReadBasicSetting(Settings::values.perform_vulkan_check); | ||
| 549 | 550 | ||
| 550 | qt_config->endGroup(); | 551 | qt_config->endGroup(); |
| 551 | } | 552 | } |
| @@ -1162,6 +1163,7 @@ void Config::SaveDebuggingValues() { | |||
| 1162 | WriteBasicSetting(Settings::values.disable_macro_jit); | 1163 | WriteBasicSetting(Settings::values.disable_macro_jit); |
| 1163 | WriteBasicSetting(Settings::values.enable_all_controllers); | 1164 | WriteBasicSetting(Settings::values.enable_all_controllers); |
| 1164 | WriteBasicSetting(Settings::values.create_crash_dumps); | 1165 | WriteBasicSetting(Settings::values.create_crash_dumps); |
| 1166 | WriteBasicSetting(Settings::values.perform_vulkan_check); | ||
| 1165 | 1167 | ||
| 1166 | qt_config->endGroup(); | 1168 | qt_config->endGroup(); |
| 1167 | } | 1169 | } |
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 622808e94..dacc75a20 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp | |||
| @@ -77,6 +77,7 @@ void ConfigureDebug::SetConfiguration() { | |||
| 77 | ui->disable_loop_safety_checks->setChecked( | 77 | ui->disable_loop_safety_checks->setChecked( |
| 78 | Settings::values.disable_shader_loop_safety_checks.GetValue()); | 78 | Settings::values.disable_shader_loop_safety_checks.GetValue()); |
| 79 | ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue()); | 79 | ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue()); |
| 80 | ui->perform_vulkan_check->setChecked(Settings::values.perform_vulkan_check.GetValue()); | ||
| 80 | 81 | ||
| 81 | #ifdef YUZU_USE_QT_WEB_ENGINE | 82 | #ifdef YUZU_USE_QT_WEB_ENGINE |
| 82 | ui->disable_web_applet->setChecked(UISettings::values.disable_web_applet.GetValue()); | 83 | ui->disable_web_applet->setChecked(UISettings::values.disable_web_applet.GetValue()); |
| @@ -117,6 +118,7 @@ void ConfigureDebug::ApplyConfiguration() { | |||
| 117 | ui->disable_loop_safety_checks->isChecked(); | 118 | ui->disable_loop_safety_checks->isChecked(); |
| 118 | Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); | 119 | Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); |
| 119 | Settings::values.extended_logging = ui->extended_logging->isChecked(); | 120 | Settings::values.extended_logging = ui->extended_logging->isChecked(); |
| 121 | Settings::values.perform_vulkan_check = ui->perform_vulkan_check->isChecked(); | ||
| 120 | UISettings::values.disable_web_applet = ui->disable_web_applet->isChecked(); | 122 | UISettings::values.disable_web_applet = ui->disable_web_applet->isChecked(); |
| 121 | Debugger::ToggleConsole(); | 123 | Debugger::ToggleConsole(); |
| 122 | Common::Log::Filter filter; | 124 | Common::Log::Filter filter; |
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 314d47af5..102c8c66c 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui | |||
| @@ -313,6 +313,16 @@ | |||
| 313 | </property> | 313 | </property> |
| 314 | </widget> | 314 | </widget> |
| 315 | </item> | 315 | </item> |
| 316 | <item row="3" column="0"> | ||
| 317 | <widget class="QCheckBox" name="perform_vulkan_check"> | ||
| 318 | <property name="toolTip"> | ||
| 319 | <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> | ||
| 320 | </property> | ||
| 321 | <property name="text"> | ||
| 322 | <string>Perform Startup Vulkan Check</string> | ||
| 323 | </property> | ||
| 324 | </widget> | ||
| 325 | </item> | ||
| 316 | </layout> | 326 | </layout> |
| 317 | </widget> | 327 | </widget> |
| 318 | </item> | 328 | </item> |
diff --git a/src/yuzu/configuration/input_profiles.cpp b/src/yuzu/configuration/input_profiles.cpp index 807afbeb2..9bb69cab1 100644 --- a/src/yuzu/configuration/input_profiles.cpp +++ b/src/yuzu/configuration/input_profiles.cpp | |||
| @@ -67,6 +67,8 @@ std::vector<std::string> InputProfiles::GetInputProfileNames() { | |||
| 67 | profile_names.push_back(profile_name); | 67 | profile_names.push_back(profile_name); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | std::stable_sort(profile_names.begin(), profile_names.end()); | ||
| 71 | |||
| 70 | return profile_names; | 72 | return profile_names; |
| 71 | } | 73 | } |
| 72 | 74 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 3c1bd19db..23245a976 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -4086,7 +4086,8 @@ int main(int argc, char* argv[]) { | |||
| 4086 | } | 4086 | } |
| 4087 | #endif | 4087 | #endif |
| 4088 | 4088 | ||
| 4089 | if (StartupChecks(argv[0], &has_broken_vulkan)) { | 4089 | if (StartupChecks(argv[0], &has_broken_vulkan, |
| 4090 | Settings::values.perform_vulkan_check.GetValue())) { | ||
| 4090 | return 0; | 4091 | return 0; |
| 4091 | } | 4092 | } |
| 4092 | 4093 | ||
diff --git a/src/yuzu/startup_checks.cpp b/src/yuzu/startup_checks.cpp index 29b87da05..fc2693f9d 100644 --- a/src/yuzu/startup_checks.cpp +++ b/src/yuzu/startup_checks.cpp | |||
| @@ -57,7 +57,7 @@ bool CheckEnvVars(bool* is_child) { | |||
| 57 | return false; | 57 | return false; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | bool StartupChecks(const char* arg0, bool* has_broken_vulkan) { | 60 | bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulkan_check) { |
| 61 | #ifdef _WIN32 | 61 | #ifdef _WIN32 |
| 62 | // Set the startup variable for child processes | 62 | // Set the startup variable for child processes |
| 63 | const bool env_var_set = SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, ENV_VAR_ENABLED_TEXT); | 63 | 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) { | |||
| 67 | return false; | 67 | return false; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | PROCESS_INFORMATION process_info; | 70 | if (perform_vulkan_check) { |
| 71 | std::memset(&process_info, '\0', sizeof(process_info)); | 71 | // Spawn child process that performs Vulkan check |
| 72 | 72 | PROCESS_INFORMATION process_info; | |
| 73 | if (!SpawnChild(arg0, &process_info, 0)) { | 73 | std::memset(&process_info, '\0', sizeof(process_info)); |
| 74 | return false; | 74 | |
| 75 | } | 75 | if (!SpawnChild(arg0, &process_info, 0)) { |
| 76 | 76 | return false; | |
| 77 | // Wait until the processs exits and get exit code from it | 77 | } |
| 78 | WaitForSingleObject(process_info.hProcess, INFINITE); | 78 | |
| 79 | DWORD exit_code = STILL_ACTIVE; | 79 | // Wait until the processs exits and get exit code from it |
| 80 | const int err = GetExitCodeProcess(process_info.hProcess, &exit_code); | 80 | WaitForSingleObject(process_info.hProcess, INFINITE); |
| 81 | if (err == 0) { | 81 | DWORD exit_code = STILL_ACTIVE; |
| 82 | std::fprintf(stderr, "GetExitCodeProcess failed with error %d\n", GetLastError()); | 82 | const int err = GetExitCodeProcess(process_info.hProcess, &exit_code); |
| 83 | } | 83 | if (err == 0) { |
| 84 | 84 | std::fprintf(stderr, "GetExitCodeProcess failed with error %d\n", GetLastError()); | |
| 85 | // Vulkan is broken if the child crashed (return value is not zero) | 85 | } |
| 86 | *has_broken_vulkan = (exit_code != 0); | 86 | |
| 87 | 87 | // Vulkan is broken if the child crashed (return value is not zero) | |
| 88 | if (CloseHandle(process_info.hProcess) == 0) { | 88 | *has_broken_vulkan = (exit_code != 0); |
| 89 | std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError()); | 89 | |
| 90 | } | 90 | if (CloseHandle(process_info.hProcess) == 0) { |
| 91 | if (CloseHandle(process_info.hThread) == 0) { | 91 | std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError()); |
| 92 | std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError()); | 92 | } |
| 93 | if (CloseHandle(process_info.hThread) == 0) { | ||
| 94 | std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError()); | ||
| 95 | } | ||
| 93 | } | 96 | } |
| 94 | 97 | ||
| 95 | if (!SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, nullptr)) { | 98 | if (!SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, nullptr)) { |
| @@ -98,26 +101,28 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan) { | |||
| 98 | } | 101 | } |
| 99 | 102 | ||
| 100 | #elif defined(YUZU_UNIX) | 103 | #elif defined(YUZU_UNIX) |
| 101 | const pid_t pid = fork(); | 104 | if (perform_vulkan_check) { |
| 102 | if (pid == 0) { | 105 | const pid_t pid = fork(); |
| 103 | CheckVulkan(); | 106 | if (pid == 0) { |
| 104 | return true; | 107 | CheckVulkan(); |
| 105 | } else if (pid == -1) { | 108 | return true; |
| 106 | const int err = errno; | 109 | } else if (pid == -1) { |
| 107 | std::fprintf(stderr, "fork failed with error %d\n", err); | 110 | const int err = errno; |
| 108 | return false; | 111 | std::fprintf(stderr, "fork failed with error %d\n", err); |
| 109 | } | 112 | return false; |
| 110 | 113 | } | |
| 111 | // Get exit code from child process | 114 | |
| 112 | int status; | 115 | // Get exit code from child process |
| 113 | const int r_val = wait(&status); | 116 | int status; |
| 114 | if (r_val == -1) { | 117 | const int r_val = wait(&status); |
| 115 | const int err = errno; | 118 | if (r_val == -1) { |
| 116 | std::fprintf(stderr, "wait failed with error %d\n", err); | 119 | const int err = errno; |
| 117 | return false; | 120 | std::fprintf(stderr, "wait failed with error %d\n", err); |
| 121 | return false; | ||
| 122 | } | ||
| 123 | // Vulkan is broken if the child crashed (return value is not zero) | ||
| 124 | *has_broken_vulkan = (status != 0); | ||
| 118 | } | 125 | } |
| 119 | // Vulkan is broken if the child crashed (return value is not zero) | ||
| 120 | *has_broken_vulkan = (status != 0); | ||
| 121 | #endif | 126 | #endif |
| 122 | return false; | 127 | return false; |
| 123 | } | 128 | } |
diff --git a/src/yuzu/startup_checks.h b/src/yuzu/startup_checks.h index f2fc2d9d4..d8e563be6 100644 --- a/src/yuzu/startup_checks.h +++ b/src/yuzu/startup_checks.h | |||
| @@ -13,7 +13,7 @@ constexpr char ENV_VAR_ENABLED_TEXT[] = "ON"; | |||
| 13 | 13 | ||
| 14 | void CheckVulkan(); | 14 | void CheckVulkan(); |
| 15 | bool CheckEnvVars(bool* is_child); | 15 | bool CheckEnvVars(bool* is_child); |
| 16 | bool StartupChecks(const char* arg0, bool* has_broken_vulkan); | 16 | bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulkan_check); |
| 17 | 17 | ||
| 18 | #ifdef _WIN32 | 18 | #ifdef _WIN32 |
| 19 | bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags); | 19 | bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags); |