Celestia

Форк
0
/
glsupport.cpp 
146 строк · 4.5 Кб
1
#include "glsupport.h"
2
#include <algorithm>
3
#include <cstring>
4
#include <fmt/format.h>
5
#include <celutil/gettext.h>
6

7
namespace celestia::gl
8
{
9

10
#ifdef GL_ES
11
CELAPI bool OES_vertex_array_object        = false;
12
CELAPI bool OES_texture_border_clamp       = false;
13
CELAPI bool OES_geometry_shader            = false;
14
#else
15
CELAPI bool ARB_vertex_array_object        = false;
16
CELAPI bool ARB_framebuffer_object         = false;
17
#endif
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;
26

27
namespace
28
{
29

30
bool EnableGeomShaders = true;
31

32
inline bool has_extension(const char *name) noexcept
33
{
34
    return epoxy_has_gl_extension(name);
35
}
36

37
bool check_extension(util::array_view<std::string> list, const char *name) noexcept
38
{
39
    return std::find(list.begin(), list.end(), std::string(name)) == list.end()
40
           && has_extension(name);
41
}
42

43
void enable_workarounds()
44
{
45
    bool isMesa = false;
46
    bool isAMD = false;
47
    bool isNavi = false;
48

49
    const char* s;
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"
53
    if (s != nullptr)
54
        isMesa = std::strstr(s, "Mesa") != nullptr;
55

56
    s = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
57
    // "AMD" for radeonsi
58
    // "Mesa/X.org" for llvmpipe
59
    // "Collabora Ltd" for zink
60
    if (s != nullptr)
61
        isAMD = std::strcmp(s, "AMD") == 0;
62

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))""
68
    if (s != nullptr)
69
        isNavi = std::strstr(s, "navi") != nullptr;
70

71
    // https://gitlab.freedesktop.org/mesa/mesa/-/issues/9971
72
    if (isMesa && isAMD && isNavi)
73
        EnableGeomShaders = false;
74
}
75

76
} // namespace
77

78
bool init(util::array_view<std::string> ignore) noexcept
79
{
80
#ifdef GL_ES
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");
84
#else
85
    ARB_vertex_array_object        = check_extension(ignore, "GL_ARB_vertex_array_object");
86
    if (!has_extension("GL_ARB_framebuffer_object"))
87
    {
88
        fmt::print(_("Mandatory extension GL_ARB_framebuffer_object is missing!\n"));
89
        return false;
90
    }
91
#endif
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");
96

97
    GLint pointSizeRange[2];
98
    GLfloat lineWidthRange[2];
99
#ifdef GL_ES
100
    glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
101
    glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);
102
#else
103
    glGetIntegerv(GL_SMOOTH_POINT_SIZE_RANGE, pointSizeRange);
104
    glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, lineWidthRange);
105
#endif
106
    maxPointSize = pointSizeRange[1];
107
    maxLineWidth = lineWidthRange[1];
108

109
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
110

111
    if (gl::EXT_texture_filter_anisotropic)
112
        glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxTextureAnisotropy);
113

114
    enable_workarounds();
115

116
    return true;
117
}
118

119
bool checkVersion(int v) noexcept
120
{
121
    static int version = 0;
122
    if (version == 0)
123
        version = epoxy_gl_version(); // this function always queries GL
124
    return version >= v;
125
}
126

127
bool hasGeomShader() noexcept
128
{
129
#ifdef GL_ES
130
    return EnableGeomShaders && checkVersion(celestia::gl::GLES_3_2);
131
#else
132
    return EnableGeomShaders && checkVersion(celestia::gl::GL_3_2);
133
#endif
134
}
135

136
void enableGeomShaders() noexcept
137
{
138
    EnableGeomShaders = true;
139
}
140

141
void disableGeomShaders() noexcept
142
{
143
    EnableGeomShaders = false;
144
}
145

146
} // end namespace celestia::gl
147

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.