diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 56f82d8997..4f25f7ef14 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -31,6 +31,7 @@ set(SOURCES_QT_SDL ROMInfoDialog.cpp RAMInfoDialog.cpp TitleManagerDialog.cpp + SupportedRenderers.cpp OSD_shaders.h font.h Platform.cpp diff --git a/src/frontend/qt_sdl/SupportedRenderers.cpp b/src/frontend/qt_sdl/SupportedRenderers.cpp new file mode 100644 index 0000000000..35ec0fbe89 --- /dev/null +++ b/src/frontend/qt_sdl/SupportedRenderers.cpp @@ -0,0 +1,81 @@ +/* + Copyright 2016-2024 melonDS team + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include "types.h" +#include "Platform.h" +#include "Config.h" +#include "GPU.h" +#include "main.h" + +#include "SupportedRenderers.h" + +SupportedRenderers* SupportedRenderers::instance = nullptr; + +SupportedRenderers::SupportedRenderers(QWidget* parent) +{ + if (SupportedRenderers::instance == nullptr) + instance = this; + + software = true; + + // OpenGL + setSupportedOpenGLRenderers(parent); + + // Future renderers +} + +SupportedRenderers::~SupportedRenderers() {} + +void SupportedRenderers::setSupportedOpenGLRenderers(QWidget* parent) +{ + ScreenPanelGL *glPanel = new ScreenPanelGL(parent); + std::optional windowInfo = glPanel->getWindowInfo(); + + if (windowInfo.has_value()) + { + std::array versionsToTry = { + GL::Context::Version{GL::Context::Profile::Core, 4, 3}, + GL::Context::Version{GL::Context::Profile::Core, 3, 2} + }; + + std::unique_ptr glContext = GL::Context::Create(*windowInfo, versionsToTry); + + if (glContext) + { + const char* glVersionStr = reinterpret_cast(glGetString(GL_VERSION)); + + if (glVersionStr && strlen(glVersionStr) >= 3) + { + int gl_version = 0; + + // A proper version string or object isn't provided, so we have to parse it ourselves + if (isdigit(glVersionStr[0]) && isdigit(glVersionStr[2])) + gl_version = (glVersionStr[0] - '0') * 100 + + (glVersionStr[2] - '0') * 10; + + // OpenGL 4.3 is required for Compute Shaders while 3.2 is the base requirement + if (gl_version >= 430) + computeGl = true; + if (gl_version >= 320) + baseGl = true; + } + } + } + + delete glPanel; +} \ No newline at end of file diff --git a/src/frontend/qt_sdl/SupportedRenderers.h b/src/frontend/qt_sdl/SupportedRenderers.h new file mode 100644 index 0000000000..3a14b84079 --- /dev/null +++ b/src/frontend/qt_sdl/SupportedRenderers.h @@ -0,0 +1,52 @@ +/* + Copyright 2016-2024 melonDS team + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef SUPPORTEDRENDERERS_H +#define SUPPORTEDRENDERERS_H + +using namespace melonDS; + +#include "glad/glad.h" + +#include + +#include "EmuInstance.h" + + +class SupportedRenderers +{ +public: + explicit SupportedRenderers(QWidget* parent); + ~SupportedRenderers(); + + static SupportedRenderers* instance; + + // Software + bool software; + + // OpenGL + bool baseGl; + bool computeGl; + + // Future renderers + +private: + void setSupportedOpenGLRenderers(QWidget* parent); +}; + +#endif // SUPPORTEDRENDERERS_H diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index 619ecda35c..bea6f00997 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -24,6 +24,7 @@ #include "Config.h" #include "GPU.h" #include "main.h" +#include "SupportedRenderers.h" #include "VideoSettingsDialog.h" #include "ui_VideoSettingsDialog.h" @@ -39,11 +40,39 @@ VideoSettingsDialog* VideoSettingsDialog::currentDlg = nullptr; void VideoSettingsDialog::setEnabled() { + bool baseGl = SupportedRenderers::instance->baseGl; + bool computeGl = SupportedRenderers::instance->computeGl; + auto& cfg = emuInstance->getGlobalConfig(); int renderer = cfg.GetInt("3D.Renderer"); + int oglDisplay = cfg.GetBool("Screen.UseGL"); + + if (!computeGl) + { + ui->rb3DCompute->setEnabled(false); + if (renderer == renderer3D_OpenGLCompute) // fallback to software renderer + { + ui->rb3DSoftware->setChecked(true); + renderer = renderer3D_Software; + } + } + if (!baseGl) // fallback to software renderer + { + renderer = renderer3D_Software; + oglDisplay = false; + + ui->rb3DOpenGL->setEnabled(false); + ui->cbGLDisplay->setChecked(false); + ui->rb3DSoftware->setChecked(true); + } + + cfg.SetInt("3D.Renderer", renderer); + cfg.SetBool("Screen.UseGL", oglDisplay); bool softwareRenderer = renderer == renderer3D_Software; - ui->cbGLDisplay->setEnabled(softwareRenderer); + + ui->cbGLDisplay->setEnabled(softwareRenderer && baseGl); + setVsyncControlEnable(oglDisplay || !softwareRenderer); ui->cbSoftwareThreaded->setEnabled(softwareRenderer); ui->cbxGLResolution->setEnabled(!softwareRenderer); ui->cbBetterPolygons->setEnabled(renderer == renderer3D_OpenGL); @@ -146,6 +175,7 @@ void VideoSettingsDialog::on_VideoSettingsDialog_rejected() void VideoSettingsDialog::setVsyncControlEnable(bool hasOGL) { + ui->label_2->setEnabled(hasOGL); ui->cbVSync->setEnabled(hasOGL); ui->sbVSyncInterval->setEnabled(hasOGL); } diff --git a/src/frontend/qt_sdl/Window.cpp b/src/frontend/qt_sdl/Window.cpp index 5c599e7052..5416f4dd67 100644 --- a/src/frontend/qt_sdl/Window.cpp +++ b/src/frontend/qt_sdl/Window.cpp @@ -83,6 +83,7 @@ #include "CameraManager.h" #include "Window.h" #include "AboutDialog.h" +#include "SupportedRenderers.h" using namespace melonDS; @@ -693,6 +694,10 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) : // if the window was closed in fullscreen do not restore this setWindowState(windowState() & ~Qt::WindowFullScreen); } + + if (id == 0 && SupportedRenderers::instance == nullptr) + SupportedRenderers* renderers = new SupportedRenderers(this); + show(); panel = nullptr;