X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fglapi%2Fglapi.c;h=47a1f164582fb77de2d52f435eb43e93b28814aa;hb=711555d1e347f0e64e6b1b2d0e402e0ee72ace07;hp=f529c356220da364ddeb553215e44af2e9e07107;hpb=e9fa7908d16a0dcf28a1357c2c1760980d58c8ec;p=mesa.git diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c index f529c356220..47a1f164582 100644 --- a/src/mesa/glapi/glapi.c +++ b/src/mesa/glapi/glapi.c @@ -1,10 +1,8 @@ -/* $Id: glapi.c,v 1.27 2000/01/27 00:26:03 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.3 + * Version: 6.3 * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -32,70 +30,252 @@ * There are functions to set/get the current dispatch table for the * current thread and to manage registration/dispatch of dynamically * added extension functions. + * + * It's intended that this file and the other glapi*.[ch] files are + * flexible enough to be reused in several places: XFree86, DRI- + * based libGL.so, and perhaps the SGI SI. + * + * NOTE: There are no dependencies on Mesa in this code. + * + * Versions (API changes): + * 2000/02/23 - original version for Mesa 3.3 and XFree86 4.0 + * 2001/01/16 - added dispatch override feature for Mesa 3.5 + * 2002/06/28 - added _glapi_set_warning_func(), Mesa 4.1. + * 2002/10/01 - _glapi_get_proc_address() will now generate new entrypoints + * itself (using offset ~0). _glapi_add_entrypoint() can be + * called afterward and it'll fill in the correct dispatch + * offset. This allows DRI libGL to avoid probing for DRI + * drivers! No changes to the public glapi interface. */ -#ifdef HAVE_CONFIG_H -#include "conf.h" -#endif -#include -#include /* to get NULL */ -#include +#include "glheader.h" #include "glapi.h" -#include "glapinoop.h" #include "glapioffsets.h" #include "glapitable.h" +#include "glthread.h" +/***** BEGIN NO-OP DISPATCH *****/ +static GLboolean WarnFlag = GL_FALSE; +static _glapi_warning_func warning_func; -/* This is used when thread safety is disabled */ -struct _glapi_table *_glapi_Dispatch = &__glapi_noop_table; +static void init_glapi_relocs(void); -/* Used when thread safety disabled */ -void *_glapi_CurrentContext = NULL; +static _glapi_proc generate_entrypoint(GLuint functionOffset); +static void fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset); +/* + * Enable/disable printing of warning messages. + */ +PUBLIC void +_glapi_noop_enable_warnings(GLboolean enable) +{ + WarnFlag = enable; +} -#if defined(THREADS) +/* + * Register a callback function for reporting errors. + */ +PUBLIC void +_glapi_set_warning_func( _glapi_warning_func func ) +{ + warning_func = func; +} -#include "glthread.h" +static GLboolean +warn(void) +{ + if ((WarnFlag || getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) + && warning_func) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} -/* Flag to indicate whether thread-safe dispatch is enabled */ -static GLboolean ThreadSafe = GL_FALSE; -static _glthread_TSD DispatchTSD; +#define KEYWORD1 static +#define KEYWORD2 GLAPIENTRY +#define NAME(func) NoOp##func + +#define F NULL + +#define DISPATCH(func, args, msg) \ + if (warn()) { \ + warning_func(NULL, "GL User Error: called without context: %s", #func); \ + } + +#define RETURN_DISPATCH(func, args, msg) \ + if (warn()) { \ + warning_func(NULL, "GL User Error: called without context: %s", #func); \ + } \ + return 0 -static void dispatch_thread_init() +#define DISPATCH_TABLE_NAME __glapi_noop_table +#define UNUSED_TABLE_NAME __unused_noop_functions + +#define TABLE_ENTRY(name) (_glapi_proc) NoOp##name + +static GLint NoOpUnused(void) { - _glthread_InitTSD(&DispatchTSD); + if (warn()) { + warning_func(NULL, "GL User Error: calling extension function without a current context\n"); + } + return 0; } +#include "glapitemp.h" + +/***** END NO-OP DISPATCH *****/ + + + +/***** BEGIN THREAD-SAFE DISPATCH *****/ + +#if defined(THREADS) + +#if defined(GLX_USE_TLS) + +__thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))) + = (struct _glapi_table *) __glapi_noop_table; + +static __thread struct _glapi_table * _glapi_tls_RealDispatch + __attribute__((tls_model("initial-exec"))) + = (struct _glapi_table *) __glapi_noop_table; -static _glthread_TSD ContextTSD; +__thread void * _glapi_tls_Context + __attribute__((tls_model("initial-exec"))); -static void context_thread_init() +/** + * Legacy per-thread dispatch pointer. This is only needed to support + * non-TLS DRI drivers. + */ + +_glthread_TSD _gl_DispatchTSD; + +#else + +/** + * \name Multi-threaded control support variables + * + * If thread-safety is supported, there are two potential mechanisms that can + * be used. The old-style mechanism would set \c _glapi_Dispatch to a special + * thread-safe dispatch table. These dispatch routines would call + * \c _glapi_get_dispatch to get the actual dispatch pointer. In this + * setup \c _glapi_Dispatch could never be \c NULL. This dual layered + * dispatch setup performed great for single-threaded apps, but didn't + * perform well for multithreaded apps. + * + * In the new mechansim, there are two variables. The first is + * \c _glapi_DispatchTSD. In the single-threaded case, this variable points + * to the dispatch table. In the multi-threaded case, this variable is + * \c NULL, and thread-specific variable \c _gl_DispatchTSD points to the + * actual dispatch table. \c _glapi_DispatchTSD is used to signal to the + * static dispatch functions to call \c _glapi_get_dispatch to get the real + * dispatch table. + * + * There is a race condition in setting \c _glapi_DispatchTSD to \c NULL. + * It is possible for the original thread to be setting it at the same instant + * a new thread, perhaps running on a different processor, is clearing it. + * Because of that, \c ThreadSafe, which can only ever be changed to + * \c GL_TRUE, is used to determine whether or not the application is + * multithreaded. + */ +/*@{*/ +static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */ +_glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */ +static _glthread_TSD RealDispatchTSD; /**< only when using override */ +static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ +/*@}*/ + +#endif /* defined(GLX_USE_TLS) */ + +#define DISPATCH_TABLE_NAME __glapi_threadsafe_table +#define UNUSED_TABLE_NAME __unused_threadsafe_functions + +#define TABLE_ENTRY(name) (_glapi_proc) gl##name + +static GLint glUnused(void) { - _glthread_InitTSD(&ContextTSD); + return 0; } +#include "glapitemp.h" + #endif +/***** END THREAD-SAFE DISPATCH *****/ -static GLuint MaxDispatchOffset = sizeof(struct _glapi_table) / sizeof(void *) - 1; -static GLboolean GetSizeCalled = GL_FALSE; +#if defined(GLX_USE_TLS) +/** + * \name Old dispatch pointers + * + * Very old DRI based drivers assume that \c _glapi_Dispatch will never be + * \c NULL. Becuase of that, special "thread-safe" dispatch functions are + * needed here. Slightly more recent drivers detect the multi-threaded case + * by \c _glapi_DispatchTSD being \c NULL. + * + * \deprecated + * + * \warning + * \c _glapi_RealDispatch does not exist in TLS builds. I don't think it was + * ever used outside libGL.so, so this should be safe. + */ +/*@{*/ +PUBLIC const struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table; +PUBLIC const struct _glapi_table *_glapi_DispatchTSD = NULL; +PUBLIC const void *_glapi_Context = NULL; +/*@}*/ +#else -/* +PUBLIC struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_noop_table; +#if defined( THREADS ) +PUBLIC struct _glapi_table *_glapi_DispatchTSD = (struct _glapi_table *) __glapi_noop_table; +#endif +PUBLIC struct _glapi_table *_glapi_RealDispatch = (struct _glapi_table *) __glapi_noop_table; + +/* Used when thread safety disabled */ +PUBLIC void *_glapi_Context = NULL; + +#endif /* defined(GLX_USE_TLS) */ + + +static GLboolean DispatchOverride = GL_FALSE; + + + +/** + * strdup() is actually not a standard ANSI C or POSIX routine. + * Irix will not define it if ANSI mode is in effect. + */ +static char * +str_dup(const char *str) +{ + char *copy; + copy = (char*) malloc(strlen(str) + 1); + if (!copy) + return NULL; + strcpy(copy, str); + return copy; +} + + + +/** * We should call this periodically from a function such as glXMakeCurrent - * in order to test if multiple threads are being used. When we detect - * that situation we should then call _glapi_enable_thread_safety() + * in order to test if multiple threads are being used. */ -void +PUBLIC void _glapi_check_multithread(void) { -#if defined(THREADS) +#if defined(THREADS) && !defined(GLX_USE_TLS) if (!ThreadSafe) { static unsigned long knownID; static GLboolean firstCall = GL_TRUE; @@ -105,71 +285,80 @@ _glapi_check_multithread(void) } else if (knownID != _glthread_GetID()) { ThreadSafe = GL_TRUE; + _glapi_set_dispatch(NULL); } } - if (ThreadSafe) { + else if (!_glapi_get_dispatch()) { /* make sure that this thread's dispatch pointer isn't null */ - if (!_glapi_get_dispatch()) { - _glapi_set_dispatch(NULL); - } + _glapi_set_dispatch(NULL); } #endif } -/* +/** * Set the current context pointer for this thread. * The context pointer is an opaque type which should be cast to * void from the real context pointer type. */ -void -_glapi_set_current_context(void *context) +PUBLIC void +_glapi_set_context(void *context) { -#if defined(THREADS) - _glthread_SetTSD(&ContextTSD, context, context_thread_init); - if (ThreadSafe) - _glapi_CurrentContext = NULL; - else - _glapi_CurrentContext = context; + (void) __unused_noop_functions; /* silence a warning */ +#if defined(GLX_USE_TLS) + _glapi_tls_Context = context; +#elif defined(THREADS) + (void) __unused_threadsafe_functions; /* silence a warning */ + _glthread_SetTSD(&ContextTSD, context); + _glapi_Context = (ThreadSafe) ? NULL : context; #else - _glapi_CurrentContext = context; + _glapi_Context = context; #endif } -/* +/** * Get the current context pointer for this thread. * The context pointer is an opaque type which should be cast from * void to the real context pointer type. */ -void * -_glapi_get_current_context(void) +PUBLIC void * +_glapi_get_context(void) { -#if defined(THREADS) +#if defined(GLX_USE_TLS) + return _glapi_tls_Context; +#elif defined(THREADS) if (ThreadSafe) { return _glthread_GetTSD(&ContextTSD); } else { - return _glapi_CurrentContext; + return _glapi_Context; } #else - return _glapi_CurrentContext; + return _glapi_Context; #endif } -/* +/** * Set the global or per-thread dispatch table pointer. */ -void +PUBLIC void _glapi_set_dispatch(struct _glapi_table *dispatch) { +#if defined(PTHREADS) || defined(GLX_USE_TLS) + static pthread_once_t once_control = PTHREAD_ONCE_INIT; + + + pthread_once( & once_control, init_glapi_relocs ); +#endif + if (!dispatch) { /* use the no-op functions */ - dispatch = &__glapi_noop_table; + dispatch = (struct _glapi_table *) __glapi_noop_table; } #ifdef DEBUG else { @@ -177,32 +366,76 @@ _glapi_set_dispatch(struct _glapi_table *dispatch) } #endif -#if defined(THREADS) - _glthread_SetTSD(&DispatchTSD, (void*) dispatch, dispatch_thread_init); - if (ThreadSafe) - _glapi_Dispatch = NULL; - else +#if defined(GLX_USE_TLS) + if (DispatchOverride) { + _glapi_tls_RealDispatch = dispatch; + } + else { + _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch); + _glapi_tls_Dispatch = dispatch; + } +#elif defined(THREADS) + if (DispatchOverride) { + _glthread_SetTSD(&RealDispatchTSD, (void *) dispatch); + if (ThreadSafe) + _glapi_RealDispatch = (struct _glapi_table*) __glapi_threadsafe_table; + else + _glapi_RealDispatch = dispatch; + } + else { + /* normal operation */ + _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch); + if (ThreadSafe) { + _glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table; + _glapi_DispatchTSD = NULL; + } + else { + _glapi_Dispatch = dispatch; + _glapi_DispatchTSD = dispatch; + } + } +#else /*THREADS*/ + if (DispatchOverride) { + _glapi_RealDispatch = dispatch; + } + else { _glapi_Dispatch = dispatch; -#else - _glapi_Dispatch = dispatch; -#endif + } +#endif /*THREADS*/ } -/* +/** * Return pointer to current dispatch table for calling thread. */ -struct _glapi_table * +PUBLIC struct _glapi_table * _glapi_get_dispatch(void) { -#if defined(THREADS) +#if defined(GLX_USE_TLS) + struct _glapi_table * api = (DispatchOverride) + ? _glapi_tls_RealDispatch : _glapi_tls_Dispatch; + + assert( api != NULL ); + return api; +#elif defined(THREADS) if (ThreadSafe) { - return (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); + if (DispatchOverride) { + return (struct _glapi_table *) _glthread_GetTSD(&RealDispatchTSD); + } + else { + return (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD); + } } else { - assert(_glapi_Dispatch); - return _glapi_Dispatch; + if (DispatchOverride) { + assert(_glapi_RealDispatch); + return _glapi_RealDispatch; + } + else { + assert(_glapi_DispatchTSD); + return _glapi_DispatchTSD; + } } #else return _glapi_Dispatch; @@ -210,70 +443,211 @@ _glapi_get_dispatch(void) } +/* + * Notes on dispatch overrride: + * + * Dispatch override allows an external agent to hook into the GL dispatch + * mechanism before execution goes into the core rendering library. For + * example, a trace mechanism would insert itself as an overrider, print + * logging info for each GL function, then dispatch to the real GL function. + * + * libGLS (GL Stream library) is another agent that might use override. + * + * We don't allow more than one layer of overriding at this time. + * In the future we may allow nested/layered override. In that case + * _glapi_begin_dispatch_override() will return an override layer, + * _glapi_end_dispatch_override(layer) will remove an override layer + * and _glapi_get_override_dispatch(layer) will return the dispatch + * table for a given override layer. layer = 0 will be the "real" + * dispatch table. + */ /* - * Return size of dispatch table struct as number of functions (or - * slots). + * Return: dispatch override layer number. */ -GLuint -_glapi_get_dispatch_table_size(void) +PUBLIC int +_glapi_begin_dispatch_override(struct _glapi_table *override) { - /* return sizeof(struct _glapi_table) / sizeof(void *);*/ - GetSizeCalled = GL_TRUE; - return MaxDispatchOffset + 1; + struct _glapi_table *real = _glapi_get_dispatch(); + + assert(!DispatchOverride); /* can't nest at this time */ + DispatchOverride = GL_TRUE; + + _glapi_set_dispatch(real); + +#if defined(GLX_USE_TLS) + _glthread_SetTSD(&_gl_DispatchTSD, (void *) override); + _glapi_tls_Dispatch = override; +#elif defined(THREADS) + _glthread_SetTSD(&_gl_DispatchTSD, (void *) override); + if ( ThreadSafe ) { + _glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table; + _glapi_DispatchTSD = NULL; + } + else { + _glapi_Dispatch = override; + _glapi_DispatchTSD = override; + } +#else + _glapi_Dispatch = override; +#endif + return 1; } +PUBLIC void +_glapi_end_dispatch_override(int layer) +{ + struct _glapi_table *real = _glapi_get_dispatch(); + (void) layer; + DispatchOverride = GL_FALSE; + _glapi_set_dispatch(real); + /* the rest of this isn't needed, just play it safe */ +#if defined(GLX_USE_TLS) + _glapi_tls_RealDispatch = NULL; +#else +# if defined(THREADS) + _glthread_SetTSD(&RealDispatchTSD, NULL); +# endif + _glapi_RealDispatch = NULL; +#endif +} -/* - * Get API dispatcher version string. - * XXX this isn't well defined yet. - */ -const char * -_glapi_get_version(void) + +PUBLIC struct _glapi_table * +_glapi_get_override_dispatch(int layer) { - return "1.2"; + if (layer == 0) { + return _glapi_get_dispatch(); + } + else { + if (DispatchOverride) { +#if defined(GLX_USE_TLS) + return (struct _glapi_table *) _glapi_tls_Dispatch; +#elif defined(THREADS) + return (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD); +#else + return _glapi_Dispatch; +#endif + } + else { + return NULL; + } + } } -struct name_address_pair { - const char *Name; - GLvoid *Address; -}; +#if !defined( USE_X86_ASM ) +#define NEED_FUNCTION_POINTER +#endif + +/* The code in this file is auto-generated with Python */ +#include "glprocs.h" -static struct name_address_pair static_functions[1000]; +/** + * Search the table of static entrypoint functions for the named function + * and return the corresponding glprocs_table_t entry. + */ +static const glprocs_table_t * +find_entry( const char * n ) +{ + GLuint i; + for (i = 0; static_functions[i].Name_offset >= 0; i++) { + const char * test_name; -/* + test_name = gl_string_table + static_functions[i].Name_offset; + if (strcmp(test_name, n) == 0) { + return & static_functions[i]; + } + } + return NULL; +} + + +/** * Return dispatch table offset of the named static (built-in) function. * Return -1 if function not found. */ static GLint get_static_proc_offset(const char *funcName) { - GLuint i; - for (i = 0; static_functions[i].Name; i++) { - if (strcmp(static_functions[i].Name, funcName) == 0) { - return i; - } + const glprocs_table_t * const f = find_entry( funcName ); + + if ( f != NULL ) { + return f->Offset; } return -1; } -/* +#ifdef USE_X86_ASM + +#if defined( GLX_USE_TLS ) +extern GLubyte gl_dispatch_functions_start[]; +extern GLubyte gl_dispatch_functions_end[]; +#else +extern const GLubyte gl_dispatch_functions_start[]; +#endif + +# if defined(THREADS) && !defined(GLX_USE_TLS) +# define X86_DISPATCH_FUNCTION_SIZE 32 +# else +# define X86_DISPATCH_FUNCTION_SIZE 16 +# endif + + +/** * Return dispatch function address the named static (built-in) function. * Return NULL if function not found. */ -static GLvoid * +static const _glapi_proc get_static_proc_address(const char *funcName) { - GLuint i = get_static_proc_offset(funcName); - if (i >= 0) - return static_functions[i].Address; - else + const glprocs_table_t * const f = find_entry( funcName ); + + if ( f != NULL ) { + return (_glapi_proc) (gl_dispatch_functions_start + + (X86_DISPATCH_FUNCTION_SIZE * f->Offset)); + } + else { return NULL; + } +} + +#else + + +/** + * Return pointer to the named static (built-in) function. + * \return NULL if function not found. + */ +static const _glapi_proc +get_static_proc_address(const char *funcName) +{ + const glprocs_table_t * const f = find_entry( funcName ); + return ( f != NULL ) ? f->Address : NULL; +} + +#endif /* USE_X86_ASM */ + + +/** + * Return the name of the function at the given offset in the dispatch + * table. For debugging only. + */ +static const char * +get_static_proc_name( GLuint offset ) +{ + GLuint i; + + for (i = 0; static_functions[i].Name_offset >= 0; i++) { + if (static_functions[i].Offset == offset) { + return gl_string_table + static_functions[i].Name_offset; + } + } + return NULL; } @@ -282,100 +656,399 @@ get_static_proc_address(const char *funcName) * Extension function management. */ +/* + * Number of extension functions which we can dynamically add at runtime. + */ +#define MAX_EXTENSION_FUNCS 300 + + +/* + * The dispatch table size (number of entries) is the size of the + * _glapi_table struct plus the number of dynamic entries we can add. + * The extra slots can be filled in by DRI drivers that register new extension + * functions. + */ +#define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS) + + +/** + * Track information about a function added to the GL API. + */ +struct _glapi_function { + /** + * Name of the function. + */ + const char * name; + + + /** + * Text string that describes the types of the parameters passed to the + * named function. Parameter types are converted to characters using the + * following rules: + * - 'i' for \c GLint, \c GLuint, and \c GLenum + * - 'p' for any pointer type + * - 'f' for \c GLfloat and \c GLclampf + * - 'd' for \c GLdouble and \c GLclampd + */ + const char * parameter_signature; + -struct _glapi_ext_entrypoint { - const char *Name; /* the extension function's name */ - GLuint Offset; /* relative to start of dispatch table */ - GLvoid *Address; /* address of dispatch function */ + /** + * Offset in the dispatch table where the pointer to the real function is + * located. If the driver has not requested that the named function be + * added to the dispatch table, this will have the value ~0. + */ + unsigned dispatch_offset; + + + /** + * Pointer to the dispatch stub for the named function. + * + * \todo + * The semantic of this field should be changed slightly. Currently, it + * is always expected to be non-\c NULL. However, it would be better to + * only allocate the entry-point stub when the application requests the + * function via \c glXGetProcAddress. This would save memory for all the + * functions that the driver exports but that the application never wants + * to call. + */ + _glapi_proc dispatch_stub; }; -static struct _glapi_ext_entrypoint ExtEntryTable[_GLAPI_EXTRA_SLOTS]; -static GLuint NumExtEntryPoints = 0; +static struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS]; +static GLuint NumExtEntryPoints = 0; +#ifdef USE_SPARC_ASM +extern void __glapi_sparc_icache_flush(unsigned int *); +#endif -/* +/** * Generate a dispatch function (entrypoint) which jumps through * the given slot number (offset) in the current dispatch table. + * We need assembly language in order to accomplish this. */ -static void * -generate_entrypoint(GLuint offset) +static _glapi_proc +generate_entrypoint(GLuint functionOffset) { - /* XXX need to generate some assembly code here */ +#if defined(USE_X86_ASM) + /* 32 is chosen as something of a magic offset. For x86, the dispatch + * at offset 32 is the first one where the offset in the + * "jmp OFFSET*4(%eax)" can't be encoded in a single byte. + */ + const GLubyte * const template_func = gl_dispatch_functions_start + + (X86_DISPATCH_FUNCTION_SIZE * 32); + GLubyte * const code = (GLubyte *) malloc( X86_DISPATCH_FUNCTION_SIZE ); + + + if ( code != NULL ) { + (void) memcpy( code, template_func, X86_DISPATCH_FUNCTION_SIZE ); + fill_in_entrypoint_offset( (_glapi_proc) code, functionOffset ); + } + return (_glapi_proc) code; +#elif defined(USE_SPARC_ASM) + +#ifdef __arch64__ + static const unsigned int insn_template[] = { + 0x05000000, /* sethi %uhi(_glapi_Dispatch), %g2 */ + 0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */ + 0x8410a000, /* or %g2, %ulo(_glapi_Dispatch), %g2 */ + 0x82106000, /* or %g1, %lo(_glapi_Dispatch), %g1 */ + 0x8528b020, /* sllx %g2, 32, %g2 */ + 0xc2584002, /* ldx [%g1 + %g2], %g1 */ + 0x05000000, /* sethi %hi(8 * glapioffset), %g2 */ + 0x8410a000, /* or %g2, %lo(8 * glapioffset), %g2 */ + 0xc6584002, /* ldx [%g1 + %g2], %g3 */ + 0x81c0c000, /* jmpl %g3, %g0 */ + 0x01000000 /* nop */ + }; +#else + static const unsigned int insn_template[] = { + 0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */ + 0xc2006000, /* ld [%g1 + %lo(_glapi_Dispatch)], %g1 */ + 0xc6006000, /* ld [%g1 + %lo(4*glapioffset)], %g3 */ + 0x81c0c000, /* jmpl %g3, %g0 */ + 0x01000000 /* nop */ + }; +#endif + unsigned int *code = (unsigned int *) malloc(sizeof(insn_template)); + unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch; + if (code) { + memcpy(code, insn_template, sizeof(insn_template)); + +#ifdef __arch64__ + code[0] |= (glapi_addr >> (32 + 10)); + code[1] |= ((glapi_addr & 0xffffffff) >> 10); + __glapi_sparc_icache_flush(&code[0]); + code[2] |= ((glapi_addr >> 32) & ((1 << 10) - 1)); + code[3] |= (glapi_addr & ((1 << 10) - 1)); + __glapi_sparc_icache_flush(&code[2]); + code[6] |= ((functionOffset * 8) >> 10); + code[7] |= ((functionOffset * 8) & ((1 << 10) - 1)); + __glapi_sparc_icache_flush(&code[6]); +#else + code[0] |= (glapi_addr >> 10); + code[1] |= (glapi_addr & ((1 << 10) - 1)); + __glapi_sparc_icache_flush(&code[0]); + code[2] |= (functionOffset * 4); + __glapi_sparc_icache_flush(&code[2]); +#endif + } + return (_glapi_proc) code; +#else + (void) functionOffset; return NULL; +#endif /* USE_*_ASM */ } - -/* - * Add a new extension function entrypoint. - * Return: GL_TRUE = success or GL_FALSE = failure +/** + * This function inserts a new dispatch offset into the assembly language + * stub that was generated with the preceeding function. */ -GLboolean -_glapi_add_entrypoint(const char *funcName, GLuint offset) +static void +fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset) { - GLint index; +#if defined(USE_X86_ASM) + GLubyte * const code = (GLubyte *) entrypoint; + + +#if X86_DISPATCH_FUNCTION_SIZE == 32 + *((unsigned int *)(code + 11)) = 4 * offset; + *((unsigned int *)(code + 22)) = 4 * offset; +#elif X86_DISPATCH_FUNCTION_SIZE == 16 && defined( GLX_USE_TLS ) + *((unsigned int *)(code + 8)) = 4 * offset; +#elif X86_DISPATCH_FUNCTION_SIZE == 16 + *((unsigned int *)(code + 7)) = 4 * offset; +#else +# error Invalid X86_DISPATCH_FUNCTION_SIZE! +#endif - /* Make sure we don't try to add a new entrypoint after someone - * has already called _glapi_get_dispatch_table_size()! If that's - * happened the caller's information will now be out of date. - */ - assert(!GetSizeCalled); +#elif defined(USE_SPARC_ASM) + + /* XXX this hasn't been tested! */ + unsigned int *code = (unsigned int *) entrypoint; +#ifdef __arch64__ + code[6] = 0x05000000; /* sethi %hi(8 * glapioffset), %g2 */ + code[7] = 0x8410a000; /* or %g2, %lo(8 * glapioffset), %g2 */ + code[6] |= ((offset * 8) >> 10); + code[7] |= ((offset * 8) & ((1 << 10) - 1)); + __glapi_sparc_icache_flush(&code[6]); +#else /* __arch64__ */ + code[2] = 0xc6006000; /* ld [%g1 + %lo(4*glapioffset)], %g3 */ + code[2] |= (offset * 4); + __glapi_sparc_icache_flush(&code[2]); +#endif /* __arch64__ */ + +#else - /* first check if the named function is already statically present */ - index = get_static_proc_offset(funcName); + /* an unimplemented architecture */ + (void) entrypoint; + (void) offset; - if (index >= 0) { - assert(index == offset); - return GL_TRUE; +#endif /* USE_*_ASM */ +} + + +/** + * Generate new entrypoint + * + * Use a temporary dispatch offset of ~0 (i.e. -1). Later, when the driver + * calls \c _glapi_add_dispatch we'll put in the proper offset. If that + * never happens, and the user calls this function, he'll segfault. That's + * what you get when you try calling a GL function that doesn't really exist. + * + * \param funcName Name of the function to create an entry-point for. + * + * \sa _glapi_add_entrypoint + */ + +static struct _glapi_function * +add_function_name( const char * funcName ) +{ + struct _glapi_function * entry = NULL; + + if (NumExtEntryPoints < MAX_EXTENSION_FUNCS) { + _glapi_proc entrypoint = generate_entrypoint(~0); + if (entrypoint != NULL) { + entry = & ExtEntryTable[NumExtEntryPoints]; + + ExtEntryTable[NumExtEntryPoints].name = str_dup(funcName); + ExtEntryTable[NumExtEntryPoints].parameter_signature = NULL; + ExtEntryTable[NumExtEntryPoints].dispatch_offset = ~0; + ExtEntryTable[NumExtEntryPoints].dispatch_stub = entrypoint; + NumExtEntryPoints++; + } } - /* else if (offset < _glapi_get_dispatch_table_size()) { */ - else { - /* be sure index and name match known data */ - GLuint i; - for (i = 0; i < NumExtEntryPoints; i++) { - if (strcmp(ExtEntryTable[i].Name, funcName) == 0) { - /* function already registered with api */ - if (ExtEntryTable[i].Offset == offset) { - return GL_TRUE; /* offsets match */ - } - else { - return GL_FALSE; /* bad offset! */ - } - } + + return entry; +} + + +/** + * Fill-in the dispatch stub for the named function. + * + * This function is intended to be called by a hardware driver. When called, + * a dispatch stub may be created created for the function. A pointer to this + * dispatch function will be returned by glXGetProcAddress. + * + * \param function_names Array of pointers to function names that should + * share a common dispatch offset. + * \param parameter_signature String representing the types of the parameters + * passed to the named function. Parameter types + * are converted to characters using the following + * rules: + * - 'i' for \c GLint, \c GLuint, and \c GLenum + * - 'p' for any pointer type + * - 'f' for \c GLfloat and \c GLclampf + * - 'd' for \c GLdouble and \c GLclampd + * + * \returns + * The offset in the dispatch table of the named function. A pointer to the + * driver's implementation of the named function should be stored at + * \c dispatch_table[\c offset]. + * + * \sa glXGetProcAddress + * + * \warning + * This function can only handle up to 8 names at a time. As far as I know, + * the maximum number of names ever associated with an existing GL function is + * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, + * \c glPointParameterfARB, and \c glPointParameterf), so this should not be + * too painful of a limitation. + * + * \todo + * Determine whether or not \c parameter_signature should be allowed to be + * \c NULL. It doesn't seem like much of a hardship for drivers to have to + * pass in an empty string. + * + * \todo + * Determine if code should be added to reject function names that start with + * 'glX'. + * + * \bug + * Add code to compare \c parameter_signature with the parameter signature of + * a static function. In order to do that, we need to find a way to \b get + * the parameter signature of a static function. + */ + +PUBLIC int +_glapi_add_dispatch( const char * const * function_names, + const char * parameter_signature ) +{ + static int next_dynamic_offset = _gloffset_FIRST_DYNAMIC; + const char * const real_sig = (parameter_signature != NULL) + ? parameter_signature : ""; + struct _glapi_function * entry[8]; + GLboolean is_static[8]; + unsigned i; + unsigned j; + int offset = ~0; + int new_offset; + + + (void) memset( is_static, 0, sizeof( is_static ) ); + (void) memset( entry, 0, sizeof( entry ) ); + + for ( i = 0 ; function_names[i] != NULL ; i++ ) { + /* Do some trivial validation on the name of the function. + */ + +#ifdef MANGLE + if (!function_names[i] || function_names[i][0] != 'm' || function_names[i][1] != 'g' || function_names[i][2] != 'l') + return GL_FALSE; +#else + if (!function_names[i] || function_names[i][0] != 'g' || function_names[i][1] != 'l') + return GL_FALSE; +#endif + + + /* Determine if the named function already exists. If the function does + * exist, it must have the same parameter signature as the function + * being added. + */ + + new_offset = get_static_proc_offset(function_names[i]); + if (new_offset >= 0) { + /* FIXME: Make sure the parameter signatures match! How do we get + * FIXME: the parameter signature for static functions? + */ + + if ( (offset != ~0) && (new_offset != offset) ) { + return -1; + } + + is_static[i] = GL_TRUE; + offset = new_offset; } - assert(NumExtEntryPoints < _GLAPI_EXTRA_SLOTS); - ExtEntryTable[NumExtEntryPoints].Name = strdup(funcName); - ExtEntryTable[NumExtEntryPoints].Offset = offset; - ExtEntryTable[NumExtEntryPoints].Address = generate_entrypoint(offset); - NumExtEntryPoints++; + + + for ( j = 0 ; j < NumExtEntryPoints ; j++ ) { + if (strcmp(ExtEntryTable[j].name, function_names[i]) == 0) { + /* The offset may be ~0 if the function name was added by + * glXGetProcAddress but never filled in by the driver. + */ + + if (ExtEntryTable[j].dispatch_offset != ~0) { + if (strcmp(real_sig, ExtEntryTable[j].parameter_signature) + != 0) { + return -1; + } + + if ( (offset != ~0) && (ExtEntryTable[j].dispatch_offset != offset) ) { + return -1; + } + + offset = ExtEntryTable[j].dispatch_offset; + } + + entry[i] = & ExtEntryTable[j]; + break; + } + } + } - if (offset > MaxDispatchOffset) - MaxDispatchOffset = offset; - return GL_TRUE; + if (offset == ~0) { + offset = next_dynamic_offset; + next_dynamic_offset++; } -/* - else { - return GL_FALSE; + + + for ( i = 0 ; function_names[i] != NULL ; i++ ) { + if (! is_static[i] ) { + if (entry[i] == NULL) { + entry[i] = add_function_name( function_names[i] ); + if (entry[i] == NULL) { + /* FIXME: Possible memory leak here. + */ + return -1; + } + } + + + entry[i]->parameter_signature = str_dup(real_sig); + fill_in_entrypoint_offset(entry[i]->dispatch_stub, offset); + entry[i]->dispatch_offset = offset; + } } -*/ + + return offset; } - -/* +/** * Return offset of entrypoint for named function within dispatch table. */ -GLint +PUBLIC GLint _glapi_get_proc_offset(const char *funcName) { /* search extension functions first */ - GLint i; + GLuint i; for (i = 0; i < NumExtEntryPoints; i++) { - if (strcmp(ExtEntryTable[i].Name, funcName) == 0) { - return ExtEntryTable[i].Offset; + if (strcmp(ExtEntryTable[i].name, funcName) == 0) { + return ExtEntryTable[i].dispatch_offset; } } @@ -385,59 +1058,103 @@ _glapi_get_proc_offset(const char *funcName) -/* - * Return entrypoint for named function. +/** + * Return pointer to the named function. If the function name isn't found + * in the name of static functions, try generating a new API entrypoint on + * the fly with assembly language. */ -const GLvoid * +PUBLIC _glapi_proc _glapi_get_proc_address(const char *funcName) { + struct _glapi_function * entry; + GLuint i; + +#ifdef MANGLE + if (funcName[0] != 'm' || funcName[1] != 'g' || funcName[2] != 'l') + return NULL; +#else + if (funcName[0] != 'g' || funcName[1] != 'l') + return NULL; +#endif + /* search extension functions first */ - GLint i; for (i = 0; i < NumExtEntryPoints; i++) { - if (strcmp(ExtEntryTable[i].Name, funcName) == 0) { - return ExtEntryTable[i].Address; + if (strcmp(ExtEntryTable[i].name, funcName) == 0) { + return ExtEntryTable[i].dispatch_stub; } } /* search static functions */ - return get_static_proc_address(funcName); -} + { + const _glapi_proc func = get_static_proc_address(funcName); + if (func) + return func; + } + entry = add_function_name(funcName); + return (entry == NULL) ? NULL : entry->dispatch_stub; +} -/* +/** * Return the name of the function at the given dispatch offset. * This is only intended for debugging. */ -const char * +PUBLIC const char * _glapi_get_proc_name(GLuint offset) { - GLuint n = sizeof(static_functions) / sizeof(struct name_address_pair); - if (offset < n) { - return static_functions[offset].Name; + GLuint i; + const char * n; + + /* search built-in functions */ + n = get_static_proc_name(offset); + if ( n != NULL ) { + return n; } - else { - /* search added extension functions */ - GLuint i; - for (i = 0; i < NumExtEntryPoints; i++) { - if (ExtEntryTable[i].Offset == offset) { - return ExtEntryTable[i].Name; - } + + /* search added extension functions */ + for (i = 0; i < NumExtEntryPoints; i++) { + if (ExtEntryTable[i].dispatch_offset == offset) { + return ExtEntryTable[i].name; } - return NULL; } + return NULL; } -/* +/** + * Return size of dispatch table struct as number of functions (or + * slots). + */ +PUBLIC GLuint +_glapi_get_dispatch_table_size(void) +{ + return DISPATCH_TABLE_SIZE; +} + + + +/** + * Get API dispatcher version string. + */ +PUBLIC const char * +_glapi_get_version(void) +{ + return "20021001"; /* YYYYMMDD */ +} + + + +/** * Make sure there are no NULL pointers in the given dispatch table. - * Intented for debugging purposes. + * Intended for debugging purposes. */ -void +PUBLIC void _glapi_check_table(const struct _glapi_table *table) { +#ifdef DEBUG const GLuint entries = _glapi_get_dispatch_table_size(); const void **tab = (const void **) table; GLuint i; @@ -445,7 +1162,6 @@ _glapi_check_table(const struct _glapi_table *table) assert(tab[i]); } -#ifdef DEBUG /* Do some spot checks to be sure that the dispatch table * slots are assigned correctly. */ @@ -478,10 +1194,10 @@ _glapi_check_table(const struct _glapi_table *table) assert(ResetMinMaxOffset == offset); } { - GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColorEXT"); - char *blendColorFunc = (char*) &table->BlendColorEXT; + GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor"); + char *blendColorFunc = (char*) &table->BlendColor; GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *); - assert(blendColorOffset == _gloffset_BlendColorEXT); + assert(blendColorOffset == _gloffset_BlendColor); assert(blendColorOffset == offset); } { @@ -491,938 +1207,53 @@ _glapi_check_table(const struct _glapi_table *table) assert(istextureOffset == _gloffset_IsTextureEXT); assert(istextureOffset == offset); } -#endif -} - - -/********************************************************************** - * Generate the GL entrypoint functions here. - */ - -#define KEYWORD1 -#define KEYWORD2 GLAPIENTRY -#if defined(USE_X86_ASM) && !defined(__WIN32__) && !defined(XF86DRI) -#define NAME(func) _glapi_fallback_##func -#elif defined(USE_MGL_NAMESPACE) -#define NAME(func) mgl##func + { + GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT"); + char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT; + GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *); + assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT); + assert(secondaryColor3fOffset == offset); + assert(_glapi_get_proc_address("glSecondaryColor3fEXT") == (_glapi_proc) &glSecondaryColor3fEXT); + } + { + GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV"); + char *pointParameterivFunc = (char*) &table->PointParameterivNV; + GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *); + assert(pointParameterivOffset == _gloffset_PointParameterivNV); + assert(pointParameterivOffset == offset); + assert(_glapi_get_proc_address("glPointParameterivNV") == (_glapi_proc) &glPointParameterivNV); + } + { + GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV"); + char *setFenceFunc = (char*) &table->SetFenceNV; + GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *); + assert(setFenceOffset == _gloffset_SetFenceNV); + assert(setFenceOffset == offset); + assert(_glapi_get_proc_address("glSetFenceNV") == (_glapi_proc) &glSetFenceNV); + } #else -#define NAME(func) gl##func + (void) table; #endif - -#ifdef DEBUG - -#include - -static int -trace(void) -{ - static int trace = -1; - if (trace < 0) - trace = getenv("MESA_TRACE") ? 1 : 0; - return trace > 0; } -#define DISPATCH(FUNC, ARGS, MESSAGE) \ - const struct _glapi_table *dispatch; \ - dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ - if (trace()) printf MESSAGE; \ - (dispatch->FUNC) ARGS - -#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ - const struct _glapi_table *dispatch; \ - dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ - if (trace()) printf MESSAGE; \ - return (dispatch->FUNC) ARGS - -#else - -#define DISPATCH(FUNC, ARGS, MESSAGE) \ - const struct _glapi_table *dispatch; \ - dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ - (dispatch->FUNC) ARGS - -#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ - const struct _glapi_table *dispatch; \ - dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ - return (dispatch->FUNC) ARGS - -#endif - - -#ifndef GLAPIENTRY -#define GLAPIENTRY -#endif - -#include "glapitemp.h" - -/* - * For each entry in static_functions[] which use this function - * we should implement a dispatch function in glapitemp.h and - * in glapinoop.c +/** + * Perform platform-specific GL API entry-point fixups. + * + * */ -static int NotImplemented(void) +static void +init_glapi_relocs( void ) { - return 0; -} - - - -static struct name_address_pair static_functions[] = { - { "NotImplemented", (GLvoid *) NotImplemented }, - - /* GL 1.1 */ - { "glAccum", (GLvoid *) glAccum }, - { "glAlphaFunc", (GLvoid *) glAlphaFunc }, - { "glBegin", (GLvoid *) glBegin }, - { "glBitmap", (GLvoid *) glBitmap }, - { "glBlendFunc", (GLvoid *) glBlendFunc }, - { "glCallList", (GLvoid *) glCallList }, - { "glCallLists", (GLvoid *) glCallLists }, - { "glClear", (GLvoid *) glClear }, - { "glClearAccum", (GLvoid *) glClearAccum }, - { "glClearColor", (GLvoid *) glClearColor }, - { "glClearDepth", (GLvoid *) glClearDepth }, - { "glClearIndex", (GLvoid *) glClearIndex }, - { "glClearStencil", (GLvoid *) glClearStencil }, - { "glClipPlane", (GLvoid *) glClipPlane }, - { "glColor3b", (GLvoid *) glColor3b }, - { "glColor3bv", (GLvoid *) glColor3bv }, - { "glColor3d", (GLvoid *) glColor3d }, - { "glColor3dv", (GLvoid *) glColor3dv }, - { "glColor3f", (GLvoid *) glColor3f }, - { "glColor3fv", (GLvoid *) glColor3fv }, - { "glColor3i", (GLvoid *) glColor3i }, - { "glColor3iv", (GLvoid *) glColor3iv }, - { "glColor3s", (GLvoid *) glColor3s }, - { "glColor3sv", (GLvoid *) glColor3sv }, - { "glColor3ub", (GLvoid *) glColor3ub }, - { "glColor3ubv", (GLvoid *) glColor3ubv }, - { "glColor3ui", (GLvoid *) glColor3ui }, - { "glColor3uiv", (GLvoid *) glColor3uiv }, - { "glColor3us", (GLvoid *) glColor3us }, - { "glColor3usv", (GLvoid *) glColor3usv }, - { "glColor4b", (GLvoid *) glColor4b }, - { "glColor4bv", (GLvoid *) glColor4bv }, - { "glColor4d", (GLvoid *) glColor4d }, - { "glColor4dv", (GLvoid *) glColor4dv }, - { "glColor4f", (GLvoid *) glColor4f }, - { "glColor4fv", (GLvoid *) glColor4fv }, - { "glColor4i", (GLvoid *) glColor4i }, - { "glColor4iv", (GLvoid *) glColor4iv }, - { "glColor4s", (GLvoid *) glColor4s }, - { "glColor4sv", (GLvoid *) glColor4sv }, - { "glColor4ub", (GLvoid *) glColor4ub }, - { "glColor4ubv", (GLvoid *) glColor4ubv }, - { "glColor4ui", (GLvoid *) glColor4ui }, - { "glColor4uiv", (GLvoid *) glColor4uiv }, - { "glColor4us", (GLvoid *) glColor4us }, - { "glColor4usv", (GLvoid *) glColor4usv }, - { "glColorMask", (GLvoid *) glColorMask }, - { "glColorMaterial", (GLvoid *) glColorMaterial }, - { "glCopyPixels", (GLvoid *) glCopyPixels }, - { "glCullFace", (GLvoid *) glCullFace }, - { "glDeleteLists", (GLvoid *) glDeleteLists }, - { "glDepthFunc", (GLvoid *) glDepthFunc }, - { "glDepthMask", (GLvoid *) glDepthMask }, - { "glDepthRange", (GLvoid *) glDepthRange }, - { "glDisable", (GLvoid *) glDisable }, - { "glDrawBuffer", (GLvoid *) glDrawBuffer }, - { "glDrawPixels", (GLvoid *) glDrawPixels }, - { "glEdgeFlag", (GLvoid *) glEdgeFlag }, - { "glEdgeFlagv", (GLvoid *) glEdgeFlagv }, - { "glEnable", (GLvoid *) glEnable }, - { "glEnd", (GLvoid *) glEnd }, - { "glEndList", (GLvoid *) glEndList }, - { "glEvalCoord1d", (GLvoid *) glEvalCoord1d }, - { "glEvalCoord1dv", (GLvoid *) glEvalCoord1dv }, - { "glEvalCoord1f", (GLvoid *) glEvalCoord1f }, - { "glEvalCoord1fv", (GLvoid *) glEvalCoord1fv }, - { "glEvalCoord2d", (GLvoid *) glEvalCoord2d }, - { "glEvalCoord2dv", (GLvoid *) glEvalCoord2dv }, - { "glEvalCoord2f", (GLvoid *) glEvalCoord2f }, - { "glEvalCoord2fv", (GLvoid *) glEvalCoord2fv }, - { "glEvalMesh1", (GLvoid *) glEvalMesh1 }, - { "glEvalMesh2", (GLvoid *) glEvalMesh2 }, - { "glEvalPoint1", (GLvoid *) glEvalPoint1 }, - { "glEvalPoint2", (GLvoid *) glEvalPoint2 }, - { "glFeedbackBuffer", (GLvoid *) glFeedbackBuffer }, - { "glFinish", (GLvoid *) glFinish }, - { "glFlush", (GLvoid *) glFlush }, - { "glFogf", (GLvoid *) glFogf }, - { "glFogfv", (GLvoid *) glFogfv }, - { "glFogi", (GLvoid *) glFogi }, - { "glFogiv", (GLvoid *) glFogiv }, - { "glFrontFace", (GLvoid *) glFrontFace }, - { "glFrustum", (GLvoid *) glFrustum }, - { "glGenLists", (GLvoid *) glGenLists }, - { "glGetBooleanv", (GLvoid *) glGetBooleanv }, - { "glGetClipPlane", (GLvoid *) glGetClipPlane }, - { "glGetDoublev", (GLvoid *) glGetDoublev }, - { "glGetError", (GLvoid *) glGetError }, - { "glGetFloatv", (GLvoid *) glGetFloatv }, - { "glGetIntegerv", (GLvoid *) glGetIntegerv }, - { "glGetLightfv", (GLvoid *) glGetLightfv }, - { "glGetLightiv", (GLvoid *) glGetLightiv }, - { "glGetMapdv", (GLvoid *) glGetMapdv }, - { "glGetMapfv", (GLvoid *) glGetMapfv }, - { "glGetMapiv", (GLvoid *) glGetMapiv }, - { "glGetMaterialfv", (GLvoid *) glGetMaterialfv }, - { "glGetMaterialiv", (GLvoid *) glGetMaterialiv }, - { "glGetPixelMapfv", (GLvoid *) glGetPixelMapfv }, - { "glGetPixelMapuiv", (GLvoid *) glGetPixelMapuiv }, - { "glGetPixelMapusv", (GLvoid *) glGetPixelMapusv }, - { "glGetPolygonStipple", (GLvoid *) glGetPolygonStipple }, - { "glGetString", (GLvoid *) glGetString }, - { "glGetTexEnvfv", (GLvoid *) glGetTexEnvfv }, - { "glGetTexEnviv", (GLvoid *) glGetTexEnviv }, - { "glGetTexGendv", (GLvoid *) glGetTexGendv }, - { "glGetTexGenfv", (GLvoid *) glGetTexGenfv }, - { "glGetTexGeniv", (GLvoid *) glGetTexGeniv }, - { "glGetTexImage", (GLvoid *) glGetTexImage }, - { "glGetTexLevelParameterfv", (GLvoid *) glGetTexLevelParameterfv }, - { "glGetTexLevelParameteriv", (GLvoid *) glGetTexLevelParameteriv }, - { "glGetTexParameterfv", (GLvoid *) glGetTexParameterfv }, - { "glGetTexParameteriv", (GLvoid *) glGetTexParameteriv }, - { "glHint", (GLvoid *) glHint }, - { "glIndexMask", (GLvoid *) glIndexMask }, - { "glIndexd", (GLvoid *) glIndexd }, - { "glIndexdv", (GLvoid *) glIndexdv }, - { "glIndexf", (GLvoid *) glIndexf }, - { "glIndexfv", (GLvoid *) glIndexfv }, - { "glIndexi", (GLvoid *) glIndexi }, - { "glIndexiv", (GLvoid *) glIndexiv }, - { "glIndexs", (GLvoid *) glIndexs }, - { "glIndexsv", (GLvoid *) glIndexsv }, - { "glInitNames", (GLvoid *) glInitNames }, - { "glIsEnabled", (GLvoid *) glIsEnabled }, - { "glIsList", (GLvoid *) glIsList }, - { "glLightModelf", (GLvoid *) glLightModelf }, - { "glLightModelfv", (GLvoid *) glLightModelfv }, - { "glLightModeli", (GLvoid *) glLightModeli }, - { "glLightModeliv", (GLvoid *) glLightModeliv }, - { "glLightf", (GLvoid *) glLightf }, - { "glLightfv", (GLvoid *) glLightfv }, - { "glLighti", (GLvoid *) glLighti }, - { "glLightiv", (GLvoid *) glLightiv }, - { "glLineStipple", (GLvoid *) glLineStipple }, - { "glLineWidth", (GLvoid *) glLineWidth }, - { "glListBase", (GLvoid *) glListBase }, - { "glLoadIdentity", (GLvoid *) glLoadIdentity }, - { "glLoadMatrixd", (GLvoid *) glLoadMatrixd }, - { "glLoadMatrixf", (GLvoid *) glLoadMatrixf }, - { "glLoadName", (GLvoid *) glLoadName }, - { "glLogicOp", (GLvoid *) glLogicOp }, - { "glMap1d", (GLvoid *) glMap1d }, - { "glMap1f", (GLvoid *) glMap1f }, - { "glMap2d", (GLvoid *) glMap2d }, - { "glMap2f", (GLvoid *) glMap2f }, - { "glMapGrid1d", (GLvoid *) glMapGrid1d }, - { "glMapGrid1f", (GLvoid *) glMapGrid1f }, - { "glMapGrid2d", (GLvoid *) glMapGrid2d }, - { "glMapGrid2f", (GLvoid *) glMapGrid2f }, - { "glMaterialf", (GLvoid *) glMaterialf }, - { "glMaterialfv", (GLvoid *) glMaterialfv }, - { "glMateriali", (GLvoid *) glMateriali }, - { "glMaterialiv", (GLvoid *) glMaterialiv }, - { "glMatrixMode", (GLvoid *) glMatrixMode }, - { "glMultMatrixd", (GLvoid *) glMultMatrixd }, - { "glMultMatrixf", (GLvoid *) glMultMatrixf }, - { "glNewList", (GLvoid *) glNewList }, - { "glNormal3b", (GLvoid *) glNormal3b }, - { "glNormal3bv", (GLvoid *) glNormal3bv }, - { "glNormal3d", (GLvoid *) glNormal3d }, - { "glNormal3dv", (GLvoid *) glNormal3dv }, - { "glNormal3f", (GLvoid *) glNormal3f }, - { "glNormal3fv", (GLvoid *) glNormal3fv }, - { "glNormal3i", (GLvoid *) glNormal3i }, - { "glNormal3iv", (GLvoid *) glNormal3iv }, - { "glNormal3s", (GLvoid *) glNormal3s }, - { "glNormal3sv", (GLvoid *) glNormal3sv }, - { "glOrtho", (GLvoid *) glOrtho }, - { "glPassThrough", (GLvoid *) glPassThrough }, - { "glPixelMapfv", (GLvoid *) glPixelMapfv }, - { "glPixelMapuiv", (GLvoid *) glPixelMapuiv }, - { "glPixelMapusv", (GLvoid *) glPixelMapusv }, - { "glPixelStoref", (GLvoid *) glPixelStoref }, - { "glPixelStorei", (GLvoid *) glPixelStorei }, - { "glPixelTransferf", (GLvoid *) glPixelTransferf }, - { "glPixelTransferi", (GLvoid *) glPixelTransferi }, - { "glPixelZoom", (GLvoid *) glPixelZoom }, - { "glPointSize", (GLvoid *) glPointSize }, - { "glPolygonMode", (GLvoid *) glPolygonMode }, - { "glPolygonOffset", (GLvoid *) glPolygonOffset }, - { "glPolygonStipple", (GLvoid *) glPolygonStipple }, - { "glPopAttrib", (GLvoid *) glPopAttrib }, - { "glPopMatrix", (GLvoid *) glPopMatrix }, - { "glPopName", (GLvoid *) glPopName }, - { "glPushAttrib", (GLvoid *) glPushAttrib }, - { "glPushMatrix", (GLvoid *) glPushMatrix }, - { "glPushName", (GLvoid *) glPushName }, - { "glRasterPos2d", (GLvoid *) glRasterPos2d }, - { "glRasterPos2dv", (GLvoid *) glRasterPos2dv }, - { "glRasterPos2f", (GLvoid *) glRasterPos2f }, - { "glRasterPos2fv", (GLvoid *) glRasterPos2fv }, - { "glRasterPos2i", (GLvoid *) glRasterPos2i }, - { "glRasterPos2iv", (GLvoid *) glRasterPos2iv }, - { "glRasterPos2s", (GLvoid *) glRasterPos2s }, - { "glRasterPos2sv", (GLvoid *) glRasterPos2sv }, - { "glRasterPos3d", (GLvoid *) glRasterPos3d }, - { "glRasterPos3dv", (GLvoid *) glRasterPos3dv }, - { "glRasterPos3f", (GLvoid *) glRasterPos3f }, - { "glRasterPos3fv", (GLvoid *) glRasterPos3fv }, - { "glRasterPos3i", (GLvoid *) glRasterPos3i }, - { "glRasterPos3iv", (GLvoid *) glRasterPos3iv }, - { "glRasterPos3s", (GLvoid *) glRasterPos3s }, - { "glRasterPos3sv", (GLvoid *) glRasterPos3sv }, - { "glRasterPos4d", (GLvoid *) glRasterPos4d }, - { "glRasterPos4dv", (GLvoid *) glRasterPos4dv }, - { "glRasterPos4f", (GLvoid *) glRasterPos4f }, - { "glRasterPos4fv", (GLvoid *) glRasterPos4fv }, - { "glRasterPos4i", (GLvoid *) glRasterPos4i }, - { "glRasterPos4iv", (GLvoid *) glRasterPos4iv }, - { "glRasterPos4s", (GLvoid *) glRasterPos4s }, - { "glRasterPos4sv", (GLvoid *) glRasterPos4sv }, - { "glReadBuffer", (GLvoid *) glReadBuffer }, - { "glReadPixels", (GLvoid *) glReadPixels }, - { "glRectd", (GLvoid *) glRectd }, - { "glRectdv", (GLvoid *) glRectdv }, - { "glRectf", (GLvoid *) glRectf }, - { "glRectfv", (GLvoid *) glRectfv }, - { "glRecti", (GLvoid *) glRecti }, - { "glRectiv", (GLvoid *) glRectiv }, - { "glRects", (GLvoid *) glRects }, - { "glRectsv", (GLvoid *) glRectsv }, - { "glRenderMode", (GLvoid *) glRenderMode }, - { "glRotated", (GLvoid *) glRotated }, - { "glRotatef", (GLvoid *) glRotatef }, - { "glScaled", (GLvoid *) glScaled }, - { "glScalef", (GLvoid *) glScalef }, - { "glScissor", (GLvoid *) glScissor }, - { "glSelectBuffer", (GLvoid *) glSelectBuffer }, - { "glShadeModel", (GLvoid *) glShadeModel }, - { "glStencilFunc", (GLvoid *) glStencilFunc }, - { "glStencilMask", (GLvoid *) glStencilMask }, - { "glStencilOp", (GLvoid *) glStencilOp }, - { "glTexCoord1d", (GLvoid *) glTexCoord1d }, - { "glTexCoord1dv", (GLvoid *) glTexCoord1dv }, - { "glTexCoord1f", (GLvoid *) glTexCoord1f }, - { "glTexCoord1fv", (GLvoid *) glTexCoord1fv }, - { "glTexCoord1i", (GLvoid *) glTexCoord1i }, - { "glTexCoord1iv", (GLvoid *) glTexCoord1iv }, - { "glTexCoord1s", (GLvoid *) glTexCoord1s }, - { "glTexCoord1sv", (GLvoid *) glTexCoord1sv }, - { "glTexCoord2d", (GLvoid *) glTexCoord2d }, - { "glTexCoord2dv", (GLvoid *) glTexCoord2dv }, - { "glTexCoord2f", (GLvoid *) glTexCoord2f }, - { "glTexCoord2fv", (GLvoid *) glTexCoord2fv }, - { "glTexCoord2i", (GLvoid *) glTexCoord2i }, - { "glTexCoord2iv", (GLvoid *) glTexCoord2iv }, - { "glTexCoord2s", (GLvoid *) glTexCoord2s }, - { "glTexCoord2sv", (GLvoid *) glTexCoord2sv }, - { "glTexCoord3d", (GLvoid *) glTexCoord3d }, - { "glTexCoord3dv", (GLvoid *) glTexCoord3dv }, - { "glTexCoord3f", (GLvoid *) glTexCoord3f }, - { "glTexCoord3fv", (GLvoid *) glTexCoord3fv }, - { "glTexCoord3i", (GLvoid *) glTexCoord3i }, - { "glTexCoord3iv", (GLvoid *) glTexCoord3iv }, - { "glTexCoord3s", (GLvoid *) glTexCoord3s }, - { "glTexCoord3sv", (GLvoid *) glTexCoord3sv }, - { "glTexCoord4d", (GLvoid *) glTexCoord4d }, - { "glTexCoord4dv", (GLvoid *) glTexCoord4dv }, - { "glTexCoord4f", (GLvoid *) glTexCoord4f }, - { "glTexCoord4fv", (GLvoid *) glTexCoord4fv }, - { "glTexCoord4i", (GLvoid *) glTexCoord4i }, - { "glTexCoord4iv", (GLvoid *) glTexCoord4iv }, - { "glTexCoord4s", (GLvoid *) glTexCoord4s }, - { "glTexCoord4sv", (GLvoid *) glTexCoord4sv }, - { "glTexEnvf", (GLvoid *) glTexEnvf }, - { "glTexEnvfv", (GLvoid *) glTexEnvfv }, - { "glTexEnvi", (GLvoid *) glTexEnvi }, - { "glTexEnviv", (GLvoid *) glTexEnviv }, - { "glTexGend", (GLvoid *) glTexGend }, - { "glTexGendv", (GLvoid *) glTexGendv }, - { "glTexGenf", (GLvoid *) glTexGenf }, - { "glTexGenfv", (GLvoid *) glTexGenfv }, - { "glTexGeni", (GLvoid *) glTexGeni }, - { "glTexGeniv", (GLvoid *) glTexGeniv }, - { "glTexImage1D", (GLvoid *) glTexImage1D }, - { "glTexImage2D", (GLvoid *) glTexImage2D }, - { "glTexParameterf", (GLvoid *) glTexParameterf }, - { "glTexParameterfv", (GLvoid *) glTexParameterfv }, - { "glTexParameteri", (GLvoid *) glTexParameteri }, - { "glTexParameteriv", (GLvoid *) glTexParameteriv }, - { "glTranslated", (GLvoid *) glTranslated }, - { "glTranslatef", (GLvoid *) glTranslatef }, - { "glVertex2d", (GLvoid *) glVertex2d }, - { "glVertex2dv", (GLvoid *) glVertex2dv }, - { "glVertex2f", (GLvoid *) glVertex2f }, - { "glVertex2fv", (GLvoid *) glVertex2fv }, - { "glVertex2i", (GLvoid *) glVertex2i }, - { "glVertex2iv", (GLvoid *) glVertex2iv }, - { "glVertex2s", (GLvoid *) glVertex2s }, - { "glVertex2sv", (GLvoid *) glVertex2sv }, - { "glVertex3d", (GLvoid *) glVertex3d }, - { "glVertex3dv", (GLvoid *) glVertex3dv }, - { "glVertex3f", (GLvoid *) glVertex3f }, - { "glVertex3fv", (GLvoid *) glVertex3fv }, - { "glVertex3i", (GLvoid *) glVertex3i }, - { "glVertex3iv", (GLvoid *) glVertex3iv }, - { "glVertex3s", (GLvoid *) glVertex3s }, - { "glVertex3sv", (GLvoid *) glVertex3sv }, - { "glVertex4d", (GLvoid *) glVertex4d }, - { "glVertex4dv", (GLvoid *) glVertex4dv }, - { "glVertex4f", (GLvoid *) glVertex4f }, - { "glVertex4fv", (GLvoid *) glVertex4fv }, - { "glVertex4i", (GLvoid *) glVertex4i }, - { "glVertex4iv", (GLvoid *) glVertex4iv }, - { "glVertex4s", (GLvoid *) glVertex4s }, - { "glVertex4sv", (GLvoid *) glVertex4sv }, - { "glViewport", (GLvoid *) glViewport }, - - /* GL 1.1 */ -#ifdef GL_VERSION_1_1 -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glAreTexturesResident", (GLvoid *) NAME(glAreTexturesResident) }, - { "glArrayElement", (GLvoid *) NAME(glArrayElement) }, - { "glBindTexture", (GLvoid *) NAME(glBindTexture) }, - { "glColorPointer", (GLvoid *) NAME(glColorPointer) }, - { "glCopyTexImage1D", (GLvoid *) NAME(glCopyTexImage1D) }, - { "glCopyTexImage2D", (GLvoid *) NAME(glCopyTexImage2D) }, - { "glCopyTexSubImage1D", (GLvoid *) NAME(glCopyTexSubImage1D) }, - { "glCopyTexSubImage2D", (GLvoid *) NAME(glCopyTexSubImage2D) }, - { "glDeleteTextures", (GLvoid *) NAME(glDeleteTextures) }, - { "glDisableClientState", (GLvoid *) NAME(glDisableClientState) }, - { "glDrawArrays", (GLvoid *) NAME(glDrawArrays) }, - { "glDrawElements", (GLvoid *) NAME(glDrawElements) }, - { "glEdgeFlagPointer", (GLvoid *) NAME(glEdgeFlagPointer) }, - { "glEnableClientState", (GLvoid *) NAME(glEnableClientState) }, - { "glGenTextures", (GLvoid *) NAME(glGenTextures) }, - { "glGetPointerv", (GLvoid *) NAME(glGetPointerv) }, - { "glIndexPointer", (GLvoid *) NAME(glIndexPointer) }, - { "glIndexub", (GLvoid *) NAME(glIndexub) }, - { "glIndexubv", (GLvoid *) NAME(glIndexubv) }, - { "glInterleavedArrays", (GLvoid *) NAME(glInterleavedArrays) }, - { "glIsTexture", (GLvoid *) NAME(glIsTexture) }, - { "glNormalPointer", (GLvoid *) NAME(glNormalPointer) }, - { "glPopClientAttrib", (GLvoid *) NAME(glPopClientAttrib) }, - { "glPrioritizeTextures", (GLvoid *) NAME(glPrioritizeTextures) }, - { "glPushClientAttrib", (GLvoid *) NAME(glPushClientAttrib) }, - { "glTexCoordPointer", (GLvoid *) NAME(glTexCoordPointer) }, - { "glTexSubImage1D", (GLvoid *) NAME(glTexSubImage1D) }, - { "glTexSubImage2D", (GLvoid *) NAME(glTexSubImage2D) }, - { "glVertexPointer", (GLvoid *) NAME(glVertexPointer) }, -#undef NAME - - /* GL 1.2 */ -#ifdef GL_VERSION_1_2 -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glCopyTexSubImage3D", (GLvoid *) NAME(glCopyTexSubImage3D) }, - { "glDrawRangeElements", (GLvoid *) NAME(glDrawRangeElements) }, - { "glTexImage3D", (GLvoid *) NAME(glTexImage3D) }, - { "glTexSubImage3D", (GLvoid *) NAME(glTexSubImage3D) }, -#undef NAME - - /* GL_ARB_imaging */ -#ifdef GL_ARB_imaging -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glBlendColor", (GLvoid *) NAME(glBlendColor) }, - { "glBlendEquation", (GLvoid *) NAME(glBlendEquation) }, - { "glColorSubTable", (GLvoid *) NAME(glColorSubTable) }, - { "glColorTable", (GLvoid *) NAME(glColorTable) }, - { "glColorTableParameterfv", (GLvoid *) NAME(glColorTableParameterfv) }, - { "glColorTableParameteriv", (GLvoid *) NAME(glColorTableParameteriv) }, - { "glConvolutionFilter1D", (GLvoid *) NAME(glConvolutionFilter1D) }, - { "glConvolutionFilter2D", (GLvoid *) NAME(glConvolutionFilter2D) }, - { "glConvolutionParameterf", (GLvoid *) NAME(glConvolutionParameterf) }, - { "glConvolutionParameterfv", (GLvoid *) NAME(glConvolutionParameterfv) }, - { "glConvolutionParameteri", (GLvoid *) NAME(glConvolutionParameteri) }, - { "glConvolutionParameteriv", (GLvoid *) NAME(glConvolutionParameteriv) }, - { "glCopyColorSubTable", (GLvoid *) NAME(glCopyColorSubTable) }, - { "glCopyColorTable", (GLvoid *) NAME(glCopyColorTable) }, - { "glCopyConvolutionFilter1D", (GLvoid *) NAME(glCopyConvolutionFilter1D) }, - { "glCopyConvolutionFilter2D", (GLvoid *) NAME(glCopyConvolutionFilter2D) }, - { "glGetColorTable", (GLvoid *) NAME(glGetColorTable) }, - { "glGetColorTableParameterfv", (GLvoid *) NAME(glGetColorTableParameterfv) }, - { "glGetColorTableParameteriv", (GLvoid *) NAME(glGetColorTableParameteriv) }, - { "glGetConvolutionFilter", (GLvoid *) NAME(glGetConvolutionFilter) }, - { "glGetConvolutionParameterfv", (GLvoid *) NAME(glGetConvolutionParameterfv) }, - { "glGetConvolutionParameteriv", (GLvoid *) NAME(glGetConvolutionParameteriv) }, - { "glGetHistogram", (GLvoid *) NAME(glGetHistogram) }, - { "glGetHistogramParameterfv", (GLvoid *) NAME(glGetHistogramParameterfv) }, - { "glGetHistogramParameteriv", (GLvoid *) NAME(glGetHistogramParameteriv) }, - { "glGetMinmax", (GLvoid *) NAME(glGetMinmax) }, - { "glGetMinmaxParameterfv", (GLvoid *) NAME(glGetMinmaxParameterfv) }, - { "glGetMinmaxParameteriv", (GLvoid *) NAME(glGetMinmaxParameteriv) }, - { "glGetSeparableFilter", (GLvoid *) NAME(glGetSeparableFilter) }, - { "glHistogram", (GLvoid *) NAME(glHistogram) }, - { "glMinmax", (GLvoid *) NAME(glMinmax) }, - { "glResetHistogram", (GLvoid *) NAME(glResetHistogram) }, - { "glResetMinmax", (GLvoid *) NAME(glResetMinmax) }, - { "glSeparableFilter2D", (GLvoid *) NAME(glSeparableFilter2D) }, -#undef NAME - - /* GL_ARB_multitexture */ -#ifdef GL_ARB_multitexture -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glActiveTextureARB", (GLvoid *) NAME(glActiveTextureARB) }, - { "glClientActiveTextureARB", (GLvoid *) NAME(glClientActiveTextureARB) }, - { "glMultiTexCoord1dARB", (GLvoid *) NAME(glMultiTexCoord1dARB) }, - { "glMultiTexCoord1dvARB", (GLvoid *) NAME(glMultiTexCoord1dvARB) }, - { "glMultiTexCoord1fARB", (GLvoid *) NAME(glMultiTexCoord1fARB) }, - { "glMultiTexCoord1fvARB", (GLvoid *) NAME(glMultiTexCoord1fvARB) }, - { "glMultiTexCoord1iARB", (GLvoid *) NAME(glMultiTexCoord1iARB) }, - { "glMultiTexCoord1ivARB", (GLvoid *) NAME(glMultiTexCoord1ivARB) }, - { "glMultiTexCoord1sARB", (GLvoid *) NAME(glMultiTexCoord1sARB) }, - { "glMultiTexCoord1svARB", (GLvoid *) NAME(glMultiTexCoord1svARB) }, - { "glMultiTexCoord2dARB", (GLvoid *) NAME(glMultiTexCoord2dARB) }, - { "glMultiTexCoord2dvARB", (GLvoid *) NAME(glMultiTexCoord2dvARB) }, - { "glMultiTexCoord2fARB", (GLvoid *) NAME(glMultiTexCoord2fARB) }, - { "glMultiTexCoord2fvARB", (GLvoid *) NAME(glMultiTexCoord2fvARB) }, - { "glMultiTexCoord2iARB", (GLvoid *) NAME(glMultiTexCoord2iARB) }, - { "glMultiTexCoord2ivARB", (GLvoid *) NAME(glMultiTexCoord2ivARB) }, - { "glMultiTexCoord2sARB", (GLvoid *) NAME(glMultiTexCoord2sARB) }, - { "glMultiTexCoord2svARB", (GLvoid *) NAME(glMultiTexCoord2svARB) }, - { "glMultiTexCoord3dARB", (GLvoid *) NAME(glMultiTexCoord3dARB) }, - { "glMultiTexCoord3dvARB", (GLvoid *) NAME(glMultiTexCoord3dvARB) }, - { "glMultiTexCoord3fARB", (GLvoid *) NAME(glMultiTexCoord3fARB) }, - { "glMultiTexCoord3fvARB", (GLvoid *) NAME(glMultiTexCoord3fvARB) }, - { "glMultiTexCoord3iARB", (GLvoid *) NAME(glMultiTexCoord3iARB) }, - { "glMultiTexCoord3ivARB", (GLvoid *) NAME(glMultiTexCoord3ivARB) }, - { "glMultiTexCoord3sARB", (GLvoid *) NAME(glMultiTexCoord3sARB) }, - { "glMultiTexCoord3svARB", (GLvoid *) NAME(glMultiTexCoord3svARB) }, - { "glMultiTexCoord4dARB", (GLvoid *) NAME(glMultiTexCoord4dARB) }, - { "glMultiTexCoord4dvARB", (GLvoid *) NAME(glMultiTexCoord4dvARB) }, - { "glMultiTexCoord4fARB", (GLvoid *) NAME(glMultiTexCoord4fARB) }, - { "glMultiTexCoord4fvARB", (GLvoid *) NAME(glMultiTexCoord4fvARB) }, - { "glMultiTexCoord4iARB", (GLvoid *) NAME(glMultiTexCoord4iARB) }, - { "glMultiTexCoord4ivARB", (GLvoid *) NAME(glMultiTexCoord4ivARB) }, - { "glMultiTexCoord4sARB", (GLvoid *) NAME(glMultiTexCoord4sARB) }, - { "glMultiTexCoord4svARB", (GLvoid *) NAME(glMultiTexCoord4svARB) }, -#undef NAME - - /* 2. GL_EXT_blend_color */ -#ifdef GL_EXT_blend_color -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glBlendColorEXT", (GLvoid *) NAME(glBlendColorEXT) }, -#undef NAME - - /* 3. GL_EXT_polygon_offset */ -#ifdef GL_EXT_polygon_offset -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glPolygonOffsetEXT", (GLvoid *) NAME(glPolygonOffsetEXT) }, -#undef NAME - - /* 6. GL_EXT_texture3D */ -#ifdef GL_EXT_texture3D -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glCopyTexSubImage3DEXT", (GLvoid *) NAME(glCopyTexSubImage3DEXT) }, - { "glTexImage3DEXT", (GLvoid *) NAME(glTexImage3DEXT) }, - { "glTexSubImage3DEXT", (GLvoid *) NAME(glTexSubImage3DEXT) }, -#undef NAME - - /* 7. GL_SGI_texture_filter4 */ -#ifdef GL_SGI_texture_filter4 -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glGetTexFilterFuncSGIS", (GLvoid *) NAME(glGetTexFilterFuncSGIS) }, - { "glTexFilterFuncSGIS", (GLvoid *) NAME(glTexFilterFuncSGIS) }, -#undef NAME - - /* 9. GL_EXT_subtexture */ -#ifdef GL_EXT_subtexture -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glTexSubImage1DEXT", (GLvoid *) NAME(glTexSubImage1DEXT) }, - { "glTexSubImage2DEXT", (GLvoid *) NAME(glTexSubImage2DEXT) }, -#undef NAME - - /* 10. GL_EXT_copy_texture */ -#ifdef GL_EXT_copy_texture -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glCopyTexImage1DEXT", (GLvoid *) NAME(glCopyTexImage1DEXT) }, - { "glCopyTexImage2DEXT", (GLvoid *) NAME(glCopyTexImage2DEXT) }, - { "glCopyTexSubImage1DEXT", (GLvoid *) NAME(glCopyTexSubImage1DEXT) }, - { "glCopyTexSubImage2DEXT", (GLvoid *) NAME(glCopyTexSubImage2DEXT) }, -#undef NAME - - /* 11. GL_EXT_histogram */ -#ifdef GL_EXT_histogram -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glGetHistogramEXT", (GLvoid *) NAME(glGetHistogramEXT) }, - { "glGetHistogramParameterfvEXT", (GLvoid *) NAME(glGetHistogramParameterfvEXT) }, - { "glGetHistogramParameterivEXT", (GLvoid *) NAME(glGetHistogramParameterivEXT) }, - { "glGetMinmaxEXT", (GLvoid *) NAME(glGetMinmaxEXT) }, - { "glGetMinmaxParameterfvEXT", (GLvoid *) NAME(glGetMinmaxParameterfvEXT) }, - { "glGetMinmaxParameterivEXT", (GLvoid *) NAME(glGetMinmaxParameterivEXT) }, - { "glHistogramEXT", (GLvoid *) NAME(glHistogramEXT) }, - { "glMinmaxEXT", (GLvoid *) NAME(glMinmaxEXT) }, - { "glResetHistogramEXT", (GLvoid *) NAME(glResetHistogramEXT) }, - { "glResetMinmaxEXT", (GLvoid *) NAME(glResetMinmaxEXT) }, -#undef NAME - - /* 12. GL_EXT_convolution */ -#ifdef GL_EXT_convolution -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glConvolutionFilter1DEXT", (GLvoid *) NAME(glConvolutionFilter1DEXT) }, - { "glConvolutionFilter2DEXT", (GLvoid *) NAME(glConvolutionFilter2DEXT) }, - { "glConvolutionParameterfEXT", (GLvoid *) NAME(glConvolutionParameterfEXT) }, - { "glConvolutionParameterfvEXT", (GLvoid *) NAME(glConvolutionParameterfvEXT) }, - { "glConvolutionParameteriEXT", (GLvoid *) NAME(glConvolutionParameteriEXT) }, - { "glConvolutionParameterivEXT", (GLvoid *) NAME(glConvolutionParameterivEXT) }, - { "glCopyConvolutionFilter1DEXT", (GLvoid *) NAME(glCopyConvolutionFilter1DEXT) }, - { "glCopyConvolutionFilter2DEXT", (GLvoid *) NAME(glCopyConvolutionFilter2DEXT) }, - { "glGetConvolutionFilterEXT", (GLvoid *) NAME(glGetConvolutionFilterEXT) }, - { "glGetConvolutionParameterivEXT", (GLvoid *) NAME(glGetConvolutionParameterivEXT) }, - { "glGetConvolutionParameterfvEXT", (GLvoid *) NAME(glGetConvolutionParameterfvEXT) }, - { "glGetSeparableFilterEXT", (GLvoid *) NAME(glGetSeparableFilterEXT) }, - { "glSeparableFilter2DEXT", (GLvoid *) NAME(glSeparableFilter2DEXT) }, -#undef NAME - - /* 14. GL_SGI_color_table */ -#ifdef GL_SGI_color_table -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glColorTableSGI", (GLvoid *) NAME(glColorTableSGI) }, - { "glColorTableParameterfvSGI", (GLvoid *) NAME(glColorTableParameterfvSGI) }, - { "glColorTableParameterivSGI", (GLvoid *) NAME(glColorTableParameterivSGI) }, - { "glCopyColorTableSGI", (GLvoid *) NAME(glCopyColorTableSGI) }, - { "glGetColorTableSGI", (GLvoid *) NAME(glGetColorTableSGI) }, - { "glGetColorTableParameterfvSGI", (GLvoid *) NAME(glGetColorTableParameterfvSGI) }, - { "glGetColorTableParameterivSGI", (GLvoid *) NAME(glGetColorTableParameterivSGI) }, -#undef NAME - - /* 15. GL_SGIS_pixel_texture */ -#ifdef GL_SGIS_pixel_texture -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glPixelTexGenParameterfSGIS", (GLvoid *) NAME(glPixelTexGenParameterfSGIS) }, - { "glPixelTexGenParameteriSGIS", (GLvoid *) NAME(glPixelTexGenParameteriSGIS) }, - { "glGetPixelTexGenParameterfvSGIS", (GLvoid *) NAME(glGetPixelTexGenParameterfvSGIS) }, - { "glGetPixelTexGenParameterivSGIS", (GLvoid *) NAME(glGetPixelTexGenParameterivSGIS) }, -#undef NAME - - /* 16. GL_SGIS_texture4D */ -#ifdef GL_SGIS_texture4D -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glTexImage4DSGIS", (GLvoid *) NAME(glTexImage4DSGIS) }, - { "glTexSubImage4DSGIS", (GLvoid *) NAME(glTexSubImage4DSGIS) }, -#undef NAME - - /* 20. GL_EXT_texture_object */ -#ifdef GL_EXT_texture_object -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glAreTexturesResidentEXT", (GLvoid *) NAME(glAreTexturesResidentEXT) }, - { "glBindTextureEXT", (GLvoid *) NAME(glBindTextureEXT) }, - { "glDeleteTexturesEXT", (GLvoid *) NAME(glDeleteTexturesEXT) }, - { "glGenTexturesEXT", (GLvoid *) NAME(glGenTexturesEXT) }, - { "glIsTextureEXT", (GLvoid *) NAME(glIsTextureEXT) }, - { "glPrioritizeTexturesEXT", (GLvoid *) NAME(glPrioritizeTexturesEXT) }, -#undef NAME - - /* 21. GL_SGIS_detail_texture */ -#ifdef GL_SGIS_detail_texture -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glDetailTexFuncSGIS", (GLvoid *) NAME(glDetailTexFuncSGIS) }, - { "glGetDetailTexFuncSGIS", (GLvoid *) NAME(glGetDetailTexFuncSGIS) }, -#undef NAME - - /* 22. GL_SGIS_sharpen_texture */ -#ifdef GL_SGIS_sharpen_texture -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glGetSharpenTexFuncSGIS", (GLvoid *) NAME(glGetSharpenTexFuncSGIS) }, - { "glSharpenTexFuncSGIS", (GLvoid *) NAME(glSharpenTexFuncSGIS) }, -#undef NAME - - /* 25. GL_SGIS_multisample */ -#ifdef GL_SGIS_multisample -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glSampleMaskSGIS", (GLvoid *) NAME(glSampleMaskSGIS) }, - { "glSamplePatternSGIS", (GLvoid *) NAME(glSamplePatternSGIS) }, -#undef NAME - - /* 30. GL_EXT_vertex_array */ -#ifdef GL_EXT_vertex_array -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glArrayElementEXT", (GLvoid *) NAME(glArrayElementEXT) }, - { "glColorPointerEXT", (GLvoid *) NAME(glColorPointerEXT) }, - { "glDrawArraysEXT", (GLvoid *) NAME(glDrawArraysEXT) }, - { "glEdgeFlagPointerEXT", (GLvoid *) NAME(glEdgeFlagPointerEXT) }, - { "glGetPointervEXT", (GLvoid *) NAME(glGetPointervEXT) }, - { "glIndexPointerEXT", (GLvoid *) NAME(glIndexPointerEXT) }, - { "glNormalPointerEXT", (GLvoid *) NAME(glNormalPointerEXT) }, - { "glTexCoordPointerEXT", (GLvoid *) NAME(glTexCoordPointerEXT) }, - { "glVertexPointerEXT", (GLvoid *) NAME(glVertexPointerEXT) }, -#undef NAME - - /* 37. GL_EXT_blend_minmax */ -#ifdef GL_EXT_blend_minmax -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glBlendEquationEXT", (GLvoid *) NAME(glBlendEquationEXT) }, -#undef NAME - - /* 52. GL_SGIX_sprite */ -#ifdef GL_SGIX_sprite -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glSpriteParameterfSGIX", (GLvoid *) NAME(glSpriteParameterfSGIX) }, - { "glSpriteParameterfvSGIX", (GLvoid *) NAME(glSpriteParameterfvSGIX) }, - { "glSpriteParameteriSGIX", (GLvoid *) NAME(glSpriteParameteriSGIX) }, - { "glSpriteParameterivSGIX", (GLvoid *) NAME(glSpriteParameterivSGIX) }, -#undef NAME - - /* 54. GL_EXT_point_parameters */ -#ifdef GL_EXT_point_parameters -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glPointParameterfEXT", (GLvoid *) NAME(glPointParameterfEXT) }, - { "glPointParameterfvEXT", (GLvoid *) NAME(glPointParameterfvEXT) }, -#undef NAME - - /* 55. GL_SGIX_instruments */ -#ifdef GL_SGIX_instruments -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glInstrumentsBufferSGIX", (GLvoid *) NAME(glInstrumentsBufferSGIX) }, - { "glStartInstrumentsSGIX", (GLvoid *) NAME(glStartInstrumentsSGIX) }, - { "glStopInstrumentsSGIX", (GLvoid *) NAME(glStopInstrumentsSGIX) }, - { "glReadInstrumentsSGIX", (GLvoid *) NAME(glReadInstrumentsSGIX) }, - { "glPollInstrumentsSGIX", (GLvoid *) NAME(glPollInstrumentsSGIX) }, - { "glGetInstrumentsSGIX", (GLvoid *) NAME(glGetInstrumentsSGIX) }, -#undef NAME - - /* 57. GL_SGIX_framezoom */ -#ifdef GL_SGIX_framezoom -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glFrameZoomSGIX", (GLvoid *) NAME(glFrameZoomSGIX) }, -#undef NAME - - /* 60. GL_SGIX_reference_plane */ -#ifdef GL_SGIX_reference_plane -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glReferencePlaneSGIX", (GLvoid *) NAME(glReferencePlaneSGIX) }, -#undef NAME - - /* 61. GL_SGIX_flush_raster */ -#ifdef GL_SGIX_flush_raster -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glFlushRasterSGIX", (GLvoid *) NAME(glFlushRasterSGIX) }, -#undef NAME - - /* 66. GL_HP_image_transform */ -#ifdef GL_HP_image_transform -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glGetImageTransformParameterfvHP", (GLvoid *) NAME(glGetImageTransformParameterfvHP) }, - { "glGetImageTransformParameterivHP", (GLvoid *) NAME(glGetImageTransformParameterivHP) }, - { "glImageTransformParameterfHP", (GLvoid *) NAME(glImageTransformParameterfHP) }, - { "glImageTransformParameterfvHP", (GLvoid *) NAME(glImageTransformParameterfvHP) }, - { "glImageTransformParameteriHP", (GLvoid *) NAME(glImageTransformParameteriHP) }, - { "glImageTransformParameterivHP", (GLvoid *) NAME(glImageTransformParameterivHP) }, -#undef NAME - - /* 74. GL_EXT_color_subtable */ -#ifdef GL_EXT_color_subtable -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glColorSubTableEXT", (GLvoid *) NAME(glColorSubTableEXT) }, - { "glCopyColorSubTableEXT", (GLvoid *) NAME(glCopyColorSubTableEXT) }, -#undef NAME - - /* 77. GL_PGI_misc_hints */ -#ifdef GL_PGI_misc_hints -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glHintPGI", (GLvoid *) NAME(glHintPGI) }, -#undef NAME - - /* 78. GL_EXT_paletted_texture */ -#ifdef GL_EXT_paletted_texture -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glColorTableEXT", (GLvoid *) NAME(glColorTableEXT) }, - { "glGetColorTableEXT", (GLvoid *) NAME(glGetColorTableEXT) }, - { "glGetColorTableParameterfvEXT", (GLvoid *) NAME(glGetColorTableParameterfvEXT) }, - { "glGetColorTableParameterivEXT", (GLvoid *) NAME(glGetColorTableParameterivEXT) }, -#undef NAME - - /* 80. GL_SGIX_list_priority */ -#ifdef GL_SGIX_list_priority -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glGetListParameterfvSGIX", (GLvoid *) NAME(glGetListParameterfvSGIX) }, - { "glGetListParameterivSGIX", (GLvoid *) NAME(glGetListParameterivSGIX) }, - { "glListParameterfSGIX", (GLvoid *) NAME(glListParameterfSGIX) }, - { "glListParameterfvSGIX", (GLvoid *) NAME(glListParameterfvSGIX) }, - { "glListParameteriSGIX", (GLvoid *) NAME(glListParameteriSGIX) }, - { "glListParameterivSGIX", (GLvoid *) NAME(glListParameterivSGIX) }, -#undef NAME - - /* 94. GL_EXT_index_material */ -#ifdef GL_EXT_index_material -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glIndexMaterialEXT", (GLvoid *) NAME(glIndexMaterialEXT) }, -#undef NAME - - /* 95. GL_EXT_index_func */ -#ifdef GL_EXT_index_func -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glIndexFuncEXT", (GLvoid *) NAME(glIndexFuncEXT) }, -#undef NAME - - /* 97. GL_EXT_compiled_vertex_array */ -#ifdef GL_EXT_compiled_vertex_array -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glLockArraysEXT", (GLvoid *) NAME(glLockArraysEXT) }, - { "glUnlockArraysEXT", (GLvoid *) NAME(glUnlockArraysEXT) }, -#undef NAME - - /* 98. GL_EXT_cull_vertex */ -#ifdef GL_EXT_cull_vertex -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glCullParameterfvEXT", (GLvoid *) NAME(glCullParameterfvEXT) }, - { "glCullParameterdvEXT", (GLvoid *) NAME(glCullParameterdvEXT) }, -#undef NAME - - /* 173. GL_EXT/INGR_blend_func_separate */ -#ifdef GL_INGR_blend_func_separate -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glBlendFuncSeparateINGR", (GLvoid *) NAME(glBlendFuncSeparateINGR) }, -#undef NAME - - /* GL_MESA_window_pos */ -#ifdef MESA_window_pos -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glWindowPos4fMESA", (GLvoid *) NAME(glWindowPos4fMESA) }, -#undef NAME - - /* GL_MESA_resize_buffers */ -#ifdef MESA_resize_buffers -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glResizeBuffersMESA", (GLvoid *) NAME(glResizeBuffersMESA) }, -#undef NAME - - /* GL_ARB_transpose_matrix */ -#ifdef GL_ARB_transpose_matrix -#define NAME(X) X -#else -#define NAME(X) NotImplemented -#endif - { "glLoadTransposeMatrixdARB", (GLvoid *) NAME(glLoadTransposeMatrixdARB) }, - { "glLoadTransposeMatrixfARB", (GLvoid *) NAME(glLoadTransposeMatrixfARB) }, - { "glMultTransposeMatrixdARB", (GLvoid *) NAME(glMultTransposeMatrixdARB) }, - { "glMultTransposeMatrixfARB", (GLvoid *) NAME(glMultTransposeMatrixfARB) }, -#undef NAME +#if defined( USE_X86_ASM ) && defined( GLX_USE_TLS ) + extern void * _x86_get_dispatch(void); + const GLubyte * const get_disp = (const GLubyte *) _x86_get_dispatch; + GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start; - /* - * XXX many more extenstion functions to add. - */ - - { NULL, NULL } /* end of list marker */ -}; + while ( curr_func != (GLubyte *) gl_dispatch_functions_end ) { + (void) memcpy( curr_func, get_disp, 6 ); + curr_func += X86_DISPATCH_FUNCTION_SIZE; + } +#endif /* defined( USE_X86_ASM ) && defined( GLX_USE_TLS ) */ +}