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 332c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#include "glapi/glapi_priv.h" 345b426288c2dbc42ef44ea13fe37afa77223107bbChia-I Wu#include "glapi/glapitable.h" 35e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu 36e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu 37e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu#define FIRST_DYNAMIC_OFFSET (sizeof(struct _glapi_table) / sizeof(void *)) 38a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 39a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 40f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis/********************************************************************** 41f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis * Static function management. 42f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis */ 43f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 44f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 451ccef926be46dce3b6b5c76e812e2fae4e205ce7Adam Jackson#if !defined(DISPATCH_FUNCTION_SIZE) 46a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# define NEED_FUNCTION_POINTER 47a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 485b426288c2dbc42ef44ea13fe37afa77223107bbChia-I Wu#include "glapi/glprocs.h" 49a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 50a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 51a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 52a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Search the table of static entrypoint functions for the named function 53a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * and return the corresponding glprocs_table_t entry. 54a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 55a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic const glprocs_table_t * 56f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzisget_static_proc( const char * n ) 57a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 58a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 59a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; static_functions[i].Name_offset >= 0; i++) { 60a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char *testName = gl_string_table + static_functions[i].Name_offset; 614447fddc82a2c0245e798c90492293d875d186d0Brian Paul#ifdef MANGLE 6220ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis /* skip the prefix on the name */ 634447fddc82a2c0245e798c90492293d875d186d0Brian Paul if (strcmp(testName, n + 1) == 0) 644447fddc82a2c0245e798c90492293d875d186d0Brian Paul#else 654447fddc82a2c0245e798c90492293d875d186d0Brian Paul if (strcmp(testName, n) == 0) 664447fddc82a2c0245e798c90492293d875d186d0Brian Paul#endif 674447fddc82a2c0245e798c90492293d875d186d0Brian Paul { 68a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return &static_functions[i]; 69a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 70a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 71a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 72a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 73a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 74a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 75a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 76a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return dispatch table offset of the named static (built-in) function. 77a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return -1 if function not found. 78a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 79a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic GLint 80a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_offset(const char *funcName) 81a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 82f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis const glprocs_table_t * const f = get_static_proc( funcName ); 83f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis if (f == NULL) { 84f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return -1; 85a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 86f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 87f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return f->Offset; 88a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 89a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 90a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 91cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 92a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 93a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return dispatch function address for the named static (built-in) function. 94a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return NULL if function not found. 95a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 96a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic _glapi_proc 97a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_address(const char *funcName) 98a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 99f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis const glprocs_table_t * const f = get_static_proc( funcName ); 100f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis if (f == NULL) { 101f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return NULL; 102f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis } 103f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis 104a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if defined(DISPATCH_FUNCTION_SIZE) && defined(GLX_INDIRECT_RENDERING) 105f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return (f->Address == NULL) 106f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis ? get_entrypoint_address(f->Offset) 107f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis : f->Address; 108a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#elif defined(DISPATCH_FUNCTION_SIZE) 109f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return get_entrypoint_address(f->Offset); 110a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 111f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return f->Address; 112a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 113a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 114a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 115a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 116a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 117a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 118a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return the name of the function at the given offset in the dispatch 119a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * table. For debugging only. 120a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 121a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic const char * 122a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_name( GLuint offset ) 123a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 124a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 125a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; static_functions[i].Name_offset >= 0; i++) { 126a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (static_functions[i].Offset == offset) { 127a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return gl_string_table + static_functions[i].Name_offset; 128a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 129a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 130a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 131a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 132a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 133a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 134a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 135a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/********************************************************************** 136a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Extension function management. 137a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 138a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 139a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 140a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 141a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Track information about a function added to the GL API. 142a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 143a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstruct _glapi_function { 144a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 145a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Name of the function. 146a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 147a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * name; 148a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 149a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 150a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 151a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Text string that describes the types of the parameters passed to the 152a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * named function. Parameter types are converted to characters using the 153a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * following rules: 154a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'i' for \c GLint, \c GLuint, and \c GLenum 155a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'p' for any pointer type 156a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'f' for \c GLfloat and \c GLclampf 157a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'd' for \c GLdouble and \c GLclampd 158a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 159a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * parameter_signature; 160a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 161a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 162a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 163a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Offset in the dispatch table where the pointer to the real function is 164a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * located. If the driver has not requested that the named function be 165a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * added to the dispatch table, this will have the value ~0. 166a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 167a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned dispatch_offset; 168a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 169a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 170a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 171a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Pointer to the dispatch stub for the named function. 172a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 173a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 174a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The semantic of this field should be changed slightly. Currently, it 175a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * is always expected to be non-\c NULL. However, it would be better to 176a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * only allocate the entry-point stub when the application requests the 177a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * function via \c glXGetProcAddress. This would save memory for all the 178a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * functions that the driver exports but that the application never wants 179a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * to call. 180a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 181a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul _glapi_proc dispatch_stub; 182a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul}; 183a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 184a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 185a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS]; 186a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic GLuint NumExtEntryPoints = 0; 187a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 188a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 1895b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisstatic struct _glapi_function * 1905b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisget_extension_proc(const char *funcName) 19158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 19258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLuint i; 19358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis for (i = 0; i < NumExtEntryPoints; i++) { 19458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (strcmp(ExtEntryTable[i].name, funcName) == 0) { 1955b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return & ExtEntryTable[i]; 19658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 19758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 1985b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return NULL; 1995b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis} 2005b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2015b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2025b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisstatic GLint 2035b2340c493cdf8d776e717b00acf0a8002858976George Sapountzisget_extension_proc_offset(const char *funcName) 2045b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis{ 2055b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis const struct _glapi_function * const f = get_extension_proc( funcName ); 2065b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis if (f == NULL) { 2075b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return -1; 2085b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis } 2095b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2105b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return f->dispatch_offset; 21158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 21258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 21358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 21458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisstatic _glapi_proc 21558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisget_extension_proc_address(const char *funcName) 21658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 2175b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis const struct _glapi_function * const f = get_extension_proc( funcName ); 2185b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis if (f == NULL) { 2195b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return NULL; 22058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 2215b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis 2225b2340c493cdf8d776e717b00acf0a8002858976George Sapountzis return f->dispatch_stub; 22358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 22458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 22558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 22658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisstatic const char * 22758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzisget_extension_proc_name(GLuint offset) 22858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis{ 22958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLuint i; 23058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis for (i = 0; i < NumExtEntryPoints; i++) { 23158985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (ExtEntryTable[i].dispatch_offset == offset) { 23258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return ExtEntryTable[i].name; 23358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 23458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis } 23558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return NULL; 23658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis} 23758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 23858985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 239a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 240cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis * strdup() is actually not a standard ANSI C or POSIX routine. 241cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis * Irix will not define it if ANSI mode is in effect. 242cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis */ 243cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzisstatic char * 244cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzisstr_dup(const char *str) 245cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis{ 246cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis char *copy; 247cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis copy = (char*) malloc(strlen(str) + 1); 248cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis if (!copy) 249cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis return NULL; 2506405ecb399a52e4d3fe0c002bcd9b3485cbd1360Brian Paul strcpy(copy, str); 251cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis return copy; 252cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis} 253cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 254cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis 255cccdc1783fda33da6fc12befdf288b74866e5dfaGeorge Sapountzis/** 256a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Generate new entrypoint 257a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 258a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Use a temporary dispatch offset of ~0 (i.e. -1). Later, when the driver 259a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * calls \c _glapi_add_dispatch we'll put in the proper offset. If that 260a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * never happens, and the user calls this function, he'll segfault. That's 261a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * what you get when you try calling a GL function that doesn't really exist. 262a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 263a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param funcName Name of the function to create an entry-point for. 264a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 265a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \sa _glapi_add_entrypoint 266a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 267a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 268a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic struct _glapi_function * 269a97226352fb8063d4d0084523312b4880dae5ac7Brian Pauladd_function_name( const char * funcName ) 270a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 271a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry = NULL; 272cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis _glapi_proc entrypoint = NULL; 273cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis char * name_dup = NULL; 274cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 275cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis if (NumExtEntryPoints >= MAX_EXTENSION_FUNCS) 276cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis return NULL; 277cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 278cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis if (funcName == NULL) 279cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis return NULL; 280cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 281cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis name_dup = str_dup(funcName); 282cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis if (name_dup == NULL) 283cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis return NULL; 284cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 285cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entrypoint = generate_entrypoint(~0); 286cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 287cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis if (entrypoint == NULL) { 288cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis free(name_dup); 289cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis return NULL; 290a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 291a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 292cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry = & ExtEntryTable[NumExtEntryPoints]; 293cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis NumExtEntryPoints++; 294cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 295cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry->name = name_dup; 296cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry->parameter_signature = NULL; 297cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry->dispatch_offset = ~0; 298cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis entry->dispatch_stub = entrypoint; 299cae4fdda8d27cac21714571adb0bfada6d96152aGeorge Sapountzis 300a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return entry; 301a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 302a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 303a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 3043833a76eef6b45b82c102a49055602632f960a99George Sapountzisstatic struct _glapi_function * 3053833a76eef6b45b82c102a49055602632f960a99George Sapountzisset_entry_info( struct _glapi_function * entry, const char * signature, unsigned offset ) 3063833a76eef6b45b82c102a49055602632f960a99George Sapountzis{ 3073833a76eef6b45b82c102a49055602632f960a99George Sapountzis char * sig_dup = NULL; 3083833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3093833a76eef6b45b82c102a49055602632f960a99George Sapountzis if (signature == NULL) 3103833a76eef6b45b82c102a49055602632f960a99George Sapountzis return NULL; 3113833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3123833a76eef6b45b82c102a49055602632f960a99George Sapountzis sig_dup = str_dup(signature); 3133833a76eef6b45b82c102a49055602632f960a99George Sapountzis if (sig_dup == NULL) 3143833a76eef6b45b82c102a49055602632f960a99George Sapountzis return NULL; 3153833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3163833a76eef6b45b82c102a49055602632f960a99George Sapountzis fill_in_entrypoint_offset(entry->dispatch_stub, offset); 3173833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3183833a76eef6b45b82c102a49055602632f960a99George Sapountzis entry->parameter_signature = sig_dup; 3193833a76eef6b45b82c102a49055602632f960a99George Sapountzis entry->dispatch_offset = offset; 3203833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3213833a76eef6b45b82c102a49055602632f960a99George Sapountzis return entry; 3223833a76eef6b45b82c102a49055602632f960a99George Sapountzis} 3233833a76eef6b45b82c102a49055602632f960a99George Sapountzis 3243833a76eef6b45b82c102a49055602632f960a99George Sapountzis 325a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 326a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Fill-in the dispatch stub for the named function. 327a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 328a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function is intended to be called by a hardware driver. When called, 329a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * a dispatch stub may be created created for the function. A pointer to this 330a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * dispatch function will be returned by glXGetProcAddress. 331a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 332a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param function_names Array of pointers to function names that should 333a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * share a common dispatch offset. 334a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param parameter_signature String representing the types of the parameters 335a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * passed to the named function. Parameter types 336a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * are converted to characters using the following 337a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * rules: 338a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'i' for \c GLint, \c GLuint, and \c GLenum 339a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'p' for any pointer type 340a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'f' for \c GLfloat and \c GLclampf 341a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'd' for \c GLdouble and \c GLclampd 342a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 343a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \returns 344a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The offset in the dispatch table of the named function. A pointer to the 345a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * driver's implementation of the named function should be stored at 346a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c dispatch_table[\c offset]. Return -1 if error/problem. 347a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 348a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \sa glXGetProcAddress 349a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 350a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \warning 351a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function can only handle up to 8 names at a time. As far as I know, 352a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the maximum number of names ever associated with an existing GL function is 353a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, 354a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c glPointParameterfARB, and \c glPointParameterf), so this should not be 355a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * too painful of a limitation. 356a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 357a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 358a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Determine whether or not \c parameter_signature should be allowed to be 359a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c NULL. It doesn't seem like much of a hardship for drivers to have to 360a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * pass in an empty string. 361a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 362a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 363a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Determine if code should be added to reject function names that start with 364a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 'glX'. 365a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 366a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \bug 367a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Add code to compare \c parameter_signature with the parameter signature of 368a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * a static function. In order to do that, we need to find a way to \b get 369a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the parameter signature of a static function. 370a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 371a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 372a73c6540d9a7f6e26d8568ba2fc522cb865f0a6cChia-I Wuint 373a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_add_dispatch( const char * const * function_names, 374a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * parameter_signature ) 375a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 376e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu static int next_dynamic_offset = FIRST_DYNAMIC_OFFSET; 377a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * const real_sig = (parameter_signature != NULL) 378a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ? parameter_signature : ""; 379a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry[8]; 380a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLboolean is_static[8]; 381a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned i; 382a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul int offset = ~0; 383a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 3847cd8f0ef9d905080dc857c4739be9780b24a7fd2George Sapountzis init_glapi_relocs_once(); 385a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 386a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memset( is_static, 0, sizeof( is_static ) ); 387a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memset( entry, 0, sizeof( entry ) ); 388a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 3890d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* Find the _single_ dispatch offset for all function names that already 3900d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis * exist (and have a dispatch offset). 3910d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis */ 3920d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis 393a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( i = 0 ; function_names[i] != NULL ; i++ ) { 394ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis const char * funcName = function_names[i]; 395ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis int static_offset; 396ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis int extension_offset; 397a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 398ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if (funcName[0] != 'g' || funcName[1] != 'l') 399a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 400ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 401ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis /* search built-in functions */ 402ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis static_offset = get_static_proc_offset(funcName); 403ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 404ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if (static_offset >= 0) { 405ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 406ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis is_static[i] = GL_TRUE; 407ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 408a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* FIXME: Make sure the parameter signatures match! How do we get 409a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * FIXME: the parameter signature for static functions? 410a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 411a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 412ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if ( (offset != ~0) && (static_offset != offset) ) { 413a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 414a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 415a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 416ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis offset = static_offset; 417bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis 418bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis continue; 419a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 420ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 421ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis /* search added extension functions */ 422ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis entry[i] = get_extension_proc(funcName); 423f9cc6b3ee7c95130992d67c080ff9bc8e8a6d789George Sapountzis 424f9cc6b3ee7c95130992d67c080ff9bc8e8a6d789George Sapountzis if (entry[i] != NULL) { 425ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis extension_offset = entry[i]->dispatch_offset; 426f9cc6b3ee7c95130992d67c080ff9bc8e8a6d789George Sapountzis 427ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis /* The offset may be ~0 if the function name was added by 428ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis * glXGetProcAddress but never filled in by the driver. 429ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis */ 430a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 431ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if (extension_offset == ~0) { 432ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis continue; 433ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis } 434a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 435ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if (strcmp(real_sig, entry[i]->parameter_signature) != 0) { 436ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis return -1; 437ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis } 438a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 439ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis if ( (offset != ~0) && (extension_offset != offset) ) { 440ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis return -1; 441ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis } 442ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis 443ddabf0a151c2ef318e5de45238556c6568540681George Sapountzis offset = extension_offset; 444a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 445a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 446a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 4470d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* If all function names are either new (or with no dispatch offset), 4480d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis * allocate a new dispatch offset. 4490d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis */ 4500d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis 451a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (offset == ~0) { 452a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul offset = next_dynamic_offset; 453a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul next_dynamic_offset++; 454a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 455a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 4560d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* Fill in the dispatch offset for the new function names (and those with 4570d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis * no dispatch offset). 4580d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis */ 4590d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis 460a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( i = 0 ; function_names[i] != NULL ; i++ ) { 461c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis if (is_static[i]) { 462c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis continue; 463c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis } 464c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis 4650d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* generate entrypoints for new function names */ 466c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis if (entry[i] == NULL) { 467c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis entry[i] = add_function_name( function_names[i] ); 468a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (entry[i] == NULL) { 469c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis /* FIXME: Possible memory leak here. */ 470c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis return -1; 471a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 472a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 473c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis 474bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis if (entry[i]->dispatch_offset == ~0) { 475bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis set_entry_info( entry[i], real_sig, offset ); 476bae31355150f66f7130d76a2ab4d4b735f239c71George Sapountzis } 477a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 478c4b630efdb882f824e9099b9cb2e07d8db2e3549George Sapountzis 479a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return offset; 480a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 481a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 482a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 483a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 484a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return offset of entrypoint for named function within dispatch table. 485a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 486a73c6540d9a7f6e26d8568ba2fc522cb865f0a6cChia-I WuGLint 487a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_offset(const char *funcName) 488a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 48958985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis GLint offset; 49058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 491a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search extension functions first */ 49258985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis offset = get_extension_proc_offset(funcName); 49358985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (offset >= 0) 49458985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return offset; 49558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis 496a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search static functions */ 497a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return get_static_proc_offset(funcName); 498a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 499a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 500a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 501a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 502a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 503a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return pointer to the named function. If the function name isn't found 504a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * in the name of static functions, try generating a new API entrypoint on 505a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the fly with assembly language. 506a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 507a73c6540d9a7f6e26d8568ba2fc522cb865f0a6cChia-I Wu_glapi_proc 508a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_address(const char *funcName) 509a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 51058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis _glapi_proc func; 511a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry; 512a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 5137cd8f0ef9d905080dc857c4739be9780b24a7fd2George Sapountzis init_glapi_relocs_once(); 5147cd8f0ef9d905080dc857c4739be9780b24a7fd2George Sapountzis 515a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#ifdef MANGLE 51620ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis /* skip the prefix on the name */ 51720ed2445b3b98f2b49a26ad4b45859a908583311George Sapountzis if (funcName[1] != 'g' || funcName[2] != 'l') 518a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 519a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 520a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (funcName[0] != 'g' || funcName[1] != 'l') 521a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 522a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 523a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 524a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search extension functions first */ 52558985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis func = get_extension_proc_address(funcName); 52658985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis if (func) 52758985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return func; 528a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 529a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search static functions */ 530f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis func = get_static_proc_address(funcName); 531f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis if (func) 532f0c18da2cf01bc11dc720caed4590ae7eca128f1George Sapountzis return func; 533a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 5340d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis /* generate entrypoint, dispatch offset must be filled in by the driver */ 535a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry = add_function_name(funcName); 5360d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis if (entry == NULL) 5370d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis return NULL; 5380d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis 5390d1dde5b010feba1afe5b51cc6fe66c85371f70bGeorge Sapountzis return entry->dispatch_stub; 540a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 541a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 542a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 543a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 544a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 545a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return the name of the function at the given dispatch offset. 546a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This is only intended for debugging. 547a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 548a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulconst char * 549a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_name(GLuint offset) 550a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 551a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * n; 552a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 553a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search built-in functions */ 554a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul n = get_static_proc_name(offset); 555a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( n != NULL ) { 556a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return n; 557a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 558a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 559a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search added extension functions */ 56058985c36be85c668d059165d8282f8c8e4c7a380George Sapountzis return get_extension_proc_name(offset); 561a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 562fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 563fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 564fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis 5652c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/********************************************************************** 5662c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * GL API table functions. 5672c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 5682c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5692c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5702c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/** 5712c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Return size of dispatch table struct as number of functions (or 5722c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * slots). 5732c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 574a73c6540d9a7f6e26d8568ba2fc522cb865f0a6cChia-I WuGLuint 5752c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis_glapi_get_dispatch_table_size(void) 5762c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis{ 577e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu /* 578e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu * The dispatch table size (number of entries) is the size of the 579e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu * _glapi_table struct plus the number of dynamic entries we can add. 580e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu * The extra slots can be filled in by DRI drivers that register new 581e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu * extension functions. 582e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu */ 583e4dbfa44ed018d124e1531077d506c8c914c1a51Chia-I Wu return FIRST_DYNAMIC_OFFSET + MAX_EXTENSION_FUNCS; 5842c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis} 5852c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5862c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 5872c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis/** 5882c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Make sure there are no NULL pointers in the given dispatch table. 5892c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis * Intended for debugging purposes. 5902c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis */ 5912c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzisvoid 5922c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis_glapi_check_table_not_null(const struct _glapi_table *table) 5932c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis{ 5942c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#ifdef EXTRA_DEBUG /* set to DEBUG for extra DEBUG */ 5952c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis const GLuint entries = _glapi_get_dispatch_table_size(); 5962c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis const void **tab = (const void **) table; 5972c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis GLuint i; 5982c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis for (i = 1; i < entries; i++) { 5992c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis assert(tab[i]); 6002c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis } 6012c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#else 6022c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis (void) table; 6032c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#endif 6042c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis} 6052c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 6062c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis 607fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis/** 608fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis * Do some spot checks to be sure that the dispatch table 609fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis * slots are assigned correctly. For debugging only. 610fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis */ 611fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzisvoid 612fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis_glapi_check_table(const struct _glapi_table *table) 613fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis{ 6142c8b5ffed9a787e896b540a95be48ef401d5f007George Sapountzis#ifdef EXTRA_DEBUG /* set to DEBUG for extra DEBUG */ 615fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 616fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint BeginOffset = _glapi_get_proc_offset("glBegin"); 617fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *BeginFunc = (char*) &table->Begin; 618fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (BeginFunc - (char *) table) / sizeof(void *); 619fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(BeginOffset == offset); 620fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 621fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 622fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint viewportOffset = _glapi_get_proc_offset("glViewport"); 623fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *viewportFunc = (char*) &table->Viewport; 624fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (viewportFunc - (char *) table) / sizeof(void *); 625fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(viewportOffset == offset); 626fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 627fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 628fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer"); 629fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *VertexPointerFunc = (char*) &table->VertexPointer; 630fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *); 631fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(VertexPointerOffset == offset); 632fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 633fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 634fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax"); 635fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *ResetMinMaxFunc = (char*) &table->ResetMinmax; 636fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *); 637fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(ResetMinMaxOffset == offset); 638fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 639fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 640fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor"); 641fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *blendColorFunc = (char*) &table->BlendColor; 642fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *); 643fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(blendColorOffset == offset); 644fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 645fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 646fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT"); 647fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT; 648fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *); 649fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(secondaryColor3fOffset == offset); 650fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 651fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 652fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV"); 653fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *pointParameterivFunc = (char*) &table->PointParameterivNV; 654fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *); 655fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(pointParameterivOffset == offset); 656fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 657fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis { 658fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV"); 659fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis char *setFenceFunc = (char*) &table->SetFenceNV; 660fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *); 661fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis assert(setFenceOffset == offset); 662fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis } 663d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis#else 664d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis (void) table; 665d3f24ab33c284325abaf4b250f8928d4d53836e1George Sapountzis#endif 666fae5758fac963ce014e3d43f1bca7fb489e02bf9George Sapountzis} 667