Home | History | Annotate | Download | only in glsl
      1 /*
      2  * Copyright  2013 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 "ir.h"
     25 
     26 /**
     27  * Helper for checking equality when one instruction might be NULL, since you
     28  * can't access a's vtable in that case.
     29  */
     30 static bool
     31 possibly_null_equals(const ir_instruction *a, const ir_instruction *b,
     32                      enum ir_node_type ignore)
     33 {
     34    if (!a || !b)
     35       return !a && !b;
     36 
     37    return a->equals(b, ignore);
     38 }
     39 
     40 /**
     41  * The base equality function: Return not equal for anything we don't know
     42  * about.
     43  */
     44 bool
     45 ir_instruction::equals(const ir_instruction *, enum ir_node_type) const
     46 {
     47    return false;
     48 }
     49 
     50 bool
     51 ir_constant::equals(const ir_instruction *ir, enum ir_node_type) const
     52 {
     53    const ir_constant *other = ir->as_constant();
     54    if (!other)
     55       return false;
     56 
     57    if (type != other->type)
     58       return false;
     59 
     60    for (unsigned i = 0; i < type->components(); i++) {
     61       if (type->base_type == GLSL_TYPE_DOUBLE) {
     62          if (value.d[i] != other->value.d[i])
     63             return false;
     64       } else {
     65          if (value.u[i] != other->value.u[i])
     66             return false;
     67       }
     68    }
     69 
     70    return true;
     71 }
     72 
     73 bool
     74 ir_dereference_variable::equals(const ir_instruction *ir,
     75                                 enum ir_node_type) const
     76 {
     77    const ir_dereference_variable *other = ir->as_dereference_variable();
     78    if (!other)
     79       return false;
     80 
     81    return var == other->var;
     82 }
     83 
     84 bool
     85 ir_dereference_array::equals(const ir_instruction *ir,
     86                              enum ir_node_type ignore) const
     87 {
     88    const ir_dereference_array *other = ir->as_dereference_array();
     89    if (!other)
     90       return false;
     91 
     92    if (type != other->type)
     93       return false;
     94 
     95    if (!array->equals(other->array, ignore))
     96       return false;
     97 
     98    if (!array_index->equals(other->array_index, ignore))
     99       return false;
    100 
    101    return true;
    102 }
    103 
    104 bool
    105 ir_swizzle::equals(const ir_instruction *ir,
    106                    enum ir_node_type ignore) const
    107 {
    108    const ir_swizzle *other = ir->as_swizzle();
    109    if (!other)
    110       return false;
    111 
    112    if (type != other->type)
    113       return false;
    114 
    115    if (ignore != ir_type_swizzle) {
    116       if (mask.x != other->mask.x ||
    117           mask.y != other->mask.y ||
    118           mask.z != other->mask.z ||
    119           mask.w != other->mask.w) {
    120          return false;
    121       }
    122    }
    123 
    124    return val->equals(other->val, ignore);
    125 }
    126 
    127 bool
    128 ir_texture::equals(const ir_instruction *ir, enum ir_node_type ignore) const
    129 {
    130    const ir_texture *other = ir->as_texture();
    131    if (!other)
    132       return false;
    133 
    134    if (type != other->type)
    135       return false;
    136 
    137    if (op != other->op)
    138       return false;
    139 
    140    if (!possibly_null_equals(coordinate, other->coordinate, ignore))
    141       return false;
    142 
    143    if (!possibly_null_equals(projector, other->projector, ignore))
    144       return false;
    145 
    146    if (!possibly_null_equals(shadow_comparator, other->shadow_comparator, ignore))
    147       return false;
    148 
    149    if (!possibly_null_equals(offset, other->offset, ignore))
    150       return false;
    151 
    152    if (!sampler->equals(other->sampler, ignore))
    153       return false;
    154 
    155    switch (op) {
    156    case ir_tex:
    157    case ir_lod:
    158    case ir_query_levels:
    159    case ir_texture_samples:
    160    case ir_samples_identical:
    161       break;
    162    case ir_txb:
    163       if (!lod_info.bias->equals(other->lod_info.bias, ignore))
    164          return false;
    165       break;
    166    case ir_txl:
    167    case ir_txf:
    168    case ir_txs:
    169       if (!lod_info.lod->equals(other->lod_info.lod, ignore))
    170          return false;
    171       break;
    172    case ir_txd:
    173       if (!lod_info.grad.dPdx->equals(other->lod_info.grad.dPdx, ignore) ||
    174           !lod_info.grad.dPdy->equals(other->lod_info.grad.dPdy, ignore))
    175          return false;
    176       break;
    177    case ir_txf_ms:
    178       if (!lod_info.sample_index->equals(other->lod_info.sample_index, ignore))
    179          return false;
    180       break;
    181    case ir_tg4:
    182       if (!lod_info.component->equals(other->lod_info.component, ignore))
    183          return false;
    184       break;
    185    default:
    186       assert(!"Unrecognized texture op");
    187    }
    188 
    189    return true;
    190 }
    191 
    192 bool
    193 ir_expression::equals(const ir_instruction *ir, enum ir_node_type ignore) const
    194 {
    195    const ir_expression *other = ir->as_expression();
    196    if (!other)
    197       return false;
    198 
    199    if (type != other->type)
    200       return false;
    201 
    202    if (operation != other->operation)
    203       return false;
    204 
    205    for (unsigned i = 0; i < get_num_operands(); i++) {
    206       if (!operands[i]->equals(other->operands[i], ignore))
    207          return false;
    208    }
    209 
    210    return true;
    211 }
    212