diff --git a/Source/Core/VideoBackends/OGL/OGLConfig.cpp b/Source/Core/VideoBackends/OGL/OGLConfig.cpp index ab31592bd2..e5e1bff83f 100644 --- a/Source/Core/VideoBackends/OGL/OGLConfig.cpp +++ b/Source/Core/VideoBackends/OGL/OGLConfig.cpp @@ -333,11 +333,7 @@ bool PopulateConfig(GLContext* m_main_gl_context) 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.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageNone; 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"); @@ -368,9 +364,10 @@ bool PopulateConfig(GLContext* m_main_gl_context) 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.SupportedESPointSize = + GLExtensions::Supports("GL_OES_geometry_point_size") ? EsPointSizeType::PointSizeOes : + GLExtensions::Supports("GL_EXT_geometry_point_size") ? EsPointSizeType::PointSizeExt : + EsPointSizeType::PointSizeNone; g_ogl_config.SupportedESTextureBuffer = GLExtensions::Supports("VERSION_GLES_3_2") ? EsTexbufType::TexbufCore : GLExtensions::Supports("GL_OES_texture_buffer") ? EsTexbufType::TexbufOes : @@ -410,21 +407,16 @@ bool PopulateConfig(GLContext* m_main_gl_context) 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.bSupportsGeometryShaders && + g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone; 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; + if (GLExtensions::Supports("GL_OES_texture_storage_multisample_2d_array")) + g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageOes; 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 { @@ -434,7 +426,8 @@ bool PopulateConfig(GLContext* m_main_gl_context) 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.bSupportsGSInstancing = + g_ogl_config.SupportedESPointSize != EsPointSizeType::PointSizeNone; g_Config.backend_info.bSupportsPaletteConversion = true; g_Config.backend_info.bSupportsSSAA = true; g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; @@ -443,8 +436,7 @@ bool PopulateConfig(GLContext* m_main_gl_context) 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_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore; g_Config.backend_info.bSupportsBitfield = true; g_Config.backend_info.bSupportsDynamicSamplerIndexing = true; g_Config.backend_info.bSupportsSettingObjectNames = true; @@ -452,6 +444,9 @@ bool PopulateConfig(GLContext* m_main_gl_context) } else { + if (GLExtensions::Supports("GL_ARB_texture_storage_multisample")) + g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore; + if (GLExtensions::Version() < 300) { PanicAlertFmtT("GPU: OGL ERROR: Need at least GLSL 1.30\n" @@ -498,6 +493,7 @@ bool PopulateConfig(GLContext* m_main_gl_context) g_ogl_config.eSupportedGLSLVersion = Glsl430; } g_ogl_config.bSupportsTextureStorage = true; + g_ogl_config.SupportedMultisampleTexStorage = MultisampleTexStorageType::TexStorageCore; g_ogl_config.bSupportsImageLoadStore = true; g_Config.backend_info.bSupportsSSAA = true; g_Config.backend_info.bSupportsSettingObjectNames = true; diff --git a/Source/Core/VideoBackends/OGL/OGLConfig.h b/Source/Core/VideoBackends/OGL/OGLConfig.h index 570e1954eb..4929901b09 100644 --- a/Source/Core/VideoBackends/OGL/OGLConfig.h +++ b/Source/Core/VideoBackends/OGL/OGLConfig.h @@ -22,6 +22,14 @@ enum GlslVersion GlslEs310, // GLES 3.1 GlslEs320, // GLES 3.2 }; + +enum class EsPointSizeType +{ + PointSizeNone, + PointSizeOes, + PointSizeExt, +}; + enum class EsTexbufType { TexbufNone, @@ -37,6 +45,13 @@ enum class EsFbFetchType FbFetchArm, }; +enum class MultisampleTexStorageType +{ + TexStorageNone, + TexStorageCore, + TexStorageOes, +}; + // ogl-only config, so not in VideoConfig.h struct VideoConfig { @@ -51,11 +66,10 @@ struct VideoConfig bool bSupportsAEP; bool bSupportsDebug; bool bSupportsCopySubImage; - u8 SupportedESPointSize; + EsPointSizeType SupportedESPointSize; EsTexbufType SupportedESTextureBuffer; bool bSupportsTextureStorage; - bool bSupports2DTextureStorageMultisample; - bool bSupports3DTextureStorageMultisample; + MultisampleTexStorageType SupportedMultisampleTexStorage; bool bSupportsConservativeDepth; bool bSupportsImageLoadStore; bool bSupportsAniso; diff --git a/Source/Core/VideoBackends/OGL/OGLTexture.cpp b/Source/Core/VideoBackends/OGL/OGLTexture.cpp index 4e90211c59..d3274a3528 100644 --- a/Source/Core/VideoBackends/OGL/OGLTexture.cpp +++ b/Source/Core/VideoBackends/OGL/OGLTexture.cpp @@ -130,12 +130,18 @@ OGLTexture::OGLTexture(const TextureConfig& tex_config, std::string_view name) GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(m_config.format, true); if (tex_config.IsMultisampled()) { - if (g_ogl_config.bSupportsTextureStorage) + ASSERT(g_ogl_config.bSupportsMSAA); + if (g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone) + { glTexStorage3DMultisample(target, tex_config.samples, gl_internal_format, m_config.width, m_config.height, m_config.layers, GL_FALSE); + } else + { + ASSERT(!g_ogl_config.bIsES); glTexImage3DMultisample(target, tex_config.samples, gl_internal_format, m_config.width, m_config.height, m_config.layers, GL_FALSE); + } } else if (g_ogl_config.bSupportsTextureStorage) { diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index eff1497e7f..a149c9fad0 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -664,12 +664,13 @@ void ProgramShaderCache::CreateHeader() std::string SupportedESTextureBuffer; switch (g_ogl_config.SupportedESPointSize) { - case 1: + case EsPointSizeType::PointSizeOes: SupportedESPointSize = "#extension GL_OES_geometry_point_size : enable"; break; - case 2: + case EsPointSizeType::PointSizeExt: SupportedESPointSize = "#extension GL_EXT_geometry_point_size : enable"; break; + case EsPointSizeType::PointSizeNone: default: SupportedESPointSize = ""; break; @@ -721,6 +722,13 @@ void ProgramShaderCache::CreateHeader() break; } + // The sampler2DMSArray keyword is reserved in GLSL ES 3.0 and 3.1, but is available in 3.2 and + // with GL_OES_texture_storage_multisample_2d_array for 3.1. + // See https://bugs.dolphin-emu.org/issues/13198. + const bool use_multisample_2d_array_precision = + v >= GlslEs320 || + g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone; + std::string shader_shuffle_string; if (g_ogl_config.bSupportsKHRShaderSubgroup) { @@ -758,6 +766,7 @@ void ProgramShaderCache::CreateHeader() "{}\n" // shader thread shuffle "{}\n" // derivative control "{}\n" // query levels + "{}\n" // OES multisample texture storage // Precision defines for GLSL ES "{}\n" @@ -843,12 +852,18 @@ void ProgramShaderCache::CreateHeader() g_ActiveConfig.backend_info.bSupportsTextureQueryLevels ? "#extension GL_ARB_texture_query_levels : enable" : "", + // Note: GL_ARB_texture_storage_multisample doesn't have an #extension, as it doesn't + // need to change GLSL, but on GLES 3.1 sampler2DMSArray is a reserved keyword unless + // the extension is enabled. Thus, we don't need to check TexStorageCore/have an ARB version. + g_ogl_config.SupportedMultisampleTexStorage == MultisampleTexStorageType::TexStorageOes ? + "#extension GL_OES_texture_storage_multisample_2d_array : enable" : + "", is_glsles ? "precision highp float;" : "", is_glsles ? "precision highp int;" : "", is_glsles ? "precision highp sampler2DArray;" : "", (is_glsles && g_ActiveConfig.backend_info.bSupportsPaletteConversion) ? "precision highp usamplerBuffer;" : "", - v > GlslEs300 ? "precision highp sampler2DMSArray;" : "", + use_multisample_2d_array_precision ? "precision highp sampler2DMSArray;" : "", v >= GlslEs310 ? "precision highp image2DArray;" : ""); }