summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2023-06-09 15:07:07 +0200
committerGitHub <noreply@github.com>2023-06-09 15:07:07 +0200
commit8f51a9d2d8a88993167cd1c3b8d447bee1ca6407 (patch)
tree31ea53fda80c4e7e4476cd2a16b17de89102b9c7 /Source/Core
parent092773ad0cd31cb0f3d111254e4e0bdb24f2c795 (diff)
parentac48b2eea43164349e6b112604d44490a4d731c5 (diff)
Merge pull request #11699 from Pokechu22/gl-check-maximum-samples
OpenGL: Check the list of supported AA modes instead of hardcoding
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/GL/GLExtensions/GLExtensions.cpp2
-rw-r--r--Source/Core/Core/Core.cpp4
-rw-r--r--Source/Core/DolphinLib.props2
-rw-r--r--Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp50
-rw-r--r--Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp4
-rw-r--r--Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.h2
-rw-r--r--Source/Core/DolphinQt/MainWindow.cpp11
-rw-r--r--Source/Core/DolphinQt/MainWindow.h2
-rw-r--r--Source/Core/UICommon/CMakeLists.txt2
-rw-r--r--Source/Core/UICommon/VideoUtils.cpp43
-rw-r--r--Source/Core/UICommon/VideoUtils.h12
-rw-r--r--Source/Core/VideoBackends/D3D/D3DMain.cpp2
-rw-r--r--Source/Core/VideoBackends/D3D/VideoBackend.h2
-rw-r--r--Source/Core/VideoBackends/D3D12/VideoBackend.cpp2
-rw-r--r--Source/Core/VideoBackends/D3D12/VideoBackend.h2
-rw-r--r--Source/Core/VideoBackends/Metal/MTLMain.mm2
-rw-r--r--Source/Core/VideoBackends/Metal/VideoBackend.h2
-rw-r--r--Source/Core/VideoBackends/Null/NullBackend.cpp2
-rw-r--r--Source/Core/VideoBackends/Null/VideoBackend.h2
-rw-r--r--Source/Core/VideoBackends/OGL/OGLConfig.cpp127
-rw-r--r--Source/Core/VideoBackends/OGL/OGLConfig.h2
-rw-r--r--Source/Core/VideoBackends/OGL/OGLGfx.cpp6
-rw-r--r--Source/Core/VideoBackends/OGL/OGLMain.cpp77
-rw-r--r--Source/Core/VideoBackends/OGL/OGLTexture.cpp6
-rw-r--r--Source/Core/VideoBackends/OGL/OGLTexture.h1
-rw-r--r--Source/Core/VideoBackends/OGL/VideoBackend.h4
-rw-r--r--Source/Core/VideoBackends/Software/SWmain.cpp2
-rw-r--r--Source/Core/VideoBackends/Software/VideoBackend.h2
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKMain.cpp2
-rw-r--r--Source/Core/VideoBackends/Vulkan/VideoBackend.h2
-rw-r--r--Source/Core/VideoCommon/VideoBackendBase.cpp8
-rw-r--r--Source/Core/VideoCommon/VideoBackendBase.h6
32 files changed, 237 insertions, 158 deletions
diff --git a/Source/Core/Common/GL/GLExtensions/GLExtensions.cpp b/Source/Core/Common/GL/GLExtensions/GLExtensions.cpp
index d43e898ca5..e761f9e05a 100644
--- a/Source/Core/Common/GL/GLExtensions/GLExtensions.cpp
+++ b/Source/Core/Common/GL/GLExtensions/GLExtensions.cpp
@@ -1674,7 +1674,7 @@ const GLFunc gl_function_array[] = {
GLFUNC_REQUIRES(glDrawArraysInstancedBaseInstance, "VERSION_4_2"),
GLFUNC_REQUIRES(glDrawElementsInstancedBaseInstance, "VERSION_4_2"),
GLFUNC_REQUIRES(glDrawElementsInstancedBaseVertexBaseInstance, "VERSION_4_2"),
- GLFUNC_REQUIRES(glGetInternalformativ, "VERSION_4_2"),
+ GLFUNC_REQUIRES(glGetInternalformativ, "VERSION_4_2 |VERSION_GLES_3"),
GLFUNC_REQUIRES(glGetActiveAtomicCounterBufferiv, "VERSION_4_2"),
GLFUNC_REQUIRES(glBindImageTexture, "VERSION_4_2"),
GLFUNC_REQUIRES(glMemoryBarrier, "VERSION_4_2"),
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index fb97379411..dbcca8a687 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -261,7 +261,7 @@ bool Init(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
Host_UpdateMainFrame(); // Disable any menus or buttons at boot
// Manually reactivate the video backend in case a GameINI overrides the video backend setting.
- VideoBackendBase::PopulateBackendInfo();
+ VideoBackendBase::PopulateBackendInfo(wsi);
// Issue any API calls which must occur on the main thread for the graphics backend.
WindowSystemInfo prepared_wsi(wsi);
@@ -579,7 +579,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
system.GetPowerPC().GetDebugInterface().Clear(guard);
}};
- VideoBackendBase::PopulateBackendInfo();
+ VideoBackendBase::PopulateBackendInfo(wsi);
if (!g_video_backend->Initialize(wsi))
{
diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props
index 05142ae672..ec9ac2065a 100644
--- a/Source/Core/DolphinLib.props
+++ b/Source/Core/DolphinLib.props
@@ -534,7 +534,6 @@
<ClInclude Include="UICommon\ResourcePack\ResourcePack.h" />
<ClInclude Include="UICommon\UICommon.h" />
<ClInclude Include="UICommon\USBUtils.h" />
- <ClInclude Include="UICommon\VideoUtils.h" />
<ClInclude Include="UpdaterCommon\UI.h" />
<ClInclude Include="UpdaterCommon\UpdaterCommon.h" />
<ClInclude Include="VideoBackends\D3D\D3DBase.h" />
@@ -1160,7 +1159,6 @@
<ClCompile Include="UICommon\ResourcePack\ResourcePack.cpp" />
<ClCompile Include="UICommon\UICommon.cpp" />
<ClCompile Include="UICommon\USBUtils.cpp" />
- <ClCompile Include="UICommon\VideoUtils.cpp" />
<ClCompile Include="UpdaterCommon\UpdaterCommon.cpp" />
<ClCompile Include="VideoBackends\D3D\D3DBase.cpp" />
<ClCompile Include="VideoBackends\D3D\D3DBoundingBox.cpp" />
diff --git a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
index 113c9fe835..c5889d2ad4 100644
--- a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp
@@ -23,8 +23,6 @@
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/Settings.h"
-#include "UICommon/VideoUtils.h"
-
#include "VideoCommon/PostProcessing.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoCommon.h"
@@ -260,18 +258,38 @@ void EnhancementsWidget::LoadSettings()
m_block_save = true;
// Anti-Aliasing
- const int aa_selection = Config::Get(Config::GFX_MSAA);
+ const u32 aa_selection = Config::Get(Config::GFX_MSAA);
const bool ssaa = Config::Get(Config::GFX_SSAA);
const int aniso = Config::Get(Config::GFX_ENHANCE_MAX_ANISOTROPY);
const TextureFilteringMode tex_filter_mode =
Config::Get(Config::GFX_ENHANCE_FORCE_TEXTURE_FILTERING);
m_aa_combo->clear();
- for (const auto& option : VideoUtils::GetAvailableAntialiasingModes(m_msaa_modes))
- m_aa_combo->addItem(option == "None" ? tr("None") : QString::fromStdString(option));
- m_aa_combo->setCurrentText(
- QString::fromStdString(std::to_string(aa_selection) + "x " + (ssaa ? "SSAA" : "MSAA")));
+ for (const u32 aa_mode : g_Config.backend_info.AAModes)
+ {
+ if (aa_mode == 1)
+ m_aa_combo->addItem(tr("None"), 1);
+ else
+ m_aa_combo->addItem(tr("%1x MSAA").arg(aa_mode), static_cast<int>(aa_mode));
+
+ if (aa_mode == aa_selection && !ssaa)
+ m_aa_combo->setCurrentIndex(m_aa_combo->count() - 1);
+ }
+ if (g_Config.backend_info.bSupportsSSAA)
+ {
+ for (const u32 aa_mode : g_Config.backend_info.AAModes)
+ {
+ if (aa_mode != 1) // don't show "None" twice
+ {
+ // Mark SSAA using negative values in the variant
+ m_aa_combo->addItem(tr("%1x SSAA").arg(aa_mode), -static_cast<int>(aa_mode));
+ if (aa_mode == aa_selection && ssaa)
+ m_aa_combo->setCurrentIndex(m_aa_combo->count() - 1);
+ }
+ }
+ }
+
m_aa_combo->setEnabled(m_aa_combo->count() > 1);
switch (tex_filter_mode)
@@ -310,22 +328,10 @@ void EnhancementsWidget::SaveSettings()
if (m_block_save)
return;
- bool is_ssaa = m_aa_combo->currentText().endsWith(QStringLiteral("SSAA"));
-
- int aa_value = m_aa_combo->currentIndex();
-
- if (aa_value == 0)
- {
- aa_value = 1;
- }
- else
- {
- if (aa_value > m_msaa_modes)
- aa_value -= m_msaa_modes;
- aa_value = std::pow(2, aa_value);
- }
- Config::SetBaseOrCurrent(Config::GFX_MSAA, static_cast<unsigned int>(aa_value));
+ const u32 aa_value = static_cast<u32>(std::abs(m_aa_combo->currentData().toInt()));
+ const bool is_ssaa = m_aa_combo->currentData().toInt() < 0;
+ Config::SetBaseOrCurrent(Config::GFX_MSAA, aa_value);
Config::SetBaseOrCurrent(Config::GFX_SSAA, is_ssaa);
const int texture_filtering_selection = m_texture_filtering_combo->currentData().toInt();
diff --git a/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp b/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp
index 535458685c..7b31cc7f6e 100644
--- a/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp
+++ b/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp
@@ -24,7 +24,7 @@
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h"
-GraphicsWindow::GraphicsWindow(MainWindow* parent) : QDialog(parent)
+GraphicsWindow::GraphicsWindow(MainWindow* parent) : QDialog(parent), m_main_window(parent)
{
CreateMainLayout();
@@ -68,7 +68,7 @@ void GraphicsWindow::CreateMainLayout()
void GraphicsWindow::OnBackendChanged(const QString& backend_name)
{
Config::SetBase(Config::MAIN_GFX_BACKEND, backend_name.toStdString());
- VideoBackendBase::PopulateBackendInfoFromUI();
+ VideoBackendBase::PopulateBackendInfoFromUI(m_main_window->GetWindowSystemInfo());
setWindowTitle(
tr("%1 Graphics Configuration").arg(tr(g_video_backend->GetDisplayName().c_str())));
diff --git a/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.h b/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.h
index c345de3fef..5949a2dda3 100644
--- a/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.h
+++ b/Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.h
@@ -28,4 +28,6 @@ signals:
private:
void CreateMainLayout();
void OnBackendChanged(const QString& backend);
+
+ MainWindow* const m_main_window;
};
diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp
index 8262c8f01e..42a6a04603 100644
--- a/Source/Core/DolphinQt/MainWindow.cpp
+++ b/Source/Core/DolphinQt/MainWindow.cpp
@@ -343,12 +343,17 @@ MainWindow::~MainWindow()
Config::Save();
}
+WindowSystemInfo MainWindow::GetWindowSystemInfo() const
+{
+ return ::GetWindowSystemInfo(m_render_widget->windowHandle());
+}
+
void MainWindow::InitControllers()
{
if (g_controller_interface.IsInit())
return;
- UICommon::InitControllers(GetWindowSystemInfo(windowHandle()));
+ UICommon::InitControllers(::GetWindowSystemInfo(windowHandle()));
m_hotkey_scheduler = new HotkeyScheduler();
m_hotkey_scheduler->Start();
@@ -1098,7 +1103,7 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
// Boot up, show an error if it fails to load the game.
if (!BootManager::BootCore(std::move(parameters),
- GetWindowSystemInfo(m_render_widget->windowHandle())))
+ ::GetWindowSystemInfo(m_render_widget->windowHandle())))
{
ModalMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok);
HideRenderWidget();
@@ -1206,7 +1211,7 @@ void MainWindow::HideRenderWidget(bool reinit, bool is_exit)
// The controller interface will still be registered to the old render widget, if the core
// has booted. Therefore, we should re-bind it to the main window for now. When the core
// is next started, it will be swapped back to the new render widget.
- g_controller_interface.ChangeWindow(GetWindowSystemInfo(windowHandle()).render_window,
+ g_controller_interface.ChangeWindow(::GetWindowSystemInfo(windowHandle()).render_window,
is_exit ? ControllerInterface::WindowChangeReason::Exit :
ControllerInterface::WindowChangeReason::Other);
}
diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h
index fa3a274bfc..4654202ed7 100644
--- a/Source/Core/DolphinQt/MainWindow.h
+++ b/Source/Core/DolphinQt/MainWindow.h
@@ -50,6 +50,7 @@ class ThreadWidget;
class ToolBar;
class WatchWidget;
class WiiTASInputWindow;
+struct WindowSystemInfo;
namespace DiscIO
{
@@ -76,6 +77,7 @@ public:
~MainWindow();
void Show();
+ WindowSystemInfo GetWindowSystemInfo() const;
bool eventFilter(QObject* object, QEvent* event) override;
diff --git a/Source/Core/UICommon/CMakeLists.txt b/Source/Core/UICommon/CMakeLists.txt
index f2ffbd0821..947aeae346 100644
--- a/Source/Core/UICommon/CMakeLists.txt
+++ b/Source/Core/UICommon/CMakeLists.txt
@@ -23,8 +23,6 @@ add_library(uicommon
UICommon.h
USBUtils.cpp
USBUtils.h
- VideoUtils.cpp
- VideoUtils.h
)
target_link_libraries(uicommon
diff --git a/Source/Core/UICommon/VideoUtils.cpp b/Source/Core/UICommon/VideoUtils.cpp
deleted file mode 100644
index 17947e81b2..0000000000
--- a/Source/Core/UICommon/VideoUtils.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 Dolphin Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "UICommon/VideoUtils.h"
-
-#include "Common/Assert.h"
-#include "VideoCommon/VideoConfig.h"
-
-namespace VideoUtils
-{
-std::vector<std::string> GetAvailableAntialiasingModes(int& msaa_modes)
-{
- std::vector<std::string> modes;
- const auto& aa_modes = g_Config.backend_info.AAModes;
- const bool supports_ssaa = g_Config.backend_info.bSupportsSSAA;
- msaa_modes = 0;
-
- for (const auto mode : aa_modes)
- {
- if (mode == 1)
- {
- modes.push_back("None");
- ASSERT_MSG(VIDEO, !supports_ssaa || msaa_modes == 0, "SSAA setting won't work correctly");
- }
- else
- {
- modes.push_back(std::to_string(mode) + "x MSAA");
- msaa_modes++;
- }
- }
-
- if (supports_ssaa)
- {
- for (const auto mode : aa_modes)
- {
- if (mode != 1)
- modes.push_back(std::to_string(mode) + "x SSAA");
- }
- }
-
- return modes;
-}
-} // namespace VideoUtils
diff --git a/Source/Core/UICommon/VideoUtils.h b/Source/Core/UICommon/VideoUtils.h
deleted file mode 100644
index 492813adab..0000000000
--- a/Source/Core/UICommon/VideoUtils.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 Dolphin Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <string>
-#include <vector>
-
-namespace VideoUtils
-{
-std::vector<std::string> GetAvailableAntialiasingModes(int& m_msaa_modes);
-} // namespace VideoUtils
diff --git a/Source/Core/VideoBackends/D3D/D3DMain.cpp b/Source/Core/VideoBackends/D3D/D3DMain.cpp
index 8256674ad5..4f797fcb26 100644
--- a/Source/Core/VideoBackends/D3D/D3DMain.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DMain.cpp
@@ -63,7 +63,7 @@ std::optional<std::string> VideoBackend::GetWarningMessage() const
return result;
}
-void VideoBackend::InitBackendInfo()
+void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{
if (!D3DCommon::LoadLibraries())
return;
diff --git a/Source/Core/VideoBackends/D3D/VideoBackend.h b/Source/Core/VideoBackends/D3D/VideoBackend.h
index 1349d13b2b..6a94f8c7a3 100644
--- a/Source/Core/VideoBackends/D3D/VideoBackend.h
+++ b/Source/Core/VideoBackends/D3D/VideoBackend.h
@@ -18,7 +18,7 @@ public:
std::string GetDisplayName() const override;
std::optional<std::string> GetWarningMessage() const override;
- void InitBackendInfo() override;
+ void InitBackendInfo(const WindowSystemInfo& wsi) override;
static constexpr const char* NAME = "D3D";
diff --git a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp
index afc5bb96e8..f82b7d961b 100644
--- a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp
+++ b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp
@@ -36,7 +36,7 @@ std::string VideoBackend::GetDisplayName() const
return "Direct3D 12";
}
-void VideoBackend::InitBackendInfo()
+void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{
if (!D3DCommon::LoadLibraries())
return;
diff --git a/Source/Core/VideoBackends/D3D12/VideoBackend.h b/Source/Core/VideoBackends/D3D12/VideoBackend.h
index 7d3126b38c..db03b738d0 100644
--- a/Source/Core/VideoBackends/D3D12/VideoBackend.h
+++ b/Source/Core/VideoBackends/D3D12/VideoBackend.h
@@ -16,7 +16,7 @@ public:
std::string GetName() const override;
std::string GetDisplayName() const override;
- void InitBackendInfo() override;
+ void InitBackendInfo(const WindowSystemInfo& wsi) override;
static constexpr const char* NAME = "D3D12";
diff --git a/Source/Core/VideoBackends/Metal/MTLMain.mm b/Source/Core/VideoBackends/Metal/MTLMain.mm
index f799d5eea1..7042e091fd 100644
--- a/Source/Core/VideoBackends/Metal/MTLMain.mm
+++ b/Source/Core/VideoBackends/Metal/MTLMain.mm
@@ -119,7 +119,7 @@ void Metal::VideoBackend::Shutdown()
ObjectCache::Shutdown();
}
-void Metal::VideoBackend::InitBackendInfo()
+void Metal::VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{
@autoreleasepool
{
diff --git a/Source/Core/VideoBackends/Metal/VideoBackend.h b/Source/Core/VideoBackends/Metal/VideoBackend.h
index 3a567718e2..a6a24173e5 100644
--- a/Source/Core/VideoBackends/Metal/VideoBackend.h
+++ b/Source/Core/VideoBackends/Metal/VideoBackend.h
@@ -18,7 +18,7 @@ public:
std::string GetDisplayName() const override;
std::optional<std::string> GetWarningMessage() const override;
- void InitBackendInfo() override;
+ void InitBackendInfo(const WindowSystemInfo& wsi) override;
void PrepareWindow(WindowSystemInfo& wsi) override;
diff --git a/Source/Core/VideoBackends/Null/NullBackend.cpp b/Source/Core/VideoBackends/Null/NullBackend.cpp
index 900a911699..28afcce4dc 100644
--- a/Source/Core/VideoBackends/Null/NullBackend.cpp
+++ b/Source/Core/VideoBackends/Null/NullBackend.cpp
@@ -25,7 +25,7 @@
namespace Null
{
-void VideoBackend::InitBackendInfo()
+void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{
g_Config.backend_info.api_type = APIType::Nothing;
g_Config.backend_info.MaxTextureSize = 16384;
diff --git a/Source/Core/VideoBackends/Null/VideoBackend.h b/Source/Core/VideoBackends/Null/VideoBackend.h
index f08098cfd0..4437c0c48d 100644
--- a/Source/Core/VideoBackends/Null/VideoBackend.h
+++ b/Source/Core/VideoBackends/Null/VideoBackend.h
@@ -15,7 +15,7 @@ public:
std::string GetName() const override { return NAME; }
std::string GetDisplayName() const override;
- void InitBackendInfo() override;
+ void InitBackendInfo(const WindowSystemInfo& wsi) override;
static constexpr const char* NAME = "Null";
};
diff --git a/Source/Core/VideoBackends/OGL/OGLConfig.cpp b/Source/Core/VideoBackends/OGL/OGLConfig.cpp
index 95998b836b..2695402b63 100644
--- a/Source/Core/VideoBackends/OGL/OGLConfig.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLConfig.cpp
@@ -3,6 +3,11 @@
#include "VideoBackends/OGL/OGLConfig.h"
+#include <cstdio>
+#include <string>
+#include <string_view>
+
+#include "Common/Assert.h"
#include "Common/GL/GLContext.h"
#include "Common/GL/GLExtensions/GLExtensions.h"
#include "Common/Logging/LogManager.h"
@@ -10,14 +15,13 @@
#include "Core/Config/GraphicsSettings.h"
+#include "VideoBackends/OGL/OGLTexture.h"
+
#include "VideoCommon/DriverDetails.h"
+#include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/VideoConfig.h"
-#include <cstdio>
-#include <string>
-#include <string_view>
-
namespace OGL
{
void InitDriverInfo()
@@ -537,9 +541,118 @@ bool PopulateConfig(GLContext* m_main_gl_context)
g_Config.backend_info.bSupportsEarlyZ =
g_ogl_config.bSupportsImageLoadStore || g_ogl_config.bSupportsConservativeDepth;
- glGetIntegerv(GL_MAX_SAMPLES, &g_ogl_config.max_samples);
- if (g_ogl_config.max_samples < 1 || !g_ogl_config.bSupportsMSAA)
- g_ogl_config.max_samples = 1;
+ g_Config.backend_info.AAModes.clear();
+ if (g_ogl_config.bSupportsMSAA)
+ {
+ bool supportsGetInternalFormat =
+ GLExtensions::Supports("VERSION_4_2") || GLExtensions::Supports("VERSION_GLES_3");
+ if (supportsGetInternalFormat)
+ {
+ // Note: GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES should technically be used for
+ // GL_OES_texture_storage_multisample_2d_array, but both are 0x9102 so it does not matter.
+
+ std::vector<int> color_aa_modes;
+ {
+ GLenum colorInternalFormat = OGLTexture::GetGLInternalFormatForTextureFormat(
+ FramebufferManager::GetEFBColorFormat(), true);
+ GLint num_color_sample_counts = 0;
+ glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, colorInternalFormat,
+ GL_NUM_SAMPLE_COUNTS, 1, &num_color_sample_counts);
+
+ ASSERT_MSG(VIDEO, num_color_sample_counts >= 0,
+ "negative GL_NUM_SAMPLE_COUNTS for colors does not make sense: {}",
+ num_color_sample_counts);
+ color_aa_modes.reserve(num_color_sample_counts + 1);
+ if (num_color_sample_counts > 0)
+ {
+ color_aa_modes.resize(num_color_sample_counts);
+
+ static_assert(sizeof(GLint) == sizeof(u32));
+ glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, colorInternalFormat, GL_SAMPLES,
+ num_color_sample_counts,
+ reinterpret_cast<GLint*>(color_aa_modes.data()));
+ ASSERT_MSG(VIDEO, std::is_sorted(color_aa_modes.rbegin(), color_aa_modes.rend()),
+ "GPU driver didn't return sorted color AA modes: [{}]",
+ fmt::join(color_aa_modes, ", "));
+ }
+
+ if (color_aa_modes.empty() || color_aa_modes.back() != 1)
+ color_aa_modes.push_back(1);
+ }
+
+ std::vector<int> depth_aa_modes;
+ {
+ GLenum depthInternalFormat = OGLTexture::GetGLInternalFormatForTextureFormat(
+ FramebufferManager::GetEFBColorFormat(), true);
+ GLint num_depth_sample_counts = 0;
+ glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, depthInternalFormat,
+ GL_NUM_SAMPLE_COUNTS, 1, &num_depth_sample_counts);
+
+ ASSERT_MSG(VIDEO, num_depth_sample_counts >= 0,
+ "negative GL_NUM_SAMPLE_COUNTS for depth does not make sense: {}",
+ num_depth_sample_counts);
+ depth_aa_modes.reserve(num_depth_sample_counts + 1);
+ if (num_depth_sample_counts > 0)
+ {
+ depth_aa_modes.resize(num_depth_sample_counts);
+
+ static_assert(sizeof(GLint) == sizeof(u32));
+ glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, depthInternalFormat, GL_SAMPLES,
+ num_depth_sample_counts,
+ reinterpret_cast<GLint*>(depth_aa_modes.data()));
+ ASSERT_MSG(VIDEO, std::is_sorted(depth_aa_modes.rbegin(), depth_aa_modes.rend()),
+ "GPU driver didn't return sorted depth AA modes: [{}]",
+ fmt::join(depth_aa_modes, ", "));
+ }
+
+ if (depth_aa_modes.empty() || depth_aa_modes.back() != 1)
+ depth_aa_modes.push_back(1);
+ }
+
+ // The spec says supported sample formats are returned in descending numeric order.
+ // It also says "Only positive values are returned", but does not specify whether 1 is
+ // included or not; it seems like NVIDIA and Intel GPUs do not include it.
+ // We've inserted 1 at the back of both if not present to handle this.
+ g_Config.backend_info.AAModes.clear();
+ g_Config.backend_info.AAModes.reserve(std::min(color_aa_modes.size(), depth_aa_modes.size()));
+ // We only want AA modes that are supported for both the color and depth textures. Probably
+ // the support is the same, though. rbegin/rend are used to swap the order ahead of time.
+ std::set_intersection(color_aa_modes.rbegin(), color_aa_modes.rend(), depth_aa_modes.rbegin(),
+ depth_aa_modes.rend(),
+ std::back_inserter(g_Config.backend_info.AAModes));
+ }
+ else
+ {
+ // The documentation for glGetInternalformativ says its value is at least the minimum of
+ // GL_MAX_SAMPLES, GL_MAX_COLOR_TEXTURE_SAMPLES, and GL_MAX_DEPTH_TEXTURE_SAMPLES (and
+ // GL_MAX_INTEGER_SAMPLES for integer textures, assumed not applicable here).
+ GLint max_color_samples = 0;
+ glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_color_samples);
+ GLint max_depth_samples = 0;
+ glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_depth_samples);
+ // Note: The desktop OpenGL ref pages don't actually say that GL_MAX_SAMPLES is a valid
+ // parameter for glGetIntegerv (though the ES ones do). However, MAX_SAMPLES is
+ // referenced in the GL 3.1 spec and by GL_ARB_texture_multisample (which is written against
+ // the OpenGL 3.1 spec), so presumably it is valid.
+ GLint max_samples = 0;
+ glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
+ u32 supported_max_samples =
+ static_cast<u32>(std::min({max_samples, max_color_samples, max_depth_samples}));
+
+ while (supported_max_samples > 1)
+ {
+ g_Config.backend_info.AAModes.push_back(supported_max_samples);
+ supported_max_samples /= 2;
+ }
+ g_Config.backend_info.AAModes.push_back(1);
+ // The UI wants ascending order
+ std::reverse(g_Config.backend_info.AAModes.begin(), g_Config.backend_info.AAModes.end());
+ }
+ }
+ else
+ {
+ g_Config.backend_info.AAModes = {1};
+ }
const bool bSupportsIsHelperInvocation = g_ogl_config.bIsES ?
g_ogl_config.eSupportedGLSLVersion >= GlslEs320 :
diff --git a/Source/Core/VideoBackends/OGL/OGLConfig.h b/Source/Core/VideoBackends/OGL/OGLConfig.h
index 6a50269222..2b78c35c2b 100644
--- a/Source/Core/VideoBackends/OGL/OGLConfig.h
+++ b/Source/Core/VideoBackends/OGL/OGLConfig.h
@@ -82,8 +82,6 @@ struct VideoConfig
const char* gl_vendor;
const char* gl_renderer;
const char* gl_version;
-
- s32 max_samples;
};
void InitDriverInfo();
diff --git a/Source/Core/VideoBackends/OGL/OGLGfx.cpp b/Source/Core/VideoBackends/OGL/OGLGfx.cpp
index e83ff209ea..e545ed7f4b 100644
--- a/Source/Core/VideoBackends/OGL/OGLGfx.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLGfx.cpp
@@ -146,12 +146,6 @@ OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scal
}
}
- if (!PopulateConfig(m_main_gl_context.get()))
- {
- // Not all needed extensions are supported, so we have to stop here.
- // Else some of the next calls might crash.
- return;
- }
InitDriverInfo();
// Setup Debug logging
diff --git a/Source/Core/VideoBackends/OGL/OGLMain.cpp b/Source/Core/VideoBackends/OGL/OGLMain.cpp
index c47b94ceb8..13f47a054f 100644
--- a/Source/Core/VideoBackends/OGL/OGLMain.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLMain.cpp
@@ -74,8 +74,45 @@ std::string VideoBackend::GetDisplayName() const
return _trans("OpenGL");
}
-void VideoBackend::InitBackendInfo()
+void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{
+ std::unique_ptr<GLContext> temp_gl_context =
+ GLContext::Create(wsi, g_Config.stereo_mode == StereoMode::QuadBuffer, true, false,
+ Config::Get(Config::GFX_PREFER_GLES));
+
+ if (!temp_gl_context)
+ return;
+
+ FillBackendInfo(temp_gl_context.get());
+}
+
+bool VideoBackend::InitializeGLExtensions(GLContext* context)
+{
+ // Init extension support.
+ if (!GLExtensions::Init(context))
+ {
+ // OpenGL 2.0 is required for all shader based drawings. There is no way to get this by
+ // extensions
+ PanicAlertFmtT("GPU: OGL ERROR: Does your video card support OpenGL 2.0?");
+ return false;
+ }
+
+ if (GLExtensions::Version() < 300)
+ {
+ // integer vertex attributes require a gl3 only function
+ PanicAlertFmtT("GPU: OGL ERROR: Need OpenGL version 3.\n"
+ "GPU: Does your video card support OpenGL 3?");
+ return false;
+ }
+
+ return true;
+}
+
+bool VideoBackend::FillBackendInfo(GLContext* context)
+{
+ if (!InitializeGLExtensions(context))
+ return false;
+
g_Config.backend_info.api_type = APIType::OpenGL;
g_Config.backend_info.MaxTextureSize = 16384;
g_Config.backend_info.bUsesLowerLeftOrigin = true;
@@ -105,7 +142,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsGPUTextureDecoding = true;
g_Config.backend_info.bSupportsBBox = true;
- // Overwritten in OGLRender.cpp later
+ // Overwritten in OGLConfig.cpp later
g_Config.backend_info.bSupportsDualSourceBlend = true;
g_Config.backend_info.bSupportsPrimitiveRestart = true;
g_Config.backend_info.bSupportsPaletteConversion = true;
@@ -123,33 +160,6 @@ void VideoBackend::InitBackendInfo()
// aamodes - 1 is to stay consistent with D3D (means no AA)
g_Config.backend_info.AAModes = {1, 2, 4, 8};
-}
-
-bool VideoBackend::InitializeGLExtensions(GLContext* context)
-{
- // Init extension support.
- if (!GLExtensions::Init(context))
- {
- // OpenGL 2.0 is required for all shader based drawings. There is no way to get this by
- // extensions
- PanicAlertFmtT("GPU: OGL ERROR: Does your video card support OpenGL 2.0?");
- return false;
- }
-
- if (GLExtensions::Version() < 300)
- {
- // integer vertex attributes require a gl3 only function
- PanicAlertFmtT("GPU: OGL ERROR: Need OpenGL version 3.\n"
- "GPU: Does your video card support OpenGL 3?");
- return false;
- }
-
- return true;
-}
-
-bool VideoBackend::FillBackendInfo()
-{
- InitBackendInfo();
// check for the max vertex attributes
GLint numvertexattribs = 0;
@@ -172,6 +182,13 @@ bool VideoBackend::FillBackendInfo()
return false;
}
+ if (!PopulateConfig(context))
+ {
+ // Not all needed extensions are supported, so we have to stop here.
+ // Else some of the next calls might crash.
+ return false;
+ }
+
// TODO: Move the remaining fields from the Renderer constructor here.
return true;
}
@@ -184,7 +201,7 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
if (!main_gl_context)
return false;
- if (!InitializeGLExtensions(main_gl_context.get()) || !FillBackendInfo())
+ if (!FillBackendInfo(main_gl_context.get()))
return false;
auto gfx = std::make_unique<OGLGfx>(std::move(main_gl_context), wsi.render_surface_scale);
diff --git a/Source/Core/VideoBackends/OGL/OGLTexture.cpp b/Source/Core/VideoBackends/OGL/OGLTexture.cpp
index 0e4e99f59b..f8894a365b 100644
--- a/Source/Core/VideoBackends/OGL/OGLTexture.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLTexture.cpp
@@ -15,9 +15,7 @@
namespace OGL
{
-namespace
-{
-GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool storage)
+GLenum OGLTexture::GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool storage)
{
switch (format)
{
@@ -55,6 +53,8 @@ GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool st
}
}
+namespace
+{
GLenum GetGLFormatForTextureFormat(AbstractTextureFormat format)
{
switch (format)
diff --git a/Source/Core/VideoBackends/OGL/OGLTexture.h b/Source/Core/VideoBackends/OGL/OGLTexture.h
index ca08910eae..53d9d7f589 100644
--- a/Source/Core/VideoBackends/OGL/OGLTexture.h
+++ b/Source/Core/VideoBackends/OGL/OGLTexture.h
@@ -36,6 +36,7 @@ public:
{
return IsMultisampled() ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY;
}
+ static GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool storage);
GLenum GetGLFormatForImageTexture() const;
private:
diff --git a/Source/Core/VideoBackends/OGL/VideoBackend.h b/Source/Core/VideoBackends/OGL/VideoBackend.h
index 4be861954e..53f7f940d5 100644
--- a/Source/Core/VideoBackends/OGL/VideoBackend.h
+++ b/Source/Core/VideoBackends/OGL/VideoBackend.h
@@ -19,12 +19,12 @@ public:
std::string GetName() const override;
std::string GetDisplayName() const override;
- void InitBackendInfo() override;
+ void InitBackendInfo(const WindowSystemInfo& wsi) override;
static constexpr const char* NAME = "OGL";
private:
bool InitializeGLExtensions(GLContext* context);
- bool FillBackendInfo();
+ bool FillBackendInfo(GLContext* context);
};
} // namespace OGL
diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp
index 8703ea4b4d..ccb040e8ad 100644
--- a/Source/Core/VideoBackends/Software/SWmain.cpp
+++ b/Source/Core/VideoBackends/Software/SWmain.cpp
@@ -62,7 +62,7 @@ std::optional<std::string> VideoSoftware::GetWarningMessage() const
"really want to enable software rendering? If unsure, select 'No'.");
}
-void VideoSoftware::InitBackendInfo()
+void VideoSoftware::InitBackendInfo(const WindowSystemInfo& wsi)
{
g_Config.backend_info.api_type = APIType::Nothing;
g_Config.backend_info.MaxTextureSize = 16384;
diff --git a/Source/Core/VideoBackends/Software/VideoBackend.h b/Source/Core/VideoBackends/Software/VideoBackend.h
index 8c3cb081ef..35c3adb1a7 100644
--- a/Source/Core/VideoBackends/Software/VideoBackend.h
+++ b/Source/Core/VideoBackends/Software/VideoBackend.h
@@ -17,7 +17,7 @@ class VideoSoftware : public VideoBackendBase
std::string GetDisplayName() const override;
std::optional<std::string> GetWarningMessage() const override;
- void InitBackendInfo() override;
+ void InitBackendInfo(const WindowSystemInfo& wsi) override;
static constexpr const char* NAME = "Software Renderer";
};
diff --git a/Source/Core/VideoBackends/Vulkan/VKMain.cpp b/Source/Core/VideoBackends/Vulkan/VKMain.cpp
index 053b592c14..2eb9b34106 100644
--- a/Source/Core/VideoBackends/Vulkan/VKMain.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKMain.cpp
@@ -30,7 +30,7 @@
namespace Vulkan
{
-void VideoBackend::InitBackendInfo()
+void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
{
VulkanContext::PopulateBackendInfo(&g_Config);
diff --git a/Source/Core/VideoBackends/Vulkan/VideoBackend.h b/Source/Core/VideoBackends/Vulkan/VideoBackend.h
index a16d149307..4e8c3a5471 100644
--- a/Source/Core/VideoBackends/Vulkan/VideoBackend.h
+++ b/Source/Core/VideoBackends/Vulkan/VideoBackend.h
@@ -16,7 +16,7 @@ public:
std::string GetName() const override { return NAME; }
std::string GetDisplayName() const override { return _trans("Vulkan"); }
- void InitBackendInfo() override;
+ void InitBackendInfo(const WindowSystemInfo& wsi) override;
void PrepareWindow(WindowSystemInfo& wsi) override;
static constexpr const char* NAME = "Vulkan";
diff --git a/Source/Core/VideoCommon/VideoBackendBase.cpp b/Source/Core/VideoCommon/VideoBackendBase.cpp
index 9d6ff70664..6e466c8557 100644
--- a/Source/Core/VideoCommon/VideoBackendBase.cpp
+++ b/Source/Core/VideoCommon/VideoBackendBase.cpp
@@ -281,7 +281,7 @@ void VideoBackendBase::ActivateBackend(const std::string& name)
g_video_backend = iter->get();
}
-void VideoBackendBase::PopulateBackendInfo()
+void VideoBackendBase::PopulateBackendInfo(const WindowSystemInfo& wsi)
{
g_Config.Refresh();
// Reset backend_info so if the backend forgets to initialize something it doesn't end up using
@@ -289,18 +289,18 @@ void VideoBackendBase::PopulateBackendInfo()
g_Config.backend_info = {};
ActivateBackend(Config::Get(Config::MAIN_GFX_BACKEND));
g_Config.backend_info.DisplayName = g_video_backend->GetDisplayName();
- g_video_backend->InitBackendInfo();
+ g_video_backend->InitBackendInfo(wsi);
// We validate the config after initializing the backend info, as system-specific settings
// such as anti-aliasing, or the selected adapter may be invalid, and should be checked.
g_Config.VerifyValidity();
}
-void VideoBackendBase::PopulateBackendInfoFromUI()
+void VideoBackendBase::PopulateBackendInfoFromUI(const WindowSystemInfo& wsi)
{
// If the core is running, the backend info will have been populated already.
// If we did it here, the UI thread can race with the with the GPU thread.
if (!Core::IsRunning())
- PopulateBackendInfo();
+ PopulateBackendInfo(wsi);
}
void VideoBackendBase::DoState(PointerWrap& p)
diff --git a/Source/Core/VideoCommon/VideoBackendBase.h b/Source/Core/VideoCommon/VideoBackendBase.h
index 2ce235f8f8..f5222a1936 100644
--- a/Source/Core/VideoCommon/VideoBackendBase.h
+++ b/Source/Core/VideoCommon/VideoBackendBase.h
@@ -47,7 +47,7 @@ public:
virtual std::string GetName() const = 0;
virtual std::string GetDisplayName() const { return GetName(); }
- virtual void InitBackendInfo() = 0;
+ virtual void InitBackendInfo(const WindowSystemInfo& wsi) = 0;
virtual std::optional<std::string> GetWarningMessage() const { return {}; }
// Prepares a native window for rendering. This is called on the main thread, or the
@@ -69,9 +69,9 @@ public:
static void ActivateBackend(const std::string& name);
// Fills the backend_info fields with the capabilities of the selected backend/device.
- static void PopulateBackendInfo();
+ static void PopulateBackendInfo(const WindowSystemInfo& wsi);
// Called by the UI thread when the graphics config is opened.
- static void PopulateBackendInfoFromUI();
+ static void PopulateBackendInfoFromUI(const WindowSystemInfo& wsi);
// Wrapper function which pushes the event to the GPU thread.
void DoState(PointerWrap& p);