Uses GLAD to check extensions

If GLAD failed to load an extension then we can't use it. Because all
its functions are nullptr.
This commit is contained in:
Vladislav Belov 2026-07-08 20:06:18 +02:00
parent 2c44b5301c
commit 4ca83fa071
No known key found for this signature in database
GPG key ID: 353545E45DB9CCB3

View file

@ -110,7 +110,7 @@ std::string GetDriverInformationImpl()
std::vector<std::string> GetExtensionsImpl() std::vector<std::string> GetExtensionsImpl()
{ {
std::vector<std::string> extensions; std::vector<std::string> extensions;
const std::string exts = ogl_ExtensionString(); const std::string exts{reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))};
boost::split(extensions, exts, boost::algorithm::is_space(), boost::token_compress_on); boost::split(extensions, exts, boost::algorithm::is_space(), boost::token_compress_on);
std::sort(extensions.begin(), extensions.end()); std::sort(extensions.begin(), extensions.end());
return extensions; return extensions;
@ -293,14 +293,21 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
ogl_Init(SDL_GL_GetProcAddress); ogl_Init(SDL_GL_GetProcAddress);
device->m_Name = GetNameImpl();
device->m_Version = GetVersionImpl();
device->m_DriverInformation = GetDriverInformationImpl();
device->m_Extensions = GetExtensionsImpl();
LOGMESSAGE("GL device name: %s", device->m_Name.c_str());
LOGMESSAGE("GL version: %s", device->m_Version.c_str());
#if CONFIG2_GLES #if CONFIG2_GLES
const bool minimumRequiredGLVersionSupported{ogl_HaveVersion(2, 1)}; const bool minimumRequiredGLVersionSupported{ogl_HaveVersion(2, 1)};
#else #else
const bool minimumRequiredGLVersionSupported{ogl_HaveVersion(2, 0)}; const bool minimumRequiredGLVersionSupported{ogl_HaveVersion(2, 0)};
#endif #endif
if (!minimumRequiredGLVersionSupported if (!minimumRequiredGLVersionSupported || !GLAD_GL_EXT_framebuffer_object)
|| (!ogl_HaveExtension("GL_EXT_framebuffer_object") && !ogl_HaveExtension("GL_ARB_framebuffer_object")))
{ {
// It doesn't make sense to continue working here, because we're not // It doesn't make sense to continue working here, because we're not
// able to display anything. // able to display anything.
@ -312,11 +319,6 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
); );
} }
device->m_Name = GetNameImpl();
device->m_Version = GetVersionImpl();
device->m_DriverInformation = GetDriverInformationImpl();
device->m_Extensions = GetExtensionsImpl();
// Set packing parameters for uploading and downloading data. // Set packing parameters for uploading and downloading data.
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -325,9 +327,9 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
if (g_ConfigDB.Get("renderer.backend.gl.enableframebufferinvalidating", false)) if (g_ConfigDB.Get("renderer.backend.gl.enableframebufferinvalidating", false))
{ {
#if CONFIG2_GLES #if CONFIG2_GLES
device->m_UseFramebufferInvalidating = ogl_HaveExtension("GL_EXT_discard_framebuffer"); device->m_UseFramebufferInvalidating = GLAD_GL_EXT_discard_framebuffer;
#else #else
device->m_UseFramebufferInvalidating = ogl_HaveExtension("GL_ARB_invalidate_subdata"); device->m_UseFramebufferInvalidating = GLAD_GL_ARB_invalidate_subdata;
#endif #endif
} }
@ -336,19 +338,18 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
#if CONFIG2_GLES #if CONFIG2_GLES
// Some GLES implementations have GL_EXT_texture_compression_dxt1 // Some GLES implementations have GL_EXT_texture_compression_dxt1
// but that only supports DXT1 so we can't use it. // but that only supports DXT1 so we can't use it.
capabilities.S3TC = ogl_HaveExtension("GL_EXT_texture_compression_s3tc"); capabilities.S3TC = GLAD_GL_EXT_texture_compression_s3tc;
#else #else
// Note: we don't bother checking for GL_S3_s3tc - it is incompatible // Note: we don't bother checking for GL_S3_s3tc - it is incompatible
// and irrelevant (was never widespread). // and irrelevant (was never widespread).
capabilities.S3TC = ogl_HaveExtension("GL_EXT_texture_compression_s3tc"); capabilities.S3TC = GLAD_GL_EXT_texture_compression_s3tc;
#endif #endif
#if CONFIG2_GLES #if CONFIG2_GLES
capabilities.multisampling = false; capabilities.multisampling = false;
capabilities.maxSampleCount = 1; capabilities.maxSampleCount = 1;
#else #else
capabilities.multisampling = capabilities.multisampling =
ogl_HaveVersion(3, 3) && ogl_HaveVersion(3, 3) && GLAD_GL_ARB_texture_multisample;
ogl_HaveExtension("GL_ARB_texture_multisample");
if (capabilities.multisampling) if (capabilities.multisampling)
{ {
// By default GL_MULTISAMPLE should be enabled, but enable it for buggy drivers. // By default GL_MULTISAMPLE should be enabled, but enable it for buggy drivers.
@ -358,7 +359,7 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
capabilities.maxSampleCount = maxSamples; capabilities.maxSampleCount = maxSamples;
} }
#endif #endif
capabilities.anisotropicFiltering = ogl_HaveExtension("GL_EXT_texture_filter_anisotropic"); capabilities.anisotropicFiltering = GLAD_GL_EXT_texture_filter_anisotropic;
if (capabilities.anisotropicFiltering) if (capabilities.anisotropicFiltering)
{ {
GLfloat maxAnisotropy = 1.0f; GLfloat maxAnisotropy = 1.0f;
@ -370,11 +371,10 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
capabilities.maxTextureSize = maxTextureSize; capabilities.maxTextureSize = maxTextureSize;
#if CONFIG2_GLES #if CONFIG2_GLES
const bool isDebugInCore = ogl_HaveVersion(3, 2); const bool hasDebug = GLAD_GL_KHR_debug;
#else #else
const bool isDebugInCore = ogl_HaveVersion(4, 3); const bool hasDebug = GLAD_GL_KHR_debug;
#endif #endif
const bool hasDebug = isDebugInCore || ogl_HaveExtension("GL_KHR_debug");
if (hasDebug) if (hasDebug)
{ {
#ifdef NDEBUG #ifdef NDEBUG
@ -412,10 +412,9 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
#else #else
capabilities.instancing = capabilities.instancing =
(ogl_HaveVersion(3, 3) || (ogl_HaveVersion(3, 3) ||
(ogl_HaveExtension("GL_ARB_draw_instanced") && (GLAD_GL_ARB_draw_instanced && GLAD_GL_ARB_instanced_arrays));
ogl_HaveExtension("GL_ARB_instanced_arrays")));
GLint maxStorageBufferSize{0}; GLint maxStorageBufferSize{0};
if (ogl_HaveExtension("GL_ARB_shader_storage_buffer_object")) if (GLAD_GL_ARB_shader_storage_buffer_object)
glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxStorageBufferSize); glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxStorageBufferSize);
// Storage buffers might not work correctly on some Mesa drivers or might have // Storage buffers might not work correctly on some Mesa drivers or might have
// decreased performance. We need to investigate it further but for now we // decreased performance. We need to investigate it further but for now we
@ -427,11 +426,11 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
capabilities.computeShaders && maxStorageBufferSize > 0 capabilities.computeShaders && maxStorageBufferSize > 0
&& static_cast<size_t>(maxStorageBufferSize) >= 128 * MiB && static_cast<size_t>(maxStorageBufferSize) >= 128 * MiB
&& !disableStorageForMesa && !disableStorageForMesa
&& ogl_HaveExtension("GL_ARB_uniform_buffer_object") && GLAD_GL_ARB_uniform_buffer_object
&& ogl_HaveExtension("GL_ARB_shader_storage_buffer_object") && GLAD_GL_ARB_shader_storage_buffer_object
&& ogl_HaveExtension("GL_ARB_half_float_vertex") && GLAD_GL_ARB_half_float_vertex
&& ogl_HaveExtension("GL_ARB_program_interface_query"); && GLAD_GL_ARB_program_interface_query;
capabilities.timestamps = ogl_HaveExtension("GL_ARB_timer_query"); capabilities.timestamps = GLAD_GL_ARB_timer_query;
if (capabilities.timestamps) if (capabilities.timestamps)
capabilities.timestampMultiplier = 1.0 / 1e9; capabilities.timestampMultiplier = 1.0 / 1e9;
#endif #endif
@ -549,51 +548,48 @@ void CDevice::Report(const Script::Request& rq, JS::HandleValue settings)
// Core OpenGL 3.0: // Core OpenGL 3.0:
if (ogl_HaveExtension("GL_EXT_gpu_shader4")) if (GLAD_GL_EXT_gpu_shader4)
{ {
INTEGER(MIN_PROGRAM_TEXEL_OFFSET_EXT); // no _EXT version of these in glext.h INTEGER(MIN_PROGRAM_TEXEL_OFFSET_EXT); // no _EXT version of these in glext.h
INTEGER(MAX_PROGRAM_TEXEL_OFFSET_EXT); INTEGER(MAX_PROGRAM_TEXEL_OFFSET_EXT);
} }
if (ogl_HaveExtension("GL_EXT_framebuffer_object")) INTEGER(MAX_COLOR_ATTACHMENTS_EXT);
{ INTEGER(MAX_RENDERBUFFER_SIZE_EXT);
INTEGER(MAX_COLOR_ATTACHMENTS_EXT);
INTEGER(MAX_RENDERBUFFER_SIZE_EXT);
}
if (ogl_HaveExtension("GL_EXT_framebuffer_multisample")) if (GLAD_GL_EXT_framebuffer_multisample)
{ {
INTEGER(MAX_SAMPLES_EXT); INTEGER(MAX_SAMPLES_EXT);
} }
if (ogl_HaveExtension("GL_EXT_texture_array")) if (GLAD_GL_EXT_texture_array)
{ {
INTEGER(MAX_ARRAY_TEXTURE_LAYERS_EXT); INTEGER(MAX_ARRAY_TEXTURE_LAYERS_EXT);
} }
// Other interesting extensions: // Other interesting extensions:
if (ogl_HaveExtension("GL_EXT_timer_query") || ogl_HaveExtension("GL_ARB_timer_query")) if (GLAD_GL_ARB_timer_query)
{ {
QUERY_COUNTER_BITS(TIME_ELAPSED); QUERY_COUNTER_BITS(TIME_ELAPSED);
} }
if (ogl_HaveExtension("GL_ARB_timer_query")) if (GLAD_GL_ARB_timer_query)
{ {
QUERY_COUNTER_BITS(TIMESTAMP); QUERY_COUNTER_BITS(TIMESTAMP);
} }
if (ogl_HaveExtension("GL_EXT_texture_filter_anisotropic")) if (GLAD_GL_EXT_texture_filter_anisotropic)
{ {
FLOAT(MAX_TEXTURE_MAX_ANISOTROPY_EXT); FLOAT(MAX_TEXTURE_MAX_ANISOTROPY_EXT);
} }
if (ogl_HaveExtension("GL_ARB_texture_rectangle")) if (GLAD_GL_ARB_texture_rectangle)
{ {
INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB); INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB);
} }
if (ogl_HaveExtension("GL_ARB_geometry_shader4")) if (GLAD_GL_ARB_geometry_shader4)
{ {
INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB); INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB);
INTEGER(MAX_GEOMETRY_OUTPUT_VERTICES_ARB); INTEGER(MAX_GEOMETRY_OUTPUT_VERTICES_ARB);
@ -603,13 +599,13 @@ void CDevice::Report(const Script::Request& rq, JS::HandleValue settings)
INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB); INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB);
} }
if (ogl_HaveExtension("GL_ARB_uniform_buffer_object")) if (GLAD_GL_ARB_uniform_buffer_object)
{ {
INTEGER(MAX_UNIFORM_BLOCK_SIZE); INTEGER(MAX_UNIFORM_BLOCK_SIZE);
INTEGER(MAX_UNIFORM_BUFFER_BINDINGS); INTEGER(MAX_UNIFORM_BUFFER_BINDINGS);
} }
if (ogl_HaveExtension("GL_ARB_shader_storage_buffer_object")) if (GLAD_GL_ARB_shader_storage_buffer_object)
{ {
INTEGER(MAX_SHADER_STORAGE_BLOCK_SIZE); INTEGER(MAX_SHADER_STORAGE_BLOCK_SIZE);
INTEGER(MAX_SHADER_STORAGE_BUFFER_BINDINGS); INTEGER(MAX_SHADER_STORAGE_BUFFER_BINDINGS);