1
0
forked from 0ad/0ad

Moves backend capabilities to CDevice.

This was SVN commit r26366.
This commit is contained in:
Vladislav Belov 2022-02-13 21:46:03 +00:00
parent 4de89c3db1
commit aaf378f041
12 changed files with 70 additions and 125 deletions

View File

@ -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())
{

View File

@ -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
}
}

View File

@ -131,8 +131,8 @@ private:
std::unique_ptr<Renderer::Backend::GL::CFramebuffer> m_MultisampleFramebuffer;
std::unique_ptr<Renderer::Backend::GL::CTexture>
m_MultisampleColorTex, m_MultisampleDepthTex;
GLsizei m_MultisampleCount;
std::vector<GLsizei> m_AllowedSampleCounts;
uint32_t m_MultisampleCount;
std::vector<uint32_t> m_AllowedSampleCounts;
// The current screen dimensions in pixels.
int m_Width, m_Height;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -200,15 +200,36 @@ std::unique_ptr<CDevice> 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;

View File

@ -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<CFramebuffer> m_Backbuffer;
bool m_HasS3TC = false;
Capabilities m_Capabilities{};
};
} // namespace GL

View File

@ -138,9 +138,13 @@ std::unique_ptr<CTexture> 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 ||