Ian Romanick wrote:
Here's an updated version of that patch. There are some significant differences.
I hate it when I do that....
Index: src/mesa/glapi/gl_procs.py =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/glapi/gl_procs.py,v retrieving revision 1.1 diff -u -d -r1.1 gl_procs.py --- a/src/mesa/glapi/gl_procs.py 18 May 2004 18:33:40 -0000 1.1 +++ b/src/mesa/glapi/gl_procs.py 24 May 2004 23:04:12 -0000 @@ -36,48 +36,137 @@ class PrintGlProcs(gl_XML.FilterGLAPISpecBase): name = "gl_procs.py (from Mesa)" - def __init__(self): + def __init__(self, long_strings): + self.long_strings = long_strings gl_XML.FilterGLAPISpecBase.__init__(self) self.license = license.bsd_license_template % ( \ """Copyright (C) 1999-2001 Brian Paul All Rights Reserved. (C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") + def printRealHeader(self): - print '' print '/* This file is only included by glapi.c and is used for' print ' * the GetProcAddress() function' print ' */' print '' - print 'static const struct name_address_offset static_functions[] = {' + print 'typedef struct {' + print ' int Name_offset;' + print '#ifdef NEED_FUNCTION_POINTER' + print ' void * Address;' + print '#endif' + print ' unsigned int Offset;' + print '} glprocs_table_t;' + print '' + print '#ifdef NEED_FUNCTION_POINTER' + print '# define NAME_FUNC_OFFSET(n,f,o) { n , gl ## f , o }' + print '#else' + print '# define NAME_FUNC_OFFSET(n,f,o) { n , o }' + print '#endif' + print '' return def printRealFooter(self): - print ' { NULL, NULL, 0 } /* end of list marker */' - print '};' + print '' + print '#undef NAME_FUNC_OFFSET' return - def printFunction(self, f): - print ' { "gl%s", (GLvoid *) gl%s, _gloffset_%s },' \ - % (f.name, f.name, f.real_name) + def printFunctionString(self, f): + if self.long_strings: + print ' "gl%s\\0"' % (f.name) + else: + print " 'g','l',", + for c in f.name: + print "'%s'," % (c), + + print "'\\0'," + + def printFunctionOffset(self, f, offset_of_name): + print ' NAME_FUNC_OFFSET( % 5u, %s, _gloffset_%s ),' % (offset_of_name, f.name, f.real_name) + + + def printFunctions(self): + print '' + if self.long_strings: + print 'static const char gl_string_table[] =' + else: + print 'static const char gl_string_table[] = {' + + keys = self.functions.keys() + keys.sort() + for k in keys: + if k < 0: continue + self.printFunctionString(self.functions[k]) + + keys.reverse() + for k in keys: + if k >= -1: continue + self.printFunctionString(self.functions[k]) + + if self.long_strings: + print ' ;' + else: + print '};' + + print '' + print 'static const glprocs_table_t static_functions[] = {' + + keys = self.functions.keys() + keys.sort() + base_offset = 0 + for k in keys: + if k < 0: continue + self.printFunctionOffset(self.functions[k], base_offset) + + # The length of the function's name, plus 2 for "gl", + # plus 1 for the NUL. + + base_offset += len(self.functions[k].name) + 3 + + keys.reverse() + for k in keys: + if k >= -1: continue + self.printFunctionOffset(self.functions[k], base_offset) + + # The length of the function's name, plus 2 for "gl", + # plus 1 for the NUL. + + base_offset += len(self.functions[k].name) + 3 + + print ' NAME_FUNC_OFFSET( -1, NULL, -1 )' + print '};' + return def show_usage(): - print "Usage: %s [-f input_file_name]" % sys.argv[0] + print "Usage: %s [-f input_file_name] [-m mode]" % sys.argv[0] + print "mode can be one of:" + print " long - Create code for compilers that can handle very " + print " long string constants. (default)" + print " short - Create code for compilers that can only handle " + print " ANSI C89 string constants." sys.exit(1) if __name__ == '__main__': file_name = "gl_API.xml" try: - (args, trail) = getopt.getopt(sys.argv[1:], "f:") + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") except Exception,e: show_usage() + long_string = 1 for (arg,val) in args: if arg == "-f": file_name = val + elif arg == "-m": + if val == "short": + long_string = 0 + elif val == "long": + long_string = 1 + else: + show_usage() - dh = PrintGlProcs() + dh = PrintGlProcs( long_string ) parser = make_parser() parser.setFeature(feature_namespaces, 0) Index: src/mesa/glapi/gl_x86_asm.py =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/glapi/gl_x86_asm.py,v retrieving revision 1.1 diff -u -d -r1.1 gl_x86_asm.py --- a/src/mesa/glapi/gl_x86_asm.py 18 May 2004 18:33:40 -0000 1.1 +++ b/src/mesa/glapi/gl_x86_asm.py 24 May 2004 23:04:12 -0000 @@ -77,15 +77,57 @@ print '#define GLOBL_FN(x) GLOBL x' print '#endif' print '' - print '#define GL_STUB(fn,off,stack)\t\t\t\t\\' + print '#if defined(PTHREADS)' + print '# define GL_STUB(fn,off,fn_alt)\t\t\t\t\\' print 'ALIGNTEXT16;\t\t\t\t\t\t\\' - print 'GLOBL_FN(GL_PREFIX(fn, fn ## @ ## stack));\t\t\\' - print 'GL_PREFIX(fn, fn ## @ ## stack):\t\t\t\\' + print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\\' + print 'GL_PREFIX(fn, fn_alt):\t\t\t\\' print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\' + print '\tTEST_L(EAX, EAX) ;\t\t\t\t\\' + print '\tJE(1f) ;\t\t\t\t\t\\' + print '\tJMP(GL_OFFSET(off)) ;\t\t\t\t\\' + print '1:\tCALL(get_dispatch) ;\t\t\t\t\\' print '\tJMP(GL_OFFSET(off))' + print '#elif defined(THREADS)' + print '# define GL_STUB(fn,off,fn_alt)\t\t\t\t\\' + print 'ALIGNTEXT16;\t\t\t\t\t\t\\' + print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\\' + print 'GL_PREFIX(fn, fn_alt):\t\t\t\\' + print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\' + print '\tTEST_L(EAX, EAX) ;\t\t\t\t\\' + print '\tJE(1f) ;\t\t\t\t\t\\' + print '\tJMP(GL_OFFSET(off)) ;\t\t\t\t\\' + print '1:\tCALL(_glapi_get_dispatch) ;\t\t\t\t\\' + print '\tJMP(GL_OFFSET(off))' + print '#else /* Non-threaded version. */' + print '# define GL_STUB(fn,off,fn_alt)\t\t\t\t\\' + print 'ALIGNTEXT16;\t\t\t\t\t\t\\' + print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\\' + print 'GL_PREFIX(fn, fn_alt):\t\t\t\\' + print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\' + print '\tJMP(GL_OFFSET(off))' + print '#endif' print '' print 'SEG_TEXT' + print '' + print '#ifdef PTHREADS' print 'EXTERN GLNAME(_glapi_Dispatch)' + print 'EXTERN GLNAME(_gl_DispatchTSD)' + print 'EXTERN GLNAME(pthread_getspecific)' + print '' + print 'ALIGNTEXT16' + print 'GLNAME(get_dispatch):' + print '\tSUB_L(CONST(24), ESP)' + print '\tPUSH_L(GLNAME(_gl_DispatchTSD))' + print '\tCALL(GLNAME(pthread_getspecific))' + print '\tADD_L(CONST(28), ESP)' + print '\tRET' + print '#elif defined(THREADS)' + print 'EXTERN GLNAME(_glapi_get_dispatch)' + print '#endif' + print '' + print '\t\tALIGNTEXT16 ; GLOBL gl_dispatch_functions_start' + print 'gl_dispatch_functions_start:' print '' return @@ -95,11 +137,10 @@ return def printFunction(self, f): - if f.fn_offset == -1: return - stack = self.get_stack_size(f) - print '\tGL_STUB(%s, _gloffset_%s, %u)' % (f.name, f.real_name, stack) + alt = "[EMAIL PROTECTED]" % (f.name, stack) + print '\tGL_STUB(%s, _gloffset_%s, %s)' % (f.name, f.real_name, alt) return def show_usage(): Index: src/mesa/glapi/glapi.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/glapi/glapi.c,v retrieving revision 1.73 diff -u -d -r1.73 glapi.c --- a/src/mesa/glapi/glapi.c 23 Apr 2004 20:33:07 -0000 1.73 +++ b/src/mesa/glapi/glapi.c 24 May 2004 23:04:12 -0000 @@ -142,42 +142,11 @@ #if defined(THREADS) static GLboolean ThreadSafe = GL_FALSE; /* In thread-safe mode? */ -static _glthread_TSD DispatchTSD; /* Per-thread dispatch pointer */ +_glthread_TSD _gl_DispatchTSD; /* Per-thread dispatch pointer */ static _glthread_TSD RealDispatchTSD; /* only when using override */ static _glthread_TSD ContextTSD; /* Per-thread context pointer */ - -#define KEYWORD1 static -#define KEYWORD2 GLAPIENTRY -#define NAME(func) _ts_##func - -#define DISPATCH(FUNC, ARGS, MESSAGE) \ - struct _glapi_table *dispatch; \ - dispatch = (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); \ - if (!dispatch) \ - dispatch = (struct _glapi_table *) __glapi_noop_table; \ - (dispatch->FUNC) ARGS - -#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ - struct _glapi_table *dispatch; \ - dispatch = (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); \ - if (!dispatch) \ - dispatch = (struct _glapi_table *) __glapi_noop_table; \ - return (dispatch->FUNC) ARGS - -#define DISPATCH_TABLE_NAME __glapi_threadsafe_table -#define UNUSED_TABLE_NAME __usused_threadsafe_functions - -#define TABLE_ENTRY(name) (void *) _ts_##name - -static int _ts_Unused(void) -{ - return 0; -} - -#include "glapitemp.h" - -#endif +#endif /* defined(THREADS) */ /***** END THREAD-SAFE DISPATCH *****/ @@ -303,15 +272,15 @@ if (DispatchOverride) { _glthread_SetTSD(&RealDispatchTSD, (void *) dispatch); if (ThreadSafe) - _glapi_RealDispatch = (struct _glapi_table*) __glapi_threadsafe_table; + _glapi_RealDispatch = (struct _glapi_table*) NULL; else _glapi_RealDispatch = dispatch; } else { /* normal operation */ - _glthread_SetTSD(&DispatchTSD, (void *) dispatch); + _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch); if (ThreadSafe) - _glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table; + _glapi_Dispatch = (struct _glapi_table *) NULL; else _glapi_Dispatch = dispatch; } @@ -339,7 +308,7 @@ return (struct _glapi_table *) _glthread_GetTSD(&RealDispatchTSD); } else { - return (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); + return (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD); } } else { @@ -391,9 +360,9 @@ _glapi_set_dispatch(real); #if defined(THREADS) - _glthread_SetTSD(&DispatchTSD, (void *) override); + _glthread_SetTSD(&_gl_DispatchTSD, (void *) override); if (ThreadSafe) - _glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table; + _glapi_Dispatch = (struct _glapi_table *) NULL; else _glapi_Dispatch = override; #else @@ -427,7 +396,7 @@ else { if (DispatchOverride) { #if defined(THREADS) - return (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); + return (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD); #else return _glapi_Dispatch; #endif @@ -446,10 +415,30 @@ }; +#if !defined( USE_X86_ASM ) +#define NEED_FUNC_POINTER +#endif + /* The code in this file is auto-generated with Python */ #include "glprocs.h" +static const glprocs_table_t * +find_entry( const char * n ) +{ + unsigned 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. @@ -458,27 +447,67 @@ 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 static_functions[i].Offset; - } + const glprocs_table_t * const f = find_entry( funcName ); + + if ( f != NULL ) { + return f->Offset; } return -1; } +#ifdef USE_X86_ASM +extern const GLubyte gl_dispatch_functions_start[]; + +# if defined(PTHREADS) +# 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 GLvoid * get_static_proc_address(const char *funcName) { - GLint i; - for (i = 0; static_functions[i].Name; i++) { - if (strcmp(static_functions[i].Name, funcName) == 0) { - return static_functions[i].Address; + const glprocs_table_t * const f = find_entry( funcName ); + + if ( f != NULL ) { + return gl_dispatch_functions_start + + (X86_DISPATCH_FUNCTION_SIZE * f->Offset); + } + else { + return NULL; + } +} + +#else + +/* + * Return dispatch function address the named static (built-in) function. + * Return NULL if function not found. + */ +static const GLvoid * +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 */ + + +static const char * +get_static_proc_name( GLuint offset ) +{ + unsigned 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; @@ -802,13 +831,13 @@ const char * _glapi_get_proc_name(GLuint offset) { - const GLuint n = sizeof(static_functions) / sizeof(struct name_address_offset); GLuint i; + const char * n; /* search built-in functions */ - for (i = 0; i < n; i++) { - if (static_functions[i].Offset == offset) - return static_functions[i].Name; + n = get_static_proc_name(offset); + if ( n != NULL ) { + return n; } /* search added extension functions */ Index: src/mesa/main/dispatch.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/main/dispatch.c,v retrieving revision 1.31 diff -u -d -r1.31 dispatch.c --- a/src/mesa/main/dispatch.c 21 Oct 2003 22:22:19 -0000 1.31 +++ b/src/mesa/main/dispatch.c 24 May 2004 23:04:12 -0000 @@ -57,25 +57,40 @@ #define NAME(func) gl##func #endif +#if !defined __GNUC__ || __GNUC__ < 3 +# define __builtin_expect(x, y) x +#endif #if 0 /* Use this to log GL calls to stdout (for DEBUG only!) */ #define F stdout -#define DISPATCH(FUNC, ARGS, MESSAGE) \ - fprintf MESSAGE; \ - (_glapi_Dispatch->FUNC) ARGS; +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + const struct _glapi_table * const d = \ + (__builtin_expect(_glapi_Dispatch != NULL, 1)) \ + ? _glapiDispatch : _glapi_get_dispatch(); \ + fprintf MESSAGE; \ + (d->FUNC) ARGS; #define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ - fprintf MESSAGE; \ - return (_glapi_Dispatch->FUNC) ARGS + const struct _glapi_table * const d = \ + (__builtin_expect(_glapi_Dispatch != NULL, 1)) \ + ? _glapiDispatch : _glapi_get_dispatch(); \ + fprintf MESSAGE; \ + return (d->FUNC) ARGS; #else #define DISPATCH(FUNC, ARGS, MESSAGE) \ - (_glapi_Dispatch->FUNC) ARGS; + const struct _glapi_table * const d = \ + (__builtin_expect(_glapi_Dispatch != NULL, 1)) \ + ? _glapiDispatch : _glapi_get_dispatch(); \ + (d->FUNC) ARGS; #define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ - return (_glapi_Dispatch->FUNC) ARGS + const struct _glapi_table * const d = \ + (__builtin_expect(_glapi_Dispatch != NULL, 1)) \ + ? _glapiDispatch : _glapi_get_dispatch(); \ + return (d->FUNC) ARGS; #endif /* logging */