summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/OGLConfig.cpp
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2023-02-09 19:59:16 +1300
committerGitHub <noreply@github.com>2023-02-09 19:59:16 +1300
commitccf92a3e56764d6378c436a8040519a5bffc3372 (patch)
treee2b330b225044e1901e77a6ed147cf21b9d7ac0e /Source/Core/VideoBackends/OGL/OGLConfig.cpp
parent72b22ef0a54f841b1c52d49cf0e00d3b12c29ac7 (diff)
parent5c1b3ac61d7e660a9d1c206dbd0e615d637d3272 (diff)
Merge pull request #11522 from phire/KillRendererWithFire
Kill Renderer (with phire)
Diffstat (limited to 'Source/Core/VideoBackends/OGL/OGLConfig.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/OGLConfig.cpp612
1 files changed, 612 insertions, 0 deletions
diff --git a/Source/Core/VideoBackends/OGL/OGLConfig.cpp b/Source/Core/VideoBackends/OGL/OGLConfig.cpp
new file mode 100644
index 0000000000..bafc28841d
--- /dev/null
+++ b/Source/Core/VideoBackends/OGL/OGLConfig.cpp
@@ -0,0 +1,612 @@
+// Copyright 2023 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "VideoBackends/OGL/OGLConfig.h"
+
+#include "Common/GL/GLContext.h"
+#include "Common/GL/GLExtensions/GLExtensions.h"
+#include "Common/Logging/LogManager.h"
+#include "Common/MsgHandler.h"
+
+#include "Core/Config/GraphicsSettings.h"
+
+#include "VideoCommon/DriverDetails.h"
+#include "VideoCommon/OnScreenDisplay.h"
+#include "VideoCommon/VideoConfig.h"
+
+#include <cstdio>
+#include <string>
+#include <string_view>
+
+namespace OGL
+{
+void InitDriverInfo()
+{
+ const std::string_view svendor(g_ogl_config.gl_vendor);
+ const std::string_view srenderer(g_ogl_config.gl_renderer);
+ const std::string_view sversion(g_ogl_config.gl_version);
+ DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN;
+ DriverDetails::Driver driver = DriverDetails::DRIVER_UNKNOWN;
+ DriverDetails::Family family = DriverDetails::Family::UNKNOWN;
+ double version = 0.0;
+
+ // Get the vendor first
+ if (svendor == "NVIDIA Corporation")
+ {
+ if (srenderer != "NVIDIA Tegra")
+ {
+ vendor = DriverDetails::VENDOR_NVIDIA;
+ }
+ else
+ {
+ vendor = DriverDetails::VENDOR_TEGRA;
+ }
+ }
+ else if (svendor == "ATI Technologies Inc." || svendor == "Advanced Micro Devices, Inc.")
+ {
+ vendor = DriverDetails::VENDOR_ATI;
+ }
+ else if (sversion.find("Mesa") != std::string::npos)
+ {
+ vendor = DriverDetails::VENDOR_MESA;
+ }
+ else if (svendor.find("Intel") != std::string::npos)
+ {
+ vendor = DriverDetails::VENDOR_INTEL;
+ }
+ else if (svendor == "ARM")
+ {
+ vendor = DriverDetails::VENDOR_ARM;
+ }
+ else if (svendor == "http://limadriver.org/")
+ {
+ vendor = DriverDetails::VENDOR_ARM;
+ driver = DriverDetails::DRIVER_LIMA;
+ }
+ else if (svendor == "Qualcomm")
+ {
+ vendor = DriverDetails::VENDOR_QUALCOMM;
+ }
+ else if (svendor == "Imagination Technologies")
+ {
+ vendor = DriverDetails::VENDOR_IMGTEC;
+ }
+ else if (svendor == "Vivante Corporation")
+ {
+ vendor = DriverDetails::VENDOR_VIVANTE;
+ }
+
+ // Get device family and driver version...if we care about it
+ switch (vendor)
+ {
+ case DriverDetails::VENDOR_QUALCOMM:
+ {
+ driver = DriverDetails::DRIVER_QUALCOMM;
+ double glVersion;
+ sscanf(g_ogl_config.gl_version, "OpenGL ES %lg V@%lg", &glVersion, &version);
+ }
+ break;
+ case DriverDetails::VENDOR_ARM:
+ // Currently the Mali-T line has two families in it.
+ // Mali-T6xx and Mali-T7xx
+ // These two families are similar enough that they share bugs in their drivers.
+ //
+ // Mali drivers provide no way to explicitly find out what video driver is running.
+ // This is similar to how we can't find the Nvidia driver version in Windows.
+ // Good thing is that ARM introduces a new video driver about once every two years so we can
+ // find the driver version by the features it exposes.
+ // r2p0 - No OpenGL ES 3.0 support (We don't support this)
+ // r3p0 - OpenGL ES 3.0 support
+ // r4p0 - Supports 'GL_EXT_shader_pixel_local_storage' extension.
+
+ driver = DriverDetails::DRIVER_ARM;
+ if (GLExtensions::Supports("GL_EXT_shader_pixel_local_storage"))
+ version = 400;
+ else
+ version = 300;
+ break;
+ case DriverDetails::VENDOR_MESA:
+ {
+ if (svendor == "nouveau")
+ {
+ driver = DriverDetails::DRIVER_NOUVEAU;
+ }
+ else if (svendor == "Intel Open Source Technology Center")
+ {
+ driver = DriverDetails::DRIVER_I965;
+ if (srenderer.find("Sandybridge") != std::string::npos)
+ family = DriverDetails::Family::INTEL_SANDY;
+ else if (srenderer.find("Ivybridge") != std::string::npos)
+ family = DriverDetails::Family::INTEL_IVY;
+ }
+ else if (srenderer.find("AMD") != std::string::npos ||
+ srenderer.find("ATI") != std::string::npos)
+ {
+ driver = DriverDetails::DRIVER_R600;
+ }
+
+ int major = 0;
+ int minor = 0;
+ int release = 0;
+ sscanf(g_ogl_config.gl_version, "%*s (Core Profile) Mesa %d.%d.%d", &major, &minor, &release);
+ version = 100 * major + 10 * minor + release;
+ }
+ break;
+ case DriverDetails::VENDOR_INTEL: // Happens in OS X/Windows
+ {
+ u32 market_name;
+ sscanf(g_ogl_config.gl_renderer, "Intel HD Graphics %d", &market_name);
+ switch (market_name)
+ {
+ case 2000:
+ case 3000:
+ family = DriverDetails::Family::INTEL_SANDY;
+ break;
+ case 2500:
+ case 4000:
+ family = DriverDetails::Family::INTEL_IVY;
+ break;
+ default:
+ family = DriverDetails::Family::UNKNOWN;
+ break;
+ };
+#ifdef _WIN32
+ int glmajor = 0;
+ int glminor = 0;
+ int major = 0;
+ int minor = 0;
+ int release = 0;
+ int revision = 0;
+ // Example version string: '4.3.0 - Build 10.18.10.3907'
+ sscanf(g_ogl_config.gl_version, "%d.%d.0 - Build %d.%d.%d.%d", &glmajor, &glminor, &major,
+ &minor, &release, &revision);
+ version = 100000000 * major + 1000000 * minor + 10000 * release + revision;
+ version /= 10000;
+#endif
+ }
+ break;
+ case DriverDetails::VENDOR_NVIDIA:
+ {
+ int glmajor = 0;
+ int glminor = 0;
+ int glrelease = 0;
+ int major = 0;
+ int minor = 0;
+ // TODO: this is known to be broken on Windows
+ // Nvidia seems to have removed their driver version from this string, so we can't get it.
+ // hopefully we'll never have to workaround Nvidia bugs
+ sscanf(g_ogl_config.gl_version, "%d.%d.%d NVIDIA %d.%d", &glmajor, &glminor, &glrelease, &major,
+ &minor);
+ version = 100 * major + minor;
+ }
+ break;
+ case DriverDetails::VENDOR_IMGTEC:
+ {
+ // Example version string:
+ // "OpenGL ES 3.2 build 1.9@4850625"
+ // Ends up as "109.4850625" - "1.9" being the branch, "4850625" being the build's change ID
+ // The change ID only makes sense to compare within a branch
+ driver = DriverDetails::DRIVER_IMGTEC;
+ double gl_version;
+ int major, minor, change;
+ constexpr double change_scale = 10000000;
+ sscanf(g_ogl_config.gl_version, "OpenGL ES %lg build %d.%d@%d", &gl_version, &major, &minor,
+ &change);
+ version = 100 * major + minor;
+ if (change >= change_scale)
+ {
+ ERROR_LOG_FMT(VIDEO, "Version changeID overflow - change:{} scale:{}", change, change_scale);
+ }
+ else
+ {
+ version += static_cast<double>(change) / change_scale;
+ }
+ }
+ break;
+ // We don't care about these
+ default:
+ break;
+ }
+ DriverDetails::Init(DriverDetails::API_OPENGL, vendor, driver, version, family);
+}
+
+bool PopulateConfig(GLContext* m_main_gl_context)
+{
+ bool bSuccess = true;
+ bool supports_glsl_cache = false;
+
+ g_ogl_config.gl_vendor = (const char*)glGetString(GL_VENDOR);
+ g_ogl_config.gl_renderer = (const char*)glGetString(GL_RENDERER);
+ g_ogl_config.gl_version = (const char*)glGetString(GL_VERSION);
+
+ if (!m_main_gl_context->IsGLES())
+ {
+ if (!GLExtensions::Supports("GL_ARB_framebuffer_object"))
+ {
+ // We want the ogl3 framebuffer instead of the ogl2 one for better blitting support.
+ // It's also compatible with the gles3 one.
+ PanicAlertFmtT("GPU: ERROR: Need GL_ARB_framebuffer_object for multiple render targets.\n"
+ "GPU: Does your video card support OpenGL 3.0?");
+ bSuccess = false;
+ }
+
+ if (!GLExtensions::Supports("GL_ARB_vertex_array_object"))
+ {
+ // This extension is used to replace lots of pointer setting function.
+ // Also gles3 requires to use it.
+ PanicAlertFmtT("GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n"
+ "GPU: Does your video card support OpenGL 3.0?");
+ bSuccess = false;
+ }
+
+ if (!GLExtensions::Supports("GL_ARB_map_buffer_range"))
+ {
+ // ogl3 buffer mapping for better streaming support.
+ // The ogl2 one also isn't in gles3.
+ PanicAlertFmtT("GPU: OGL ERROR: Need GL_ARB_map_buffer_range.\n"
+ "GPU: Does your video card support OpenGL 3.0?");
+ bSuccess = false;
+ }
+
+ if (!GLExtensions::Supports("GL_ARB_uniform_buffer_object"))
+ {
+ // ubo allow us to keep the current constants on shader switches
+ // we also can stream them much nicer and pack into it whatever we want to
+ PanicAlertFmtT("GPU: OGL ERROR: Need GL_ARB_uniform_buffer_object.\n"
+ "GPU: Does your video card support OpenGL 3.1?");
+ bSuccess = false;
+ }
+ else if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_UBO))
+ {
+ PanicAlertFmtT(
+ "Buggy GPU driver detected.\n"
+ "Please either install the closed-source GPU driver or update your Mesa 3D version.");
+ bSuccess = false;
+ }
+
+ if (!GLExtensions::Supports("GL_ARB_sampler_objects"))
+ {
+ // Our sampler cache uses this extension. It could easyly be workaround and it's by far the
+ // highest requirement, but it seems that no driver lacks support for it.
+ PanicAlertFmtT("GPU: OGL ERROR: Need GL_ARB_sampler_objects.\n"
+ "GPU: Does your video card support OpenGL 3.3?");
+ bSuccess = false;
+ }
+ }
+
+ // Copy the GPU name to g_Config, so Analytics can see it.
+ g_Config.backend_info.AdapterName = g_ogl_config.gl_renderer;
+
+ g_Config.backend_info.bSupportsDualSourceBlend =
+ (GLExtensions::Supports("GL_ARB_blend_func_extended") ||
+ GLExtensions::Supports("GL_EXT_blend_func_extended"));
+ g_Config.backend_info.bSupportsPrimitiveRestart =
+ !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART) &&
+ ((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart"));
+ g_Config.backend_info.bSupportsFragmentStoresAndAtomics =
+ GLExtensions::Supports("GL_ARB_shader_storage_buffer_object");
+ g_Config.backend_info.bSupportsVSLinePointExpand =
+ GLExtensions::Supports("GL_ARB_shader_storage_buffer_object");
+ g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5");
+ g_Config.backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") &&
+ GLExtensions::Supports("GL_ARB_sample_shading");
+ g_Config.backend_info.bSupportsGeometryShaders =
+ GLExtensions::Version() >= 320 &&
+ !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_GEOMETRY_SHADERS);
+ g_Config.backend_info.bSupportsPaletteConversion =
+ GLExtensions::Supports("GL_ARB_texture_buffer_object") ||
+ GLExtensions::Supports("GL_OES_texture_buffer") ||
+ GLExtensions::Supports("GL_EXT_texture_buffer");
+ g_Config.backend_info.bSupportsClipControl = GLExtensions::Supports("GL_ARB_clip_control");
+ g_ogl_config.bSupportsCopySubImage =
+ (GLExtensions::Supports("GL_ARB_copy_image") || GLExtensions::Supports("GL_NV_copy_image") ||
+ GLExtensions::Supports("GL_EXT_copy_image") ||
+ GLExtensions::Supports("GL_OES_copy_image")) &&
+ !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_COPYIMAGE);
+ g_ogl_config.bSupportsTextureSubImage = GLExtensions::Supports("ARB_get_texture_sub_image");
+
+ // Desktop OpenGL supports the binding layout if it supports 420pack
+ // OpenGL ES 3.1 supports it implicitly without an extension
+ g_Config.backend_info.bSupportsBindingLayout =
+ GLExtensions::Supports("GL_ARB_shading_language_420pack");
+
+ // Clip distance support is useless without a method to clamp the depth range
+ g_Config.backend_info.bSupportsDepthClamp = GLExtensions::Supports("GL_ARB_depth_clamp");
+
+ // Desktop OpenGL supports bitfield manulipation and dynamic sampler indexing if it supports
+ // shader5. OpenGL ES 3.1 supports it implicitly without an extension
+ g_Config.backend_info.bSupportsBitfield = GLExtensions::Supports("GL_ARB_gpu_shader5");
+ g_Config.backend_info.bSupportsDynamicSamplerIndexing =
+ GLExtensions::Supports("GL_ARB_gpu_shader5");
+
+ g_ogl_config.bIsES = m_main_gl_context->IsGLES();
+ supports_glsl_cache = GLExtensions::Supports("GL_ARB_get_program_binary");
+ g_ogl_config.bSupportsGLPinnedMemory = GLExtensions::Supports("GL_AMD_pinned_memory");
+ g_ogl_config.bSupportsGLSync = GLExtensions::Supports("GL_ARB_sync");
+ g_ogl_config.bSupportsGLBaseVertex = GLExtensions::Supports("GL_ARB_draw_elements_base_vertex") ||
+ GLExtensions::Supports("GL_EXT_draw_elements_base_vertex") ||
+ GLExtensions::Supports("GL_OES_draw_elements_base_vertex");
+ g_ogl_config.bSupportsGLBufferStorage = GLExtensions::Supports("GL_ARB_buffer_storage") ||
+ GLExtensions::Supports("GL_EXT_buffer_storage");
+ g_ogl_config.bSupportsMSAA = GLExtensions::Supports("GL_ARB_texture_multisample");
+ g_ogl_config.bSupportViewportFloat = GLExtensions::Supports("GL_ARB_viewport_array");
+ g_ogl_config.bSupportsDebug =
+ GLExtensions::Supports("GL_KHR_debug") || GLExtensions::Supports("GL_ARB_debug_output");
+ g_ogl_config.bSupportsTextureStorage = GLExtensions::Supports("GL_ARB_texture_storage");
+ g_ogl_config.bSupports3DTextureStorageMultisample =
+ GLExtensions::Supports("GL_ARB_texture_storage_multisample") ||
+ GLExtensions::Supports("GL_OES_texture_storage_multisample_2d_array");
+ g_ogl_config.bSupports2DTextureStorageMultisample =
+ GLExtensions::Supports("GL_ARB_texture_storage_multisample");
+ g_ogl_config.bSupportsImageLoadStore = GLExtensions::Supports("GL_ARB_shader_image_load_store");
+ g_ogl_config.bSupportsConservativeDepth = GLExtensions::Supports("GL_ARB_conservative_depth");
+ g_ogl_config.bSupportsAniso = GLExtensions::Supports("GL_EXT_texture_filter_anisotropic");
+ g_Config.backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader");
+ g_Config.backend_info.bSupportsST3CTextures =
+ GLExtensions::Supports("GL_EXT_texture_compression_s3tc");
+ g_Config.backend_info.bSupportsBPTCTextures =
+ GLExtensions::Supports("GL_ARB_texture_compression_bptc");
+ g_Config.backend_info.bSupportsCoarseDerivatives =
+ GLExtensions::Supports("GL_ARB_derivative_control") || GLExtensions::Version() >= 450;
+ g_Config.backend_info.bSupportsTextureQueryLevels =
+ GLExtensions::Supports("GL_ARB_texture_query_levels") || GLExtensions::Version() >= 430;
+
+ if (GLExtensions::Supports("GL_EXT_shader_framebuffer_fetch"))
+ {
+ g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchExt;
+ }
+ else if (GLExtensions::Supports("GL_ARM_shader_framebuffer_fetch"))
+ {
+ g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchArm;
+ }
+ else
+ {
+ g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchNone;
+ }
+ g_Config.backend_info.bSupportsFramebufferFetch =
+ g_ogl_config.SupportedFramebufferFetch != EsFbFetchType::FbFetchNone;
+
+ if (m_main_gl_context->IsGLES())
+ {
+ g_ogl_config.SupportedESPointSize = GLExtensions::Supports("GL_OES_geometry_point_size") ? 1 :
+ GLExtensions::Supports("GL_EXT_geometry_point_size") ? 2 :
+ 0;
+ g_ogl_config.SupportedESTextureBuffer =
+ GLExtensions::Supports("VERSION_GLES_3_2") ? EsTexbufType::TexbufCore :
+ GLExtensions::Supports("GL_OES_texture_buffer") ? EsTexbufType::TexbufOes :
+ GLExtensions::Supports("GL_EXT_texture_buffer") ? EsTexbufType::TexbufExt :
+ EsTexbufType::TexbufNone;
+
+ supports_glsl_cache = true;
+ g_ogl_config.bSupportsGLSync = true;
+
+ // TODO: Implement support for GL_EXT_clip_cull_distance when there is an extension for
+ // depth clamping.
+ g_Config.backend_info.bSupportsDepthClamp = false;
+
+ // GLES does not support logic op.
+ g_Config.backend_info.bSupportsLogicOp = false;
+
+ // glReadPixels() can't be used with non-color formats. But, if we support
+ // ARB_get_texture_sub_image (unlikely, except maybe on NVIDIA), we can use that instead.
+ g_Config.backend_info.bSupportsDepthReadback = g_ogl_config.bSupportsTextureSubImage;
+
+ // GL_TEXTURE_LOD_BIAS is not supported on GLES.
+ g_Config.backend_info.bSupportsLodBiasInSampler = false;
+
+ if (GLExtensions::Version() == 300)
+ {
+ g_ogl_config.eSupportedGLSLVersion = GlslEs300;
+ g_ogl_config.bSupportsAEP = false;
+ g_ogl_config.bSupportsTextureStorage = true;
+ g_Config.backend_info.bSupportsGeometryShaders = false;
+ }
+ else if (GLExtensions::Version() == 310)
+ {
+ g_ogl_config.eSupportedGLSLVersion = GlslEs310;
+ g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a");
+ g_Config.backend_info.bSupportsBindingLayout = true;
+ g_ogl_config.bSupportsImageLoadStore = true;
+ g_Config.backend_info.bSupportsGeometryShaders = g_ogl_config.bSupportsAEP;
+ g_Config.backend_info.bSupportsComputeShaders = true;
+ g_Config.backend_info.bSupportsGSInstancing =
+ g_Config.backend_info.bSupportsGeometryShaders && g_ogl_config.SupportedESPointSize > 0;
+ g_Config.backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP;
+ g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true;
+ g_ogl_config.bSupportsMSAA = true;
+ g_ogl_config.bSupportsTextureStorage = true;
+ g_ogl_config.bSupports2DTextureStorageMultisample = true;
+ g_Config.backend_info.bSupportsBitfield = true;
+ g_Config.backend_info.bSupportsDynamicSamplerIndexing = g_ogl_config.bSupportsAEP;
+ if (g_ActiveConfig.stereo_mode != StereoMode::Off && g_ActiveConfig.iMultisamples > 1 &&
+ !g_ogl_config.bSupports3DTextureStorageMultisample)
+ {
+ // GLES 3.1 can't support stereo rendering and MSAA
+ OSD::AddMessage("MSAA Stereo rendering isn't supported by your GPU.", 10000);
+ Config::SetCurrent(Config::GFX_MSAA, UINT32_C(1));
+ }
+ }
+ else
+ {
+ g_ogl_config.eSupportedGLSLVersion = GlslEs320;
+ g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a");
+ g_Config.backend_info.bSupportsBindingLayout = true;
+ g_ogl_config.bSupportsImageLoadStore = true;
+ g_Config.backend_info.bSupportsGeometryShaders = true;
+ g_Config.backend_info.bSupportsComputeShaders = true;
+ g_Config.backend_info.bSupportsGSInstancing = g_ogl_config.SupportedESPointSize > 0;
+ g_Config.backend_info.bSupportsPaletteConversion = true;
+ g_Config.backend_info.bSupportsSSAA = true;
+ g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true;
+ g_ogl_config.bSupportsCopySubImage = true;
+ g_ogl_config.bSupportsGLBaseVertex = true;
+ g_ogl_config.bSupportsDebug = true;
+ g_ogl_config.bSupportsMSAA = true;
+ g_ogl_config.bSupportsTextureStorage = true;
+ g_ogl_config.bSupports2DTextureStorageMultisample = true;
+ g_ogl_config.bSupports3DTextureStorageMultisample = true;
+ g_Config.backend_info.bSupportsBitfield = true;
+ g_Config.backend_info.bSupportsDynamicSamplerIndexing = true;
+ g_Config.backend_info.bSupportsSettingObjectNames = true;
+ }
+ }
+ else
+ {
+ if (GLExtensions::Version() < 300)
+ {
+ PanicAlertFmtT("GPU: OGL ERROR: Need at least GLSL 1.30\n"
+ "GPU: Does your video card support OpenGL 3.0?\n"
+ "GPU: Your driver supports GLSL {0}",
+ reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)));
+ bSuccess = false;
+ }
+ else if (GLExtensions::Version() == 300)
+ {
+ g_ogl_config.eSupportedGLSLVersion = Glsl130;
+ g_ogl_config.bSupportsImageLoadStore = false; // layout keyword is only supported on glsl150+
+ g_ogl_config.bSupportsConservativeDepth =
+ false; // layout keyword is only supported on glsl150+
+ g_Config.backend_info.bSupportsGeometryShaders =
+ false; // geometry shaders are only supported on glsl150+
+ }
+ else if (GLExtensions::Version() == 310)
+ {
+ g_ogl_config.eSupportedGLSLVersion = Glsl140;
+ g_ogl_config.bSupportsImageLoadStore = false; // layout keyword is only supported on glsl150+
+ g_ogl_config.bSupportsConservativeDepth =
+ false; // layout keyword is only supported on glsl150+
+ g_Config.backend_info.bSupportsGeometryShaders =
+ false; // geometry shaders are only supported on glsl150+
+ }
+ else if (GLExtensions::Version() == 320)
+ {
+ g_ogl_config.eSupportedGLSLVersion = Glsl150;
+ }
+ else if (GLExtensions::Version() == 330)
+ {
+ g_ogl_config.eSupportedGLSLVersion = Glsl330;
+ }
+ else if (GLExtensions::Version() >= 430)
+ {
+ // TODO: We should really parse the GL_SHADING_LANGUAGE_VERSION token.
+ g_ogl_config.eSupportedGLSLVersion = Glsl430;
+ g_ogl_config.bSupportsTextureStorage = true;
+ g_ogl_config.bSupportsImageLoadStore = true;
+ g_Config.backend_info.bSupportsSSAA = true;
+ g_Config.backend_info.bSupportsSettingObjectNames = true;
+
+ // Compute shaders are core in GL4.3.
+ g_Config.backend_info.bSupportsComputeShaders = true;
+ if (GLExtensions::Version() >= 450)
+ g_ogl_config.bSupportsTextureSubImage = true;
+ }
+ else
+ {
+ g_ogl_config.eSupportedGLSLVersion = Glsl400;
+ g_Config.backend_info.bSupportsSSAA = true;
+
+ if (GLExtensions::Version() == 420)
+ {
+ // Texture storage and shader image load/store are core in GL4.2.
+ g_ogl_config.bSupportsTextureStorage = true;
+ g_ogl_config.bSupportsImageLoadStore = true;
+ }
+ }
+
+ // Desktop OpenGL can't have the Android Extension Pack
+ g_ogl_config.bSupportsAEP = false;
+
+ // Desktop GL requires GL_PROGRAM_POINT_SIZE set to use gl_PointSize in shaders.
+ // It is implicitly enabled in GLES.
+ glEnable(GL_PROGRAM_POINT_SIZE);
+ }
+
+ g_Config.backend_info.bSupportsBBox = g_Config.backend_info.bSupportsFragmentStoresAndAtomics;
+
+ // Either method can do early-z tests. See PixelShaderGen for details.
+ 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_ogl_config.bSupportsShaderThreadShuffleNV =
+ GLExtensions::Supports("GL_NV_shader_thread_shuffle");
+
+ // We require texel buffers, image load store, and compute shaders to enable GPU texture decoding.
+ // If the driver doesn't expose the extensions, but supports GL4.3/GLES3.1, it will still be
+ // enabled in the version check below.
+ g_Config.backend_info.bSupportsGPUTextureDecoding =
+ g_Config.backend_info.bSupportsPaletteConversion &&
+ g_Config.backend_info.bSupportsComputeShaders && g_ogl_config.bSupportsImageLoadStore;
+
+ // Background compiling is supported only when shared contexts aren't broken.
+ g_Config.backend_info.bSupportsBackgroundCompiling =
+ !DriverDetails::HasBug(DriverDetails::BUG_SHARED_CONTEXT_SHADER_COMPILATION);
+
+ // Program binaries are supported on GL4.1+, ARB_get_program_binary, or ES3.
+ if (supports_glsl_cache)
+ {
+ // We need to check the number of formats supported. If zero, don't bother getting the binaries.
+ GLint num_formats = 0;
+ glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_formats);
+ supports_glsl_cache = num_formats > 0;
+ }
+ g_Config.backend_info.bSupportsPipelineCacheData = supports_glsl_cache;
+
+ int samples;
+ glGetIntegerv(GL_SAMPLES, &samples);
+ if (samples > 1)
+ {
+ // MSAA on default framebuffer isn't working because of glBlitFramebuffer.
+ // It also isn't useful as we don't render anything to the default framebuffer.
+ // We also try to get a non-msaa fb, so this only happens when forced by the driver.
+ PanicAlertFmtT(
+ "The graphics driver is forcibly enabling anti-aliasing for Dolphin. You need to "
+ "turn this off in the graphics driver's settings in order for Dolphin to work.\n\n"
+ "(MSAA with {0} samples found on default framebuffer)",
+ samples);
+ bSuccess = false;
+ }
+
+ if (!bSuccess)
+ return false;
+
+ g_Config.VerifyValidity();
+ UpdateActiveConfig();
+
+ OSD::AddMessage(fmt::format("Video Info: {}, {}, {}", g_ogl_config.gl_vendor,
+ g_ogl_config.gl_renderer, g_ogl_config.gl_version),
+ 5000);
+
+ if (!g_ogl_config.bSupportsGLBufferStorage && !g_ogl_config.bSupportsGLPinnedMemory)
+ {
+ OSD::AddMessage(fmt::format("Your OpenGL driver does not support {}_buffer_storage.",
+ m_main_gl_context->IsGLES() ? "EXT" : "ARB"),
+ 60000);
+ OSD::AddMessage("This device's performance may be poor.", 60000);
+ }
+
+ INFO_LOG_FMT(VIDEO, "Video Info: {}, {}, {}", g_ogl_config.gl_vendor, g_ogl_config.gl_renderer,
+ g_ogl_config.gl_version);
+ WARN_LOG_FMT(VIDEO, "Missing OGL Extensions: {}{}{}{}{}{}{}{}{}{}{}{}{}{}",
+ g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
+ g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ",
+ g_ActiveConfig.backend_info.bSupportsEarlyZ ? "" : "EarlyZ ",
+ g_ogl_config.bSupportsGLPinnedMemory ? "" : "PinnedMemory ",
+ supports_glsl_cache ? "" : "ShaderCache ",
+ g_ogl_config.bSupportsGLBaseVertex ? "" : "BaseVertex ",
+ g_ogl_config.bSupportsGLBufferStorage ? "" : "BufferStorage ",
+ g_ogl_config.bSupportsGLSync ? "" : "Sync ",
+ g_ogl_config.bSupportsMSAA ? "" : "MSAA ",
+ g_ActiveConfig.backend_info.bSupportsSSAA ? "" : "SSAA ",
+ g_ActiveConfig.backend_info.bSupportsGSInstancing ? "" : "GSInstancing ",
+ g_ActiveConfig.backend_info.bSupportsClipControl ? "" : "ClipControl ",
+ g_ogl_config.bSupportsCopySubImage ? "" : "CopyImageSubData ",
+ g_ActiveConfig.backend_info.bSupportsDepthClamp ? "" : "DepthClamp ");
+
+ return true;
+}
+
+} // namespace OGL