|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* Mesa 3-D graphics library |
|
|
* Mesa 3-D graphics library |
|
|
* Version: 6.3 |
|
|
|
|
|
|
|
|
* Version: 6.5 |
|
|
* |
|
|
* |
|
|
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved. |
|
|
|
|
|
|
|
|
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved. |
|
|
* |
|
|
* |
|
|
* Permission is hereby granted, free of charge, to any person obtaining a |
|
|
* Permission is hereby granted, free of charge, to any person obtaining a |
|
|
* copy of this software and associated documentation files (the "Software"), |
|
|
* copy of this software and associated documentation files (the "Software"), |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Set the global or per-thread dispatch table pointer. |
|
|
* Set the global or per-thread dispatch table pointer. |
|
|
|
|
|
* If the dispatch parameter is NULL we'll plug in the no-op dispatch |
|
|
|
|
|
* table (__glapi_noop_table). |
|
|
*/ |
|
|
*/ |
|
|
PUBLIC void |
|
|
PUBLIC void |
|
|
_glapi_set_dispatch(struct _glapi_table *dispatch) |
|
|
_glapi_set_dispatch(struct _glapi_table *dispatch) |
|
|
{ |
|
|
{ |
|
|
#if defined(PTHREADS) || defined(GLX_USE_TLS) |
|
|
#if defined(PTHREADS) || defined(GLX_USE_TLS) |
|
|
static pthread_once_t once_control = PTHREAD_ONCE_INIT; |
|
|
static pthread_once_t once_control = PTHREAD_ONCE_INIT; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_once( & once_control, init_glapi_relocs ); |
|
|
pthread_once( & once_control, init_glapi_relocs ); |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_glapi_get_dispatch(void) |
|
|
_glapi_get_dispatch(void) |
|
|
{ |
|
|
{ |
|
|
struct _glapi_table * api; |
|
|
struct _glapi_table * api; |
|
|
|
|
|
|
|
|
#if defined(GLX_USE_TLS) |
|
|
#if defined(GLX_USE_TLS) |
|
|
api = _glapi_tls_Dispatch; |
|
|
api = _glapi_tls_Dispatch; |
|
|
#elif defined(THREADS) |
|
|
#elif defined(THREADS) |
|
|
|
|
|
|
|
|
#else |
|
|
#else |
|
|
api = _glapi_Dispatch; |
|
|
api = _glapi_Dispatch; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
return api; |
|
|
return api; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
|
|
*** The rest of this file is pretty much concerned with GetProcAddress |
|
|
|
|
|
*** functionality. |
|
|
|
|
|
***/ |
|
|
|
|
|
|
|
|
#if !defined( USE_X86_ASM ) && !defined( XFree86Server ) && !defined ( XGLServer ) |
|
|
#if !defined( USE_X86_ASM ) && !defined( XFree86Server ) && !defined ( XGLServer ) |
|
|
#define NEED_FUNCTION_POINTER |
|
|
#define NEED_FUNCTION_POINTER |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
find_entry( const char * n ) |
|
|
find_entry( const char * n ) |
|
|
{ |
|
|
{ |
|
|
GLuint i; |
|
|
GLuint i; |
|
|
|
|
|
|
|
|
for (i = 0; static_functions[i].Name_offset >= 0; 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]; |
|
|
|
|
|
|
|
|
const char *testName = gl_string_table + static_functions[i].Name_offset; |
|
|
|
|
|
if (strcmp(testName, n) == 0) { |
|
|
|
|
|
return &static_functions[i]; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return NULL; |
|
|
return NULL; |
|
|
|
|
|
|
|
|
get_static_proc_offset(const char *funcName) |
|
|
get_static_proc_offset(const char *funcName) |
|
|
{ |
|
|
{ |
|
|
const glprocs_table_t * const f = find_entry( funcName ); |
|
|
const glprocs_table_t * const f = find_entry( funcName ); |
|
|
|
|
|
|
|
|
if ( f != NULL ) { |
|
|
|
|
|
|
|
|
if (f) { |
|
|
return f->Offset; |
|
|
return f->Offset; |
|
|
} |
|
|
} |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if !defined( XFree86Server ) && !defined( XGLServer ) |
|
|
|
|
|
|
|
|
#if !defined(XFree86Server) && !defined(XGLServer) |
|
|
#ifdef USE_X86_ASM |
|
|
#ifdef USE_X86_ASM |
|
|
|
|
|
|
|
|
#if defined( GLX_USE_TLS ) |
|
|
#if defined( GLX_USE_TLS ) |
|
|
|
|
|
|
|
|
# define X86_DISPATCH_FUNCTION_SIZE 16 |
|
|
# define X86_DISPATCH_FUNCTION_SIZE 16 |
|
|
# endif |
|
|
# endif |
|
|
|
|
|
|
|
|
|
|
|
#endif /* USE_X86_ASM */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Return dispatch function address the named static (built-in) function. |
|
|
|
|
|
|
|
|
* Return dispatch function address for the named static (built-in) function. |
|
|
* Return NULL if function not found. |
|
|
* Return NULL if function not found. |
|
|
*/ |
|
|
*/ |
|
|
static const _glapi_proc |
|
|
static const _glapi_proc |
|
|
get_static_proc_address(const char *funcName) |
|
|
get_static_proc_address(const char *funcName) |
|
|
{ |
|
|
{ |
|
|
const glprocs_table_t * const f = find_entry( funcName ); |
|
|
const glprocs_table_t * const f = find_entry( funcName ); |
|
|
|
|
|
|
|
|
if ( f != NULL ) { |
|
|
|
|
|
|
|
|
if (f) { |
|
|
|
|
|
#ifdef USE_X86_ASM |
|
|
return (_glapi_proc) (gl_dispatch_functions_start |
|
|
return (_glapi_proc) (gl_dispatch_functions_start |
|
|
+ (X86_DISPATCH_FUNCTION_SIZE * f->Offset)); |
|
|
+ (X86_DISPATCH_FUNCTION_SIZE * f->Offset)); |
|
|
|
|
|
#else |
|
|
|
|
|
return f->Address; |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
return NULL; |
|
|
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 /* !defined(XFree86Server) && !defined(XGLServer) */ |
|
|
|
|
|
|
|
|
#endif /* USE_X86_ASM */ |
|
|
|
|
|
#endif /* !defined( XFree86Server ) */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
|
|
|
|
|
|
get_static_proc_name( GLuint offset ) |
|
|
get_static_proc_name( GLuint offset ) |
|
|
{ |
|
|
{ |
|
|
GLuint i; |
|
|
GLuint i; |
|
|
|
|
|
|
|
|
for (i = 0; static_functions[i].Name_offset >= 0; i++) { |
|
|
for (i = 0; static_functions[i].Name_offset >= 0; i++) { |
|
|
if (static_functions[i].Offset == offset) { |
|
|
if (static_functions[i].Offset == offset) { |
|
|
return gl_string_table + static_functions[i].Name_offset; |
|
|
return gl_string_table + static_functions[i].Name_offset; |
|
|
|
|
|
|
|
|
0x81c0c000, /* jmpl %g3, %g0 */ |
|
|
0x81c0c000, /* jmpl %g3, %g0 */ |
|
|
0x01000000 /* nop */ |
|
|
0x01000000 /* nop */ |
|
|
}; |
|
|
}; |
|
|
#endif |
|
|
|
|
|
|
|
|
#endif /* __arch64__ */ |
|
|
unsigned int *code = (unsigned int *) malloc(sizeof(insn_template)); |
|
|
unsigned int *code = (unsigned int *) malloc(sizeof(insn_template)); |
|
|
unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch; |
|
|
unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch; |
|
|
if (code) { |
|
|
if (code) { |
|
|
|
|
|
|
|
|
__glapi_sparc_icache_flush(&code[0]); |
|
|
__glapi_sparc_icache_flush(&code[0]); |
|
|
code[2] |= (functionOffset * 4); |
|
|
code[2] |= (functionOffset * 4); |
|
|
__glapi_sparc_icache_flush(&code[2]); |
|
|
__glapi_sparc_icache_flush(&code[2]); |
|
|
#endif |
|
|
|
|
|
|
|
|
#endif /* __arch64__ */ |
|
|
} |
|
|
} |
|
|
return (_glapi_proc) code; |
|
|
return (_glapi_proc) code; |
|
|
#else |
|
|
#else |
|
|
|
|
|
|
|
|
#if defined(USE_X86_ASM) |
|
|
#if defined(USE_X86_ASM) |
|
|
GLubyte * const code = (GLubyte *) entrypoint; |
|
|
GLubyte * const code = (GLubyte *) entrypoint; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if X86_DISPATCH_FUNCTION_SIZE == 32 |
|
|
#if X86_DISPATCH_FUNCTION_SIZE == 32 |
|
|
*((unsigned int *)(code + 11)) = 4 * offset; |
|
|
*((unsigned int *)(code + 11)) = 4 * offset; |
|
|
*((unsigned int *)(code + 22)) = 4 * offset; |
|
|
*((unsigned int *)(code + 22)) = 4 * offset; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (offset == ~0) { |
|
|
if (offset == ~0) { |
|
|
offset = next_dynamic_offset; |
|
|
offset = next_dynamic_offset; |
|
|
next_dynamic_offset++; |
|
|
next_dynamic_offset++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for ( i = 0 ; function_names[i] != NULL ; i++ ) { |
|
|
for ( i = 0 ; function_names[i] != NULL ; i++ ) { |
|
|
if (! is_static[i] ) { |
|
|
if (! is_static[i] ) { |
|
|
if (entry[i] == NULL) { |
|
|
if (entry[i] == NULL) { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
entry[i]->parameter_signature = str_dup(real_sig); |
|
|
entry[i]->parameter_signature = str_dup(real_sig); |
|
|
fill_in_entrypoint_offset(entry[i]->dispatch_stub, offset); |
|
|
fill_in_entrypoint_offset(entry[i]->dispatch_stub, offset); |
|
|
entry[i]->dispatch_offset = offset; |
|
|
entry[i]->dispatch_offset = offset; |
|
|
|
|
|
|
|
|
return ExtEntryTable[i].dispatch_offset; |
|
|
return ExtEntryTable[i].dispatch_offset; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* search static functions */ |
|
|
/* search static functions */ |
|
|
return get_static_proc_offset(funcName); |
|
|
return get_static_proc_offset(funcName); |
|
|
} |
|
|
} |