glapi_getproc.c revision a73c6540d9a7f6e26d8568ba2fc522cb865f0a6c
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 47f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis/********************************************************************** 48f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis * Static function management. 49f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis */ 50f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 51f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 52fe14868d96d4820dba73c3a507d191b8a73c6870George Sapountzis#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) 53a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# define NEED_FUNCTION_POINTER 54a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 555b426288c2dbc42ef44ea13fe37afa77223107bbChia-I Wu#include "glapi/glprocs.h" 56a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 57a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 58a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 59a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Search the table of static entrypoint functions for the named function 60a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * and return the corresponding glprocs_table_t entry. 61a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 62a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic const glprocs_table_t * 63f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzisget_static_proc( const char * n ) 64a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 65a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 66a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; static_functions[i].Name_offset >= 0; i++) { 67a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char *testName = gl_string_table + static_functions[i].Name_offset; 684447fddc82a2c0245e798c90492293d875d186d0Brian Paul#ifdef MANGLE 6920ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis /* skip the prefix on the name */ 704447fddc82a2c0245e798c90492293d875d186d0Brian Paul if (strcmp(testName, n + 1) == 0) 714447fddc82a2c0245e798c90492293d875d186d0Brian Paul#else 724447fddc82a2c0245e798c90492293d875d186d0Brian Paul if (strcmp(testName, n) == 0) 734447fddc82a2c0245e798c90492293d875d186d0Brian Paul#endif 744447fddc82a2c0245e798c90492293d875d186d0Brian Paul { 75a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return &static_functions[i]; 76a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 77a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 78a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 79a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 80a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 81a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 82a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 83a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return dispatch table offset of the named static (built-in) function. 84a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return -1 if function not found. 85a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 86a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic GLint 87a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_offset(const char *funcName) 88a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 89f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis const glprocs_table_t * const f = get_static_proc( funcName ); 90f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis if (f == NULL) { 91f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return -1; 92a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 93f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 94f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return f->Offset; 95a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 96a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 97a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 98fe14868d96d4820dba73c3a507d191b8a73c6870George Sapountzis#if !defined(XFree86Server) 99cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 100a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 101a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return dispatch function address for the named static (built-in) function. 102a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return NULL if function not found. 103a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 104a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic _glapi_proc 105a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_address(const char *funcName) 106a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 107f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis const glprocs_table_t * const f = get_static_proc( funcName ); 108f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis if (f == NULL) { 109f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return NULL; 110f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis } 111f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 112a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if defined(DISPATCH_FUNCTION_SIZE) && defined(GLX_INDIRECT_RENDERING) 113f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return (f->Address == NULL) 114f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis ? get_entrypoint_address(f->Offset) 115f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis : f->Address; 116a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#elif defined(DISPATCH_FUNCTION_SIZE) 117f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return get_entrypoint_address(f->Offset); 118a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 119f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return f->Address; 120a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 121a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 122a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 123f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis#else 124a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 125f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzisstatic _glapi_proc 126f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzisget_static_proc_address(const char *funcName) 127f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis{ 128f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis (void) funcName; 129f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return NULL; 130f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis} 131f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 132f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis#endif /* !defined(XFree86Server) */ 133a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 134a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 135a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 136a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return the name of the function at the given offset in the dispatch 137a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * table. For debugging only. 138a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 139a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic const char * 140a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_name( GLuint offset ) 141a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 142a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 143a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; static_functions[i].Name_offset >= 0; i++) { 144a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (static_functions[i].Offset == offset) { 145a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return gl_string_table + static_functions[i].Name_offset; 146a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 147a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 148a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 149a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 150a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 151a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 152a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 153a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/********************************************************************** 154a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Extension function management. 155a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 156a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 157a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 158a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 159a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Track information about a function added to the GL API. 160a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 161a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstruct _glapi_function { 162a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 163a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Name of the function. 164a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 165a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * name; 166a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 167a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 168a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 169a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Text string that describes the types of the parameters passed to the 170a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * named function. Parameter types are converted to characters using the 171a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * following rules: 172a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'i' for \c GLint, \c GLuint, and \c GLenum 173a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'p' for any pointer type 174a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'f' for \c GLfloat and \c GLclampf 175a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'd' for \c GLdouble and \c GLclampd 176a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 177a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * parameter_signature; 178a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 179a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 180a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 181a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Offset in the dispatch table where the pointer to the real function is 182a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * located. If the driver has not requested that the named function be 183a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * added to the dispatch table, this will have the value ~0. 184a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 185a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned dispatch_offset; 186a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 187a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 188a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 189a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Pointer to the dispatch stub for the named function. 190a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 191a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 192a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The semantic of this field should be changed slightly. Currently, it 193a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * is always expected to be non-\c NULL. However, it would be better to 194a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * only allocate the entry-point stub when the application requests the 195a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * function via \c glXGetProcAddress. This would save memory for all the 196a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * functions that the driver exports but that the application never wants 197a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * to call. 198a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 199a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul _glapi_proc dispatch_stub; 200a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul}; 201a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 202a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 203a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS]; 204a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic GLuint NumExtEntryPoints = 0; 205a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 206a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 2075b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisstatic struct _glapi_function * 2085b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisget_extension_proc(const char *funcName) 20958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 21058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLuint i; 21158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis for (i = 0; i < NumExtEntryPoints; i++) { 21258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (strcmp(ExtEntryTable[i].name, funcName) == 0) { 2135b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return & ExtEntryTable[i]; 21458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 21558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 2165b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return NULL; 2175b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis} 2185b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2195b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2205b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisstatic GLint 2215b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisget_extension_proc_offset(const char *funcName) 2225b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis{ 2235b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis const struct _glapi_function * const f = get_extension_proc( funcName ); 2245b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis if (f == NULL) { 2255b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return -1; 2265b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis } 2275b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2285b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return f->dispatch_offset; 22958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 23058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 23158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 23258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisstatic _glapi_proc 23358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisget_extension_proc_address(const char *funcName) 23458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 2355b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis const struct _glapi_function * const f = get_extension_proc( funcName ); 2365b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis if (f == NULL) { 2375b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return NULL; 23858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 2395b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2405b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return f->dispatch_stub; 24158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 24258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 24358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 24458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisstatic const char * 24558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisget_extension_proc_name(GLuint offset) 24658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 24758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLuint i; 24858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis for (i = 0; i < NumExtEntryPoints; i++) { 24958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (ExtEntryTable[i].dispatch_offset == offset) { 25058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return ExtEntryTable[i].name; 25158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 25258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 25358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return NULL; 25458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 25558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 25658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 257a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 258cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis * strdup() is actually not a standard ANSI C or POSIX routine. 259cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis * Irix will not define it if ANSI mode is in effect. 260cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis */ 261cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzisstatic char * 262cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzisstr_dup(const char *str) 263cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis{ 264cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis char *copy; 265cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis copy = (char*) malloc(strlen(str) + 1); 266cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis if (!copy) 267cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis return NULL; 2686405ecb399a52e4d3fe0c002bcd9b3485cbd1360Brian Paul strcpy(copy, str); 269cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis return copy; 270cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis} 271cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 272cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 273cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis/** 274a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Generate new entrypoint 275a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 276a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Use a temporary dispatch offset of ~0 (i.e. -1). Later, when the driver 277a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * calls \c _glapi_add_dispatch we'll put in the proper offset. If that 278a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * never happens, and the user calls this function, he'll segfault. That's 279a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * what you get when you try calling a GL function that doesn't really exist. 280a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 281a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param funcName Name of the function to create an entry-point for. 282a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 283a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \sa _glapi_add_entrypoint 284a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 285a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 286a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic struct _glapi_function * 287a97226352fb8063d4d0084523312b4880dae5ac7Brian Pauladd_function_name( const char * funcName ) 288a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 289a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry = NULL; 290cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis _glapi_proc entrypoint = NULL; 291cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis char * name_dup = NULL; 292cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 293cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis if (NumExtEntryPoints >= MAX_EXTENSION_FUNCS) 294cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis return NULL; 295cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 296cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis if (funcName == NULL) 297cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis return NULL; 298cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 299cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis name_dup = str_dup(funcName); 300cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis if (name_dup == NULL) 301cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis return NULL; 302cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 303cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entrypoint = generate_entrypoint(~0); 304cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 305cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis if (entrypoint == NULL) { 306cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis free(name_dup); 307cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis return NULL; 308a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 309a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 310cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry = & ExtEntryTable[NumExtEntryPoints]; 311cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis NumExtEntryPoints++; 312cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 313cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry->name = name_dup; 314cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry->parameter_signature = NULL; 315cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry->dispatch_offset = ~0; 316cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry->dispatch_stub = entrypoint; 317cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 318a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return entry; 319a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 320a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 321a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 3223833a76eef6b45b82c102a49055602632f960a99George Sapountzisstatic struct _glapi_function * 3233833a76eef6b45b82c102a49055602632f960a99George Sapountzisset_entry_info( struct _glapi_function * entry, const char * signature, unsigned offset ) 3243833a76eef6b45b82c102a49055602632f960a99George Sapountzis{ 3253833a76eef6b45b82c102a49055602632f960a99George Sapountzis char * sig_dup = NULL; 3263833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3273833a76eef6b45b82c102a49055602632f960a99George Sapountzis if (signature == NULL) 3283833a76eef6b45b82c102a49055602632f960a99George Sapountzis return NULL; 3293833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3303833a76eef6b45b82c102a49055602632f960a99George Sapountzis sig_dup = str_dup(signature); 3313833a76eef6b45b82c102a49055602632f960a99George Sapountzis if (sig_dup == NULL) 3323833a76eef6b45b82c102a49055602632f960a99George Sapountzis return NULL; 3333833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3343833a76eef6b45b82c102a49055602632f960a99George Sapountzis fill_in_entrypoint_offset(entry->dispatch_stub, offset); 3353833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3363833a76eef6b45b82c102a49055602632f960a99George Sapountzis entry->parameter_signature = sig_dup; 3373833a76eef6b45b82c102a49055602632f960a99George Sapountzis entry->dispatch_offset = offset; 3383833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3393833a76eef6b45b82c102a49055602632f960a99George Sapountzis return entry; 3403833a76eef6b45b82c102a49055602632f960a99George Sapountzis} 3413833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3423833a76eef6b45b82c102a49055602632f960a99George Sapountzis 343a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 344a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Fill-in the dispatch stub for the named function. 345a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 346a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function is intended to be called by a hardware driver. When called, 347a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * a dispatch stub may be created created for the function. A pointer to this 348a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * dispatch function will be returned by glXGetProcAddress. 349a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 350a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param function_names Array of pointers to function names that should 351a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * share a common dispatch offset. 352a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param parameter_signature String representing the types of the parameters 353a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * passed to the named function. Parameter types 354a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * are converted to characters using the following 355a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * rules: 356a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'i' for \c GLint, \c GLuint, and \c GLenum 357a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'p' for any pointer type 358a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'f' for \c GLfloat and \c GLclampf 359a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'd' for \c GLdouble and \c GLclampd 360a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 361a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \returns 362a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The offset in the dispatch table of the named function. A pointer to the 363a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * driver's implementation of the named function should be stored at 364a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c dispatch_table[\c offset]. Return -1 if error/problem. 365a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 366a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \sa glXGetProcAddress 367a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 368a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \warning 369a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function can only handle up to 8 names at a time. As far as I know, 370a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the maximum number of names ever associated with an existing GL function is 371a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, 372a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c glPointParameterfARB, and \c glPointParameterf), so this should not be 373a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * too painful of a limitation. 374a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 375a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 376a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Determine whether or not \c parameter_signature should be allowed to be 377a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c NULL. It doesn't seem like much of a hardship for drivers to have to 378a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * pass in an empty string. 379a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 380a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 381a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Determine if code should be added to reject function names that start with 382a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 'glX'. 383a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 384a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \bug 385a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Add code to compare \c parameter_signature with the parameter signature of 386a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * a static function. In order to do that, we need to find a way to \b get 387a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the parameter signature of a static function. 388a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 389a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 390a73c6540d9a7f6e26d8568ba2fc522cb865f0a6cChia-I Wuint 391a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_add_dispatch( const char * const * function_names, 392a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * parameter_signature ) 393a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 394a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul static int next_dynamic_offset = _gloffset_FIRST_DYNAMIC; 395a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * const real_sig = (parameter_signature != NULL) 396a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ? parameter_signature : ""; 397a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry[8]; 398a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLboolean is_static[8]; 399a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned i; 400a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul int offset = ~0; 401a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 4027cd8f0ef9d905080dc857c4739be9780b24a7fd2George Sapountzis init_glapi_relocs_once(); 403a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 404a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memset( is_static, 0, sizeof( is_static ) ); 405a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memset( entry, 0, sizeof( entry ) ); 406a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 4070d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* Find the _single_ dispatch offset for all function names that already 4080d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis * exist (and have a dispatch offset). 4090d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis */ 4100d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis 411a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( i = 0 ; function_names[i] != NULL ; i++ ) { 412ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis const char * funcName = function_names[i]; 413ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis int static_offset; 414ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis int extension_offset; 415a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 416ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if (funcName[0] != 'g' || funcName[1] != 'l') 417a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 418ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 419ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis /* search built-in functions */ 420ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis static_offset = get_static_proc_offset(funcName); 421ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 422ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if (static_offset >= 0) { 423ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 424ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis is_static[i] = GL_TRUE; 425ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 426a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* FIXME: Make sure the parameter signatures match! How do we get 427a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * FIXME: the parameter signature for static functions? 428a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 429a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 430ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if ( (offset != ~0) && (static_offset != offset) ) { 431a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 432a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 433a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 434ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis offset = static_offset; 435bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis 436bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis continue; 437a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 438ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 439ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis /* search added extension functions */ 440ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis entry[i] = get_extension_proc(funcName); 441f9cc6b3ee7c95130992d67c080ff9bc8e8a6d789George Sapountzis 442f9cc6b3ee7c95130992d67c080ff9bc8e8a6d789George Sapountzis if (entry[i] != NULL) { 443ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis extension_offset = entry[i]->dispatch_offset; 444f9cc6b3ee7c95130992d67c080ff9bc8e8a6d789George Sapountzis 445ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis /* The offset may be ~0 if the function name was added by 446ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis * glXGetProcAddress but never filled in by the driver. 447ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis */ 448a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 449ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if (extension_offset == ~0) { 450ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis continue; 451ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis } 452a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 453ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if (strcmp(real_sig, entry[i]->parameter_signature) != 0) { 454ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis return -1; 455ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis } 456a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 457ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if ( (offset != ~0) && (extension_offset != offset) ) { 458ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis return -1; 459ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis } 460ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 461ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis offset = extension_offset; 462a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 463a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 464a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 4650d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* If all function names are either new (or with no dispatch offset), 4660d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis * allocate a new dispatch offset. 4670d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis */ 4680d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis 469a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (offset == ~0) { 470a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul offset = next_dynamic_offset; 471a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul next_dynamic_offset++; 472a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 473a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 4740d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* Fill in the dispatch offset for the new function names (and those with 4750d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis * no dispatch offset). 4760d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis */ 4770d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis 478a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( i = 0 ; function_names[i] != NULL ; i++ ) { 479c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis if (is_static[i]) { 480c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis continue; 481c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis } 482c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis 4830d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* generate entrypoints for new function names */ 484c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis if (entry[i] == NULL) { 485c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis entry[i] = add_function_name( function_names[i] ); 486a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (entry[i] == NULL) { 487c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis /* FIXME: Possible memory leak here. */ 488c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis return -1; 489a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 490a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 491c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis 492bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis if (entry[i]->dispatch_offset == ~0) { 493bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis set_entry_info( entry[i], real_sig, offset ); 494bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis } 495a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 496c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis 497a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return offset; 498a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 499a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 500a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 501a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 502a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return offset of entrypoint for named function within dispatch table. 503a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 504a73c6540d9a7f6e26d8568ba2fc522cb865f0a6cChia-I WuGLint 505a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_offset(const char *funcName) 506a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 50758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLint offset; 50858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 509a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search extension functions first */ 51058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis offset = get_extension_proc_offset(funcName); 51158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (offset >= 0) 51258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return offset; 51358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 514a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search static functions */ 515a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return get_static_proc_offset(funcName); 516a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 517a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 518a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 519a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 520a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 521a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return pointer to the named function. If the function name isn't found 522a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * in the name of static functions, try generating a new API entrypoint on 523a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the fly with assembly language. 524a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 525a73c6540d9a7f6e26d8568ba2fc522cb865f0a6cChia-I Wu_glapi_proc 526a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_address(const char *funcName) 527a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 52858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis _glapi_proc func; 529a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry; 530a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 5317cd8f0ef9d905080dc857c4739be9780b24a7fd2George Sapountzis init_glapi_relocs_once(); 5327cd8f0ef9d905080dc857c4739be9780b24a7fd2George Sapountzis 533a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#ifdef MANGLE 53420ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis /* skip the prefix on the name */ 53520ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis if (funcName[1] != 'g' || funcName[2] != 'l') 536a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 537a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 538a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (funcName[0] != 'g' || funcName[1] != 'l') 539a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 540a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 541a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 542a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search extension functions first */ 54358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis func = get_extension_proc_address(funcName); 54458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (func) 54558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return func; 546a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 547a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search static functions */ 548f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis func = get_static_proc_address(funcName); 549f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis if (func) 550f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return func; 551a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 5520d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* generate entrypoint, dispatch offset must be filled in by the driver */ 553a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry = add_function_name(funcName); 5540d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis if (entry == NULL) 5550d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis return NULL; 5560d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis 5570d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis return entry->dispatch_stub; 558a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 559a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 560a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 561a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 562a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 563a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return the name of the function at the given dispatch offset. 564a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This is only intended for debugging. 565a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 566a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulconst char * 567a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_name(GLuint offset) 568a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 569a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * n; 570a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 571a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search built-in functions */ 572a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul n = get_static_proc_name(offset); 573a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( n != NULL ) { 574a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return n; 575a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 576a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 577a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search added extension functions */ 57858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return get_extension_proc_name(offset); 579a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 580fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 581fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 582fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 5832c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/********************************************************************** 5842c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * GL API table functions. 5852c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 5862c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5872c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5882c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/* 5892c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * The dispatch table size (number of entries) is the size of the 5902c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * _glapi_table struct plus the number of dynamic entries we can add. 5912c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * The extra slots can be filled in by DRI drivers that register new extension 5922c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * functions. 5932c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 5942c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS) 5952c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5962c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5972c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/** 5982c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Return size of dispatch table struct as number of functions (or 5992c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * slots). 6002c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 601a73c6540d9a7f6e26d8568ba2fc522cb865f0a6cChia-I WuGLuint 6022c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis_glapi_get_dispatch_table_size(void) 6032c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis{ 6042c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis return DISPATCH_TABLE_SIZE; 6052c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis} 6062c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 6072c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 6082c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/** 6092c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Make sure there are no NULL pointers in the given dispatch table. 6102c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Intended for debugging purposes. 6112c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 6122c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzisvoid 6132c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis_glapi_check_table_not_null(const struct _glapi_table *table) 6142c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis{ 6152c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#ifdef EXTRA_DEBUG /* set to DEBUG for extra DEBUG */ 6162c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis const GLuint entries = _glapi_get_dispatch_table_size(); 6172c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis const void **tab = (const void **) table; 6182c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis GLuint i; 6192c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis for (i = 1; i < entries; i++) { 6202c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis assert(tab[i]); 6212c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis } 6222c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#else 6232c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis (void) table; 6242c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#endif 6252c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis} 6262c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 6272c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 628fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis/** 629fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis * Do some spot checks to be sure that the dispatch table 630fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis * slots are assigned correctly. For debugging only. 631fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis */ 632fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzisvoid 633fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis_glapi_check_table(const struct _glapi_table *table) 634fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis{ 6352c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#ifdef EXTRA_DEBUG /* set to DEBUG for extra DEBUG */ 636fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 637fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint BeginOffset = _glapi_get_proc_offset("glBegin"); 638fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *BeginFunc = (char*) &table->Begin; 639fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (BeginFunc - (char *) table) / sizeof(void *); 640fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(BeginOffset == _gloffset_Begin); 641fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(BeginOffset == offset); 642fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 643fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 644fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint viewportOffset = _glapi_get_proc_offset("glViewport"); 645fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *viewportFunc = (char*) &table->Viewport; 646fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (viewportFunc - (char *) table) / sizeof(void *); 647fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(viewportOffset == _gloffset_Viewport); 648fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(viewportOffset == offset); 649fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 650fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 651fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer"); 652fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *VertexPointerFunc = (char*) &table->VertexPointer; 653fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *); 654fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(VertexPointerOffset == _gloffset_VertexPointer); 655fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(VertexPointerOffset == offset); 656fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 657fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 658fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax"); 659fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *ResetMinMaxFunc = (char*) &table->ResetMinmax; 660fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *); 661fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(ResetMinMaxOffset == _gloffset_ResetMinmax); 662fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(ResetMinMaxOffset == offset); 663fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 664fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 665fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor"); 666fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *blendColorFunc = (char*) &table->BlendColor; 667fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *); 668fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(blendColorOffset == _gloffset_BlendColor); 669fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(blendColorOffset == offset); 670fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 671fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 672fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT"); 673fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT; 674fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *); 675fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT); 676fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(secondaryColor3fOffset == offset); 677fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 678fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 679fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV"); 680fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *pointParameterivFunc = (char*) &table->PointParameterivNV; 681fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *); 682fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(pointParameterivOffset == _gloffset_PointParameterivNV); 683fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(pointParameterivOffset == offset); 684fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 685fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 686fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV"); 687fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *setFenceFunc = (char*) &table->SetFenceNV; 688fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *); 689fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(setFenceOffset == _gloffset_SetFenceNV); 690fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(setFenceOffset == offset); 691fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 692d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis#else 693d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis (void) table; 694d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis#endif 695fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis} 696