Skip to content

Commit

Permalink
Reworked GLSL extension and version detection.
Browse files Browse the repository at this point in the history
Also disabled forcibly declaring GLSL available if the GL version is >= 2.0,
 because the ARB extensions use different entry points than the core version.
 Silly mistake.
  • Loading branch information
icculus committed Dec 21, 2011
1 parent f84ede3 commit e8e49ca
Showing 1 changed file with 52 additions and 44 deletions.
96 changes: 52 additions & 44 deletions mojoshader_opengl.c
Expand Up @@ -162,6 +162,8 @@ struct MOJOSHADER_glContext
// GL stuff...
int opengl_major;
int opengl_minor;
int glsl_major;
int glsl_minor;
MOJOSHADER_glProgram *bound_program;
char profile[16];

Expand Down Expand Up @@ -878,26 +880,42 @@ static void parse_opengl_version_str(const char *verstr, int *maj, int *min)
} // parse_opengl_version_str


static inline void parse_opengl_version(const char *verstr)
#if SUPPORT_PROFILE_GLSL
static inline int glsl_version_atleast(const int major, const int minor)
{
parse_opengl_version_str(verstr, &ctx->opengl_major, &ctx->opengl_minor);
} // parse_opengl_version
return ( ((ctx->glsl_major << 16) | (ctx->glsl_minor & 0xFFFF)) >=
((major << 16) | (minor & 0xFFFF)) );
} // glsl_version_atleast
#endif

static void detect_glsl_version(void)
{
ctx->glsl_major = ctx->glsl_minor = 0;

#if SUPPORT_PROFILE_GLSL
static int glsl_version_atleast(int maj, int min)
{
int glslmin = 0;
int glslmaj = 0;
ctx->glGetError(); // flush any existing error state.
const GLenum enumval = GL_SHADING_LANGUAGE_VERSION_ARB;
const char *str = (const char *) ctx->glGetString(enumval);
if (ctx->glGetError() == GL_INVALID_ENUM)
return 0; // this is a basic, 1.0-compliant implementation.
parse_opengl_version_str(str, &glslmaj, &glslmin);
return ( (glslmaj > maj) || ((glslmaj == maj) && (glslmin >= min)) );
} // glsl_version_atleast
#if PLATFORM_MACOSX
// If running on Mac OS X <= 10.4, don't ever use GLSL, even if
// the system claims it is available.
if (!macosx_version_atleast(10, 5, 0))
return;
#endif

if ( 0/* !!! FIXME: (ctx->opengl_major >= 2)*/ ||
( ctx->have_GL_ARB_shader_objects &&
ctx->have_GL_ARB_vertex_shader &&
ctx->have_GL_ARB_fragment_shader &&
ctx->have_GL_ARB_shading_language_100 ) )
{
// the GL2.0 and ARB enum is the same value.
const GLenum enumval = GL_SHADING_LANGUAGE_VERSION_ARB;
ctx->glGetError(); // flush any existing error state.
const char *str = (const char *) ctx->glGetString(enumval);
if (ctx->glGetError() == GL_INVALID_ENUM)
str = NULL;
parse_opengl_version_str(str, &ctx->glsl_major, &ctx->glsl_minor);
} // if
#endif
} // detect_glsl_version


static void load_extensions(MOJOSHADER_glGetProcAddress lookup, void *d)
Expand Down Expand Up @@ -925,7 +943,8 @@ static void load_extensions(MOJOSHADER_glGetProcAddress lookup, void *d)
set_error("missing basic OpenGL entry points");
else
{
parse_opengl_version((const char *) ctx->glGetString(GL_VERSION));
const char *str = (const char *) ctx->glGetString(GL_VERSION);
parse_opengl_version_str(str, &ctx->opengl_major, &ctx->opengl_minor);
extlist = (const char *) ctx->glGetString(GL_EXTENSIONS);
} // else

Expand All @@ -937,10 +956,10 @@ static void load_extensions(MOJOSHADER_glGetProcAddress lookup, void *d)

VERIFY_EXT(GL_ARB_vertex_program, -1, -1);
VERIFY_EXT(GL_ARB_fragment_program, -1, -1);
VERIFY_EXT(GL_ARB_shader_objects, 2, 0);
VERIFY_EXT(GL_ARB_vertex_shader, 2, 0);
VERIFY_EXT(GL_ARB_fragment_shader, 2, 0);
VERIFY_EXT(GL_ARB_shading_language_100, 2, 0);
VERIFY_EXT(GL_ARB_shader_objects, -1, -1);
VERIFY_EXT(GL_ARB_vertex_shader, -1, -1);
VERIFY_EXT(GL_ARB_fragment_shader, -1, -1);
VERIFY_EXT(GL_ARB_shading_language_100, -1, -1);
VERIFY_EXT(GL_NV_vertex_program2_option, -1, -1);
VERIFY_EXT(GL_NV_fragment_program2, -1, -1);
VERIFY_EXT(GL_NV_vertex_program3, -1, -1);
Expand All @@ -949,27 +968,25 @@ static void load_extensions(MOJOSHADER_glGetProcAddress lookup, void *d)
VERIFY_EXT(GL_OES_vertex_half_float, -1, -1);

#undef VERIFY_EXT

detect_glsl_version();
} // load_extensions


static int valid_profile(const char *profile)
{
#if SUPPORT_PROFILE_GLSL
// If running on Mac OS X <= 10.4, don't ever pick GLSL, even if
// the system claims it is available.
#if PLATFORM_MACOSX
const int allow_glsl = macosx_version_atleast(10, 5, 0);
#else
const int allow_glsl = 1;
#endif
#endif

if (!ctx->have_base_opengl)
return 0;

#define MUST_HAVE(p, x) \
if (!ctx->have_##x) { set_error(#p " profile needs " #x); return 0; }

// we might actually _have_ maj.min, but forcibly disabled GLSL elsewhere.
#define MUST_HAVE_GLSL(p, maj, min) \
if (!glsl_version_atleast(maj, min)) { \
set_error(#p " profile needs missing GLSL support"); return 0; \
}

if (profile == NULL)
{
set_error("NULL profile");
Expand Down Expand Up @@ -1008,25 +1025,16 @@ static int valid_profile(const char *profile)
#endif

#if SUPPORT_PROFILE_GLSL120
else if ((allow_glsl) && (strcmp(profile, MOJOSHADER_PROFILE_GLSL120) == 0))
{
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shader_objects);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_vertex_shader);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_fragment_shader);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shading_language_100);
// if you got here, you have all the extensions.
if (!glsl_version_atleast(1, 20))
return 0;
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSL120) == 0)
{
MUST_HAVE_GLSL(MOJOSHADER_PROFILE_GLSL120, 1, 20);
} // else if
#endif

#if SUPPORT_PROFILE_GLSL
else if ((allow_glsl) && (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0))
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0)
{
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shader_objects);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_vertex_shader);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_fragment_shader);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shading_language_100);
MUST_HAVE_GLSL(MOJOSHADER_PROFILE_GLSL, 1, 10);
} // else if
#endif

Expand Down

0 comments on commit e8e49ca

Please sign in to comment.