From aaf378f04122abc1b713121fda78627e16642067 Mon Sep 17 00:00:00 2001 From: vladislavbelov Date: Sun, 13 Feb 2022 21:46:03 +0000 Subject: [PATCH] Moves backend capabilities to CDevice. This was SVN commit r26366. --- source/graphics/ShaderManager.cpp | 11 ++---- source/renderer/PostprocManager.cpp | 19 ++-------- source/renderer/PostprocManager.h | 4 +- source/renderer/Renderer.cpp | 51 +++----------------------- source/renderer/Renderer.h | 21 ----------- source/renderer/RenderingOptions.cpp | 1 - source/renderer/RenderingOptions.h | 1 - source/renderer/SceneRenderer.cpp | 19 ++++------ source/renderer/WaterManager.cpp | 16 ++------ source/renderer/backend/gl/Device.cpp | 27 ++++++++++++-- source/renderer/backend/gl/Device.h | 15 +++++++- source/renderer/backend/gl/Texture.cpp | 10 +++-- 12 files changed, 70 insertions(+), 125 deletions(-) diff --git a/source/graphics/ShaderManager.cpp b/source/graphics/ShaderManager.cpp index 53fabdde14..1fbcdb8b19 100644 --- a/source/graphics/ShaderManager.cpp +++ b/source/graphics/ShaderManager.cpp @@ -32,6 +32,7 @@ #include "ps/XML/Xeromyces.h" #include "ps/XML/XMLWriter.h" #include "ps/VideoMode.h" +#include "renderer/backend/gl/Device.h" #include "renderer/Renderer.h" #include "renderer/RenderingOptions.h" @@ -361,9 +362,6 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin #undef AT #undef EL - // Read some defines that influence how we pick techniques - const CRenderer::Caps& capabilities = g_Renderer.GetCapabilities(); - // Prepare the preprocessor for conditional tests CPreprocessorWrapper preprocessor; preprocessor.AddDefines(baseDefines); @@ -387,18 +385,15 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin if (Attrs.GetNamedItem(at_shaders) == "arb") { if (g_VideoMode.GetBackend() != CVideoMode::Backend::GL_ARB || - !capabilities.m_ARBProgram) + !g_VideoMode.GetBackendDevice()->GetCapabilities().ARBShaders) { isUsable = false; } } else if (Attrs.GetNamedItem(at_shaders) == "glsl") { - if (g_VideoMode.GetBackend() != CVideoMode::Backend::GL || - !(capabilities.m_FragmentShader && capabilities.m_VertexShader)) - { + if (g_VideoMode.GetBackend() != CVideoMode::Backend::GL) isUsable = false; - } } else if (!Attrs.GetNamedItem(at_context).empty()) { diff --git a/source/renderer/PostprocManager.cpp b/source/renderer/PostprocManager.cpp index 2462bd3332..80aad593a8 100644 --- a/source/renderer/PostprocManager.cpp +++ b/source/renderer/PostprocManager.cpp @@ -85,13 +85,12 @@ void CPostprocManager::Initialize() if (m_IsInitialized) return; - GLint maxSamples = 0; - glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); - const GLsizei possibleSampleCounts[] = {2, 4, 8, 16}; + const uint32_t maxSamples = g_VideoMode.GetBackendDevice()->GetCapabilities().maxSampleCount; + const uint32_t possibleSampleCounts[] = {2, 4, 8, 16}; std::copy_if( std::begin(possibleSampleCounts), std::end(possibleSampleCounts), std::back_inserter(m_AllowedSampleCounts), - [maxSamples](const GLsizei sampleCount) { return sampleCount <= maxSamples; } ); + [maxSamples](const uint32_t sampleCount) { return sampleCount <= maxSamples; } ); // The screen size starts out correct and then must be updated with Resize() m_Width = g_Renderer.GetWidth(); @@ -541,16 +540,10 @@ void CPostprocManager::UpdateAntiAliasingTechnique() } else if (m_AAName.size() > msaaPrefix.size() && m_AAName.substr(0, msaaPrefix.size()) == msaaPrefix) { -#if !CONFIG2_GLES // We don't want to enable MSAA in Atlas, because it uses wxWidgets and its canvas. if (g_AtlasGameLoop && g_AtlasGameLoop->running) return; - const bool is_msaa_supported = - ogl_HaveVersion(3, 3) && - ogl_HaveExtension("GL_ARB_multisample") && - ogl_HaveExtension("GL_ARB_texture_multisample") && - !m_AllowedSampleCounts.empty(); - if (!is_msaa_supported) + if (!g_VideoMode.GetBackendDevice()->GetCapabilities().multisampling && !m_AllowedSampleCounts.empty()) { LOGWARNING("MSAA is unsupported."); return; @@ -565,10 +558,6 @@ void CPostprocManager::UpdateAntiAliasingTechnique() } m_UsingMultisampleBuffer = true; CreateMultisampleBuffer(); -#else - #warning TODO: implement and test MSAA for GLES - LOGWARNING("MSAA is unsupported."); -#endif } } diff --git a/source/renderer/PostprocManager.h b/source/renderer/PostprocManager.h index 837ec3c617..a3c021f423 100644 --- a/source/renderer/PostprocManager.h +++ b/source/renderer/PostprocManager.h @@ -131,8 +131,8 @@ private: std::unique_ptr m_MultisampleFramebuffer; std::unique_ptr m_MultisampleColorTex, m_MultisampleDepthTex; - GLsizei m_MultisampleCount; - std::vector m_AllowedSampleCounts; + uint32_t m_MultisampleCount; + std::vector m_AllowedSampleCounts; // The current screen dimensions in pixels. int m_Width, m_Height; diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 50d4472340..11fa00c2c7 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -326,46 +326,6 @@ CRenderer::~CRenderer() m.reset(); } -void CRenderer::EnumCaps() -{ - // assume support for nothing - m_Caps.m_ARBProgram = false; - m_Caps.m_ARBProgramShadow = false; - m_Caps.m_VertexShader = false; - m_Caps.m_FragmentShader = false; - m_Caps.m_Shadows = false; - m_Caps.m_PrettyWater = false; - - // now start querying extensions - if (0 == ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", NULL)) - { - m_Caps.m_ARBProgram = true; - if (ogl_HaveExtension("GL_ARB_fragment_program_shadow")) - m_Caps.m_ARBProgramShadow = true; - } - - // GLSL shaders are in core since GL2.0. - if (ogl_HaveVersion(2, 0)) - m_Caps.m_VertexShader = m_Caps.m_FragmentShader = true; - -#if CONFIG2_GLES - m_Caps.m_Shadows = true; -#else - if (0 == ogl_HaveExtensions(0, "GL_ARB_shadow", "GL_ARB_depth_texture", NULL)) - { - if (ogl_max_tex_units >= 4) - m_Caps.m_Shadows = true; - } -#endif - -#if CONFIG2_GLES - m_Caps.m_PrettyWater = true; -#else - if (m_Caps.m_VertexShader && m_Caps.m_FragmentShader) - m_Caps.m_PrettyWater = true; -#endif -} - void CRenderer::ReloadShaders() { ENSURE(m->IsOpen); @@ -378,10 +338,6 @@ bool CRenderer::Open(int width, int height) { m->IsOpen = true; - // Must query card capabilities before creating renderers that depend - // on card capabilities. - EnumCaps(); - // Dimensions m_Width = width; m_Height = height; @@ -416,9 +372,12 @@ void CRenderer::SetRenderPath(RenderPath rp) } // Renderer has been opened, so validate the selected renderpath + const bool hasShadersSupport = + g_VideoMode.GetBackendDevice()->GetCapabilities().ARBShaders || + g_VideoMode.GetBackend() != CVideoMode::Backend::GL_ARB; if (rp == RenderPath::DEFAULT) { - if (m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && g_VideoMode.GetBackend() != CVideoMode::Backend::GL_ARB)) + if (hasShadersSupport) rp = RenderPath::SHADER; else rp = RenderPath::FIXED; @@ -426,7 +385,7 @@ void CRenderer::SetRenderPath(RenderPath rp) if (rp == RenderPath::SHADER) { - if (!(m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && g_VideoMode.GetBackend() != CVideoMode::Backend::GL_ARB))) + if (!hasShadersSupport) { LOGWARNING("Falling back to fixed function\n"); rp = RenderPath::FIXED; diff --git a/source/renderer/Renderer.h b/source/renderer/Renderer.h index ed3b239f37..ad98e3a2ef 100644 --- a/source/renderer/Renderer.h +++ b/source/renderer/Renderer.h @@ -67,16 +67,6 @@ public: size_t m_Particles; }; - struct Caps - { - bool m_ARBProgram; - bool m_ARBProgramShadow; - bool m_VertexShader; - bool m_FragmentShader; - bool m_Shadows; - bool m_PrettyWater; - }; - enum class ScreenShotType { NONE, @@ -132,13 +122,6 @@ public: CDebugRenderer& GetDebugRenderer(); - /** - * GetCapabilities: Return which OpenGL capabilities are available and enabled. - * - * @return capabilities structure - */ - const Caps& GetCapabilities() const { return m_Caps; } - /** * Performs a complete frame without presenting to force loading all needed * resources. It's used for the first frame on a game start. @@ -186,10 +169,6 @@ protected: SViewPort m_Viewport; - // card capabilities - Caps m_Caps; - // build card cap bits - void EnumCaps(); // per-frame renderer stats Stats m_Stats; diff --git a/source/renderer/RenderingOptions.cpp b/source/renderer/RenderingOptions.cpp index 35ce1411f3..4b9e8268a9 100644 --- a/source/renderer/RenderingOptions.cpp +++ b/source/renderer/RenderingOptions.cpp @@ -119,7 +119,6 @@ CRenderingOptions::CRenderingOptions() : m_ConfigHooks(new ConfigHooks()) m_WaterRefraction = false; m_WaterReflection = false; m_ShadowAlphaFix = false; - m_ARBProgramShadow = true; m_ShadowPCF = false; m_Particles = false; m_Silhouettes = false; diff --git a/source/renderer/RenderingOptions.h b/source/renderer/RenderingOptions.h index c560fb27e4..a113628f5d 100644 --- a/source/renderer/RenderingOptions.h +++ b/source/renderer/RenderingOptions.h @@ -111,7 +111,6 @@ OPTION_CUSTOM_SETTER(NAME, TYPE); OPTION_GETTER(NAME, TYPE); OPTION_DEF(NAME, TY OPTION(WaterReflection, bool); OPTION(ShadowAlphaFix, bool); - OPTION(ARBProgramShadow, bool); OPTION(Particles, bool); OPTION(GPUSkinning, bool); OPTION(Silhouettes, bool); diff --git a/source/renderer/SceneRenderer.cpp b/source/renderer/SceneRenderer.cpp index 8a95f17248..d389055717 100644 --- a/source/renderer/SceneRenderer.cpp +++ b/source/renderer/SceneRenderer.cpp @@ -215,11 +215,10 @@ void CSceneRenderer::ReloadShaders() { m->globalContext = CShaderDefines(); - const CRenderer::Caps& capabilities = g_Renderer.GetCapabilities(); - if (capabilities.m_Shadows && g_RenderingOptions.GetShadows()) + if (g_RenderingOptions.GetShadows()) { m->globalContext.Add(str_USE_SHADOW, str_1); - if (capabilities.m_ARBProgramShadow && g_RenderingOptions.GetARBProgramShadow()) + if (g_VideoMode.GetBackendDevice()->GetCapabilities().ARBShadersShadow) m->globalContext.Add(str_USE_FP_SHADOW, str_1); if (g_RenderingOptions.GetShadowPCF()) m->globalContext.Add(str_USE_SHADOW_PCF, str_1); @@ -351,9 +350,8 @@ void CSceneRenderer::RenderPatches( #endif // render all the patches, including blend pass - const CRenderer::Caps& capabilities = g_Renderer.GetCapabilities(); m->terrainRenderer.RenderTerrainShader(deviceCommandContext, context, cullGroup, - (capabilities.m_Shadows && g_RenderingOptions.GetShadows()) ? &m->shadow : 0); + g_RenderingOptions.GetShadows() ? &m->shadow : nullptr); #if !CONFIG2_GLES if (m_TerrainRenderMode == WIREFRAME) @@ -846,8 +844,7 @@ void CSceneRenderer::RenderSubmissions( m->particleRenderer.PrepareForRendering(context); - const CRenderer::Caps& capabilities = g_Renderer.GetCapabilities(); - if (capabilities.m_Shadows && g_RenderingOptions.GetShadows()) + if (g_RenderingOptions.GetShadows()) { RenderShadowMap(deviceCommandContext, context); } @@ -1042,9 +1039,8 @@ void CSceneRenderer::SetSceneCamera(const CCamera& viewCamera, const CCamera& cu { m_ViewCamera = viewCamera; m_CullCamera = cullCamera; - - const CRenderer::Caps& capabilities = g_Renderer.GetCapabilities(); - if (capabilities.m_Shadows && g_RenderingOptions.GetShadows()) + + if (g_RenderingOptions.GetShadows()) m->shadow.SetupFrame(m_CullCamera, m_LightEnv->GetSunDir()); } @@ -1179,8 +1175,7 @@ void CSceneRenderer::RenderScene( m->silhouetteRenderer.RenderSubmitCasters(*this); } - const CRenderer::Caps& capabilities = g_Renderer.GetCapabilities(); - if (capabilities.m_Shadows && g_RenderingOptions.GetShadows()) + if (g_RenderingOptions.GetShadows()) { for (int cascade = 0; cascade <= m->shadow.GetCascadeCount(); ++cascade) { diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp index 300b3f888e..0fa114a389 100644 --- a/source/renderer/WaterManager.cpp +++ b/source/renderer/WaterManager.cpp @@ -153,12 +153,10 @@ int WaterManager::LoadWaterTextures() m_WaterTexture[i] = texture; } - if (!g_Renderer.GetCapabilities().m_PrettyWater) - { - // Enable rendering, now that we've succeeded this far - m_RenderWater = true; + m_RenderWater = true; + + if (!WillRenderFancyWater()) return 0; - } #if CONFIG2_GLES #warning Fix WaterManager::LoadWaterTextures on GLES @@ -245,9 +243,6 @@ int WaterManager::LoadWaterTextures() g_RenderingOptions.SetWaterRefraction(false); UpdateQuality(); } - - // Enable rendering, now that we've succeeded this far - m_RenderWater = true; #endif return 0; } @@ -297,9 +292,6 @@ void WaterManager::UnloadWaterTextures() for (size_t i = 0; i < ARRAY_SIZE(m_WaterTexture); i++) m_WaterTexture[i].reset(); - if (!g_Renderer.GetCapabilities().m_PrettyWater) - return; - for (size_t i = 0; i < ARRAY_SIZE(m_NormalMap); i++) m_NormalMap[i].reset(); @@ -1019,7 +1011,7 @@ bool WaterManager::WillRenderFancyWater() const { return m_RenderWater && g_VideoMode.GetBackend() != CVideoMode::Backend::GL_ARB && - g_RenderingOptions.GetWaterEffects() && g_Renderer.GetCapabilities().m_PrettyWater; + g_RenderingOptions.GetWaterEffects(); } size_t WaterManager::GetCurrentTextureIndex(const double& period) const diff --git a/source/renderer/backend/gl/Device.cpp b/source/renderer/backend/gl/Device.cpp index 2adee4e976..4710cc4f6c 100644 --- a/source/renderer/backend/gl/Device.cpp +++ b/source/renderer/backend/gl/Device.cpp @@ -200,15 +200,36 @@ std::unique_ptr CDevice::Create(SDL_Window* window, const bool arb) device->m_Backbuffer = CFramebuffer::CreateBackbuffer(); + Capabilities& capabilities = device->m_Capabilities; + capabilities.ARBShaders = !ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", nullptr); + if (capabilities.ARBShaders) + capabilities.ARBShadersShadow = ogl_HaveExtension("GL_ARB_fragment_program_shadow"); #if CONFIG2_GLES // Some GLES implementations have GL_EXT_texture_compression_dxt1 // but that only supports DXT1 so we can't use it. - device->m_HasS3TC = ogl_HaveExtensions(0, "GL_EXT_texture_compression_s3tc", nullptr) == 0; + capabilities.S3TC = ogl_HaveExtensions(0, "GL_EXT_texture_compression_s3tc", nullptr) == 0; #else // Note: we don't bother checking for GL_S3_s3tc - it is incompatible // and irrelevant (was never widespread). - device->m_HasS3TC = ogl_HaveExtensions(0, "GL_ARB_texture_compression", "GL_EXT_texture_compression_s3tc", nullptr) == 0; + capabilities.S3TC = ogl_HaveExtensions(0, "GL_ARB_texture_compression", "GL_EXT_texture_compression_s3tc", nullptr) == 0; #endif + capabilities.multisampling = + ogl_HaveVersion(3, 3) && + ogl_HaveExtension("GL_ARB_multisample") && + ogl_HaveExtension("GL_ARB_texture_multisample"); + if (capabilities.multisampling) + { + GLint maxSamples = 1; + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + capabilities.maxSampleCount = maxSamples; + } + capabilities.anisotropicFiltering = ogl_HaveExtension("GL_EXT_texture_filter_anisotropic"); + if (capabilities.anisotropicFiltering) + { + GLfloat maxAnisotropy = 1.0f; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); + capabilities.maxAnisotropy = maxAnisotropy; + } return device; } @@ -683,7 +704,7 @@ bool CDevice::IsFormatSupported(const Format format) const case Format::BC1_RGBA: FALLTHROUGH; case Format::BC2: FALLTHROUGH; case Format::BC3: - supported = m_HasS3TC; + supported = m_Capabilities.S3TC; break; } return supported; diff --git a/source/renderer/backend/gl/Device.h b/source/renderer/backend/gl/Device.h index 13d9eda85c..07a8409c34 100644 --- a/source/renderer/backend/gl/Device.h +++ b/source/renderer/backend/gl/Device.h @@ -44,6 +44,17 @@ class CTexture; class CDevice { public: + struct Capabilities + { + bool S3TC; + bool ARBShaders; + bool ARBShadersShadow; + bool multisampling; + bool anisotropicFiltering; + uint32_t maxSampleCount; + float maxAnisotropy; + }; + ~CDevice(); /** @@ -76,6 +87,8 @@ public: bool IsFormatSupported(const Format format) const; + const Capabilities& GetCapabilities() const { return m_Capabilities; } + private: CDevice(); @@ -94,7 +107,7 @@ private: std::unique_ptr m_Backbuffer; - bool m_HasS3TC = false; + Capabilities m_Capabilities{}; }; } // namespace GL diff --git a/source/renderer/backend/gl/Texture.cpp b/source/renderer/backend/gl/Texture.cpp index 684bbcfb8e..402a18cb4c 100644 --- a/source/renderer/backend/gl/Texture.cpp +++ b/source/renderer/backend/gl/Texture.cpp @@ -138,9 +138,13 @@ std::unique_ptr CTexture::Create(CDevice* device, const char* name, glTexParameteri(target, GL_TEXTURE_LOD_BIAS, defaultSamplerDesc.mipLODBias); #endif // !CONFIG2_GLES - // TODO: ask anisotropy feature from Device. - if (type == Type::TEXTURE_2D && defaultSamplerDesc.anisotropyEnabled && ogl_HaveExtension("GL_EXT_texture_filter_anisotropic")) - glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, defaultSamplerDesc.maxAnisotropy); + if (type == Type::TEXTURE_2D && defaultSamplerDesc.anisotropyEnabled && + texture->m_Device->GetCapabilities().anisotropicFiltering) + { + const float maxAnisotropy = std::min( + defaultSamplerDesc.maxAnisotropy, texture->m_Device->GetCapabilities().maxAnisotropy); + glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); + } if (defaultSamplerDesc.addressModeU == Sampler::AddressMode::CLAMP_TO_BORDER || defaultSamplerDesc.addressModeV == Sampler::AddressMode::CLAMP_TO_BORDER ||