add basic OpenGL extension handling
Currently only used for fence sync objects.
This commit is contained in:
parent
2cd73b6dfe
commit
db267af6f2
|
@ -1615,6 +1615,11 @@ class DXXArchive(DXXCommon):
|
|||
'3d/clipper.cpp',
|
||||
'texmap/tmapflat.cpp'
|
||||
]
|
||||
])
|
||||
# for ogl
|
||||
objects_arch_ogl = DXXCommon.create_lazy_object_property([os.path.join(srcdir, f) for f in [
|
||||
'arch/ogl/ogl_extensions.cpp'
|
||||
]
|
||||
])
|
||||
objects_arch_sdlmixer = DXXCommon.create_lazy_object_property([os.path.join(srcdir, f) for f in [
|
||||
'arch/sdl/digi_mixer_music.cpp',
|
||||
|
@ -1996,6 +2001,7 @@ class DXXProgram(DXXCommon):
|
|||
objects.extend(self.objects_similar_arch_sdlmixer)
|
||||
if (self.user_settings.opengl == 1) or (self.user_settings.opengles == 1):
|
||||
env.Append(LIBS = self.platform_settings.ogllibs)
|
||||
objects.extend(static_archive_construction.objects_arch_ogl)
|
||||
objects.extend(self.objects_similar_arch_ogl)
|
||||
else:
|
||||
message(self, "building with Software Renderer")
|
||||
|
|
97
common/arch/ogl/ogl_extensions.cpp
Normal file
97
common/arch/ogl/ogl_extensions.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* This file is part of the DXX-Rebirth project <http://www.dxx-rebirth.com/>.
|
||||
* It is copyright by its individual contributors, as recorded in the
|
||||
* project's Git history. See COPYING.txt at the top level for license
|
||||
* terms and a link to the Git history.
|
||||
*/
|
||||
|
||||
/* OpenGL extensions:
|
||||
* We use global function pointer for any extension function we want to use.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "ogl_extensions.h"
|
||||
#include "console.h"
|
||||
|
||||
/* GL_ARB_sync */
|
||||
bool ogl_have_ARB_sync = false;
|
||||
PFNGLFENCESYNCPROC glFenceSyncFunc = NULL;
|
||||
PFNGLDELETESYNCPROC glDeleteSyncFunc = NULL;
|
||||
PFNGLCLIENTWAITSYNCPROC glClientWaitSyncFunc = NULL;
|
||||
|
||||
static void parse_version_str(const char *v, long *version)
|
||||
{
|
||||
version[0]=1;
|
||||
version[1]=0;
|
||||
|
||||
if (v) {
|
||||
char *ptr;
|
||||
version[0]=strtol(v,&ptr,10);
|
||||
if (ptr[0])
|
||||
version[1]=strtol(ptr+1,NULL,10);
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_ext_supported(const char *extensions, const char *name)
|
||||
{
|
||||
if (extensions && name) {
|
||||
const char *found=strstr(extensions, name);
|
||||
if (found) {
|
||||
// check that the name is actually complete */
|
||||
char c = found[strlen(name)];
|
||||
if (c == ' ' || c == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
enum support_mode {
|
||||
NO_SUPPORT=0,
|
||||
SUPPORT_CORE=1,
|
||||
SUPPORT_EXT=2
|
||||
};
|
||||
|
||||
static support_mode is_supported(const char *extensions, const long version[2], const char *name, long major, long minor)
|
||||
{
|
||||
if ( (version[0] > major) || (version[0] == major && version[1] >= minor))
|
||||
return SUPPORT_CORE;
|
||||
|
||||
if (is_ext_supported(extensions, name))
|
||||
return SUPPORT_EXT;
|
||||
return NO_SUPPORT;
|
||||
}
|
||||
|
||||
bool ogl_extensions_init()
|
||||
{
|
||||
const char *version_str = reinterpret_cast<const char *>(glGetString(GL_VERSION));
|
||||
long version[2];
|
||||
|
||||
if (!version_str) {
|
||||
con_printf(CON_URGENT, "no valid OpenGL context when querying GL extensions!");
|
||||
return false;
|
||||
}
|
||||
parse_version_str(version_str, version);
|
||||
const char *extension_str = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
|
||||
|
||||
/* GL_ARB_sync */
|
||||
if (is_supported(extension_str, version, "GL_ARB_sync", 3, 2)) {
|
||||
glFenceSyncFunc = (PFNGLFENCESYNCPROC)SDL_GL_GetProcAddress("glFenceSync");
|
||||
glDeleteSyncFunc = (PFNGLDELETESYNCPROC)SDL_GL_GetProcAddress("glDeleteSync");
|
||||
glClientWaitSyncFunc = (PFNGLCLIENTWAITSYNCPROC)SDL_GL_GetProcAddress("glClientWaitSync");
|
||||
|
||||
}
|
||||
if (glFenceSyncFunc && glDeleteSyncFunc && glClientWaitSyncFunc) {
|
||||
con_printf(CON_VERBOSE, "GL_ARB_sync available");
|
||||
ogl_have_ARB_sync=true;
|
||||
} else {
|
||||
con_printf(CON_VERBOSE, "GL_ARB_sync not available");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
57
common/include/ogl_extensions.h
Normal file
57
common/include/ogl_extensions.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* This file is part of the DXX-Rebirth project <http://www.dxx-rebirth.com/>.
|
||||
* It is copyright by its individual contributors, as recorded in the
|
||||
* project's Git history. See COPYING.txt at the top level for license
|
||||
* terms and a link to the Git history.
|
||||
*/
|
||||
|
||||
/* OpenGL extensions:
|
||||
* We use global function pointer for any extension function we want to use.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
/* global extension stuff (from glext.h)
|
||||
*/
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#ifndef APIENTRYP
|
||||
#define APIENTRYP APIENTRY *
|
||||
#endif
|
||||
#ifndef GLAPI
|
||||
#define GLAPI extern
|
||||
#endif
|
||||
|
||||
typedef int64_t GLint64;
|
||||
typedef uint64_t GLuint64;
|
||||
|
||||
/* GL_ARB_sync */
|
||||
typedef struct __GLsync *GLsync;
|
||||
|
||||
typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
|
||||
typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
|
||||
typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
|
||||
typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
|
||||
typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
|
||||
|
||||
#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
|
||||
#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
|
||||
#define GL_TIMEOUT_EXPIRED 0x911B
|
||||
|
||||
extern bool ogl_have_ARB_sync;
|
||||
extern PFNGLFENCESYNCPROC glFenceSyncFunc;
|
||||
extern PFNGLDELETESYNCPROC glDeleteSyncFunc;
|
||||
extern PFNGLCLIENTWAITSYNCPROC glClientWaitSyncFunc;
|
||||
|
||||
/* Global initialization:
|
||||
* will need an OpenGL context and intialize all function pointers.
|
||||
*/
|
||||
extern bool ogl_extensions_init();
|
||||
|
|
@ -73,47 +73,12 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#include "ogl_extensions.h"
|
||||
|
||||
#include "compiler-make_unique.h"
|
||||
|
||||
using std::max;
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* TODO MH: this is just borrowed from glext.h for the syncgl hack,
|
||||
* I was too lazu to implement a sane GL extension handling just
|
||||
* for this experimental hack
|
||||
*/
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#ifndef APIENTRYP
|
||||
#define APIENTRYP APIENTRY *
|
||||
#endif
|
||||
#ifndef GLAPI
|
||||
#define GLAPI extern
|
||||
#endif
|
||||
|
||||
typedef struct __GLsync *GLsync;
|
||||
typedef int64_t GLint64;
|
||||
typedef uint64_t GLuint64;
|
||||
|
||||
typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
|
||||
typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
|
||||
typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
|
||||
typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
|
||||
typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
|
||||
|
||||
#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
|
||||
#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
|
||||
#define GL_TIMEOUT_EXPIRED 0x911B
|
||||
|
||||
/* Extension pointers from GL_ARB_sync */
|
||||
|
||||
static PFNGLFENCESYNCPROC glFenceSyncFunc = NULL;
|
||||
static PFNGLDELETESYNCPROC glDeleteSyncFunc = NULL;
|
||||
static PFNGLCLIENTWAITSYNCPROC glClientWaitSyncFunc = NULL;
|
||||
|
||||
/* ************************************************************************ */
|
||||
|
||||
#ifdef OGLES
|
||||
int sdl_video_flags = 0;
|
||||
|
||||
|
@ -728,9 +693,9 @@ int gr_set_mode(u_int32_t mode)
|
|||
|
||||
ogl_init_window(w,h);//platform specific code
|
||||
ogl_get_verinfo();
|
||||
ogl_extensions_init();
|
||||
|
||||
bool need_ARB_sync;
|
||||
bool have_ARB_sync = false;
|
||||
|
||||
switch (GameArg.OglSyncMethod) {
|
||||
case SYNC_GL_FENCE:
|
||||
|
@ -741,20 +706,9 @@ int gr_set_mode(u_int32_t mode)
|
|||
default:
|
||||
need_ARB_sync = false;
|
||||
}
|
||||
if (need_ARB_sync) {
|
||||
/* syncgl: try to get GL_ARB_sync, check availability, and print some info */
|
||||
glFenceSyncFunc = (PFNGLFENCESYNCPROC)SDL_GL_GetProcAddress("glFenceSync");
|
||||
glDeleteSyncFunc = (PFNGLDELETESYNCPROC)SDL_GL_GetProcAddress("glDeleteSync");
|
||||
glClientWaitSyncFunc = (PFNGLCLIENTWAITSYNCPROC)SDL_GL_GetProcAddress("glClientWaitSync");
|
||||
|
||||
if (glFenceSyncFunc && glDeleteSyncFunc && glClientWaitSyncFunc) {
|
||||
con_printf(CON_VERBOSE, "GL_ARB_sync available");
|
||||
have_ARB_sync=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (GameArg.OglSyncMethod == SYNC_GL_AUTO) {
|
||||
if (!have_ARB_sync) {
|
||||
if (!ogl_have_ARB_sync) {
|
||||
con_printf(CON_NORMAL, "GL_ARB_sync not available, disabling sync");
|
||||
GameArg.OglSyncMethod = SYNC_GL_NONE;
|
||||
need_ARB_sync = false;
|
||||
|
@ -763,7 +717,7 @@ int gr_set_mode(u_int32_t mode)
|
|||
}
|
||||
}
|
||||
|
||||
if (need_ARB_sync && !have_ARB_sync) {
|
||||
if (need_ARB_sync && !ogl_have_ARB_sync) {
|
||||
con_printf(CON_URGENT, "GL_ARB_sync not available, using fallback");
|
||||
GameArg.OglSyncMethod=SYNC_GL_FINISH_BEFORE_SWAP;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue