5
#include <celutil/gettext.h>
11
CELAPI bool OES_vertex_array_object = false;
12
CELAPI bool OES_texture_border_clamp = false;
13
CELAPI bool OES_geometry_shader = false;
15
CELAPI bool ARB_vertex_array_object = false;
16
CELAPI bool ARB_framebuffer_object = false;
18
CELAPI bool ARB_shader_texture_lod = false;
19
CELAPI bool EXT_texture_compression_s3tc = false;
20
CELAPI bool EXT_texture_filter_anisotropic = false;
21
CELAPI bool MESA_pack_invert = false;
22
CELAPI GLint maxPointSize = 0;
23
CELAPI GLint maxTextureSize = 0;
24
CELAPI GLfloat maxLineWidth = 0.0f;
25
CELAPI GLint maxTextureAnisotropy = 0;
30
bool EnableGeomShaders = true;
32
inline bool has_extension(const char *name) noexcept
34
return epoxy_has_gl_extension(name);
37
bool check_extension(util::array_view<std::string> list, const char *name) noexcept
39
return std::find(list.begin(), list.end(), std::string(name)) == list.end()
40
&& has_extension(name);
43
void enable_workarounds()
50
s = reinterpret_cast<const char*>(glGetString(GL_VERSION));
51
// "4.6 (Compatibility Profile) Mesa 22.3.6"
52
// "OpenGL ES 3.2 Mesa 22.3.6"
54
isMesa = std::strstr(s, "Mesa") != nullptr;
56
s = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
58
// "Mesa/X.org" for llvmpipe
59
// "Collabora Ltd" for zink
61
isAMD = std::strcmp(s, "AMD") == 0;
63
s = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
64
// "AMD Radeon RX 6600 (navi23, LLVM 15.0.6, DRM 3.52, 6.4.0-0.deb12.2-amd64)"" for radeonsi
65
// "llvmpipe (LLVM 15.0.6, 256 bits)""
66
// "zink (llvmpipe (LLVM 15.0.6, 256 bits))""
67
// "zink (AMD Radeon RX 6600 (RADV NAVI23))""
69
isNavi = std::strstr(s, "navi") != nullptr;
71
// https://gitlab.freedesktop.org/mesa/mesa/-/issues/9971
72
if (isMesa && isAMD && isNavi)
73
EnableGeomShaders = false;
78
bool init(util::array_view<std::string> ignore) noexcept
81
OES_vertex_array_object = check_extension(ignore, "GL_OES_vertex_array_object");
82
OES_texture_border_clamp = check_extension(ignore, "GL_OES_texture_border_clamp") || check_extension(ignore, "GL_EXT_texture_border_clamp");
83
OES_geometry_shader = check_extension(ignore, "GL_OES_geometry_shader") || check_extension(ignore, "GL_EXT_geometry_shader");
85
ARB_vertex_array_object = check_extension(ignore, "GL_ARB_vertex_array_object");
86
if (!has_extension("GL_ARB_framebuffer_object"))
88
fmt::print(_("Mandatory extension GL_ARB_framebuffer_object is missing!\n"));
92
ARB_shader_texture_lod = check_extension(ignore, "GL_ARB_shader_texture_lod");
93
EXT_texture_compression_s3tc = check_extension(ignore, "GL_EXT_texture_compression_s3tc");
94
EXT_texture_filter_anisotropic = check_extension(ignore, "GL_EXT_texture_filter_anisotropic") || check_extension(ignore, "GL_ARB_texture_filter_anisotropic");
95
MESA_pack_invert = check_extension(ignore, "GL_MESA_pack_invert");
97
GLint pointSizeRange[2];
98
GLfloat lineWidthRange[2];
100
glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
101
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);
103
glGetIntegerv(GL_SMOOTH_POINT_SIZE_RANGE, pointSizeRange);
104
glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, lineWidthRange);
106
maxPointSize = pointSizeRange[1];
107
maxLineWidth = lineWidthRange[1];
109
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
111
if (gl::EXT_texture_filter_anisotropic)
112
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxTextureAnisotropy);
114
enable_workarounds();
119
bool checkVersion(int v) noexcept
121
static int version = 0;
123
version = epoxy_gl_version(); // this function always queries GL
127
bool hasGeomShader() noexcept
130
return EnableGeomShaders && checkVersion(celestia::gl::GLES_3_2);
132
return EnableGeomShaders && checkVersion(celestia::gl::GL_3_2);
136
void enableGeomShaders() noexcept
138
EnableGeomShaders = true;
141
void disableGeomShaders() noexcept
143
EnableGeomShaders = false;
146
} // end namespace celestia::gl