Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
3
 * It is copyright by its individual contributors, as recorded in the
4
 * project's Git history.  See COPYING.txt at the top level for license
5
 * terms and a link to the Git history.
6
 */
7
 
8
/* OpenGL extensions:
9
 * We use global function pointer for any extension function we want to use.
10
 */
11
 
12
#include <string.h>
13
#include <SDL.h>
14
 
15
#include "ogl_extensions.h"
16
#include "console.h"
17
 
18
#include "dxxsconf.h"
19
#include "dsx-ns.h"
20
#include <array>
21
 
22
namespace dcx {
23
 
24
/* GL_ARB_sync */
25
bool ogl_have_ARB_sync = false;
26
PFNGLFENCESYNCPROC glFenceSyncFunc = NULL;
27
PFNGLDELETESYNCPROC glDeleteSyncFunc = NULL;
28
PFNGLCLIENTWAITSYNCPROC glClientWaitSyncFunc = NULL;
29
 
30
/* GL_EXT_texture_filter_anisotropic */
31
GLfloat ogl_maxanisotropy = 0.0f;
32
 
33
static std::array<long, 2> parse_version_str(const char *v)
34
{
35
        std::array<long, 2> version;
36
        version[0]=1;
37
        version[1]=0;
38
        if (v) {
39
                char *ptr;
40
                if (v[0] == 'O') {
41
                        // OpenGL ES uses the format "OpenGL ES-xx major.minor"
42
                        const auto &prefix_gles = "OpenGL ES-";
43
                        if (!strncmp(v, prefix_gles, sizeof(prefix_gles)-1)) {
44
                                // skip the prefix
45
                                v += sizeof(prefix_gles)-1;
46
                                // skip the profile marker
47
                                if (v[0] && v[1]) {
48
                                        v +=2;
49
                                }
50
                        }
51
                }
52
                version[0]=strtol(v,&ptr,10);
53
                if (ptr[0])
54
                        version[1]=strtol(ptr+1,NULL,10);
55
        }
56
        return version;
57
}
58
 
59
static bool is_ext_supported(const char *extensions, const char *name)
60
{
61
        if (extensions && name) {
62
                const char *found=strstr(extensions, name);
63
                if (found) {
64
                        // check that the name is actually complete */
65
                        char c = found[strlen(name)];
66
                        if (c == ' ' || c == 0)
67
                                return true;
68
                }
69
        }
70
        return false;
71
}
72
 
73
enum support_mode {
74
        NO_SUPPORT=0,
75
        SUPPORT_CORE=1,
76
        SUPPORT_EXT=2
77
};
78
 
79
static support_mode is_supported(const char *extensions, const std::array<long, 2> &version, const char *name, long major, long minor, long major_es, long minor_es)
80
{
81
#if DXX_USE_OGLES
82
        static_cast<void>(major);
83
        static_cast<void>(minor);
84
        if ( (major_es > 0) && ((version[0] > major_es) || (version[0] == major_es && version[1] >= minor_es)) )
85
                return SUPPORT_CORE;
86
#else
87
        static_cast<void>(major_es);
88
        static_cast<void>(minor_es);
89
        if ( (major > 0) && ((version[0] > major) || (version[0] == major && version[1] >= minor)) )
90
                return SUPPORT_CORE;
91
#endif
92
 
93
        if (is_ext_supported(extensions, name))
94
                return SUPPORT_EXT;
95
        return NO_SUPPORT;
96
}
97
 
98
void ogl_extensions_init()
99
{
100
        const auto version_str = reinterpret_cast<const char *>(glGetString(GL_VERSION));
101
        if (!version_str) {
102
                con_puts(CON_URGENT, "DXX-Rebirth: no valid OpenGL context when querying GL extensions!");
103
                return;
104
        }
105
        const auto version = parse_version_str(version_str);
106
        const auto extension_str = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
107
 
108
#if DXX_USE_OGLES
109
#define DXX_OGL_STRING  " ES"
110
#else
111
#define DXX_OGL_STRING  ""
112
#endif
113
        con_printf(CON_VERBOSE, "DXX-Rebirth: OpenGL" DXX_OGL_STRING ": version %ld.%ld (%s)", version[0], version[1], version_str);
114
#undef DXX_OGL_STRING
115
 
116
        /* GL_EXT_texture_filter_anisotropic */
117
        if (is_supported(extension_str, version, "GL_EXT_texture_filter_anisotropic", -1, -1, -1, -1)) {
118
                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &ogl_maxanisotropy);
119
                con_printf(CON_VERBOSE, "DXX-Rebirth: OpenGL: GL_EXT_texture_filter_anisotropic available, max anisotropy: %f", ogl_maxanisotropy);
120
        } else {
121
                ogl_maxanisotropy=0.0f;
122
                con_puts(CON_VERBOSE, "DXX-Rebirth: OpenGL: GL_EXT_texture_filter_anisotropic not available");
123
        }
124
 
125
        /* GL_ARB_sync */
126
        if (is_supported(extension_str, version, "GL_ARB_sync", 3, 2, 3, 0)) {
127
                glFenceSyncFunc = reinterpret_cast<PFNGLFENCESYNCPROC>(SDL_GL_GetProcAddress("glFenceSync"));
128
                glDeleteSyncFunc = reinterpret_cast<PFNGLDELETESYNCPROC>(SDL_GL_GetProcAddress("glDeleteSync"));
129
                glClientWaitSyncFunc = reinterpret_cast<PFNGLCLIENTWAITSYNCPROC>(SDL_GL_GetProcAddress("glClientWaitSync"));
130
 
131
        }
132
        const char *s;
133
        if (glFenceSyncFunc && glDeleteSyncFunc && glClientWaitSyncFunc) {
134
                ogl_have_ARB_sync=true;
135
                s = "DXX-Rebirth: OpenGL: GL_ARB_sync available";
136
        } else {
137
                s = "DXX-Rebirth: OpenGL: GL_ARB_sync not available";
138
        }
139
        con_puts(CON_VERBOSE, s);
140
}
141
 
142
}