Merge pull request #11699 from Pokechu22/gl-check-maximum-samples
OpenGL: Check the list of supported AA modes instead of hardcoding
This commit is contained in:
commit
8f51a9d2d8
|
@ -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"),
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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())));
|
||||
|
|
|
@ -28,4 +28,6 @@ signals:
|
|||
private:
|
||||
void CreateMainLayout();
|
||||
void OnBackendChanged(const QString& backend);
|
||||
|
||||
MainWindow* const m_main_window;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@ add_library(uicommon
|
|||
UICommon.h
|
||||
USBUtils.cpp
|
||||
USBUtils.h
|
||||
VideoUtils.cpp
|
||||
VideoUtils.h
|
||||
)
|
||||
|
||||
target_link_libraries(uicommon
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ void Metal::VideoBackend::Shutdown()
|
|||
ObjectCache::Shutdown();
|
||||
}
|
||||
|
||||
void Metal::VideoBackend::InitBackendInfo()
|
||||
void Metal::VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -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 :
|
||||
|
|
|
@ -82,8 +82,6 @@ struct VideoConfig
|
|||
const char* gl_vendor;
|
||||
const char* gl_renderer;
|
||||
const char* gl_version;
|
||||
|
||||
s32 max_samples;
|
||||
};
|
||||
|
||||
void InitDriverInfo();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
namespace Vulkan
|
||||
{
|
||||
void VideoBackend::InitBackendInfo()
|
||||
void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
|
||||
{
|
||||
VulkanContext::PopulateBackendInfo(&g_Config);
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue