glapi_getproc.c revision 5b2340c493cdf8d776e717b00acf0a8002858976
1a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/* 2a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Mesa 3-D graphics library 3a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Version: 7.1 4a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 5a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 7a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 8a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * copy of this software and associated documentation files (the "Software"), 9a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * to deal in the Software without restriction, including without limitation 10a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 12a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Software is furnished to do so, subject to the following conditions: 13a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 14a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The above copyright notice and this permission notice shall be included 15a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * in all copies or substantial portions of the Software. 16a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 17a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 24a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 25a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 261eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee * \file glapi_getproc.c 27a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 28a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Code for implementing glXGetProcAddress(), etc. 29a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This was originally in glapi.c but refactored out. 30a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 31a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 32a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 33ec91810147425f4123ec80117109925e054cc66dGeorge Sapountzis#ifdef HAVE_DIX_CONFIG_H 34ec91810147425f4123ec80117109925e054cc66dGeorge Sapountzis#include <dix-config.h> 35ec91810147425f4123ec80117109925e054cc66dGeorge Sapountzis#include "glapi/mesa.h" 36ec91810147425f4123ec80117109925e054cc66dGeorge Sapountzis#else 378e7d941d7a29aaf66f94892b3f97670c0e972c8cKeith Whitwell#include "main/glheader.h" 38f2c023291a1f2887294d2aac504f8b82857ad092Brian Paul#include "main/compiler.h" 39ec91810147425f4123ec80117109925e054cc66dGeorge Sapountzis#endif 40ec91810147425f4123ec80117109925e054cc66dGeorge Sapountzis 415b426288c2dbc42ef44ea13fe37afa77223107bbChia-I Wu#include "glapi/glapi.h" 422c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#include "glapi/glapi_priv.h" 435b426288c2dbc42ef44ea13fe37afa77223107bbChia-I Wu#include "glapi/glapitable.h" 442c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#include "glapi/glapioffsets.h" 45a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 46a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 47fe14868d96d4820dba73c3a507d191b8a73c6870George Sapountzis#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) 48a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# define NEED_FUNCTION_POINTER 49a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 50a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 51a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/* The code in this file is auto-generated with Python */ 525b426288c2dbc42ef44ea13fe37afa77223107bbChia-I Wu#include "glapi/glprocs.h" 53a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 54a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 55a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 56a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Search the table of static entrypoint functions for the named function 57a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * and return the corresponding glprocs_table_t entry. 58a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 59a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic const glprocs_table_t * 60a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulfind_entry( const char * n ) 61a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 62a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 63a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; static_functions[i].Name_offset >= 0; i++) { 64a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char *testName = gl_string_table + static_functions[i].Name_offset; 654447fddc82a2c0245e798c90492293d875d186d0Brian Paul#ifdef MANGLE 6620ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis /* skip the prefix on the name */ 674447fddc82a2c0245e798c90492293d875d186d0Brian Paul if (strcmp(testName, n + 1) == 0) 684447fddc82a2c0245e798c90492293d875d186d0Brian Paul#else 694447fddc82a2c0245e798c90492293d875d186d0Brian Paul if (strcmp(testName, n) == 0) 704447fddc82a2c0245e798c90492293d875d186d0Brian Paul#endif 714447fddc82a2c0245e798c90492293d875d186d0Brian Paul { 72a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return &static_functions[i]; 73a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 74a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 75a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 76a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 77a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 78a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 79a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 80a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return dispatch table offset of the named static (built-in) function. 81a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return -1 if function not found. 82a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 83a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic GLint 84a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_offset(const char *funcName) 85a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 86a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const glprocs_table_t * const f = find_entry( funcName ); 87a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (f) { 88a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return f->Offset; 89a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 90a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 91a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 92a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 93a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 94fe14868d96d4820dba73c3a507d191b8a73c6870George Sapountzis#if !defined(XFree86Server) 95cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 96a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 97a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return dispatch function address for the named static (built-in) function. 98a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return NULL if function not found. 99a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 100a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic _glapi_proc 101a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_address(const char *funcName) 102a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 103a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const glprocs_table_t * const f = find_entry( funcName ); 104a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (f) { 105a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if defined(DISPATCH_FUNCTION_SIZE) && defined(GLX_INDIRECT_RENDERING) 106a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return (f->Address == NULL) 10754ba95a4de749de1da73b3917aac99eb1d57d7faGeorge Sapountzis ? get_entrypoint_address(f->Offset) 108a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul : f->Address; 109a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#elif defined(DISPATCH_FUNCTION_SIZE) 11054ba95a4de749de1da73b3917aac99eb1d57d7faGeorge Sapountzis return get_entrypoint_address(f->Offset); 111a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 112a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return f->Address; 113a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 114a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 115a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul else { 116a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 117a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 118a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 119a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 120fe14868d96d4820dba73c3a507d191b8a73c6870George Sapountzis#endif /* !defined(XFree86Server) */ 121a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 122a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 123a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 124a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 125a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return the name of the function at the given offset in the dispatch 126a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * table. For debugging only. 127a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 128a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic const char * 129a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_name( GLuint offset ) 130a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 131a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 132a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; static_functions[i].Name_offset >= 0; i++) { 133a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (static_functions[i].Offset == offset) { 134a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return gl_string_table + static_functions[i].Name_offset; 135a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 136a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 137a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 138a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 139a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 140a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 141a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 142a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/********************************************************************** 143a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Extension function management. 144a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 145a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 146a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 147a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 148a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Track information about a function added to the GL API. 149a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 150a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstruct _glapi_function { 151a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 152a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Name of the function. 153a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 154a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * name; 155a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 156a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 157a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 158a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Text string that describes the types of the parameters passed to the 159a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * named function. Parameter types are converted to characters using the 160a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * following rules: 161a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'i' for \c GLint, \c GLuint, and \c GLenum 162a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'p' for any pointer type 163a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'f' for \c GLfloat and \c GLclampf 164a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'd' for \c GLdouble and \c GLclampd 165a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 166a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * parameter_signature; 167a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 168a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 169a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 170a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Offset in the dispatch table where the pointer to the real function is 171a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * located. If the driver has not requested that the named function be 172a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * added to the dispatch table, this will have the value ~0. 173a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 174a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned dispatch_offset; 175a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 176a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 177a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 178a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Pointer to the dispatch stub for the named function. 179a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 180a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 181a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The semantic of this field should be changed slightly. Currently, it 182a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * is always expected to be non-\c NULL. However, it would be better to 183a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * only allocate the entry-point stub when the application requests the 184a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * function via \c glXGetProcAddress. This would save memory for all the 185a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * functions that the driver exports but that the application never wants 186a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * to call. 187a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 188a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul _glapi_proc dispatch_stub; 189a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul}; 190a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 191a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 1922c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/* 1932c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Number of extension functions which we can dynamically add at runtime. 1942c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 1952c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#define MAX_EXTENSION_FUNCS 300 1962c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 1972c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 198a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS]; 199a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic GLuint NumExtEntryPoints = 0; 200a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 201a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 2025b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisstatic struct _glapi_function * 2035b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisget_extension_proc(const char *funcName) 20458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 20558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLuint i; 20658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis for (i = 0; i < NumExtEntryPoints; i++) { 20758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (strcmp(ExtEntryTable[i].name, funcName) == 0) { 2085b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return & ExtEntryTable[i]; 20958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 21058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 2115b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return NULL; 2125b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis} 2135b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2145b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2155b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisstatic GLint 2165b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisget_extension_proc_offset(const char *funcName) 2175b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis{ 2185b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis const struct _glapi_function * const f = get_extension_proc( funcName ); 2195b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis if (f == NULL) { 2205b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return -1; 2215b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis } 2225b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2235b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return f->dispatch_offset; 22458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 22558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 22658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 22758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisstatic _glapi_proc 22858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisget_extension_proc_address(const char *funcName) 22958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 2305b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis const struct _glapi_function * const f = get_extension_proc( funcName ); 2315b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis if (f == NULL) { 2325b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return NULL; 23358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 2345b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2355b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return f->dispatch_stub; 23658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 23758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 23858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 23958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisstatic const char * 24058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisget_extension_proc_name(GLuint offset) 24158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 24258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLuint i; 24358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis for (i = 0; i < NumExtEntryPoints; i++) { 24458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (ExtEntryTable[i].dispatch_offset == offset) { 24558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return ExtEntryTable[i].name; 24658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 24758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 24858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return NULL; 24958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 25058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 25158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 252a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 253cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis * strdup() is actually not a standard ANSI C or POSIX routine. 254cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis * Irix will not define it if ANSI mode is in effect. 255cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis */ 256cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzisstatic char * 257cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzisstr_dup(const char *str) 258cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis{ 259cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis char *copy; 260cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis copy = (char*) malloc(strlen(str) + 1); 261cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis if (!copy) 262cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis return NULL; 263cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis strcpy(copy, str); 264cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis return copy; 265cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis} 266cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 267cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 268cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis/** 269a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Generate new entrypoint 270a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 271a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Use a temporary dispatch offset of ~0 (i.e. -1). Later, when the driver 272a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * calls \c _glapi_add_dispatch we'll put in the proper offset. If that 273a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * never happens, and the user calls this function, he'll segfault. That's 274a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * what you get when you try calling a GL function that doesn't really exist. 275a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 276a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param funcName Name of the function to create an entry-point for. 277a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 278a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \sa _glapi_add_entrypoint 279a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 280a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 281a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic struct _glapi_function * 282a97226352fb8063d4d0084523312b4880dae5ac7Brian Pauladd_function_name( const char * funcName ) 283a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 284a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry = NULL; 285a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 286a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (NumExtEntryPoints < MAX_EXTENSION_FUNCS) { 287a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul _glapi_proc entrypoint = generate_entrypoint(~0); 288a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (entrypoint != NULL) { 289a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry = & ExtEntryTable[NumExtEntryPoints]; 290a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 291a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ExtEntryTable[NumExtEntryPoints].name = str_dup(funcName); 292a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ExtEntryTable[NumExtEntryPoints].parameter_signature = NULL; 293a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ExtEntryTable[NumExtEntryPoints].dispatch_offset = ~0; 294a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ExtEntryTable[NumExtEntryPoints].dispatch_stub = entrypoint; 295a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul NumExtEntryPoints++; 296a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 297a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 298a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 299a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return entry; 300a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 301a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 302a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 303a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 304a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Fill-in the dispatch stub for the named function. 305a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 306a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function is intended to be called by a hardware driver. When called, 307a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * a dispatch stub may be created created for the function. A pointer to this 308a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * dispatch function will be returned by glXGetProcAddress. 309a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 310a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param function_names Array of pointers to function names that should 311a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * share a common dispatch offset. 312a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param parameter_signature String representing the types of the parameters 313a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * passed to the named function. Parameter types 314a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * are converted to characters using the following 315a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * rules: 316a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'i' for \c GLint, \c GLuint, and \c GLenum 317a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'p' for any pointer type 318a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'f' for \c GLfloat and \c GLclampf 319a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'd' for \c GLdouble and \c GLclampd 320a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 321a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \returns 322a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The offset in the dispatch table of the named function. A pointer to the 323a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * driver's implementation of the named function should be stored at 324a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c dispatch_table[\c offset]. Return -1 if error/problem. 325a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 326a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \sa glXGetProcAddress 327a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 328a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \warning 329a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function can only handle up to 8 names at a time. As far as I know, 330a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the maximum number of names ever associated with an existing GL function is 331a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, 332a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c glPointParameterfARB, and \c glPointParameterf), so this should not be 333a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * too painful of a limitation. 334a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 335a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 336a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Determine whether or not \c parameter_signature should be allowed to be 337a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c NULL. It doesn't seem like much of a hardship for drivers to have to 338a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * pass in an empty string. 339a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 340a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 341a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Determine if code should be added to reject function names that start with 342a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 'glX'. 343a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 344a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \bug 345a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Add code to compare \c parameter_signature with the parameter signature of 346a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * a static function. In order to do that, we need to find a way to \b get 347a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the parameter signature of a static function. 348a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 349a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 350a97226352fb8063d4d0084523312b4880dae5ac7Brian PaulPUBLIC int 351a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_add_dispatch( const char * const * function_names, 352a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * parameter_signature ) 353a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 354a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul static int next_dynamic_offset = _gloffset_FIRST_DYNAMIC; 355a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * const real_sig = (parameter_signature != NULL) 356a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ? parameter_signature : ""; 357a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry[8]; 358a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLboolean is_static[8]; 359a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned i; 360a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned j; 361a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul int offset = ~0; 362a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul int new_offset; 363a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 364a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 365a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memset( is_static, 0, sizeof( is_static ) ); 366a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memset( entry, 0, sizeof( entry ) ); 367a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 368a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( i = 0 ; function_names[i] != NULL ; i++ ) { 369a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* Do some trivial validation on the name of the function. 370a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 371a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 372a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (!function_names[i] || function_names[i][0] != 'g' || function_names[i][1] != 'l') 373a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 374a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 375a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* Determine if the named function already exists. If the function does 376a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * exist, it must have the same parameter signature as the function 377a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * being added. 378a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 379a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 380a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul new_offset = get_static_proc_offset(function_names[i]); 381a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (new_offset >= 0) { 382a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* FIXME: Make sure the parameter signatures match! How do we get 383a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * FIXME: the parameter signature for static functions? 384a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 385a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 386a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( (offset != ~0) && (new_offset != offset) ) { 387a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 388a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 389a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 390a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul is_static[i] = GL_TRUE; 391a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul offset = new_offset; 392a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 393a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 394a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 395a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( j = 0 ; j < NumExtEntryPoints ; j++ ) { 396a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (strcmp(ExtEntryTable[j].name, function_names[i]) == 0) { 397a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* The offset may be ~0 if the function name was added by 398a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * glXGetProcAddress but never filled in by the driver. 399a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 400a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 401a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (ExtEntryTable[j].dispatch_offset != ~0) { 402a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (strcmp(real_sig, ExtEntryTable[j].parameter_signature) 403a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul != 0) { 404a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 405a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 406a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 407a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( (offset != ~0) && (ExtEntryTable[j].dispatch_offset != offset) ) { 408a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 409a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 410a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 411a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul offset = ExtEntryTable[j].dispatch_offset; 412a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 413a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 414a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry[i] = & ExtEntryTable[j]; 415a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul break; 416a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 417a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 418a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 419a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 420a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (offset == ~0) { 421a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul offset = next_dynamic_offset; 422a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul next_dynamic_offset++; 423a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 424a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 425a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( i = 0 ; function_names[i] != NULL ; i++ ) { 426a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (! is_static[i] ) { 427a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (entry[i] == NULL) { 428a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry[i] = add_function_name( function_names[i] ); 429a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (entry[i] == NULL) { 430a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* FIXME: Possible memory leak here. 431a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 432a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 433a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 434a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 435a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 436a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry[i]->parameter_signature = str_dup(real_sig); 437a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul fill_in_entrypoint_offset(entry[i]->dispatch_stub, offset); 438a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry[i]->dispatch_offset = offset; 439a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 440a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 441a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 442a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return offset; 443a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 444a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 445a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 446a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 447a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return offset of entrypoint for named function within dispatch table. 448a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 449a97226352fb8063d4d0084523312b4880dae5ac7Brian PaulPUBLIC GLint 450a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_offset(const char *funcName) 451a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 45258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLint offset; 45358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 454a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search extension functions first */ 45558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis offset = get_extension_proc_offset(funcName); 45658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (offset >= 0) 45758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return offset; 45858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 459a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search static functions */ 460a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return get_static_proc_offset(funcName); 461a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 462a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 463a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 464a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 465a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 466a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return pointer to the named function. If the function name isn't found 467a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * in the name of static functions, try generating a new API entrypoint on 468a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the fly with assembly language. 469a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 4708d62eb45997a199e116661e26217b4d44fb9ba1eKristian HøgsbergPUBLIC _glapi_proc 471a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_address(const char *funcName) 472a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 47358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis _glapi_proc func; 474a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry; 475a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 476a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#ifdef MANGLE 47720ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis /* skip the prefix on the name */ 47820ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis if (funcName[1] != 'g' || funcName[2] != 'l') 479a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 480a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 481a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (funcName[0] != 'g' || funcName[1] != 'l') 482a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 483a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 484a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 485a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search extension functions first */ 48658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis func = get_extension_proc_address(funcName); 48758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (func) 48858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return func; 489a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 490fe14868d96d4820dba73c3a507d191b8a73c6870George Sapountzis#if !defined( XFree86Server ) 491a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search static functions */ 492a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul { 493a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const _glapi_proc func = get_static_proc_address(funcName); 494a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (func) 495a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return func; 496a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 497a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif /* !defined( XFree86Server ) */ 498a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 499a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry = add_function_name(funcName); 500a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return (entry == NULL) ? NULL : entry->dispatch_stub; 501a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 502a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 503a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 504a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 505a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 506a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return the name of the function at the given dispatch offset. 507a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This is only intended for debugging. 508a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 509a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulconst char * 510a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_name(GLuint offset) 511a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 512a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * n; 513a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 514a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search built-in functions */ 515a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul n = get_static_proc_name(offset); 516a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( n != NULL ) { 517a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return n; 518a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 519a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 520a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search added extension functions */ 52158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return get_extension_proc_name(offset); 522a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 523fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 524fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 525fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 5262c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/********************************************************************** 5272c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * GL API table functions. 5282c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 5292c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5302c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5312c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/* 5322c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * The dispatch table size (number of entries) is the size of the 5332c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * _glapi_table struct plus the number of dynamic entries we can add. 5342c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * The extra slots can be filled in by DRI drivers that register new extension 5352c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * functions. 5362c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 5372c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS) 5382c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5392c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5402c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/** 5412c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Return size of dispatch table struct as number of functions (or 5422c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * slots). 5432c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 5442c8b5ffed9a787e896b540a95be48ef401d5f007George SapountzisPUBLIC GLuint 5452c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis_glapi_get_dispatch_table_size(void) 5462c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis{ 5472c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis return DISPATCH_TABLE_SIZE; 5482c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis} 5492c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5502c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5512c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/** 5522c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Make sure there are no NULL pointers in the given dispatch table. 5532c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Intended for debugging purposes. 5542c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 5552c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzisvoid 5562c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis_glapi_check_table_not_null(const struct _glapi_table *table) 5572c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis{ 5582c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#ifdef EXTRA_DEBUG /* set to DEBUG for extra DEBUG */ 5592c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis const GLuint entries = _glapi_get_dispatch_table_size(); 5602c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis const void **tab = (const void **) table; 5612c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis GLuint i; 5622c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis for (i = 1; i < entries; i++) { 5632c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis assert(tab[i]); 5642c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis } 5652c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#else 5662c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis (void) table; 5672c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#endif 5682c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis} 5692c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5702c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 571fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis/** 572fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis * Do some spot checks to be sure that the dispatch table 573fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis * slots are assigned correctly. For debugging only. 574fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis */ 575fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzisvoid 576fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis_glapi_check_table(const struct _glapi_table *table) 577fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis{ 5782c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#ifdef EXTRA_DEBUG /* set to DEBUG for extra DEBUG */ 579fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 580fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint BeginOffset = _glapi_get_proc_offset("glBegin"); 581fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *BeginFunc = (char*) &table->Begin; 582fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (BeginFunc - (char *) table) / sizeof(void *); 583fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(BeginOffset == _gloffset_Begin); 584fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(BeginOffset == offset); 585fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 586fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 587fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint viewportOffset = _glapi_get_proc_offset("glViewport"); 588fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *viewportFunc = (char*) &table->Viewport; 589fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (viewportFunc - (char *) table) / sizeof(void *); 590fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(viewportOffset == _gloffset_Viewport); 591fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(viewportOffset == offset); 592fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 593fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 594fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer"); 595fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *VertexPointerFunc = (char*) &table->VertexPointer; 596fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *); 597fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(VertexPointerOffset == _gloffset_VertexPointer); 598fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(VertexPointerOffset == offset); 599fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 600fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 601fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax"); 602fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *ResetMinMaxFunc = (char*) &table->ResetMinmax; 603fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *); 604fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(ResetMinMaxOffset == _gloffset_ResetMinmax); 605fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(ResetMinMaxOffset == offset); 606fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 607fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 608fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor"); 609fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *blendColorFunc = (char*) &table->BlendColor; 610fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *); 611fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(blendColorOffset == _gloffset_BlendColor); 612fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(blendColorOffset == offset); 613fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 614fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 615fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT"); 616fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT; 617fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *); 618fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT); 619fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(secondaryColor3fOffset == offset); 620fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 621fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 622fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV"); 623fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *pointParameterivFunc = (char*) &table->PointParameterivNV; 624fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *); 625fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(pointParameterivOffset == _gloffset_PointParameterivNV); 626fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(pointParameterivOffset == offset); 627fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 628fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 629fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV"); 630fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *setFenceFunc = (char*) &table->SetFenceNV; 631fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *); 632fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(setFenceOffset == _gloffset_SetFenceNV); 633fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(setFenceOffset == offset); 634fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 635d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis#else 636d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis (void) table; 637d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis#endif 638fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis} 639