Perform sanity checks on OpenGL extensions to make sure the required entry points are actually available.

This commit is contained in:
binary1248 2024-05-30 16:43:57 +02:00 committed by Chris Thrasher
parent 59414d5bfd
commit 01e4f3f783
2 changed files with 222 additions and 121 deletions

View File

@ -52,6 +52,38 @@
namespace sf::priv
{
////////////////////////////////////////////////////////////
void extensionSanityCheck()
{
static const auto check = [](int& flag, auto... entryPoints)
{
// If a required entry point is missing, flag the whole extension as unavailable
if (!(entryPoints && ...))
flag = 0;
};
#ifdef SFML_OPENGL_ES
check(GLEXT_multitexture_dependencies);
check(GLEXT_vertex_buffer_object_dependencies);
check(GLEXT_OES_blend_subtract_dependencies);
check(GLEXT_blend_func_separate_dependencies);
check(GLEXT_blend_equation_separate_dependencies);
check(GLEXT_framebuffer_object_dependencies);
check(GLEXT_EXT_blend_minmax_dependencies);
#else
check(GLEXT_blend_minmax_dependencies);
check(GLEXT_multitexture_dependencies);
check(GLEXT_blend_func_separate_dependencies);
check(GLEXT_vertex_buffer_object_dependencies);
check(GLEXT_shader_objects_dependencies);
check(GLEXT_blend_equation_separate_dependencies);
check(GLEXT_framebuffer_object_dependencies);
check(GLEXT_framebuffer_blit_dependencies);
check(GLEXT_framebuffer_multisample_dependencies);
check(GLEXT_copy_buffer_dependencies);
#endif
}
////////////////////////////////////////////////////////////
void ensureExtensionsInit()
{
@ -65,6 +97,13 @@ void ensureExtensionsInit()
#else
gladLoadGL(Context::getFunction);
#endif
// Some GL implementations don't fully follow extension specifications
// and advertise support for extensions although not providing the
// entry points specified for the corresponding extension.
// In order to protect ourselves from such implementations, we perform
// a sanity check to ensure an extension is _really_ supported, even
// from an entry point perspective.
extensionSanityCheck();
// Retrieve the context version number
int majorVersion = 0;

View File

@ -41,28 +41,43 @@
// All functionality beyond that is optional
// and has to be checked for prior to use
namespace sf::priv
{
// Stand-ins for desktop OpenGL feature-check flags
// NOLINTBEGIN(readability-identifier-naming)
inline int SF_GL_OES_multitexture = 1;
inline int SF_GL_OES_vertex_buffer_object = 1;
// NOLINTEND(readability-identifier-naming)
} // namespace sf::priv
// Core since 1.0
#define GLEXT_multitexture true
#define GLEXT_texture_edge_clamp true
#define GLEXT_EXT_texture_edge_clamp true
#define GLEXT_multitexture ::sf::priv::SF_GL_OES_multitexture
#define GLEXT_glClientActiveTexture glClientActiveTexture
#define GLEXT_glActiveTexture glActiveTexture
#define GLEXT_GL_TEXTURE0 GL_TEXTURE0
#define GLEXT_multitexture_dependencies ::sf::priv::SF_GL_OES_multitexture, glClientActiveTexture, glActiveTexture
// Core since 1.0
#define GLEXT_texture_edge_clamp true
#define GLEXT_GL_CLAMP GL_CLAMP_TO_EDGE
#define GLEXT_GL_CLAMP_TO_EDGE GL_CLAMP_TO_EDGE
// Core since 1.1
// 1.1 does not support GL_STREAM_DRAW so we just define it to GL_DYNAMIC_DRAW
#define GLEXT_vertex_buffer_object true
#define GLEXT_GL_ARRAY_BUFFER GL_ARRAY_BUFFER
#define GLEXT_GL_DYNAMIC_DRAW GL_DYNAMIC_DRAW
#define GLEXT_GL_STATIC_DRAW GL_STATIC_DRAW
#define GLEXT_GL_STREAM_DRAW GL_DYNAMIC_DRAW
#define GLEXT_vertex_buffer_object ::sf::priv::SF_GL_OES_vertex_buffer_object
#define GLEXT_glBindBuffer glBindBuffer
#define GLEXT_glBufferData glBufferData
#define GLEXT_glBufferSubData glBufferSubData
#define GLEXT_glDeleteBuffers glDeleteBuffers
#define GLEXT_glGenBuffers glGenBuffers
#define GLEXT_GL_ARRAY_BUFFER GL_ARRAY_BUFFER
#define GLEXT_GL_DYNAMIC_DRAW GL_DYNAMIC_DRAW
#define GLEXT_GL_STATIC_DRAW GL_STATIC_DRAW
#define GLEXT_GL_STREAM_DRAW GL_DYNAMIC_DRAW
#define GLEXT_vertex_buffer_object_dependencies \
::sf::priv::SF_GL_OES_vertex_buffer_object, glBindBuffer, glBufferData, glBufferSubData, glDeleteBuffers, glGenBuffers
// The following extensions are listed chronologically
// Extension macro first, followed by tokens then
@ -71,22 +86,30 @@
// The following extensions are required.
// Core since 2.0 - OES_blend_subtract
// glBlendEquation is provided by both OES_blend_subtract and EXT_blend_minmax
// If, for whatever reason, one entry point couldn't be loaded, try the other
#define GLEXT_blend_subtract SF_GLAD_GL_OES_blend_subtract
#define GLEXT_glBlendEquation glBlendEquationOES
#define GLEXT_glBlendEquation (glBlendEquationOES ? glBlendEquationOES : glBlendEquationEXT)
#define GLEXT_GL_FUNC_ADD GL_FUNC_ADD_OES
#define GLEXT_GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_OES
#define GLEXT_GL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT_OES
#define GLEXT_OES_blend_subtract_dependencies SF_GLAD_GL_OES_blend_subtract, glBlendEquationOES
// The following extensions are optional.
// Core since 2.0 - OES_blend_func_separate
#define GLEXT_blend_func_separate SF_GLAD_GL_OES_blend_func_separate
#define GLEXT_glBlendFuncSeparate glBlendFuncSeparateOES
#define GLEXT_blend_func_separate_dependencies SF_GLAD_GL_OES_blend_func_separate, glBlendFuncSeparateOES
// Core since 2.0 - OES_blend_equation_separate
#define GLEXT_blend_equation_separate SF_GLAD_GL_OES_blend_equation_separate
#define GLEXT_glBlendEquationSeparate glBlendEquationSeparateOES
#define GLEXT_blend_equation_separate_dependencies SF_GLAD_GL_OES_blend_equation_separate, glBlendEquationSeparateOES
// Core since 2.0 - OES_texture_npot
#define GLEXT_texture_non_power_of_two false
@ -114,6 +137,11 @@
#define GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_OES
#define GLEXT_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_OES
#define GLEXT_framebuffer_object_dependencies \
SF_GLAD_GL_OES_framebuffer_object, glBindRenderbufferOES, glDeleteRenderbuffersOES, glGenRenderbuffersOES, \
glRenderbufferStorageOES, glBindFramebufferOES, glDeleteFramebuffersOES, glGenFramebuffersOES, \
glCheckFramebufferStatusOES, glFramebufferTexture2DOES, glFramebufferRenderbufferOES, glGenerateMipmapOES
// Core since 3.0
#define GLEXT_packed_depth_stencil SF_GLAD_GL_OES_packed_depth_stencil
#define GLEXT_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
@ -146,9 +174,12 @@
// Core since 3.0 - EXT_blend_minmax
#define GLEXT_blend_minmax SF_GLAD_GL_EXT_blend_minmax
// glBlendEquation is provided by OES_blend_subtract, see above
#define GLEXT_GL_MIN GL_MIN_EXT
#define GLEXT_GL_MAX GL_MAX_EXT
#define GLEXT_EXT_blend_minmax_dependencies SF_GLAD_GL_EXT_blend_minmax, glBlendEquationEXT
#else
// SFML requires at a bare minimum OpenGL 1.1 capability
@ -176,6 +207,8 @@
#define GLEXT_GL_MIN GL_MIN_EXT
#define GLEXT_GL_MAX GL_MAX_EXT
#define GLEXT_blend_minmax_dependencies SF_GLAD_GL_EXT_blend_minmax, glBlendEquationEXT
// Core since 1.2 - EXT_blend_subtract
#define GLEXT_blend_subtract SF_GLAD_GL_EXT_blend_subtract
#define GLEXT_GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_EXT
@ -187,10 +220,14 @@
#define GLEXT_glActiveTexture glActiveTextureARB
#define GLEXT_GL_TEXTURE0 GL_TEXTURE0_ARB
#define GLEXT_multitexture_dependencies SF_GLAD_GL_ARB_multitexture, glClientActiveTextureARB, glActiveTextureARB
// Core since 1.4 - EXT_blend_func_separate
#define GLEXT_blend_func_separate SF_GLAD_GL_EXT_blend_func_separate
#define GLEXT_glBlendFuncSeparate glBlendFuncSeparateEXT
#define GLEXT_blend_func_separate_dependencies SF_GLAD_GL_EXT_blend_func_separate, glBlendFuncSeparateEXT
// Core since 1.5 - ARB_vertex_buffer_object
#define GLEXT_vertex_buffer_object SF_GLAD_GL_ARB_vertex_buffer_object
#define GLEXT_GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
@ -207,6 +244,10 @@
#define GLEXT_glMapBuffer glMapBufferARB
#define GLEXT_glUnmapBuffer glUnmapBufferARB
#define GLEXT_vertex_buffer_object_dependencies \
SF_GLAD_GL_ARB_vertex_buffer_object, glBindBufferARB, glBufferDataARB, glBufferSubDataARB, glDeleteBuffersARB, \
glGenBuffersARB, glMapBufferARB, glUnmapBufferARB
// Core since 2.0 - ARB_shading_language_100
#define GLEXT_shading_language_100 SF_GLAD_GL_ARB_shading_language_100
@ -244,6 +285,13 @@
#define GLEXT_GL_OBJECT_LINK_STATUS GL_OBJECT_LINK_STATUS_ARB
#define GLEXT_GLhandle GLhandleARB
#define GLEXT_shader_objects_dependencies \
SF_GLAD_GL_ARB_shader_objects, glDeleteObjectARB, glGetHandleARB, glCreateShaderObjectARB, glShaderSourceARB, \
glCompileShaderARB, glCreateProgramObjectARB, glAttachObjectARB, glLinkProgramARB, glUseProgramObjectARB, \
glUniform1fARB, glUniform2fARB, glUniform3fARB, glUniform4fARB, glUniform1iARB, glUniform2iARB, glUniform3iARB, \
glUniform4iARB, glUniform1fvARB, glUniform2fvARB, glUniform2ivARB, glUniform3fvARB, glUniform4fvARB, \
glUniformMatrix3fvARB, glUniformMatrix4fvARB, glGetObjectParameterivARB, glGetInfoLogARB, glGetUniformLocationARB
// Core since 2.0 - ARB_vertex_shader
#define GLEXT_vertex_shader SF_GLAD_GL_ARB_vertex_shader
#define GLEXT_GL_VERTEX_SHADER GL_VERTEX_SHADER_ARB
@ -260,6 +308,8 @@
#define GLEXT_blend_equation_separate SF_GLAD_GL_EXT_blend_equation_separate
#define GLEXT_glBlendEquationSeparate glBlendEquationSeparateEXT
#define GLEXT_blend_equation_separate_dependencies SF_GLAD_GL_EXT_blend_equation_separate, glBlendEquationSeparateEXT
// Core since 2.1 - EXT_texture_sRGB
#define GLEXT_texture_sRGB SF_GLAD_GL_EXT_texture_sRGB
#define GLEXT_GL_SRGB8_ALPHA8 GL_SRGB8_ALPHA8_EXT
@ -287,6 +337,11 @@
#define GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_EXT
#define GLEXT_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
#define GLEXT_framebuffer_object_dependencies \
SF_GLAD_GL_EXT_framebuffer_object, glBindRenderbufferEXT, glDeleteRenderbuffersEXT, glGenRenderbuffersEXT, \
glRenderbufferStorageEXT, glBindFramebufferEXT, glDeleteFramebuffersEXT, glGenFramebuffersEXT, \
glCheckFramebufferStatusEXT, glFramebufferTexture2DEXT, glFramebufferRenderbufferEXT, glGenerateMipmapEXT
// Core since 3.0 - EXT_packed_depth_stencil
#define GLEXT_packed_depth_stencil SF_GLAD_GL_EXT_packed_depth_stencil
#define GLEXT_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
@ -299,17 +354,24 @@
#define GLEXT_GL_DRAW_FRAMEBUFFER_BINDING GL_DRAW_FRAMEBUFFER_BINDING_EXT
#define GLEXT_GL_READ_FRAMEBUFFER_BINDING GL_READ_FRAMEBUFFER_BINDING_EXT
#define GLEXT_framebuffer_blit_dependencies SF_GLAD_GL_EXT_framebuffer_blit, glBlitFramebufferEXT
// Core since 3.0 - EXT_framebuffer_multisample
#define GLEXT_framebuffer_multisample SF_GLAD_GL_EXT_framebuffer_multisample
#define GLEXT_glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT
#define GLEXT_GL_MAX_SAMPLES GL_MAX_SAMPLES_EXT
#define GLEXT_framebuffer_multisample_dependencies \
SF_GLAD_GL_EXT_framebuffer_multisample, glRenderbufferStorageMultisampleEXT
// Core since 3.1 - ARB_copy_buffer
#define GLEXT_copy_buffer SF_GLAD_GL_ARB_copy_buffer
#define GLEXT_GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER
#define GLEXT_GL_COPY_WRITE_BUFFER GL_COPY_WRITE_BUFFER
#define GLEXT_glCopyBufferSubData glCopyBufferSubData
#define GLEXT_copy_buffer_dependencies SF_GLAD_GL_ARB_copy_buffer, glCopyBufferSubData
// Core since 3.2 - ARB_geometry_shader4
#define GLEXT_geometry_shader4 SF_GLAD_GL_ARB_geometry_shader4
#define GLEXT_GL_GEOMETRY_SHADER GL_GEOMETRY_SHADER_ARB