From b5fce8d0887721832b97ad28c65c6c287950fcc4 Mon Sep 17 00:00:00 2001 From: Edward Rudd Date: Fri, 21 Nov 2014 16:26:34 -0500 Subject: [PATCH 1/2] rework extension handling in GLEW so that they are put into a hash structure for faster lookup and also handle getting extensions in a core context. --- auto/Makefile | 3 + auto/bin/make_list.pl | 2 +- auto/src/glew_head.c | 159 +++++++++++++++++++++++++++++++++++---- auto/src/glew_head.h | 2 + auto/src/glew_init_gl.c | 34 +++++---- auto/src/glew_init_glx.c | 31 ++++---- auto/src/glew_init_wgl.c | 38 +++++----- 7 files changed, 201 insertions(+), 68 deletions(-) diff --git a/auto/Makefile b/auto/Makefile index e05ceef..d79ffad 100644 --- a/auto/Makefile +++ b/auto/Makefile @@ -140,6 +140,7 @@ $(I.DEST)/glew.h: $(EXT)/.dummy echo -e "#if defined(GLEW_MX) && defined(_WIN32)\nstruct GLEWContextStruct\n{\n#endif /* GLEW_MX */" >> $@ $(BIN)/make_struct_fun.pl GLEW_FUN_EXPORT $(GL_CORE_SPEC) $(GL_EXT_SPEC) >> $@ echo -e "\n#if defined(GLEW_MX) && !defined(_WIN32)\nstruct GLEWContextStruct\n{\n#endif /* GLEW_MX */\n" >> $@ + echo -e "\n#if defined(GLEW_MX)\nGLEWHashList *GLEW_GL_EXTENSIONS;\n#endif /* GLEW_MX */\n" >> $@ $(BIN)/make_struct_var.pl GLEW_VAR_EXPORT $(GL_CORE_SPEC) $(GL_EXT_SPEC) >> $@ echo -e "\n#ifdef GLEW_MX\n}; /* GLEWContextStruct */\n#endif /* GLEW_MX */\n" >> $@ perl -e "s/GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2;/GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1;\nGLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2;/" -pi $@ @@ -157,6 +158,7 @@ $(I.DEST)/wglew.h: $(EXT)/.dummy cat $(SRC)/wglew_mid.h >> $@ echo -e "\n#ifdef GLEW_MX\nstruct WGLEWContextStruct\n{\n#endif /* GLEW_MX */" >> $@ $(BIN)/make_struct_fun.pl WGLEW_FUN_EXPORT $(WGL_EXT_SPEC) >> $@ + echo -e "\n#if defined(GLEW_MX)\nGLEWHashList *GLEW_WGL_EXTENSIONS;\n#endif /* GLEW_MX */\n" >> $@ $(BIN)/make_struct_var.pl WGLEW_VAR_EXPORT $(WGL_EXT_SPEC) >> $@ echo -e "\n#ifdef GLEW_MX\n}; /* WGLEWContextStruct */\n#endif /* GLEW_MX */\n" >> $@ cat $(SRC)/wglew_tail.h >> $@ @@ -174,6 +176,7 @@ $(I.DEST)/glxew.h: $(EXT)/.dummy cat $(SRC)/glxew_mid.h >> $@ $(BIN)/make_struct_fun.pl GLXEW_FUN_EXPORT $(GLX_CORE_SPEC) $(GLX_EXT_SPEC) >> $@ echo -e "\n#if defined(GLEW_MX)\nstruct GLXEWContextStruct\n{\n#endif /* GLEW_MX */\n" >> $@ + echo -e "\n#if defined(GLEW_MX)\nGLEWHashList *GLEW_GLX_EXTENSIONS;\n#endif /* GLEW_MX */\n" >> $@ $(BIN)/make_struct_var.pl GLXEW_VAR_EXPORT $(GLX_CORE_SPEC) $(GLX_EXT_SPEC) >> $@ echo -e "\n#ifdef GLEW_MX\n}; /* GLXEWContextStruct */\n#endif /* GLEW_MX */\n" >> $@ perl -e "s/GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2;/GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_0;\nGLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_1;\nGLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2;/" -pi $@ diff --git a/auto/bin/make_list.pl b/auto/bin/make_list.pl index 75dc060..b76b434 100755 --- a/auto/bin/make_list.pl +++ b/auto/bin/make_list.pl @@ -46,7 +46,7 @@ if (@ARGV) if (length($extstring)) { - print " " . $extvar . " = _glewSearchExtension(\"$extstring\", extStart, extEnd);\n"; + print " " . $extvar . " = _glewHashListExists(ext_hashlist, (const GLubyte *)\"$extstring\");\n"; } if (keys %$functions) diff --git a/auto/src/glew_head.c b/auto/src/glew_head.c index e945bcd..72307c5 100644 --- a/auto/src/glew_head.c +++ b/auto/src/glew_head.c @@ -7,6 +7,7 @@ #endif #include /* For size_t */ +#include /* For free and calloc */ /* * Define glewGetContext and related helper macros. @@ -56,7 +57,6 @@ static void * (*regalGetProcAddress) (const GLchar *) = glGetProcAddressREGAL; #elif defined(__sgi) || defined (__sun) || defined(__HAIKU__) || defined(GLEW_APPLE_GLX) #include #include -#include void* dlGetProcAddress (const GLubyte* name) { @@ -77,7 +77,6 @@ void* dlGetProcAddress (const GLubyte* name) #endif /* __sgi || __sun || GLEW_APPLE_GLX */ #if defined(__APPLE__) -#include #include #include @@ -264,22 +263,150 @@ static GLboolean _glewStrSame3 (const GLubyte** a, GLuint* na, const GLubyte* b, return GL_FALSE; } -/* - * Search for name in the extensions string. Use of strstr() - * is not sufficient because extension names can be prefixes of - * other extension names. Could use strtok() but the constant - * string returned by glGetString might be in read-only memory. - */ -static GLboolean _glewSearchExtension (const char* name, const GLubyte *start, const GLubyte *end) +struct GLEWHashListStruct { - const GLubyte* p; - GLuint len = _glewStrLen((const GLubyte*)name); - p = start; - while (p < end) + const GLubyte **list; + GLuint size; +}; + +#if !defined(GLEW_MX) +GLEWHashList *GLEW_GL_EXTENSIONS; +#if defined(_WIN32) +GLEWHashList *GLEW_WGL_EXTENSIONS; +#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) +GLEWHashList *GLEW_GLX_EXTENSIONS; +#endif +#endif // !defined(GLEW_MX) + +/* A simple open addressing hashset for extensions */ +static GLuint hash_string(const GLubyte * key) +{ + GLuint hash = 0; + GLuint i = 0; + GLuint len = _glewStrCLen(key, ' '); + for (; i < len; ++i) { - GLuint n = _glewStrCLen(p, ' '); - if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; - p += n+1; + hash += key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return hash; +} + + +static void _glewHashListFree(GLEWHashList *list) +{ + if (list->list != NULL) { + free(list->list); + list->list = NULL; + list->size = 0; + } +} + + +static void _glewHashListAlloc(GLEWHashList *list, GLuint nelts) +{ + GLuint size = nelts * 3 / 2; + _glewHashListFree(list); + list->list = calloc(size, sizeof(const GLubyte*)); + list->size = size; +} + +static void _glewHashListInsert(GLEWHashList *list, const GLubyte *name) +{ + GLuint hash = hash_string(name); + + if (list->list == NULL) return; + + while(list->list[hash % list->size] != NULL) + hash++; + + list->list[hash % list->size] = name; +} + +static GLboolean _glewHashListExists(GLEWHashList *list, const GLubyte *name) +{ + GLuint hash; + GLuint len; + + if (list->list == NULL) return GL_FALSE; + + hash = hash_string((const GLubyte*)name); + len = _glewStrLen((const GLubyte*)name); + + /* + * As the hashset is bigger than the number of extensions + * this will eventually break. + */ + while(1) + { + GLuint index = hash % list->size; + GLuint n; + if (list->list[index] == NULL) + break; + + n = _glewStrCLen(list->list[index], ' '); + + if (len == n && _glewStrSame(list->list[index], (const GLubyte*)name, n)) return GL_TRUE; + ++hash; + } + return GL_FALSE; } + +static GLboolean _glewBuildGL3ExtensionList(GLEWHashList *list) +{ + GLint n, i; + glGetIntegerv(GL_NUM_EXTENSIONS, &n); + glGetStringi = (PFNGLGETSTRINGIPROC)glewGetProcAddress((const GLubyte*)"glGetStringi"); + + _glewHashListAlloc(list, n); + for (i = 0; i < n; ++i) + { + const GLubyte* extension = glGetStringi(GL_EXTENSIONS, i); + _glewHashListInsert(list, extension); + } + + return GL_TRUE; +} +/* + * initialize the extension list hash from a extension string list + */ +static GLboolean _glewBuildHashListFromString(const GLubyte* extensions, GLEWHashList *list) +{ + const GLubyte* extStart; + const GLubyte* extEnd; + const GLubyte* p; + GLuint extCount = 0; + + extStart = extensions; + if (extStart == 0) + extStart = (const GLubyte*)""; + extEnd = extStart + _glewStrLen(extStart); + + // first scan to determine number of extensions + p = extStart; + while (p < extEnd) + { + GLuint n = _glewStrCLen(p, ' '); + p += n + 1; + ++extCount; + } + + _glewHashListAlloc(list, extCount); + + // Second scan to populate the hash set + p = extStart; + while (p < extEnd) + { + GLuint n = _glewStrCLen(p, ' '); + _glewHashListInsert(list, p); + p += n+1; + } + + return GL_TRUE; +} \ No newline at end of file diff --git a/auto/src/glew_head.h b/auto/src/glew_head.h index c5592e1..bfe6046 100644 --- a/auto/src/glew_head.h +++ b/auto/src/glew_head.h @@ -188,6 +188,8 @@ typedef _W64 int ptrdiff_t; extern "C" { #endif +typedef struct GLEWHashListStruct GLEWHashList; + /* ----------------------------- GL_VERSION_1_1 ---------------------------- */ #ifndef GL_VERSION_1_1 diff --git a/auto/src/glew_init_gl.c b/auto/src/glew_init_gl.c index c438792..131a7b1 100644 --- a/auto/src/glew_init_gl.c +++ b/auto/src/glew_init_gl.c @@ -1,14 +1,11 @@ /* ------------------------------------------------------------------------- */ GLboolean GLEWAPIENTRY glewGetExtension (const char* name) -{ - const GLubyte* start; - const GLubyte* end; - start = (const GLubyte*)glGetString(GL_EXTENSIONS); - if (start == 0) - return GL_FALSE; - end = start + _glewStrLen(start); - return _glewSearchExtension(name, start, end); +{ +#if GLEW_MX + GLEWContext *ctx = glewGetContext(); +#endif + return _glewHashListExists(GLEW_GET_VAR(GLEW_GL_EXTENSIONS), (const GLubyte*)name); } /* ------------------------------------------------------------------------- */ @@ -21,8 +18,8 @@ GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) const GLubyte* s; GLuint dot; GLint major, minor; - const GLubyte* extStart; - const GLubyte* extEnd; + GLEWHashList *ext_hashlist; + /* query opengl version */ s = glGetString(GL_VERSION); dot = _glewStrCLen(s, '.'); @@ -65,9 +62,18 @@ GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) } /* query opengl extensions string */ - extStart = glGetString(GL_EXTENSIONS); - if (extStart == 0) - extStart = (const GLubyte*)""; - extEnd = extStart + _glewStrLen(extStart); + GLEW_GET_VAR(GLEW_GL_EXTENSIONS) = calloc(1, sizeof(GLEWHashList)); + + ext_hashlist = GLEW_GET_VAR(GLEW_GL_EXTENSIONS); + + if (major >= 3) + { + _glewBuildGL3ExtensionList(ext_hashlist); + } + else + { + const GLubyte* extensions = glGetString(GL_EXTENSIONS); + _glewBuildHashListFromString(extensions, ext_hashlist); + } /* initialize extensions */ diff --git a/auto/src/glew_init_glx.c b/auto/src/glew_init_glx.c index d160249..23375f8 100644 --- a/auto/src/glew_init_glx.c +++ b/auto/src/glew_init_glx.c @@ -1,22 +1,18 @@ /* ------------------------------------------------------------------------ */ GLboolean glxewGetExtension (const char* name) -{ - const GLubyte* start; - const GLubyte* end; - - if (glXGetCurrentDisplay == NULL) return GL_FALSE; - start = (const GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); - if (0 == start) return GL_FALSE; - end = start + _glewStrLen(start); - return _glewSearchExtension(name, start, end); +{ +#if GLEW_MX + GLXEWContext *ctx = glxewGetContext(); +#endif + return _glewHashListExists(GLXEW_GET_VAR(GLEW_GLX_EXTENSIONS), name); } GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST) { int major, minor; - const GLubyte* extStart; - const GLubyte* extEnd; + const GLubyte* extensions; + GLEWHashList *ext_hashlist; /* initialize core GLX 1.2 */ if (_glewInit_GLX_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT)) return GLEW_ERROR_GLX_VERSION_11_ONLY; /* initialize flags */ @@ -44,10 +40,11 @@ GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST) } } /* query GLX extension string */ - extStart = 0; - if (glXGetCurrentDisplay != NULL) - extStart = (const GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); - if (extStart == 0) - extStart = (const GLubyte *)""; - extEnd = extStart + _glewStrLen(extStart); + GLXEW_GET_VAR(GLEW_GLX_EXTENSIONS) = calloc(1, sizeof(GLEWHashList)); + + ext_hashlist = GLXEW_GET_VAR(GLEW_GLX_EXTENSIONS); + + extensions = (const GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); + _glewBuildHashListFromString(extensions, ext_hashlist); + /* initialize extensions */ diff --git a/auto/src/glew_init_wgl.c b/auto/src/glew_init_wgl.c index 7e76099..c43a5af 100644 --- a/auto/src/glew_init_wgl.c +++ b/auto/src/glew_init_wgl.c @@ -4,38 +4,36 @@ static PFNWGLGETEXTENSIONSSTRINGARBPROC _wglewGetExtensionsStringARB = NULL; static PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglewGetExtensionsStringEXT = NULL; GLboolean GLEWAPIENTRY wglewGetExtension (const char* name) -{ - const GLubyte* start; - const GLubyte* end; - if (_wglewGetExtensionsStringARB == NULL) - if (_wglewGetExtensionsStringEXT == NULL) - return GL_FALSE; - else - start = (const GLubyte*)_wglewGetExtensionsStringEXT(); - else - start = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); - if (start == 0) - return GL_FALSE; - end = start + _glewStrLen(start); - return _glewSearchExtension(name, start, end); +{ +#if GLEW_MX + WGLEWContext *ctx = wglewGetContext(); +#endif + return _glewHashListExists(WGLEW_GET_VAR(GLEW_WGL_EXTENSIONS), name); } GLenum GLEWAPIENTRY wglewContextInit (WGLEW_CONTEXT_ARG_DEF_LIST) { GLboolean crippled; - const GLubyte* extStart; - const GLubyte* extEnd; + const GLubyte* extensions; + GLEWHashList *ext_hashlist; + /* find wgl extension string query functions */ _wglewGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB"); _wglewGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT"); /* query wgl extension string */ if (_wglewGetExtensionsStringARB == NULL) if (_wglewGetExtensionsStringEXT == NULL) - extStart = (const GLubyte*)""; + extensions = (const GLubyte*)""; else - extStart = (const GLubyte*)_wglewGetExtensionsStringEXT(); + extensions = (const GLubyte*)_wglewGetExtensionsStringEXT(); else - extStart = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); - extEnd = extStart + _glewStrLen(extStart); + extensions = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); + + WGLEW_GET_VAR(GLEW_WGL_EXTENSIONS) = calloc(1, sizeof(GLEWHashList)); + + ext_hashlist = WGLEW_GET_VAR(GLEW_WGL_EXTENSIONS); + + _glewBuildHashListFromString(extensions, ext_hashlist); + /* initialize extensions */ crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL; From 0b4daf6e55c367127c697e7fc8d573189b397e23 Mon Sep 17 00:00:00 2001 From: Edward Rudd Date: Fri, 21 Nov 2014 18:12:06 -0500 Subject: [PATCH 2/2] adjust generation code so that the init functions can call other extension loader functions.. - example GL_VERSION_3_0 calling GL_ARB_vertex_array_objects --- auto/bin/make.pl | 21 +++++++++++++++++++-- auto/bin/make_def_fun.pl | 2 +- auto/bin/make_def_var.pl | 2 +- auto/bin/make_header.pl | 2 +- auto/bin/make_html.pl | 2 +- auto/bin/make_info.pl | 2 +- auto/bin/make_info_list.pl | 2 +- auto/bin/make_init.pl | 18 +++++++++++++++--- auto/bin/make_list.pl | 4 ++-- auto/bin/make_str.pl | 2 +- auto/bin/make_struct_fun.pl | 2 +- auto/bin/make_struct_var.pl | 2 +- auto/core/gl/GL_VERSION_3_0 | 4 ++++ auto/core/gl/GL_VERSION_3_1 | 1 + auto/core/gl/GL_VERSION_3_2 | 4 ++++ 15 files changed, 54 insertions(+), 16 deletions(-) diff --git a/auto/bin/make.pl b/auto/bin/make.pl index 1bd5d40..fe8f3b0 100755 --- a/auto/bin/make.pl +++ b/auto/bin/make.pl @@ -12,6 +12,7 @@ my %regex = ( function => qr/^(.+) ([a-z][a-z0-9_]*) \((.+)\)$/i, token => qr/^([A-Z][A-Z0-9_x]*)\s+((?:0x)?[0-9A-Fa-f]+|[A-Z][A-Z0-9_]*)$/, type => qr/^typedef\s+(.+)$/, + loadexts => qr/^LOAD (.*)$/, exact => qr/.*;$/, ); @@ -71,6 +72,7 @@ sub parse_ext($) my %tokens = (); my @types = (); my @exacts = (); + my @loadexts = (); my $extname = ""; # Full extension name GL_FOO_extension my $exturl = ""; # Info URL my $extstring = ""; # Relevant extension string @@ -104,7 +106,11 @@ sub parse_ext($) chomp; if (s/^\s+//) { - if (/$regex{exact}/) + if (/$regex{loadexts}/) + { + push @loadexts, $1; + } + elsif (/$regex{exact}/) { push @exacts, $_; } @@ -132,7 +138,7 @@ sub parse_ext($) close EXT; - return ($extname, $exturl, $extstring, \@types, \%tokens, \%functions, \@exacts); + return ($extname, $exturl, $extstring, \@types, \%tokens, \%functions, \@exacts, \@loadexts); } sub output_tokens($$) @@ -207,3 +213,14 @@ sub output_exacts($$) } } +sub output_loadexts($$) +{ + my ($tbl, $fnc) = @_; + if (scalar @{$tbl}) + { + local $, = "\n"; + print "\n"; + print map { &{$fnc}($_) } sort @{$tbl}; + print "\n"; + } +} diff --git a/auto/bin/make_def_fun.pl b/auto/bin/make_def_fun.pl index 40e67d5..048d715 100755 --- a/auto/bin/make_def_fun.pl +++ b/auto/bin/make_def_fun.pl @@ -29,7 +29,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); output_decls($functions, \&make_pfn_decl); } } diff --git a/auto/bin/make_def_var.pl b/auto/bin/make_def_var.pl index e484194..c153f99 100755 --- a/auto/bin/make_def_var.pl +++ b/auto/bin/make_def_var.pl @@ -23,7 +23,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); my $extvar = $extname; $extvar =~ s/GL(X*)_/GL$1EW_/; print "GLboolean " . prefix_varname($extvar) . " = GL_FALSE;\n"; diff --git a/auto/bin/make_header.pl b/auto/bin/make_header.pl index 934ef77..166b380 100755 --- a/auto/bin/make_header.pl +++ b/auto/bin/make_header.pl @@ -52,7 +52,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); make_separator($extname); print "#ifndef $extname\n#define $extname 1\n"; diff --git a/auto/bin/make_html.pl b/auto/bin/make_html.pl index ee58196..f000e66 100755 --- a/auto/bin/make_html.pl +++ b/auto/bin/make_html.pl @@ -26,7 +26,7 @@ if (@ARGV) print "\n"; foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); $cur_group = $extname; $cur_group =~ s/^(?:W?)GL(?:X?)_([A-Z0-9]+?)_.*$/$1/; $extname =~ s/^(?:W?)GL(?:X?)_(.*)$/$1/; diff --git a/auto/bin/make_info.pl b/auto/bin/make_info.pl index 5d0c7f6..80cbad2 100755 --- a/auto/bin/make_info.pl +++ b/auto/bin/make_info.pl @@ -32,7 +32,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); my $extvar = $extname; $extvar =~ s/GL(X*)_/GL$1EW_/; my $extpre = $extname; diff --git a/auto/bin/make_info_list.pl b/auto/bin/make_info_list.pl index a55106d..587ef3b 100755 --- a/auto/bin/make_info_list.pl +++ b/auto/bin/make_info_list.pl @@ -38,7 +38,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); print "#ifdef $extname\n"; print " _glewInfo_$extname();\n"; diff --git a/auto/bin/make_init.pl b/auto/bin/make_init.pl index 70abc98..53615a9 100755 --- a/auto/bin/make_init.pl +++ b/auto/bin/make_init.pl @@ -21,6 +21,15 @@ sub make_pfn_def_init($%) return " r = ((" . $_[0] . " = (PFN" . (uc $_[0]) . "PROC)glewGetProcAddress((const GLubyte*)\"" . $_[0] . "\")) == NULL) || r;"; } +sub make_loadexts_forward($%) +{ + return "static GLboolean _glewInit_" . $_[0] . "(GLEW_CONTEXT_ARG_DEF_INIT);"; +} +sub make_loadexts_call($%) +{ + return " r = _glewInit_" . $_[0] . "(GLEW_CONTEXT_ARG_VAR_INIT) || r;"; +} + #------------------------------------------------------------------------------- my @extlist = (); @@ -34,7 +43,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); #make_separator($extname); @@ -42,11 +51,14 @@ if (@ARGV) my $extvar = $extname; my $extvardef = $extname; $extvar =~ s/GL(X*)_/GL$1EW_/; - if (keys %$functions) + if (keys %$functions or keys @$loadexts) { - print "static GLboolean _glewInit_$extname (" . $type . + output_loadexts($loadexts, \&make_loadexts_forward); + + print "static GLboolean _glewInit_$extname (" . $type . "EW_CONTEXT_ARG_DEF_INIT)\n{\n GLboolean r = GL_FALSE;\n"; output_decls($functions, \&make_pfn_def_init); + output_loadexts($loadexts, \&make_loadexts_call); print "\n return r;\n}\n\n"; } #print "\nGLboolean " . prefix_varname($extvar) . " = GL_FALSE;\n\n"; diff --git a/auto/bin/make_list.pl b/auto/bin/make_list.pl index b76b434..802f506 100755 --- a/auto/bin/make_list.pl +++ b/auto/bin/make_list.pl @@ -32,7 +32,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); my $extvar = $extname; $extvar =~ s/GL(X*)_/GL$1EW_/; @@ -49,7 +49,7 @@ if (@ARGV) print " " . $extvar . " = _glewHashListExists(ext_hashlist, (const GLubyte *)\"$extstring\");\n"; } - if (keys %$functions) + if (keys %$functions or keys @$loadexts) { if ($extname =~ /WGL_.*/) { diff --git a/auto/bin/make_str.pl b/auto/bin/make_str.pl index ac4a366..1b63fa1 100755 --- a/auto/bin/make_str.pl +++ b/auto/bin/make_str.pl @@ -22,7 +22,7 @@ if (@ARGV) my $curexttype = ""; foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); my $exttype = $extname; $exttype =~ s/(W*?)GL(X*?)_(.*?_)(.*)/$3/; my $extrem = $extname; diff --git a/auto/bin/make_struct_fun.pl b/auto/bin/make_struct_fun.pl index c885960..56777dc 100755 --- a/auto/bin/make_struct_fun.pl +++ b/auto/bin/make_struct_fun.pl @@ -30,7 +30,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); output_decls($functions, \&make_pfn_decl); } } diff --git a/auto/bin/make_struct_var.pl b/auto/bin/make_struct_var.pl index c7ba2f4..0f9da0a 100755 --- a/auto/bin/make_struct_var.pl +++ b/auto/bin/make_struct_var.pl @@ -23,7 +23,7 @@ if (@ARGV) foreach my $ext (sort @extlist) { - my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts) = parse_ext($ext); + my ($extname, $exturl, $extstring, $types, $tokens, $functions, $exacts, $loadexts) = parse_ext($ext); my $extvar = $extname; $extvar =~ s/GL(X*)_/GL$1EW_/; print $export . " GLboolean " . prefix_varname($extvar) . ";\n"; diff --git a/auto/core/gl/GL_VERSION_3_0 b/auto/core/gl/GL_VERSION_3_0 index c87cdab..4b58c49 100644 --- a/auto/core/gl/GL_VERSION_3_0 +++ b/auto/core/gl/GL_VERSION_3_0 @@ -161,3 +161,7 @@ https://www.opengl.org/registry/doc/glspec30.20080923.pdf void glClearBufferfv (GLenum buffer, GLint drawBuffer, const GLfloat* value) void glClearBufferfi (GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil) const GLubyte* glGetStringi (GLenum name, GLuint index) + LOAD GL_ARB_framebuffer_object + LOAD GL_ARB_map_buffer_range + LOAD GL_ARB_uniform_buffer_object + LOAD GL_ARB_vertex_array_object diff --git a/auto/core/gl/GL_VERSION_3_1 b/auto/core/gl/GL_VERSION_3_1 index a829a77..dba0c6f 100644 --- a/auto/core/gl/GL_VERSION_3_1 +++ b/auto/core/gl/GL_VERSION_3_1 @@ -39,3 +39,4 @@ https://www.opengl.org/registry/doc/glspec31.20090528.pdf void glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount) void glTexBuffer (GLenum target, GLenum internalFormat, GLuint buffer) void glPrimitiveRestartIndex (GLuint buffer) + LOAD GL_ARB_copy_buffer diff --git a/auto/core/gl/GL_VERSION_3_2 b/auto/core/gl/GL_VERSION_3_2 index 85cea08..7603eab 100644 --- a/auto/core/gl/GL_VERSION_3_2 +++ b/auto/core/gl/GL_VERSION_3_2 @@ -26,3 +26,7 @@ https://www.opengl.org/registry/doc/glspec32.compatibility.20091207.pdf void glGetInteger64i_v (GLenum pname, GLuint index, GLint64 * data) void glGetBufferParameteri64v (GLenum target, GLenum value, GLint64 * data) void glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level) + LOAD GL_ARB_draw_elements_base_vertex + LOAD GL_ARB_provoking_vertex + LOAD GL_ARB_sync + LOAD GL_ARB_texture_multisample