remap.c revision 848b8605
1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22848b8605Smrg * DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file remap.c 28848b8605Smrg * Remap table management. 29848b8605Smrg * 30848b8605Smrg * Entries in the dispatch table are either static or dynamic. The 31848b8605Smrg * dispatch table is shared by mesa core and glapi. When they are 32848b8605Smrg * built separately, it is possible that a static entry in mesa core 33848b8605Smrg * is dynamic, or assigned a different static offset, in glapi. The 34848b8605Smrg * remap table is in charge of mapping a static entry in mesa core to 35848b8605Smrg * a dynamic entry, or the corresponding static entry, in glapi. 36848b8605Smrg */ 37848b8605Smrg 38848b8605Smrg#include "remap.h" 39848b8605Smrg#include "imports.h" 40848b8605Smrg#include "glapi/glapi.h" 41848b8605Smrg 42848b8605Smrg#define MAX_ENTRY_POINTS 16 43848b8605Smrg 44848b8605Smrg#define need_MESA_remap_table 45848b8605Smrg#include "main/remap_helper.h" 46848b8605Smrg 47848b8605Smrg 48848b8605Smrg/* this is global for quick access */ 49848b8605Smrgint driDispatchRemapTable[driDispatchRemapTable_size]; 50848b8605Smrg 51848b8605Smrg 52848b8605Smrg/** 53848b8605Smrg * Return the spec string associated with the given function index. 54848b8605Smrg * The index is available from including remap_helper.h. 55848b8605Smrg * 56848b8605Smrg * \param func_index an opaque function index. 57848b8605Smrg * 58848b8605Smrg * \return the spec string associated with the function index, or NULL. 59848b8605Smrg */ 60848b8605Smrgconst char * 61848b8605Smrg_mesa_get_function_spec(GLint func_index) 62848b8605Smrg{ 63848b8605Smrg if (func_index < Elements(_mesa_function_pool)) 64848b8605Smrg return _mesa_function_pool + func_index; 65848b8605Smrg else 66848b8605Smrg return NULL; 67848b8605Smrg} 68848b8605Smrg 69848b8605Smrg 70848b8605Smrg/** 71848b8605Smrg * Map a function by its spec. The function will be added to glapi, 72848b8605Smrg * and the dispatch offset will be returned. 73848b8605Smrg * 74848b8605Smrg * \param spec a '\0'-separated string array specifying a function. 75848b8605Smrg * It begins with the parameter signature of the function, 76848b8605Smrg * followed by the names of the entry points. An empty entry 77848b8605Smrg * point name terminates the array. 78848b8605Smrg * 79848b8605Smrg * \return the offset of the (re-)mapped function in the dispatch 80848b8605Smrg * table, or -1. 81848b8605Smrg */ 82848b8605SmrgGLint 83848b8605Smrg_mesa_map_function_spec(const char *spec) 84848b8605Smrg{ 85848b8605Smrg const char *signature; 86848b8605Smrg const char *names[MAX_ENTRY_POINTS + 1]; 87848b8605Smrg GLint num_names = 0; 88848b8605Smrg 89848b8605Smrg if (!spec) 90848b8605Smrg return -1; 91848b8605Smrg 92848b8605Smrg signature = spec; 93848b8605Smrg spec += strlen(spec) + 1; 94848b8605Smrg 95848b8605Smrg /* spec is terminated by an empty string */ 96848b8605Smrg while (*spec) { 97848b8605Smrg names[num_names] = spec; 98848b8605Smrg num_names++; 99848b8605Smrg if (num_names >= MAX_ENTRY_POINTS) 100848b8605Smrg break; 101848b8605Smrg spec += strlen(spec) + 1; 102848b8605Smrg } 103848b8605Smrg if (!num_names) 104848b8605Smrg return -1; 105848b8605Smrg 106848b8605Smrg names[num_names] = NULL; 107848b8605Smrg 108848b8605Smrg /* add the entry points to the dispatch table */ 109848b8605Smrg return _glapi_add_dispatch(names, signature); 110848b8605Smrg} 111848b8605Smrg 112848b8605Smrg 113848b8605Smrg/** 114848b8605Smrg * Map an array of functions. This is a convenient function for 115848b8605Smrg * use with arrays available from including remap_helper.h. 116848b8605Smrg * 117848b8605Smrg * Note that the dispatch offsets of the functions are not returned. 118848b8605Smrg * If they are needed, _mesa_map_function_spec() should be used. 119848b8605Smrg * 120848b8605Smrg * \param func_array an array of function remaps. 121848b8605Smrg */ 122848b8605Smrgvoid 123848b8605Smrg_mesa_map_function_array(const struct gl_function_remap *func_array) 124848b8605Smrg{ 125848b8605Smrg GLint i; 126848b8605Smrg 127848b8605Smrg if (!func_array) 128848b8605Smrg return; 129848b8605Smrg 130848b8605Smrg for (i = 0; func_array[i].func_index != -1; i++) { 131848b8605Smrg const char *spec; 132848b8605Smrg GLint offset; 133848b8605Smrg 134848b8605Smrg spec = _mesa_get_function_spec(func_array[i].func_index); 135848b8605Smrg if (!spec) { 136848b8605Smrg _mesa_problem(NULL, "invalid function index %d", 137848b8605Smrg func_array[i].func_index); 138848b8605Smrg continue; 139848b8605Smrg } 140848b8605Smrg 141848b8605Smrg offset = _mesa_map_function_spec(spec); 142848b8605Smrg /* error checks */ 143848b8605Smrg if (offset < 0) { 144848b8605Smrg const char *name = spec + strlen(spec) + 1; 145848b8605Smrg _mesa_warning(NULL, "failed to remap %s", name); 146848b8605Smrg } 147848b8605Smrg else if (func_array[i].dispatch_offset >= 0 && 148848b8605Smrg offset != func_array[i].dispatch_offset) { 149848b8605Smrg const char *name = spec + strlen(spec) + 1; 150848b8605Smrg _mesa_problem(NULL, "%s should be mapped to %d, not %d", 151848b8605Smrg name, func_array[i].dispatch_offset, offset); 152848b8605Smrg } 153848b8605Smrg } 154848b8605Smrg} 155848b8605Smrg 156848b8605Smrg 157848b8605Smrg/** 158848b8605Smrg * Map the functions which are already static. 159848b8605Smrg * 160848b8605Smrg * When a extension function are incorporated into the ABI, the 161848b8605Smrg * extension suffix is usually stripped. Mapping such functions 162848b8605Smrg * makes sure the alternative names are available. 163848b8605Smrg * 164848b8605Smrg * Note that functions mapped by _mesa_init_remap_table() are 165848b8605Smrg * excluded. 166848b8605Smrg */ 167848b8605Smrgvoid 168848b8605Smrg_mesa_map_static_functions(void) 169848b8605Smrg{ 170848b8605Smrg /* Remap static functions which have alternative names and are in the ABI. 171848b8605Smrg * This is to be on the safe side. glapi should have defined those names. 172848b8605Smrg */ 173848b8605Smrg _mesa_map_function_array(MESA_alt_functions); 174848b8605Smrg} 175848b8605Smrg 176848b8605Smrg 177848b8605Smrg/** 178848b8605Smrg * Initialize the remap table. This is called in one_time_init(). 179848b8605Smrg * The remap table needs to be initialized before calling the 180848b8605Smrg * CALL/GET/SET macros defined in main/dispatch.h. 181848b8605Smrg */ 182848b8605Smrgstatic void 183848b8605Smrg_mesa_do_init_remap_table(const char *pool, 184848b8605Smrg int size, 185848b8605Smrg const struct gl_function_pool_remap *remap) 186848b8605Smrg{ 187848b8605Smrg static GLboolean initialized = GL_FALSE; 188848b8605Smrg GLint i; 189848b8605Smrg 190848b8605Smrg if (initialized) 191848b8605Smrg return; 192848b8605Smrg initialized = GL_TRUE; 193848b8605Smrg 194848b8605Smrg /* initialize the remap table */ 195848b8605Smrg for (i = 0; i < size; i++) { 196848b8605Smrg GLint offset; 197848b8605Smrg const char *spec; 198848b8605Smrg 199848b8605Smrg /* sanity check */ 200848b8605Smrg ASSERT(i == remap[i].remap_index); 201848b8605Smrg spec = _mesa_function_pool + remap[i].pool_index; 202848b8605Smrg 203848b8605Smrg offset = _mesa_map_function_spec(spec); 204848b8605Smrg /* store the dispatch offset in the remap table */ 205848b8605Smrg driDispatchRemapTable[i] = offset; 206848b8605Smrg if (offset < 0) { 207848b8605Smrg const char *name = spec + strlen(spec) + 1; 208848b8605Smrg _mesa_warning(NULL, "failed to remap %s", name); 209848b8605Smrg } 210848b8605Smrg } 211848b8605Smrg} 212848b8605Smrg 213848b8605Smrg 214848b8605Smrgvoid 215848b8605Smrg_mesa_init_remap_table(void) 216848b8605Smrg{ 217848b8605Smrg _mesa_do_init_remap_table(_mesa_function_pool, 218848b8605Smrg driDispatchRemapTable_size, 219848b8605Smrg MESA_remap_table_functions); 220848b8605Smrg} 221