diff --git a/src/graphics/presentation/window/vulkanWindow.cpp b/src/graphics/presentation/window/vulkanWindow.cpp index 799495e9d..601a3da4b 100644 --- a/src/graphics/presentation/window/vulkanWindow.cpp +++ b/src/graphics/presentation/window/vulkanWindow.cpp @@ -169,7 +169,12 @@ static void VulkanFindPhysicalDevice(vk::Instance instance, vk::SurfaceKHR surfa EXIT_NOT_IMPLEMENTED(devices.empty()); if (Config::GetGpuIndex() >= 0) { - devices = {devices[Config::GetGpuIndex()]}; + if (static_cast(Config::GetGpuIndex()) < devices.size()) { + devices = {devices[Config::GetGpuIndex()]}; + } else { + LOGF("Vulkan GPU index %d is unavailable; selecting automatically\n", + Config::GetGpuIndex()); + } } vk::PhysicalDevice best_device = nullptr; diff --git a/src/launcher/CMakeLists.txt b/src/launcher/CMakeLists.txt index 12d116051..4d4f64bba 100644 --- a/src/launcher/CMakeLists.txt +++ b/src/launcher/CMakeLists.txt @@ -20,7 +20,7 @@ add_executable(launcher WIN32 ) -target_link_libraries(launcher Qt6::Concurrent Qt6::Network Qt6::Widgets kyty_git_version) +target_link_libraries(launcher Qt6::Concurrent Qt6::Network Qt6::Widgets Vulkan::Headers kyty_git_version) if(WIN32) target_link_libraries(launcher setupapi) endif() diff --git a/src/launcher/forms/configuration_edit_dialog.ui b/src/launcher/forms/configuration_edit_dialog.ui index eb08ec0f7..6e51c935c 100644 --- a/src/launcher/forms/configuration_edit_dialog.ui +++ b/src/launcher/forms/configuration_edit_dialog.ui @@ -127,13 +127,23 @@ Optimize shaders for code size or performance + + + GPU: + + + + Graphics device used by the emulator + + + Run in borderless desktop fullscreen Fullscreen - + Read back writable linear images Enable readback diff --git a/src/launcher/include/configuration.h b/src/launcher/include/configuration.h index 8dd41c2d8..21b771ace 100644 --- a/src/launcher/include/configuration.h +++ b/src/launcher/include/configuration.h @@ -94,6 +94,7 @@ public: QString user_name = "Kyty"; int user_id = Config::DEFAULT_USER_ID; PresentMode present_mode = PresentMode::Fifo; + int gpu_index = -1; bool fullscreen_enabled = false; bool readback_linear_images = false; int vblank_frequency = 60; @@ -121,6 +122,7 @@ public: user_name = other.user_name; user_id = other.user_id; present_mode = other.present_mode; + gpu_index = other.gpu_index; fullscreen_enabled = other.fullscreen_enabled; readback_linear_images = other.readback_linear_images; vblank_frequency = other.vblank_frequency; @@ -165,6 +167,7 @@ public: KYTY_CFG_SET(user_name); KYTY_CFG_SET(user_id); KYTY_CFG_SET(present_mode); + KYTY_CFG_SET(gpu_index); KYTY_CFG_SET(fullscreen_enabled); KYTY_CFG_SET(readback_linear_images); KYTY_CFG_SET(vblank_frequency); @@ -200,6 +203,7 @@ public: ? saved_user_id : Config::DEFAULT_USER_ID; KYTY_CFG_GET(present_mode); + gpu_index = s->value("gpu_index", -1).toInt(); if (EnumToText(present_mode).isEmpty()) { present_mode = PresentMode::Fifo; } diff --git a/src/launcher/src/configurationEditDialog.cpp b/src/launcher/src/configurationEditDialog.cpp index 6258f8b7d..094254f41 100644 --- a/src/launcher/src/configurationEditDialog.cpp +++ b/src/launcher/src/configurationEditDialog.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ #include #include #include +#include +#include #include #include "ui_configuration_edit_dialog.h" @@ -163,6 +166,35 @@ void ConfigurationEditDialog::Init(const Configuration& info) { m_ui->spinBox_user_id->setValue(info.user_id); ListInit(m_ui->comboBox_screen_resolution, info.screen_resolution); ListInit(m_ui->comboBox_present_mode, info.present_mode); + m_ui->comboBox_gpu->clear(); + m_ui->comboBox_gpu->addItem(tr("Auto")); +#if defined(__APPLE__) + if (!qEnvironmentVariableIsSet("QT_VULKAN_LIB")) { + const auto base = QCoreApplication::applicationDirPath(); + auto library = base + "/libMoltenVK.dylib"; + if (!QFileInfo::exists(library)) { + library = base + "/../Frameworks/libMoltenVK.dylib"; + } + if (QFileInfo::exists(library)) { + qputenv("QT_VULKAN_LIB", library.toUtf8()); + } + } +#endif + QVulkanInstance instance; + instance.setApiVersion(QVersionNumber(1, 3, 0)); +#if !defined(__APPLE__) + instance.setFlags(QVulkanInstance::NoPortabilityDrivers); +#endif + if (instance.create()) { + QVulkanWindow window; + window.setVulkanInstance(&instance); + for (const auto& device: window.availablePhysicalDevices()) { + m_ui->comboBox_gpu->addItem(QString::fromUtf8(device.deviceName)); + } + } + m_ui->comboBox_gpu->setCurrentIndex( + info.gpu_index >= 0 && info.gpu_index < m_ui->comboBox_gpu->count() - 1 ? info.gpu_index + 1 + : 0); m_ui->checkBox_fullscreen->setChecked(info.fullscreen_enabled); m_ui->checkBox_readback->setChecked(info.readback_linear_images); m_ui->spinBox_vblank_frequency->setValue(info.vblank_frequency); @@ -306,6 +338,7 @@ static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui) { TextToEnum(ui.comboBox_screen_resolution->currentText()); info.present_mode = TextToEnum(ui.comboBox_present_mode->currentText()); + info.gpu_index = ui.comboBox_gpu->currentIndex() - 1; info.fullscreen_enabled = ui.checkBox_fullscreen->isChecked(); info.readback_linear_images = ui.checkBox_readback->isChecked(); info.vblank_frequency = ui.spinBox_vblank_frequency->value(); diff --git a/src/launcher/src/mainDialog.cpp b/src/launcher/src/mainDialog.cpp index 44cc9ac38..7431af357 100644 --- a/src/launcher/src/mainDialog.cpp +++ b/src/launcher/src/mainDialog.cpp @@ -229,6 +229,9 @@ static QStringList CreateEmulatorArgs(const Configuration& info) { args << "--user-name" << info.user_name; args << "--user-id" << QString::number(info.user_id); args << "--present-mode" << EnumToText(info.present_mode); + if (info.gpu_index >= 0) { + args << "--gpu" << QString::number(info.gpu_index); + } if (info.fullscreen_enabled) { args << "--fullscreen"; }