add basic OpenGL extension handling

Currently only used for fence sync objects.
This commit is contained in:
derhass 2015-03-22 20:32:14 +01:00
parent 2cd73b6dfe
commit db267af6f2
4 changed files with 165 additions and 51 deletions

View file

@ -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")

View 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;
}

View 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();

View file

@ -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;
}