diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index ec05a18d5d..b17a143d34 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -179,6 +179,8 @@ add_executable(citra-qt qt_image_interface.h util/clickable_label.cpp util/clickable_label.h + util/graphics_device_info.cpp + util/graphics_device_info.h util/sequence_dialog/sequence_dialog.cpp util/sequence_dialog/sequence_dialog.h util/spinbox.cpp @@ -187,13 +189,6 @@ add_executable(citra-qt util/util.h ) -if (ENABLE_VULKAN) - target_sources(citra-qt PRIVATE - util/vk_device_info.cpp - util/vk_device_info.h - ) -endif() - file(GLOB COMPAT_LIST ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json) diff --git a/src/citra_qt/configuration/configure_dialog.cpp b/src/citra_qt/configuration/configure_dialog.cpp index 1e19f5b3c2..1644b657a0 100644 --- a/src/citra_qt/configuration/configure_dialog.cpp +++ b/src/citra_qt/configuration/configure_dialog.cpp @@ -23,14 +23,16 @@ #include "ui_configure.h" ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Core::System& system_, - std::span physical_devices, bool enable_web_config) + QString gl_renderer, std::span physical_devices, + bool enable_web_config) : QDialog(parent), ui{std::make_unique()}, registry{registry_}, system{system_}, is_powered_on{system.IsPoweredOn()}, general_tab{std::make_unique(this)}, system_tab{std::make_unique(system, this)}, input_tab{std::make_unique(this)}, hotkeys_tab{std::make_unique(this)}, - graphics_tab{std::make_unique(physical_devices, is_powered_on, this)}, + graphics_tab{ + std::make_unique(gl_renderer, physical_devices, is_powered_on, this)}, enhancements_tab{std::make_unique(this)}, audio_tab{std::make_unique(is_powered_on, this)}, camera_tab{std::make_unique(this)}, diff --git a/src/citra_qt/configuration/configure_dialog.h b/src/citra_qt/configuration/configure_dialog.h index 8f8170fe09..db2549fcbc 100644 --- a/src/citra_qt/configuration/configure_dialog.h +++ b/src/citra_qt/configuration/configure_dialog.h @@ -37,7 +37,7 @@ class ConfigureDialog : public QDialog { public: explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, Core::System& system, - std::span physical_devices, + QString gl_renderer, std::span physical_devices, bool enable_web_config = true); ~ConfigureDialog() override; diff --git a/src/citra_qt/configuration/configure_graphics.cpp b/src/citra_qt/configuration/configure_graphics.cpp index 1ed3f63b02..80c2d138d3 100644 --- a/src/citra_qt/configuration/configure_graphics.cpp +++ b/src/citra_qt/configuration/configure_graphics.cpp @@ -12,17 +12,13 @@ #include "video_core/renderer_vulkan/vk_instance.h" #endif -ConfigureGraphics::ConfigureGraphics(std::span physical_devices, bool is_powered_on, - QWidget* parent) +ConfigureGraphics::ConfigureGraphics(QString gl_renderer, std::span physical_devices, + bool is_powered_on, QWidget* parent) : QWidget(parent), ui(std::make_unique()) { ui->setupUi(this); SetupPerGameUI(); - for (const QString& name : physical_devices) { - ui->physical_device_combo->addItem(name); - } - ui->graphics_api_combo->setEnabled(!is_powered_on); ui->physical_device_combo->setEnabled(!is_powered_on); ui->toggle_async_shaders->setEnabled(!is_powered_on); @@ -37,11 +33,15 @@ ConfigureGraphics::ConfigureGraphics(std::span physical_devices, graphics_api_combo_model->item(static_cast(Settings::GraphicsAPI::Software)); software_item->setFlags(software_item->flags() & ~Qt::ItemIsEnabled); #endif + #ifndef ENABLE_OPENGL const auto opengl_item = graphics_api_combo_model->item(static_cast(Settings::GraphicsAPI::OpenGL)); opengl_item->setFlags(opengl_item->flags() & ~Qt::ItemIsEnabled); +#else + ui->opengl_renderer_name_label->setText(gl_renderer); #endif + #ifndef ENABLE_VULKAN const auto vulkan_item = graphics_api_combo_model->item(static_cast(Settings::GraphicsAPI::Vulkan)); @@ -54,6 +54,10 @@ ConfigureGraphics::ConfigureGraphics(std::span physical_devices, ui->physical_device_combo->setVisible(false); ui->spirv_shader_gen->setVisible(false); + } else { + for (const QString& name : physical_devices) { + ui->physical_device_combo->addItem(name); + } } #endif @@ -202,24 +206,24 @@ void ConfigureGraphics::SetupPerGameUI() { } void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) { - bool is_visible{}; + Settings::GraphicsAPI effective_api{}; // When configuring per-game the physical device combo should be // shown either when the global api is used and that is Vulkan or // Vulkan is set as the per-game api. if (!Settings::IsConfiguringGlobal()) { - const auto global_graphics_api = Settings::values.graphics_api.GetValue(true); const bool using_global = index == 0; - if (!using_global) { - index -= ConfigurationShared::USE_GLOBAL_OFFSET; + if (using_global) { + effective_api = Settings::values.graphics_api.GetValue(true); + } else { + effective_api = + static_cast(index - ConfigurationShared::USE_GLOBAL_OFFSET); } - const auto graphics_api = static_cast(index); - is_visible = (using_global && global_graphics_api == Settings::GraphicsAPI::Vulkan) || - graphics_api == Settings::GraphicsAPI::Vulkan; } else { - const auto graphics_api = static_cast(index); - is_visible = graphics_api == Settings::GraphicsAPI::Vulkan; + effective_api = static_cast(index); } - ui->physical_device_group->setVisible(is_visible); - ui->spirv_shader_gen->setVisible(is_visible); + + ui->physical_device_group->setVisible(effective_api == Settings::GraphicsAPI::Vulkan); + ui->spirv_shader_gen->setVisible(effective_api == Settings::GraphicsAPI::Vulkan); + ui->opengl_renderer_group->setVisible(effective_api == Settings::GraphicsAPI::OpenGL); } diff --git a/src/citra_qt/configuration/configure_graphics.h b/src/citra_qt/configuration/configure_graphics.h index 97a3fe0aab..129c4a9d51 100644 --- a/src/citra_qt/configuration/configure_graphics.h +++ b/src/citra_qt/configuration/configure_graphics.h @@ -21,8 +21,8 @@ class ConfigureGraphics : public QWidget { Q_OBJECT public: - explicit ConfigureGraphics(std::span physical_devices, bool is_powered_on, - QWidget* parent = nullptr); + explicit ConfigureGraphics(QString gl_renderer, std::span physical_devices, + bool is_powered_on, QWidget* parent = nullptr); ~ConfigureGraphics() override; void ApplyConfiguration(); diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui index be0764f4aa..a052186cd8 100644 --- a/src/citra_qt/configuration/configure_graphics.ui +++ b/src/citra_qt/configuration/configure_graphics.ui @@ -101,6 +101,34 @@ + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + OpenGL Renderer + + + + + + + + + diff --git a/src/citra_qt/configuration/configure_per_game.cpp b/src/citra_qt/configuration/configure_per_game.cpp index 5b4d400440..c11847a0d6 100644 --- a/src/citra_qt/configuration/configure_per_game.cpp +++ b/src/citra_qt/configuration/configure_per_game.cpp @@ -24,7 +24,8 @@ #include "ui_configure_per_game.h" ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name, - std::span physical_devices, Core::System& system_) + QString gl_renderer, std::span physical_devices, + Core::System& system_) : QDialog(parent), ui(std::make_unique()), filename{file_name.toStdString()}, title_id{title_id_}, system{system_} { const auto config_file_name = title_id == 0 ? std::string(FileUtil::GetFilename(filename)) @@ -35,7 +36,8 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString audio_tab = std::make_unique(is_powered_on, this); general_tab = std::make_unique(this); enhancements_tab = std::make_unique(this); - graphics_tab = std::make_unique(physical_devices, is_powered_on, this); + graphics_tab = + std::make_unique(gl_renderer, physical_devices, is_powered_on, this); system_tab = std::make_unique(system, this); debug_tab = std::make_unique(is_powered_on, this); cheat_tab = std::make_unique(system.CheatEngine(), title_id, this); diff --git a/src/citra_qt/configuration/configure_per_game.h b/src/citra_qt/configuration/configure_per_game.h index ef5ea731d0..8f8c757fdd 100644 --- a/src/citra_qt/configuration/configure_per_game.h +++ b/src/citra_qt/configuration/configure_per_game.h @@ -38,7 +38,8 @@ class ConfigurePerGame : public QDialog { public: explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name, - std::span physical_devices, Core::System& system_); + QString gl_renderer, std::span physical_devices, + Core::System& system_); ~ConfigurePerGame() override; /// Loads all button configurations to settings file diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 2798fb099b..807da30e3c 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -64,7 +64,7 @@ #include "citra_qt/uisettings.h" #include "citra_qt/updater/updater.h" #include "citra_qt/util/clickable_label.h" -#include "citra_qt/util/vk_device_info.h" +#include "citra_qt/util/graphics_device_info.h" #include "common/arch.h" #include "common/common_paths.h" #include "common/detached_tasks.h" @@ -270,6 +270,18 @@ GMainWindow::GMainWindow(Core::System& system_) connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor); connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::OnMouseActivity); +#ifdef ENABLE_OPENGL + gl_renderer = GetOpenGLRenderer(); +#if defined(_WIN32) + if (gl_renderer.startsWith(QStringLiteral("D3D12"))) { + // OpenGLOn12 supports but does not yet advertise OpenGL 4.0+ + // We can override the version here to allow Citra to work. + // TODO: Remove this when OpenGL 4.0+ is advertised. + qputenv("MESA_GL_VERSION_OVERRIDE", "4.6"); + } +#endif +#endif + #ifdef ENABLE_VULKAN physical_devices = GetVulkanPhysicalDevices(); if (physical_devices.empty()) { @@ -2158,7 +2170,7 @@ void GMainWindow::OnLoadState() { void GMainWindow::OnConfigure() { game_list->SetDirectoryWatcherEnabled(false); Settings::SetConfiguringGlobal(true); - ConfigureDialog configureDialog(this, hotkey_registry, system, physical_devices, + ConfigureDialog configureDialog(this, hotkey_registry, system, gl_renderer, physical_devices, !multiplayer_state->IsHostingPublicRoom()); connect(&configureDialog, &ConfigureDialog::LanguageChanged, this, &GMainWindow::OnLanguageChanged); @@ -3006,7 +3018,7 @@ void GMainWindow::OnConfigurePerGame() { void GMainWindow::OpenPerGameConfiguration(u64 title_id, const QString& file_name) { Settings::SetConfiguringGlobal(false); - ConfigurePerGame dialog(this, title_id, file_name, physical_devices, system); + ConfigurePerGame dialog(this, title_id, file_name, gl_renderer, physical_devices, system); const auto result = dialog.exec(); if (result != QDialog::Accepted) { diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 934b56d34a..b64bf1b32d 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -344,6 +344,7 @@ private: // Whether game was paused due to stopping video dumping bool game_paused_for_dumping = false; + QString gl_renderer; std::vector physical_devices; // Debugger panes diff --git a/src/citra_qt/util/vk_device_info.cpp b/src/citra_qt/util/graphics_device_info.cpp similarity index 58% rename from src/citra_qt/util/vk_device_info.cpp rename to src/citra_qt/util/graphics_device_info.cpp index db6ccef077..f4997b2841 100644 --- a/src/citra_qt/util/vk_device_info.cpp +++ b/src/citra_qt/util/graphics_device_info.cpp @@ -2,9 +2,34 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "citra_qt/util/vk_device_info.h" -#include "video_core/renderer_vulkan/vk_instance.h" +#include "citra_qt/util/graphics_device_info.h" +#ifdef ENABLE_OPENGL +#include +#include +#include +#endif + +#ifdef ENABLE_VULKAN +#include "video_core/renderer_vulkan/vk_instance.h" +#endif + +#ifdef ENABLE_OPENGL +QString GetOpenGLRenderer() { + QOffscreenSurface surface; + surface.create(); + + QOpenGLContext context; + if (context.create()) { + context.makeCurrent(&surface); + return QString::fromUtf8(context.functions()->glGetString(GL_RENDERER)); + } else { + return QStringLiteral(""); + } +} +#endif + +#ifdef ENABLE_VULKAN std::vector GetVulkanPhysicalDevices() { std::vector result; try { @@ -21,3 +46,4 @@ std::vector GetVulkanPhysicalDevices() { return result; } +#endif diff --git a/src/citra_qt/util/vk_device_info.h b/src/citra_qt/util/graphics_device_info.h similarity index 56% rename from src/citra_qt/util/vk_device_info.h rename to src/citra_qt/util/graphics_device_info.h index c8ef6343b0..b3dd802991 100644 --- a/src/citra_qt/util/vk_device_info.h +++ b/src/citra_qt/util/graphics_device_info.h @@ -7,5 +7,12 @@ #include #include +#ifdef ENABLE_OPENGL +/// Returns the name of the OpenGL renderer. +QString GetOpenGLRenderer(); +#endif + +#ifdef ENABLE_VULKAN /// Returns a list of all available vulkan GPUs. -std::vector GetVulkanPhysicalDevices(); \ No newline at end of file +std::vector GetVulkanPhysicalDevices(); +#endif