Home | History | Annotate | Download | only in glsl
      1 /*
      2  * Copyright  2010 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #include "compiler/glsl_types.h"
     25 #include "ir.h"
     26 #include "glsl_parser_extras.h"
     27 #include "main/errors.h"
     28 
     29 typedef enum {
     30    PARAMETER_LIST_NO_MATCH,
     31    PARAMETER_LIST_EXACT_MATCH,
     32    PARAMETER_LIST_INEXACT_MATCH /*< Match requires implicit conversion. */
     33 } parameter_list_match_t;
     34 
     35 /**
     36  * \brief Check if two parameter lists match.
     37  *
     38  * \param list_a Parameters of the function definition.
     39  * \param list_b Actual parameters passed to the function.
     40  * \see matching_signature()
     41  */
     42 static parameter_list_match_t
     43 parameter_lists_match(_mesa_glsl_parse_state *state,
     44                       const exec_list *list_a, const exec_list *list_b)
     45 {
     46    const exec_node *node_a = list_a->get_head_raw();
     47    const exec_node *node_b = list_b->get_head_raw();
     48 
     49    /* This is set to true if there is an inexact match requiring an implicit
     50     * conversion. */
     51    bool inexact_match = false;
     52 
     53    for (/* empty */
     54 	; !node_a->is_tail_sentinel()
     55 	; node_a = node_a->next, node_b = node_b->next) {
     56       /* If all of the parameters from the other parameter list have been
     57        * exhausted, the lists have different length and, by definition,
     58        * do not match.
     59        */
     60       if (node_b->is_tail_sentinel())
     61 	 return PARAMETER_LIST_NO_MATCH;
     62 
     63 
     64       const ir_variable *const param = (ir_variable *) node_a;
     65       const ir_rvalue *const actual = (ir_rvalue *) node_b;
     66 
     67       if (param->type == actual->type)
     68 	 continue;
     69 
     70       /* Try to find an implicit conversion from actual to param. */
     71       inexact_match = true;
     72       switch ((enum ir_variable_mode)(param->data.mode)) {
     73       case ir_var_auto:
     74       case ir_var_uniform:
     75       case ir_var_shader_storage:
     76       case ir_var_temporary:
     77 	 /* These are all error conditions.  It is invalid for a parameter to
     78 	  * a function to be declared as auto (not in, out, or inout) or
     79 	  * as uniform.
     80 	  */
     81 	 assert(0);
     82 	 return PARAMETER_LIST_NO_MATCH;
     83 
     84       case ir_var_const_in:
     85       case ir_var_function_in:
     86 	 if (!actual->type->can_implicitly_convert_to(param->type, state))
     87 	    return PARAMETER_LIST_NO_MATCH;
     88 	 break;
     89 
     90       case ir_var_function_out:
     91 	 if (!param->type->can_implicitly_convert_to(actual->type, state))
     92 	    return PARAMETER_LIST_NO_MATCH;
     93 	 break;
     94 
     95       case ir_var_function_inout:
     96 	 /* Since there are no bi-directional automatic conversions (e.g.,
     97 	  * there is int -> float but no float -> int), inout parameters must
     98 	  * be exact matches.
     99 	  */
    100 	 return PARAMETER_LIST_NO_MATCH;
    101 
    102       default:
    103 	 assert(false);
    104 	 return PARAMETER_LIST_NO_MATCH;
    105       }
    106    }
    107 
    108    /* If all of the parameters from the other parameter list have been
    109     * exhausted, the lists have different length and, by definition, do not
    110     * match.
    111     */
    112    if (!node_b->is_tail_sentinel())
    113       return PARAMETER_LIST_NO_MATCH;
    114 
    115    if (inexact_match)
    116       return PARAMETER_LIST_INEXACT_MATCH;
    117    else
    118       return PARAMETER_LIST_EXACT_MATCH;
    119 }
    120 
    121 
    122 /* Classes of parameter match, sorted (mostly) best matches first.
    123  * See is_better_parameter_match() below for the exceptions.
    124  * */
    125 typedef enum {
    126    PARAMETER_EXACT_MATCH,
    127    PARAMETER_FLOAT_TO_DOUBLE,
    128    PARAMETER_INT_TO_FLOAT,
    129    PARAMETER_INT_TO_DOUBLE,
    130    PARAMETER_OTHER_CONVERSION,
    131 } parameter_match_t;
    132 
    133 
    134 static parameter_match_t
    135 get_parameter_match_type(const ir_variable *param,
    136                          const ir_rvalue *actual)
    137 {
    138    const glsl_type *from_type;
    139    const glsl_type *to_type;
    140 
    141    if (param->data.mode == ir_var_function_out) {
    142       from_type = param->type;
    143       to_type = actual->type;
    144    } else {
    145       from_type = actual->type;
    146       to_type = param->type;
    147    }
    148 
    149    if (from_type == to_type)
    150       return PARAMETER_EXACT_MATCH;
    151 
    152    if (to_type->base_type == GLSL_TYPE_DOUBLE) {
    153       if (from_type->base_type == GLSL_TYPE_FLOAT)
    154          return PARAMETER_FLOAT_TO_DOUBLE;
    155       return PARAMETER_INT_TO_DOUBLE;
    156    }
    157 
    158    if (to_type->base_type == GLSL_TYPE_FLOAT)
    159       return PARAMETER_INT_TO_FLOAT;
    160 
    161    /* int -> uint and any other oddball conversions */
    162    return PARAMETER_OTHER_CONVERSION;
    163 }
    164 
    165 
    166 static bool
    167 is_better_parameter_match(parameter_match_t a_match,
    168                           parameter_match_t b_match)
    169 {
    170    /* From section 6.1 of the GLSL 4.00 spec (and the ARB_gpu_shader5 spec):
    171     *
    172     * 1. An exact match is better than a match involving any implicit
    173     * conversion.
    174     *
    175     * 2. A match involving an implicit conversion from float to double
    176     * is better than match involving any other implicit conversion.
    177     *
    178     * [XXX: Not in GLSL 4.0: Only in ARB_gpu_shader5:
    179     * 3. A match involving an implicit conversion from either int or uint
    180     * to float is better than a match involving an implicit conversion
    181     * from either int or uint to double.]
    182     *
    183     * If none of the rules above apply to a particular pair of conversions,
    184     * neither conversion is considered better than the other.
    185     *
    186     * --
    187     *
    188     * Notably, the int->uint conversion is *not* considered to be better
    189     * or worse than int/uint->float or int/uint->double.
    190     */
    191 
    192    if (a_match >= PARAMETER_INT_TO_FLOAT && b_match == PARAMETER_OTHER_CONVERSION)
    193       return false;
    194 
    195    return a_match < b_match;
    196 }
    197 
    198 
    199 static bool
    200 is_best_inexact_overload(const exec_list *actual_parameters,
    201                          ir_function_signature **matches,
    202                          int num_matches,
    203                          ir_function_signature *sig)
    204 {
    205    /* From section 6.1 of the GLSL 4.00 spec (and the ARB_gpu_shader5 spec):
    206     *
    207     * "A function definition A is considered a better
    208     * match than function definition B if:
    209     *
    210     *   * for at least one function argument, the conversion for that argument
    211     *     in A is better than the corresponding conversion in B; and
    212     *
    213     *   * there is no function argument for which the conversion in B is better
    214     *     than the corresponding conversion in A.
    215     *
    216     * If a single function definition is considered a better match than every
    217     * other matching function definition, it will be used.  Otherwise, a
    218     * semantic error occurs and the shader will fail to compile."
    219     */
    220    for (ir_function_signature **other = matches;
    221         other < matches + num_matches; other++) {
    222       if (*other == sig)
    223          continue;
    224 
    225       const exec_node *node_a = sig->parameters.get_head_raw();
    226       const exec_node *node_b = (*other)->parameters.get_head_raw();
    227       const exec_node *node_p = actual_parameters->get_head_raw();
    228 
    229       bool better_for_some_parameter = false;
    230 
    231       for (/* empty */
    232            ; !node_a->is_tail_sentinel()
    233            ; node_a = node_a->next,
    234              node_b = node_b->next,
    235              node_p = node_p->next) {
    236          parameter_match_t a_match = get_parameter_match_type(
    237                (const ir_variable *)node_a,
    238                (const ir_rvalue *)node_p);
    239          parameter_match_t b_match = get_parameter_match_type(
    240                (const ir_variable *)node_b,
    241                (const ir_rvalue *)node_p);
    242 
    243          if (is_better_parameter_match(a_match, b_match))
    244                better_for_some_parameter = true;
    245 
    246          if (is_better_parameter_match(b_match, a_match))
    247                return false;     /* B is better for this parameter */
    248       }
    249 
    250       if (!better_for_some_parameter)
    251          return false;     /* A must be better than B for some parameter */
    252 
    253    }
    254 
    255    return true;
    256 }
    257 
    258 
    259 static ir_function_signature *
    260 choose_best_inexact_overload(_mesa_glsl_parse_state *state,
    261                              const exec_list *actual_parameters,
    262                              ir_function_signature **matches,
    263                              int num_matches)
    264 {
    265    if (num_matches == 0)
    266       return NULL;
    267 
    268    if (num_matches == 1)
    269       return *matches;
    270 
    271    /* Without GLSL 4.0, ARB_gpu_shader5, or MESA_shader_integer_functions,
    272     * there is no overload resolution among multiple inexact matches. Note
    273     * that state may be NULL here if called from the linker; in that case we
    274     * assume everything supported in any GLSL version is available.
    275     */
    276    if (!state || state->is_version(400, 0) || state->ARB_gpu_shader5_enable ||
    277        state->MESA_shader_integer_functions_enable) {
    278       for (ir_function_signature **sig = matches; sig < matches + num_matches; sig++) {
    279          if (is_best_inexact_overload(actual_parameters, matches, num_matches, *sig))
    280             return *sig;
    281       }
    282    }
    283 
    284    return NULL;   /* no best candidate */
    285 }
    286 
    287 
    288 ir_function_signature *
    289 ir_function::matching_signature(_mesa_glsl_parse_state *state,
    290                                 const exec_list *actual_parameters,
    291                                 bool allow_builtins)
    292 {
    293    bool is_exact;
    294    return matching_signature(state, actual_parameters, allow_builtins,
    295                              &is_exact);
    296 }
    297 
    298 ir_function_signature *
    299 ir_function::matching_signature(_mesa_glsl_parse_state *state,
    300                                 const exec_list *actual_parameters,
    301                                 bool allow_builtins,
    302                                 bool *is_exact)
    303 {
    304    ir_function_signature **inexact_matches = NULL;
    305    ir_function_signature **inexact_matches_temp;
    306    ir_function_signature *match = NULL;
    307    int num_inexact_matches = 0;
    308 
    309    /* From page 42 (page 49 of the PDF) of the GLSL 1.20 spec:
    310     *
    311     * "If an exact match is found, the other signatures are ignored, and
    312     *  the exact match is used.  Otherwise, if no exact match is found, then
    313     *  the implicit conversions in Section 4.1.10 "Implicit Conversions" will
    314     *  be applied to the calling arguments if this can make their types match
    315     *  a signature.  In this case, it is a semantic error if there are
    316     *  multiple ways to apply these conversions to the actual arguments of a
    317     *  call such that the call can be made to match multiple signatures."
    318     */
    319    foreach_in_list(ir_function_signature, sig, &this->signatures) {
    320       /* Skip over any built-ins that aren't available in this shader. */
    321       if (sig->is_builtin() && (!allow_builtins ||
    322                                 !sig->is_builtin_available(state)))
    323          continue;
    324 
    325       switch (parameter_lists_match(state, & sig->parameters, actual_parameters)) {
    326       case PARAMETER_LIST_EXACT_MATCH:
    327          *is_exact = true;
    328          free(inexact_matches);
    329          return sig;
    330       case PARAMETER_LIST_INEXACT_MATCH:
    331          inexact_matches_temp = (ir_function_signature **)
    332                realloc(inexact_matches,
    333                        sizeof(*inexact_matches) *
    334                        (num_inexact_matches + 1));
    335          if (inexact_matches_temp == NULL) {
    336             _mesa_error_no_memory(__func__);
    337             free(inexact_matches);
    338             return NULL;
    339          }
    340          inexact_matches = inexact_matches_temp;
    341          inexact_matches[num_inexact_matches++] = sig;
    342          continue;
    343       case PARAMETER_LIST_NO_MATCH:
    344 	 continue;
    345       default:
    346 	 assert(false);
    347 	 return NULL;
    348       }
    349    }
    350 
    351    /* There is no exact match (we would have returned it by now).  If there
    352     * are multiple inexact matches, the call is ambiguous, which is an error.
    353     *
    354     * FINISHME: Report a decent error.  Returning NULL will likely result in
    355     * FINISHME: a "no matching signature" error; it should report that the
    356     * FINISHME: call is ambiguous.  But reporting errors from here is hard.
    357     */
    358    *is_exact = false;
    359 
    360    match = choose_best_inexact_overload(state, actual_parameters,
    361                                         inexact_matches, num_inexact_matches);
    362 
    363    free(inexact_matches);
    364    return match;
    365 }
    366 
    367 
    368 static bool
    369 parameter_lists_match_exact(const exec_list *list_a, const exec_list *list_b)
    370 {
    371    const exec_node *node_a = list_a->get_head_raw();
    372    const exec_node *node_b = list_b->get_head_raw();
    373 
    374    for (/* empty */
    375 	; !node_a->is_tail_sentinel() && !node_b->is_tail_sentinel()
    376 	; node_a = node_a->next, node_b = node_b->next) {
    377       ir_variable *a = (ir_variable *) node_a;
    378       ir_variable *b = (ir_variable *) node_b;
    379 
    380       /* If the types of the parameters do not match, the parameters lists
    381        * are different.
    382        */
    383       if (a->type != b->type)
    384          return false;
    385    }
    386 
    387    /* Unless both lists are exhausted, they differ in length and, by
    388     * definition, do not match.
    389     */
    390    return (node_a->is_tail_sentinel() == node_b->is_tail_sentinel());
    391 }
    392 
    393 ir_function_signature *
    394 ir_function::exact_matching_signature(_mesa_glsl_parse_state *state,
    395                                       const exec_list *actual_parameters)
    396 {
    397    foreach_in_list(ir_function_signature, sig, &this->signatures) {
    398       /* Skip over any built-ins that aren't available in this shader. */
    399       if (sig->is_builtin() && !sig->is_builtin_available(state))
    400          continue;
    401 
    402       if (parameter_lists_match_exact(&sig->parameters, actual_parameters))
    403 	 return sig;
    404    }
    405    return NULL;
    406 }
    407