Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.7
      4  *
      5  * Copyright (C) 2009 Chia-I Wu <olv (at) 0xlab.org>
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     23  * DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 
     27 /**
     28  * \file remap.c
     29  * Remap table management.
     30  *
     31  * Entries in the dispatch table are either static or dynamic.  The
     32  * dispatch table is shared by mesa core and glapi.  When they are
     33  * built separately, it is possible that a static entry in mesa core
     34  * is dynamic, or assigned a different static offset, in glapi.  The
     35  * remap table is in charge of mapping a static entry in mesa core to
     36  * a dynamic entry, or the corresponding static entry, in glapi.
     37  */
     38 
     39 #include "mfeatures.h"
     40 
     41 #if FEATURE_remap_table
     42 
     43 #include "remap.h"
     44 #include "imports.h"
     45 #include "glapi/glapi.h"
     46 
     47 #define MAX_ENTRY_POINTS 16
     48 
     49 #define need_MESA_remap_table
     50 #include "main/remap_helper.h"
     51 
     52 
     53 /* this is global for quick access */
     54 int driDispatchRemapTable[driDispatchRemapTable_size];
     55 
     56 
     57 /**
     58  * Return the spec string associated with the given function index.
     59  * The index is available from including remap_helper.h.
     60  *
     61  * \param func_index an opaque function index.
     62  *
     63  * \return the spec string associated with the function index, or NULL.
     64  */
     65 const char *
     66 _mesa_get_function_spec(GLint func_index)
     67 {
     68    if (func_index < Elements(_mesa_function_pool))
     69       return _mesa_function_pool + func_index;
     70    else
     71       return NULL;
     72 }
     73 
     74 
     75 /**
     76  * Map a function by its spec.  The function will be added to glapi,
     77  * and the dispatch offset will be returned.
     78  *
     79  * \param spec a '\0'-separated string array specifying a function.
     80  *        It begins with the parameter signature of the function,
     81  *        followed by the names of the entry points.  An empty entry
     82  *        point name terminates the array.
     83  *
     84  * \return the offset of the (re-)mapped function in the dispatch
     85  *         table, or -1.
     86  */
     87 GLint
     88 _mesa_map_function_spec(const char *spec)
     89 {
     90    const char *signature;
     91    const char *names[MAX_ENTRY_POINTS + 1];
     92    GLint num_names = 0;
     93 
     94    if (!spec)
     95       return -1;
     96 
     97    signature = spec;
     98    spec += strlen(spec) + 1;
     99 
    100    /* spec is terminated by an empty string */
    101    while (*spec) {
    102       names[num_names] = spec;
    103       num_names++;
    104       if (num_names >= MAX_ENTRY_POINTS)
    105          break;
    106       spec += strlen(spec) + 1;
    107    }
    108    if (!num_names)
    109       return -1;
    110 
    111    names[num_names] = NULL;
    112 
    113    /* add the entry points to the dispatch table */
    114    return _glapi_add_dispatch(names, signature);
    115 }
    116 
    117 
    118 /**
    119  * Map an array of functions.  This is a convenient function for
    120  * use with arrays available from including remap_helper.h.
    121  *
    122  * Note that the dispatch offsets of the functions are not returned.
    123  * If they are needed, _mesa_map_function_spec() should be used.
    124  *
    125  * \param func_array an array of function remaps.
    126  */
    127 void
    128 _mesa_map_function_array(const struct gl_function_remap *func_array)
    129 {
    130    GLint i;
    131 
    132    if (!func_array)
    133       return;
    134 
    135    for (i = 0; func_array[i].func_index != -1; i++) {
    136       const char *spec;
    137       GLint offset;
    138 
    139       spec = _mesa_get_function_spec(func_array[i].func_index);
    140       if (!spec) {
    141          _mesa_problem(NULL, "invalid function index %d",
    142                        func_array[i].func_index);
    143          continue;
    144       }
    145 
    146       offset = _mesa_map_function_spec(spec);
    147       /* error checks */
    148       if (offset < 0) {
    149          const char *name = spec + strlen(spec) + 1;
    150          _mesa_warning(NULL, "failed to remap %s", name);
    151       }
    152       else if (func_array[i].dispatch_offset >= 0 &&
    153                offset != func_array[i].dispatch_offset) {
    154          const char *name = spec + strlen(spec) + 1;
    155          _mesa_problem(NULL, "%s should be mapped to %d, not %d",
    156                        name, func_array[i].dispatch_offset, offset);
    157       }
    158    }
    159 }
    160 
    161 
    162 /**
    163  * Map the functions which are already static.
    164  *
    165  * When a extension function are incorporated into the ABI, the
    166  * extension suffix is usually stripped.  Mapping such functions
    167  * makes sure the alternative names are available.
    168  *
    169  * Note that functions mapped by _mesa_init_remap_table() are
    170  * excluded.
    171  */
    172 void
    173 _mesa_map_static_functions(void)
    174 {
    175    /* Remap static functions which have alternative names and are in the ABI.
    176     * This is to be on the safe side.  glapi should have defined those names.
    177     */
    178    _mesa_map_function_array(MESA_alt_functions);
    179 }
    180 
    181 
    182 /**
    183  * Initialize the remap table.  This is called in one_time_init().
    184  * The remap table needs to be initialized before calling the
    185  * CALL/GET/SET macros defined in main/dispatch.h.
    186  */
    187 static void
    188 _mesa_do_init_remap_table(const char *pool,
    189 			  int size,
    190 			  const struct gl_function_pool_remap *remap)
    191 {
    192    static GLboolean initialized = GL_FALSE;
    193    GLint i;
    194 
    195    if (initialized)
    196       return;
    197    initialized = GL_TRUE;
    198 
    199    /* initialize the remap table */
    200    for (i = 0; i < size; i++) {
    201       GLint offset;
    202       const char *spec;
    203 
    204       /* sanity check */
    205       ASSERT(i == remap[i].remap_index);
    206       spec = _mesa_function_pool + remap[i].pool_index;
    207 
    208       offset = _mesa_map_function_spec(spec);
    209       /* store the dispatch offset in the remap table */
    210       driDispatchRemapTable[i] = offset;
    211       if (offset < 0)
    212          _mesa_warning(NULL, "failed to remap index %d", i);
    213    }
    214 }
    215 
    216 
    217 void
    218 _mesa_init_remap_table(void)
    219 {
    220    _mesa_do_init_remap_table(_mesa_function_pool,
    221 			     driDispatchRemapTable_size,
    222 			     MESA_remap_table_functions);
    223 }
    224 
    225 
    226 #endif /* FEATURE_remap_table */
    227