X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fglapi%2Fglapi_getproc.c;h=1d0389e057469745db937a9ca75a505466758bc3;hb=f9cc6b3ee7c95130992d67c080ff9bc8e8a6d789;hp=6d40b495c7e71424d264bcba09d354c67e556a21;hpb=47ad296a183929c2007c35c60d722b4ac680417d;p=mesa.git diff --git a/src/mesa/glapi/glapi_getproc.c b/src/mesa/glapi/glapi_getproc.c index 6d40b495c7e..1d0389e0574 100644 --- a/src/mesa/glapi/glapi_getproc.c +++ b/src/mesa/glapi/glapi_getproc.c @@ -23,58 +23,36 @@ */ /** - * \file glapi_getproc. + * \file glapi_getproc.c * * Code for implementing glXGetProcAddress(), etc. * This was originally in glapi.c but refactored out. */ -#include -#include +#ifdef HAVE_DIX_CONFIG_H +#include +#include "glapi/mesa.h" +#else #include "main/glheader.h" -#include "glapi.h" -#include "glapioffsets.h" -#include "glapitable.h" - +#include "main/compiler.h" +#endif -static void -fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset); +#include "glapi/glapi.h" +#include "glapi/glapi_priv.h" +#include "glapi/glapitable.h" +#include "glapi/glapioffsets.h" -/** - * strdup() is actually not a standard ANSI C or POSIX routine. - * Irix will not define it if ANSI mode is in effect. +/********************************************************************** + * Static function management. */ -static char * -str_dup(const char *str) -{ - char *copy; - copy = (char*) malloc(strlen(str) + 1); - if (!copy) - return NULL; - strcpy(copy, str); - return copy; -} - -#if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS) -# define DISPATCH_FUNCTION_SIZE 16 -#elif defined(USE_X86_ASM) -# if defined(THREADS) && !defined(GLX_USE_TLS) -# define DISPATCH_FUNCTION_SIZE 32 -# else -# define DISPATCH_FUNCTION_SIZE 16 -# endif -#endif - -#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) && !defined(XGLServer) +#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) # define NEED_FUNCTION_POINTER #endif - -/* The code in this file is auto-generated with Python */ -#include "glprocs.h" +#include "glapi/glprocs.h" /** @@ -82,12 +60,18 @@ str_dup(const char *str) * and return the corresponding glprocs_table_t entry. */ static const glprocs_table_t * -find_entry( const char * n ) +get_static_proc( const char * n ) { GLuint i; for (i = 0; static_functions[i].Name_offset >= 0; i++) { const char *testName = gl_string_table + static_functions[i].Name_offset; - if (strcmp(testName, n) == 0) { +#ifdef MANGLE + /* skip the prefix on the name */ + if (strcmp(testName, n + 1) == 0) +#else + if (strcmp(testName, n) == 0) +#endif + { return &static_functions[i]; } } @@ -102,26 +86,16 @@ find_entry( const char * n ) static GLint get_static_proc_offset(const char *funcName) { - const glprocs_table_t * const f = find_entry( funcName ); - if (f) { - return f->Offset; + const glprocs_table_t * const f = get_static_proc( funcName ); + if (f == NULL) { + return -1; } - return -1; -} + return f->Offset; +} -#if !defined(XFree86Server) && !defined(XGLServer) -#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 - -#endif /* USE_X86_ASM */ +#if !defined(XFree86Server) /** * Return dispatch function address for the named static (built-in) function. @@ -130,27 +104,32 @@ extern const GLubyte gl_dispatch_functions_start[]; static _glapi_proc get_static_proc_address(const char *funcName) { - const glprocs_table_t * const f = find_entry( funcName ); - if (f) { + const glprocs_table_t * const f = get_static_proc( funcName ); + if (f == NULL) { + return NULL; + } + #if defined(DISPATCH_FUNCTION_SIZE) && defined(GLX_INDIRECT_RENDERING) - return (f->Address == NULL) - ? (_glapi_proc) (gl_dispatch_functions_start - + (DISPATCH_FUNCTION_SIZE * f->Offset)) - : f->Address; + return (f->Address == NULL) + ? get_entrypoint_address(f->Offset) + : f->Address; #elif defined(DISPATCH_FUNCTION_SIZE) - return (_glapi_proc) (gl_dispatch_functions_start - + (DISPATCH_FUNCTION_SIZE * f->Offset)); + return get_entrypoint_address(f->Offset); #else - return f->Address; + return f->Address; #endif - } - else { - return NULL; - } } -#endif /* !defined(XFree86Server) && !defined(XGLServer) */ +#else + +static _glapi_proc +get_static_proc_address(const char *funcName) +{ + (void) funcName; + return NULL; +} +#endif /* !defined(XFree86Server) */ /** @@ -221,137 +200,79 @@ struct _glapi_function { }; +/* + * Number of extension functions which we can dynamically add at runtime. + */ +#define MAX_EXTENSION_FUNCS 300 + + 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 _glapi_proc -generate_entrypoint(GLuint functionOffset) +static struct _glapi_function * +get_extension_proc(const char *funcName) { -#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 - + (DISPATCH_FUNCTION_SIZE * 32); - GLubyte * const code = (GLubyte *) malloc(DISPATCH_FUNCTION_SIZE); + GLuint i; + for (i = 0; i < NumExtEntryPoints; i++) { + if (strcmp(ExtEntryTable[i].name, funcName) == 0) { + return & ExtEntryTable[i]; + } + } + return NULL; +} - if ( code != NULL ) { - (void) memcpy(code, template_func, DISPATCH_FUNCTION_SIZE); - fill_in_entrypoint_offset( (_glapi_proc) code, functionOffset ); +static GLint +get_extension_proc_offset(const char *funcName) +{ + const struct _glapi_function * const f = get_extension_proc( funcName ); + if (f == NULL) { + return -1; } - 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 /* __arch64__ */ - 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 /* __arch64__ */ - } - return (_glapi_proc) code; -#else - (void) functionOffset; - return NULL; -#endif /* USE_*_ASM */ + return f->dispatch_offset; } -/** - * This function inserts a new dispatch offset into the assembly language - * stub that was generated with the preceeding function. - */ -static void -fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset) +static _glapi_proc +get_extension_proc_address(const char *funcName) { -#if defined(USE_X86_ASM) - GLubyte * const code = (GLubyte *) entrypoint; - -#if DISPATCH_FUNCTION_SIZE == 32 - *((unsigned int *)(code + 11)) = 4 * offset; - *((unsigned int *)(code + 22)) = 4 * offset; -#elif DISPATCH_FUNCTION_SIZE == 16 && defined( GLX_USE_TLS ) - *((unsigned int *)(code + 8)) = 4 * offset; -#elif DISPATCH_FUNCTION_SIZE == 16 - *((unsigned int *)(code + 7)) = 4 * offset; -#else -# error Invalid DISPATCH_FUNCTION_SIZE! -#endif + const struct _glapi_function * const f = get_extension_proc( funcName ); + if (f == NULL) { + return NULL; + } -#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__ */ + return f->dispatch_stub; +} -#else - /* an unimplemented architecture */ - (void) entrypoint; - (void) offset; +static const char * +get_extension_proc_name(GLuint offset) +{ + GLuint i; + for (i = 0; i < NumExtEntryPoints; i++) { + if (ExtEntryTable[i].dispatch_offset == offset) { + return ExtEntryTable[i].name; + } + } + return NULL; +} -#endif /* USE_*_ASM */ + +/** + * 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; } @@ -447,7 +368,6 @@ _glapi_add_dispatch( const char * const * function_names, struct _glapi_function * entry[8]; GLboolean is_static[8]; unsigned i; - unsigned j; int offset = ~0; int new_offset; @@ -482,28 +402,25 @@ _glapi_add_dispatch( const char * const * function_names, } - for ( j = 0 ; j < NumExtEntryPoints ; j++ ) { - if (strcmp(ExtEntryTable[j].name, function_names[i]) == 0) { + entry[i] = get_extension_proc(function_names[i]); + + if (entry[i] != NULL) { + /* 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) { + if (entry[i]->dispatch_offset != ~0) { + if (strcmp(real_sig, entry[i]->parameter_signature) != 0) { return -1; } - if ( (offset != ~0) && (ExtEntryTable[j].dispatch_offset != offset) ) { + if ( (offset != ~0) && (entry[i]->dispatch_offset != offset) ) { return -1; } - offset = ExtEntryTable[j].dispatch_offset; + offset = entry[i]->dispatch_offset; } - - entry[i] = & ExtEntryTable[j]; - break; - } } } @@ -539,13 +456,13 @@ _glapi_add_dispatch( const char * const * function_names, PUBLIC GLint _glapi_get_proc_offset(const char *funcName) { + GLint offset; + /* search extension functions first */ - GLuint i; - for (i = 0; i < NumExtEntryPoints; i++) { - if (strcmp(ExtEntryTable[i].name, funcName) == 0) { - return ExtEntryTable[i].dispatch_offset; - } - } + offset = get_extension_proc_offset(funcName); + if (offset >= 0) + return offset; + /* search static functions */ return get_static_proc_offset(funcName); } @@ -557,14 +474,15 @@ _glapi_get_proc_offset(const char *funcName) * in the name of static functions, try generating a new API entrypoint on * the fly with assembly language. */ -_glapi_proc +PUBLIC _glapi_proc _glapi_get_proc_address(const char *funcName) { + _glapi_proc func; struct _glapi_function * entry; - GLuint i; #ifdef MANGLE - if (funcName[0] != 'm' || funcName[1] != 'g' || funcName[2] != 'l') + /* skip the prefix on the name */ + if (funcName[1] != 'g' || funcName[2] != 'l') return NULL; #else if (funcName[0] != 'g' || funcName[1] != 'l') @@ -572,20 +490,14 @@ _glapi_get_proc_address(const char *funcName) #endif /* search extension functions first */ - for (i = 0; i < NumExtEntryPoints; i++) { - if (strcmp(ExtEntryTable[i].name, funcName) == 0) { - return ExtEntryTable[i].dispatch_stub; - } - } + func = get_extension_proc_address(funcName); + if (func) + return func; -#if !defined( XFree86Server ) && !defined( XGLServer ) /* search static functions */ - { - const _glapi_proc func = get_static_proc_address(funcName); - if (func) - return func; - } -#endif /* !defined( XFree86Server ) */ + func = get_static_proc_address(funcName); + if (func) + return func; entry = add_function_name(funcName); return (entry == NULL) ? NULL : entry->dispatch_stub; @@ -600,7 +512,6 @@ _glapi_get_proc_address(const char *funcName) const char * _glapi_get_proc_name(GLuint offset) { - GLuint i; const char * n; /* search built-in functions */ @@ -610,10 +521,121 @@ _glapi_get_proc_name(GLuint offset) } /* search added extension functions */ - for (i = 0; i < NumExtEntryPoints; i++) { - if (ExtEntryTable[i].dispatch_offset == offset) { - return ExtEntryTable[i].name; - } + return get_extension_proc_name(offset); +} + + + +/********************************************************************** + * GL API table functions. + */ + + +/* + * 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) + + +/** + * Return size of dispatch table struct as number of functions (or + * slots). + */ +PUBLIC GLuint +_glapi_get_dispatch_table_size(void) +{ + return DISPATCH_TABLE_SIZE; +} + + +/** + * Make sure there are no NULL pointers in the given dispatch table. + * Intended for debugging purposes. + */ +void +_glapi_check_table_not_null(const struct _glapi_table *table) +{ +#ifdef EXTRA_DEBUG /* set to DEBUG for extra DEBUG */ + const GLuint entries = _glapi_get_dispatch_table_size(); + const void **tab = (const void **) table; + GLuint i; + for (i = 1; i < entries; i++) { + assert(tab[i]); } - return NULL; +#else + (void) table; +#endif +} + + +/** + * Do some spot checks to be sure that the dispatch table + * slots are assigned correctly. For debugging only. + */ +void +_glapi_check_table(const struct _glapi_table *table) +{ +#ifdef EXTRA_DEBUG /* set to DEBUG for extra DEBUG */ + { + GLuint BeginOffset = _glapi_get_proc_offset("glBegin"); + char *BeginFunc = (char*) &table->Begin; + GLuint offset = (BeginFunc - (char *) table) / sizeof(void *); + assert(BeginOffset == _gloffset_Begin); + assert(BeginOffset == offset); + } + { + GLuint viewportOffset = _glapi_get_proc_offset("glViewport"); + char *viewportFunc = (char*) &table->Viewport; + GLuint offset = (viewportFunc - (char *) table) / sizeof(void *); + assert(viewportOffset == _gloffset_Viewport); + assert(viewportOffset == offset); + } + { + GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer"); + char *VertexPointerFunc = (char*) &table->VertexPointer; + GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *); + assert(VertexPointerOffset == _gloffset_VertexPointer); + assert(VertexPointerOffset == offset); + } + { + GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax"); + char *ResetMinMaxFunc = (char*) &table->ResetMinmax; + GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *); + assert(ResetMinMaxOffset == _gloffset_ResetMinmax); + assert(ResetMinMaxOffset == offset); + } + { + GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor"); + char *blendColorFunc = (char*) &table->BlendColor; + GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *); + assert(blendColorOffset == _gloffset_BlendColor); + assert(blendColorOffset == offset); + } + { + 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); + } + { + 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); + } + { + 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); + } +#else + (void) table; +#endif }