Home | History | Annotate | Line # | Download | only in sfn
      1 /* -*- mesa-c++  -*-
      2  *
      3  * Copyright (c) 2020 Collabora LTD
      4  *
      5  * Author: Gert Wollny <gert.wollny (at) collabora.com>
      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  * on the rights to use, copy, modify, merge, publish, distribute, sub
     11  * license, and/or sell copies of the Software, and to permit persons to whom
     12  * the Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the next
     15  * paragraph) shall be included in all copies or substantial portions of the
     16  * Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     21  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  */
     26 
     27 #include "sfn_nir.h"
     28 
     29 #include "nir.h"
     30 #include "nir_builder.h"
     31 
     32 #include <map>
     33 #include <vector>
     34 #include <iostream>
     35 
     36 namespace r600 {
     37 
     38 using std::map;
     39 using std::pair;
     40 using std::make_pair;
     41 using std::vector;
     42 
     43 class LowerSplit64BitVar : public NirLowerInstruction {
     44 public:
     45 
     46    ~LowerSplit64BitVar();
     47    using VarSplit = pair<nir_variable*, nir_variable*>;
     48    using VarMap = map<unsigned, VarSplit>;
     49 
     50    nir_ssa_def *
     51    split_double_load_deref(nir_intrinsic_instr *intr);
     52 
     53    nir_ssa_def *
     54    split_double_store_deref(nir_intrinsic_instr *intr);
     55 
     56 private:
     57    nir_ssa_def *
     58    split_load_deref_array(nir_intrinsic_instr *intr, nir_src& index);
     59 
     60    nir_ssa_def *
     61    split_load_deref_var(nir_intrinsic_instr *intr);
     62 
     63    nir_ssa_def *
     64    split_store_deref_array(nir_intrinsic_instr *intr, nir_deref_instr *deref);
     65 
     66    nir_ssa_def *
     67    split_store_deref_var(nir_intrinsic_instr *intr, nir_deref_instr *deref1);
     68 
     69    VarSplit get_var_pair(nir_variable *old_var);
     70 
     71    nir_ssa_def *
     72    merge_64bit_loads(nir_ssa_def *load1, nir_ssa_def *load2, bool out_is_vec3);
     73 
     74    nir_ssa_def *split_double_load(nir_intrinsic_instr *load1);
     75 
     76    nir_ssa_def *
     77    split_store_output(nir_intrinsic_instr *store1);
     78 
     79    nir_ssa_def *split_double_load_uniform(nir_intrinsic_instr *intr);
     80 
     81    nir_ssa_def *
     82    split_double_load_ssbo(nir_intrinsic_instr *intr);
     83 
     84    nir_ssa_def *
     85    split_double_load_ubo(nir_intrinsic_instr *intr);
     86 
     87    nir_ssa_def *
     88    split_reduction(nir_ssa_def *src[2][2], nir_op op1, nir_op op2, nir_op reduction);
     89 
     90    nir_ssa_def *
     91    split_reduction3(nir_alu_instr *alu,
     92                     nir_op op1, nir_op op2, nir_op reduction);
     93 
     94    nir_ssa_def *
     95    split_reduction4(nir_alu_instr *alu,
     96                     nir_op op1, nir_op op2, nir_op reduction);
     97 
     98    nir_ssa_def *split_bcsel(nir_alu_instr *alu);
     99 
    100    nir_ssa_def *split_load_const(nir_load_const_instr *lc);
    101 
    102    bool filter(const nir_instr *instr) const override;
    103    nir_ssa_def *lower(nir_instr *instr) override;
    104 
    105    VarMap m_varmap;
    106    vector<nir_variable*> m_old_vars;
    107    vector<nir_instr *> m_old_stores;
    108 };
    109 
    110 
    111 bool
    112 LowerSplit64BitVar::filter(const nir_instr *instr) const
    113 {
    114    switch (instr->type) {
    115    case  nir_instr_type_intrinsic: {
    116       auto intr = nir_instr_as_intrinsic(instr);
    117 
    118       switch (intr->intrinsic) {
    119       case nir_intrinsic_load_deref:
    120       case nir_intrinsic_load_uniform:
    121       case nir_intrinsic_load_input:
    122       case nir_intrinsic_load_ubo:
    123       case nir_intrinsic_load_ssbo:
    124          if (nir_dest_bit_size(intr->dest) != 64)
    125             return false;
    126          return nir_dest_num_components(intr->dest) >= 3;
    127       case nir_intrinsic_store_output:
    128          if (nir_src_bit_size(intr->src[0]) != 64)
    129             return false;
    130          return nir_src_num_components(intr->src[0]) >= 3;
    131       case nir_intrinsic_store_deref:
    132          if (nir_src_bit_size(intr->src[1]) != 64)
    133             return false;
    134          return nir_src_num_components(intr->src[1]) >= 3;
    135       default:
    136          return false;
    137       }
    138    }
    139    case  nir_instr_type_alu: {
    140       auto alu = nir_instr_as_alu(instr);
    141       switch (alu->op) {
    142       case nir_op_bcsel:
    143          if (nir_dest_num_components(alu->dest.dest) < 3)
    144             return false;
    145          return nir_dest_bit_size(alu->dest.dest) == 64;
    146       case nir_op_bany_fnequal3:
    147       case nir_op_bany_fnequal4:
    148       case nir_op_ball_fequal3:
    149       case nir_op_ball_fequal4:
    150       case nir_op_bany_inequal3:
    151       case nir_op_bany_inequal4:
    152       case nir_op_ball_iequal3:
    153       case nir_op_ball_iequal4:
    154       case nir_op_fdot3:
    155       case nir_op_fdot4:
    156          return nir_src_bit_size(alu->src[1].src) == 64;
    157       default:
    158          return false;
    159       }
    160    }
    161    case nir_instr_type_load_const: {
    162       auto lc = nir_instr_as_load_const(instr);
    163       if (lc->def.bit_size != 64)
    164          return false;
    165       return lc->def.num_components >= 3;
    166    }
    167    default:
    168       return false;
    169    }
    170 }
    171 
    172 nir_ssa_def *
    173 LowerSplit64BitVar::merge_64bit_loads(nir_ssa_def *load1,
    174                                       nir_ssa_def *load2, bool out_is_vec3)
    175 {
    176    if (out_is_vec3)
    177       return nir_vec3(b, nir_channel(b, load1, 0),
    178                       nir_channel(b, load1, 1),
    179                       nir_channel(b, load2, 0));
    180    else
    181       return nir_vec4(b, nir_channel(b, load1, 0),
    182                       nir_channel(b, load1, 1),
    183                       nir_channel(b, load2, 0),
    184                       nir_channel(b, load2, 1));
    185 }
    186 
    187 LowerSplit64BitVar::~LowerSplit64BitVar()
    188 {
    189    for(auto&& v: m_old_vars)
    190       exec_node_remove(&v->node);
    191 
    192    for(auto&& v: m_old_stores)
    193       nir_instr_remove(v);
    194 }
    195 
    196 nir_ssa_def *
    197 LowerSplit64BitVar::split_double_store_deref(nir_intrinsic_instr *intr)
    198 {
    199    auto deref = nir_instr_as_deref(intr->src[0].ssa->parent_instr);
    200    if (deref->deref_type == nir_deref_type_var)
    201       return split_store_deref_var(intr, deref);
    202    else if (deref->deref_type == nir_deref_type_array)
    203       return split_store_deref_array(intr, deref);
    204    else {
    205       unreachable("only splitting of stores to vars and arrays is supported");
    206    }
    207 }
    208 
    209 nir_ssa_def *
    210 LowerSplit64BitVar::split_double_load_deref(nir_intrinsic_instr *intr)
    211 {
    212    auto deref = nir_instr_as_deref(intr->src[0].ssa->parent_instr);
    213    if (deref->deref_type == nir_deref_type_var)
    214       return split_load_deref_var(intr);
    215    else if (deref->deref_type == nir_deref_type_array)
    216       return split_load_deref_array(intr, deref->arr.index);
    217    else {
    218       unreachable(0 && "only splitting of loads from vars and arrays is supported");
    219    }
    220    m_old_stores.push_back(&intr->instr);
    221 }
    222 
    223 nir_ssa_def *
    224 LowerSplit64BitVar::split_load_deref_array(nir_intrinsic_instr *intr, nir_src& index)
    225 {
    226    auto old_var = nir_intrinsic_get_var(intr, 0);
    227    unsigned old_components = old_var->type->without_array()->components();
    228 
    229    assert(old_components > 2 && old_components <= 4);
    230 
    231    auto vars = get_var_pair(old_var);
    232 
    233    auto deref1 = nir_build_deref_var(b, vars.first);
    234    auto deref_array1 = nir_build_deref_array(b, deref1, nir_ssa_for_src(b, index, 1));
    235    auto load1 = nir_build_load_deref(b, 2, 64, &deref_array1->dest.ssa, (enum gl_access_qualifier)0);
    236 
    237    auto deref2 = nir_build_deref_var(b, vars.second);
    238    auto deref_array2 = nir_build_deref_array(b, deref2, nir_ssa_for_src(b, index, 1));
    239 
    240    auto load2 = nir_build_load_deref(b, old_components - 2, 64, &deref_array2->dest.ssa, (enum gl_access_qualifier)0);
    241 
    242    return merge_64bit_loads(load1, load2, old_components == 3);
    243 }
    244 
    245 nir_ssa_def *
    246 LowerSplit64BitVar::split_store_deref_array(nir_intrinsic_instr *intr, nir_deref_instr *deref)
    247 {
    248    auto old_var = nir_intrinsic_get_var(intr, 0);
    249    unsigned old_components = old_var->type->without_array()->components();
    250 
    251    assert(old_components > 2 && old_components <= 4);
    252 
    253    auto src_xy = nir_channels(b, intr->src[1].ssa, 3);
    254 
    255    auto vars = get_var_pair(old_var);
    256 
    257    auto deref1 = nir_build_deref_var(b, vars.first);
    258    auto deref_array1 = nir_build_deref_array(b, deref1, nir_ssa_for_src(b, deref->arr.index, 1));
    259 
    260    nir_build_store_deref(b, &deref_array1->dest.ssa, src_xy, 3);
    261 
    262    auto deref2 = nir_build_deref_var(b, vars.second);
    263    auto deref_array2 = nir_build_deref_array(b, deref2, nir_ssa_for_src(b, deref->arr.index, 1));
    264 
    265    if (old_components == 3)
    266       nir_build_store_deref(b, &deref_array2->dest.ssa, nir_channel(b, intr->src[1].ssa, 2), 1);
    267    else
    268       nir_build_store_deref(b, &deref_array2->dest.ssa, nir_channels(b, intr->src[1].ssa, 0xc), 3);
    269 
    270    return NIR_LOWER_INSTR_PROGRESS_REPLACE;
    271 }
    272 
    273 nir_ssa_def *
    274 LowerSplit64BitVar::split_store_deref_var(nir_intrinsic_instr *intr, nir_deref_instr *deref)
    275 {
    276    auto old_var = nir_intrinsic_get_var(intr, 0);
    277    unsigned old_components = old_var->type->without_array()->components();
    278 
    279    assert(old_components > 2 && old_components <= 4);
    280 
    281    auto src_xy = nir_channels(b, intr->src[1].ssa, 3);
    282 
    283    auto vars = get_var_pair(old_var);
    284 
    285    auto deref1 = nir_build_deref_var(b, vars.first);
    286    nir_build_store_deref(b, &deref1->dest.ssa, src_xy, 3);
    287 
    288    auto deref2 = nir_build_deref_var(b, vars.second);
    289    if (old_components == 3)
    290       nir_build_store_deref(b, &deref2->dest.ssa, nir_channel(b, intr->src[1].ssa, 2), 1);
    291    else
    292       nir_build_store_deref(b, &deref2->dest.ssa, nir_channels(b, intr->src[1].ssa, 0xc), 3);
    293 
    294    return NIR_LOWER_INSTR_PROGRESS_REPLACE;
    295 }
    296 
    297 nir_ssa_def *
    298 LowerSplit64BitVar::split_load_deref_var(nir_intrinsic_instr *intr)
    299 {
    300    auto old_var = nir_intrinsic_get_var(intr, 0);
    301    auto vars = get_var_pair(old_var);
    302    unsigned old_components = old_var->type->components();
    303 
    304    nir_deref_instr *deref1 = nir_build_deref_var(b, vars.first);
    305    auto *load1 = nir_load_deref(b, deref1);
    306 
    307    nir_deref_instr *deref2 = nir_build_deref_var(b, vars.second);
    308    deref2->type = vars.second->type;
    309 
    310    auto *load2 = nir_load_deref(b, deref2);
    311 
    312    return merge_64bit_loads(load1, load2, old_components == 3);
    313 }
    314 
    315 LowerSplit64BitVar::VarSplit
    316 LowerSplit64BitVar::get_var_pair(nir_variable *old_var)
    317 {
    318    auto split_vars = m_varmap.find(old_var->data.driver_location);
    319 
    320    assert(old_var->type->without_array()->components() > 2);
    321 
    322    if (split_vars == m_varmap.end()) {
    323       auto var1 = nir_variable_clone(old_var, b->shader);
    324       auto var2 = nir_variable_clone(old_var, b->shader);
    325 
    326       var1->type = glsl_dvec_type(2);
    327       var2->type = glsl_dvec_type(old_var->type->without_array()->components() - 2);
    328 
    329       if (old_var->type->is_array()) {
    330          var1->type = glsl_array_type(var1->type, old_var->type->array_size(), 0);
    331          var2->type = glsl_array_type(var2->type, old_var->type->array_size(), 0);
    332       }
    333 
    334       if (old_var->data.mode == nir_var_shader_in ||
    335           old_var->data.mode == nir_var_shader_out) {
    336          ++var2->data.driver_location;
    337          ++var2->data.location;
    338          nir_shader_add_variable(b->shader, var1);
    339          nir_shader_add_variable(b->shader, var2);
    340       } else if (old_var->data.mode == nir_var_function_temp) {
    341          exec_list_push_tail(&b->impl->locals, &var1->node);
    342          exec_list_push_tail(&b->impl->locals, &var2->node);
    343       }
    344 
    345       m_varmap[old_var->data.driver_location] = make_pair(var1, var2);
    346    }
    347    return m_varmap[old_var->data.driver_location];
    348 }
    349 
    350 
    351 nir_ssa_def *
    352 LowerSplit64BitVar::split_double_load(nir_intrinsic_instr *load1)
    353 {
    354    unsigned old_components = nir_dest_num_components(load1->dest);
    355    auto load2 = nir_instr_as_intrinsic(nir_instr_clone(b->shader, &load1->instr));
    356    nir_io_semantics sem = nir_intrinsic_io_semantics(load1);
    357 
    358    load1->dest.ssa.num_components = 2;
    359    sem.num_slots = 1;
    360    nir_intrinsic_set_io_semantics(load1, sem);
    361 
    362    load2->dest.ssa.num_components = old_components - 2;
    363    sem.location += 1;
    364    nir_intrinsic_set_io_semantics(load2, sem);
    365    nir_intrinsic_set_base(load2, nir_intrinsic_base(load1) + 1);
    366    nir_builder_instr_insert(b, &load2->instr);
    367 
    368    return merge_64bit_loads(&load1->dest.ssa, &load2->dest.ssa, old_components == 3);
    369 }
    370 
    371 
    372 nir_ssa_def *
    373 LowerSplit64BitVar::split_store_output(nir_intrinsic_instr *store1)
    374 {
    375    auto src = store1->src[0];
    376    unsigned old_components = nir_src_num_components(src);
    377    nir_io_semantics sem = nir_intrinsic_io_semantics(store1);
    378 
    379    auto store2 = nir_instr_as_intrinsic(nir_instr_clone(b->shader, &store1->instr));
    380    auto src1 = nir_channels(b, src.ssa, 3);
    381    auto src2 = nir_channels(b, src.ssa, old_components == 3 ? 4 : 0xc);
    382 
    383    nir_instr_rewrite_src(&store1->instr, &src, nir_src_for_ssa(src1));
    384    nir_intrinsic_set_write_mask(store1, 3);
    385 
    386    nir_instr_rewrite_src(&store2->instr, &src, nir_src_for_ssa(src2));
    387    nir_intrinsic_set_write_mask(store2, old_components == 3 ? 1 : 3);
    388 
    389    sem.num_slots = 1;
    390    nir_intrinsic_set_io_semantics(store1, sem);
    391 
    392    sem.location += 1;
    393    nir_intrinsic_set_io_semantics(store2, sem);
    394    nir_intrinsic_set_base(store2, nir_intrinsic_base(store1));
    395 
    396    nir_builder_instr_insert(b, &store2->instr);
    397    return NIR_LOWER_INSTR_PROGRESS;
    398 }
    399 
    400 
    401 nir_ssa_def *
    402 LowerSplit64BitVar::split_double_load_uniform(nir_intrinsic_instr *intr)
    403 {
    404    unsigned second_components = nir_dest_num_components(intr->dest) - 2;
    405    nir_intrinsic_instr *load2 = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_uniform);
    406    load2->src[0] = nir_src_for_ssa(nir_iadd_imm(b, intr->src[0].ssa, 1));
    407    nir_intrinsic_set_dest_type(load2, nir_intrinsic_dest_type(intr));
    408    nir_intrinsic_set_base(load2, nir_intrinsic_base(intr));
    409    nir_intrinsic_set_range(load2, nir_intrinsic_range(intr));
    410    load2->num_components = second_components;
    411 
    412    nir_ssa_dest_init(&load2->instr, &load2->dest, second_components, 64, nullptr);
    413    nir_builder_instr_insert(b, &load2->instr);
    414 
    415    intr->dest.ssa.num_components = intr->num_components = 2;
    416 
    417    if (second_components == 1)
    418       return nir_vec3(b, nir_channel(b, &intr->dest.ssa, 0),
    419                       nir_channel(b, &intr->dest.ssa, 1),
    420                       nir_channel(b, &load2->dest.ssa, 0));
    421    else
    422       return nir_vec4(b, nir_channel(b, &intr->dest.ssa, 0),
    423                       nir_channel(b, &intr->dest.ssa, 1),
    424                       nir_channel(b, &load2->dest.ssa, 0),
    425                       nir_channel(b, &load2->dest.ssa, 1));
    426 }
    427 
    428 nir_ssa_def *
    429 LowerSplit64BitVar::split_double_load_ssbo(nir_intrinsic_instr *intr)
    430 {
    431    unsigned second_components = nir_dest_num_components(intr->dest) - 2;
    432    nir_intrinsic_instr *load2 = nir_instr_as_intrinsic(nir_instr_clone(b->shader, &intr->instr));
    433 
    434    auto new_src0 = nir_src_for_ssa(nir_iadd_imm(b, intr->src[0].ssa, 1));
    435    nir_instr_rewrite_src(&load2->instr, &load2->src[0], new_src0);
    436    load2->num_components = second_components;
    437    nir_ssa_dest_init(&load2->instr, &load2->dest, second_components, 64, nullptr);
    438 
    439    nir_intrinsic_set_dest_type(load2, nir_intrinsic_dest_type(intr));
    440    nir_builder_instr_insert(b, &load2->instr);
    441 
    442    intr->dest.ssa.num_components = intr->num_components = 2;
    443 
    444    return merge_64bit_loads(&intr->dest.ssa, &load2->dest.ssa, second_components == 1);
    445 }
    446 
    447 
    448 nir_ssa_def *
    449 LowerSplit64BitVar::split_double_load_ubo(nir_intrinsic_instr *intr)
    450 {
    451    unsigned second_components = nir_dest_num_components(intr->dest) - 2;
    452    nir_intrinsic_instr *load2 = nir_instr_as_intrinsic(nir_instr_clone(b->shader, &intr->instr));
    453    load2->src[0] = intr->src[0];
    454    load2->src[1] = nir_src_for_ssa(nir_iadd_imm(b, intr->src[1].ssa, 16));
    455    nir_intrinsic_set_range_base(load2, nir_intrinsic_range_base(intr) + 16);
    456    nir_intrinsic_set_range(load2, nir_intrinsic_range(intr));
    457    nir_intrinsic_set_access(load2, nir_intrinsic_access(intr));
    458    nir_intrinsic_set_align_mul(load2, nir_intrinsic_align_mul(intr));
    459    nir_intrinsic_set_align_offset(load2, nir_intrinsic_align_offset(intr) + 16);
    460 
    461    load2->num_components = second_components;
    462 
    463    nir_ssa_dest_init(&load2->instr, &load2->dest, second_components, 64, nullptr);
    464    nir_builder_instr_insert(b, &load2->instr);
    465 
    466    intr->dest.ssa.num_components = intr->num_components = 2;
    467 
    468    return merge_64bit_loads(&intr->dest.ssa, &load2->dest.ssa, second_components == 1);
    469 }
    470 
    471 nir_ssa_def *
    472 LowerSplit64BitVar::split_reduction(nir_ssa_def *src[2][2], nir_op op1, nir_op op2, nir_op reduction)
    473 {
    474    auto cmp0 = nir_build_alu(b, op1, src[0][0], src[0][1], nullptr, nullptr);
    475    auto cmp1 = nir_build_alu(b, op2, src[1][0], src[1][1], nullptr, nullptr);
    476    return nir_build_alu(b, reduction, cmp0, cmp1, nullptr, nullptr);
    477 }
    478 
    479 nir_ssa_def *
    480 LowerSplit64BitVar::split_reduction3(nir_alu_instr *alu,
    481                                      nir_op op1, nir_op op2, nir_op reduction)
    482 {
    483    nir_ssa_def *src[2][2];
    484 
    485    src[0][0] = nir_channels(b, nir_ssa_for_src(b, alu->src[0].src, 2), 3);
    486    src[0][1] = nir_channels(b, nir_ssa_for_src(b, alu->src[1].src, 2), 3);
    487 
    488    src[1][0]  = nir_channel(b, nir_ssa_for_src(b, alu->src[0].src, 3), 2);
    489    src[1][1]  = nir_channel(b, nir_ssa_for_src(b, alu->src[1].src, 3), 2);
    490 
    491    return split_reduction(src, op1, op2, reduction);
    492 }
    493 
    494 nir_ssa_def *
    495 LowerSplit64BitVar::split_reduction4(nir_alu_instr *alu,
    496                                      nir_op op1, nir_op op2, nir_op reduction)
    497 {
    498    nir_ssa_def *src[2][2];
    499 
    500    src[0][0] = nir_channels(b, nir_ssa_for_src(b, alu->src[0].src, 2), 3);
    501    src[0][1] = nir_channels(b, nir_ssa_for_src(b, alu->src[1].src, 2), 3);
    502 
    503    src[1][0]  = nir_channels(b, nir_ssa_for_src(b, alu->src[0].src, 4), 0xc);
    504    src[1][1]  = nir_channels(b, nir_ssa_for_src(b, alu->src[1].src, 4), 0xc);
    505 
    506    return split_reduction(src, op1, op2, reduction);
    507 }
    508 
    509 nir_ssa_def *
    510 LowerSplit64BitVar::split_bcsel(nir_alu_instr *alu)
    511 {
    512    static nir_ssa_def *dest[4];
    513    for (unsigned i = 0; i < nir_dest_num_components(alu->dest.dest); ++i) {
    514       dest[i] = nir_bcsel(b,
    515                           nir_channel(b, alu->src[0].src.ssa, i),
    516                           nir_channel(b, alu->src[1].src.ssa, i),
    517                           nir_channel(b, alu->src[2].src.ssa, i));
    518    }
    519    return nir_vec(b, dest, nir_dest_num_components(alu->dest.dest));
    520 }
    521 
    522 nir_ssa_def *
    523 LowerSplit64BitVar::split_load_const(nir_load_const_instr *lc)
    524 {
    525    nir_ssa_def *ir[4];
    526    for (unsigned i = 0; i < lc->def.num_components; ++i)
    527       ir[i] = nir_imm_double(b, lc->value[i].f64);
    528 
    529    return nir_vec(b, ir, lc->def.num_components);
    530 }
    531 
    532 nir_ssa_def *
    533 LowerSplit64BitVar::lower(nir_instr *instr)
    534 {
    535    switch (instr->type) {
    536    case nir_instr_type_intrinsic: {
    537       auto intr = nir_instr_as_intrinsic(instr);
    538       switch (intr->intrinsic) {
    539       case nir_intrinsic_load_deref:
    540          return this->split_double_load_deref(intr);
    541       case nir_intrinsic_load_uniform:
    542          return split_double_load_uniform(intr);
    543       case nir_intrinsic_load_ubo:
    544          return split_double_load_ubo(intr);
    545       case nir_intrinsic_load_ssbo:
    546          return split_double_load_ssbo(intr);
    547       case nir_intrinsic_load_input:
    548          return split_double_load(intr);
    549       case nir_intrinsic_store_output:
    550          return split_store_output(intr);
    551       case nir_intrinsic_store_deref:
    552          return split_double_store_deref(intr);
    553       default:
    554          assert(0);
    555       }
    556    }
    557    case  nir_instr_type_alu: {
    558       auto alu = nir_instr_as_alu(instr);
    559       nir_print_instr(instr, stderr);
    560       fprintf(stderr, "\n");
    561       switch (alu->op) {
    562       case nir_op_bany_fnequal3:
    563          return split_reduction3(alu, nir_op_bany_fnequal2, nir_op_fneu, nir_op_ior);
    564       case nir_op_ball_fequal3:
    565          return split_reduction3(alu, nir_op_ball_fequal2, nir_op_feq, nir_op_iand);
    566       case nir_op_bany_inequal3:
    567          return split_reduction3(alu, nir_op_bany_inequal2, nir_op_ine, nir_op_ior);
    568       case nir_op_ball_iequal3:
    569          return split_reduction3(alu, nir_op_ball_iequal2, nir_op_ieq, nir_op_iand);
    570       case nir_op_fdot3:
    571          return split_reduction3(alu, nir_op_fdot2, nir_op_fmul, nir_op_fadd);
    572       case nir_op_bany_fnequal4:
    573          return split_reduction4(alu, nir_op_bany_fnequal2, nir_op_bany_fnequal2, nir_op_ior);
    574       case nir_op_ball_fequal4:
    575          return split_reduction4(alu, nir_op_ball_fequal2, nir_op_ball_fequal2, nir_op_iand);
    576       case nir_op_bany_inequal4:
    577          return split_reduction4(alu, nir_op_bany_inequal2, nir_op_bany_inequal2, nir_op_ior);
    578       case nir_op_ball_iequal4:
    579          return split_reduction4(alu, nir_op_bany_fnequal2, nir_op_bany_fnequal2, nir_op_ior);
    580       case nir_op_fdot4:
    581          return split_reduction4(alu, nir_op_fdot2, nir_op_fdot2, nir_op_fadd);
    582       case nir_op_bcsel:
    583          return split_bcsel(alu);
    584       default:
    585          assert(0);
    586       }
    587    }
    588    case nir_instr_type_load_const: {
    589       auto lc = nir_instr_as_load_const(instr);
    590       return split_load_const(lc);
    591    }
    592    default:
    593       assert(0);
    594    }
    595    return nullptr;
    596 }
    597 
    598 /* Split 64 bit instruction so that at most two 64 bit components are
    599  * used in one instruction */
    600 
    601 bool
    602 r600_nir_split_64bit_io(nir_shader *sh)
    603 {
    604    return LowerSplit64BitVar().run(sh);
    605 }
    606 
    607 /* */
    608 class Lower64BitToVec2 : public NirLowerInstruction {
    609 
    610 private:
    611    bool filter(const nir_instr *instr) const override;
    612    nir_ssa_def *lower(nir_instr *instr) override;
    613 
    614    nir_ssa_def *load_deref_64_to_vec2(nir_intrinsic_instr *intr);
    615    nir_ssa_def *load_uniform_64_to_vec2(nir_intrinsic_instr *intr);
    616    nir_ssa_def *load_ssbo_64_to_vec2(nir_intrinsic_instr *intr);
    617    nir_ssa_def *load_64_to_vec2(nir_intrinsic_instr *intr);
    618    nir_ssa_def *store_64_to_vec2(nir_intrinsic_instr *intr);
    619 };
    620 
    621 bool
    622 Lower64BitToVec2::filter(const nir_instr *instr) const
    623 {
    624    switch (instr->type) {
    625    case nir_instr_type_intrinsic:  {
    626       auto intr = nir_instr_as_intrinsic(instr);
    627 
    628       switch (intr->intrinsic) {
    629       case nir_intrinsic_load_deref:
    630       case nir_intrinsic_load_input:
    631       case nir_intrinsic_load_uniform:
    632       case nir_intrinsic_load_ubo:
    633       case nir_intrinsic_load_ubo_vec4:
    634       case nir_intrinsic_load_ssbo:
    635          return nir_dest_bit_size(intr->dest) == 64;
    636       case nir_intrinsic_store_deref: {
    637          if (nir_src_bit_size(intr->src[1]) == 64)
    638             return true;
    639          auto var = nir_intrinsic_get_var(intr, 0);
    640          if (var->type->without_array()->bit_size() == 64)
    641             return true;
    642          return (var->type->without_array()->components() != intr->num_components);
    643       }
    644       default:
    645          return false;
    646       }
    647    }
    648    case nir_instr_type_alu: {
    649       auto alu = nir_instr_as_alu(instr);
    650       return nir_dest_bit_size(alu->dest.dest) == 64;
    651    }
    652    case nir_instr_type_phi: {
    653       auto phi = nir_instr_as_phi(instr);
    654       return nir_dest_bit_size(phi->dest) == 64;
    655    }
    656    case nir_instr_type_load_const:  {
    657       auto lc = nir_instr_as_load_const(instr);
    658       return lc->def.bit_size == 64;
    659    }
    660    case nir_instr_type_ssa_undef:  {
    661       auto undef = nir_instr_as_ssa_undef(instr);
    662       return undef->def.bit_size == 64;
    663    }
    664    default:
    665       return false;
    666    }
    667 }
    668 
    669 nir_ssa_def *
    670 Lower64BitToVec2::lower(nir_instr *instr)
    671 {
    672    switch (instr->type) {
    673    case nir_instr_type_intrinsic:  {
    674       auto intr = nir_instr_as_intrinsic(instr);
    675       switch (intr->intrinsic) {
    676       case nir_intrinsic_load_deref:
    677          return load_deref_64_to_vec2(intr);
    678       case nir_intrinsic_load_uniform:
    679          return load_uniform_64_to_vec2(intr);
    680       case nir_intrinsic_load_ssbo:
    681          return load_ssbo_64_to_vec2(intr);
    682       case nir_intrinsic_load_input:
    683       case nir_intrinsic_load_ubo:
    684       case nir_intrinsic_load_ubo_vec4:
    685          return load_64_to_vec2(intr);
    686       case nir_intrinsic_store_deref:
    687          return store_64_to_vec2(intr);
    688       default:
    689 
    690          return nullptr;
    691       }
    692    }
    693    case nir_instr_type_alu: {
    694       auto alu = nir_instr_as_alu(instr);
    695       alu->dest.dest.ssa.bit_size = 32;
    696       alu->dest.dest.ssa.num_components *= 2;
    697       alu->dest.write_mask = (1 << alu->dest.dest.ssa.num_components) - 1;
    698       switch (alu->op) {
    699       case nir_op_pack_64_2x32_split:
    700          alu->op = nir_op_vec2;
    701          break;
    702       case nir_op_pack_64_2x32:
    703          alu->op = nir_op_mov;
    704          break;
    705       case nir_op_vec2:
    706          return nir_vec4(b,
    707                          nir_channel(b, alu->src[0].src.ssa, 0),
    708                          nir_channel(b, alu->src[0].src.ssa, 1),
    709                          nir_channel(b, alu->src[1].src.ssa, 0),
    710                          nir_channel(b, alu->src[1].src.ssa, 1));
    711       default:
    712          return NULL;
    713       }
    714       return NIR_LOWER_INSTR_PROGRESS;
    715    }
    716    case nir_instr_type_phi: {
    717       auto phi = nir_instr_as_phi(instr);
    718       phi->dest.ssa.bit_size = 32;
    719       phi->dest.ssa.num_components = 2;
    720       return NIR_LOWER_INSTR_PROGRESS;
    721    }
    722    case nir_instr_type_load_const:  {
    723       auto lc = nir_instr_as_load_const(instr);
    724       assert(lc->def.num_components < 3);
    725       nir_const_value val[4] = {0};
    726       for (uint i = 0; i < lc->def.num_components; ++i) {
    727          uint64_t v = lc->value[i].u64;
    728          val[0].u32 = v & 0xffffffff;
    729          val[1].u32 = (v >> 32) & 0xffffffff;
    730       }
    731 
    732       return nir_build_imm(b, 2 * lc->def.num_components, 32, val);
    733    }
    734    case nir_instr_type_ssa_undef:  {
    735       auto undef = nir_instr_as_ssa_undef(instr);
    736       undef->def.num_components *= 2;
    737       undef->def.bit_size = 32;
    738       return NIR_LOWER_INSTR_PROGRESS;
    739    }
    740    default:
    741       return nullptr;
    742    }
    743 
    744 }
    745 
    746 
    747 nir_ssa_def *
    748 Lower64BitToVec2::load_deref_64_to_vec2(nir_intrinsic_instr *intr)
    749 {
    750    auto deref = nir_instr_as_deref(intr->src[0].ssa->parent_instr);
    751    auto var = nir_intrinsic_get_var(intr, 0);
    752    unsigned components = var->type->without_array()->components();
    753    if (var->type->without_array()->bit_size() == 64) {
    754       components *= 2;
    755       if (deref->deref_type == nir_deref_type_var) {
    756          var->type = glsl_vec_type(components);
    757       } else if (deref->deref_type == nir_deref_type_array) {
    758 
    759          var->type = glsl_array_type(glsl_vec_type(components),
    760                                      var->type->array_size(), 0);
    761 
    762       } else {
    763          nir_print_shader(b->shader, stderr);
    764          assert(0 && "Only lowring of var and array derefs supported\n");
    765       }
    766    }
    767    deref->type = var->type;
    768    if (deref->deref_type == nir_deref_type_array) {
    769       auto deref_array = nir_instr_as_deref(deref->parent.ssa->parent_instr);
    770       deref_array->type = var->type;
    771       deref->type = deref_array->type->without_array();
    772    }
    773 
    774    intr->num_components = components;
    775    intr->dest.ssa.bit_size = 32;
    776    intr->dest.ssa.num_components = components;
    777    return NIR_LOWER_INSTR_PROGRESS;
    778 }
    779 
    780 nir_ssa_def *
    781 Lower64BitToVec2::store_64_to_vec2(nir_intrinsic_instr *intr)
    782 {
    783    auto deref = nir_instr_as_deref(intr->src[0].ssa->parent_instr);
    784    auto var = nir_intrinsic_get_var(intr, 0);
    785 
    786    unsigned components = var->type->without_array()->components();
    787    unsigned wrmask = nir_intrinsic_write_mask(intr);
    788    if (var->type->without_array()->bit_size() == 64) {
    789       components *= 2;
    790       if (deref->deref_type == nir_deref_type_var) {
    791          var->type = glsl_vec_type(components);
    792       } else if (deref->deref_type == nir_deref_type_array) {
    793          var->type = glsl_array_type(glsl_vec_type(components),
    794                                      var->type->array_size(), 0);
    795       } else {
    796             nir_print_shader(b->shader, stderr);
    797             assert(0 && "Only lowring of var and array derefs supported\n");
    798       }
    799    }
    800    deref->type = var->type;
    801    if (deref->deref_type == nir_deref_type_array) {
    802       auto deref_array = nir_instr_as_deref(deref->parent.ssa->parent_instr);
    803       deref_array->type = var->type;
    804       deref->type = deref_array->type->without_array();
    805    }
    806    intr->num_components = components;
    807    nir_intrinsic_set_write_mask(intr, wrmask == 1 ? 3 : 0xf);
    808    return NIR_LOWER_INSTR_PROGRESS;
    809 }
    810 
    811 
    812 nir_ssa_def *
    813 Lower64BitToVec2::load_uniform_64_to_vec2(nir_intrinsic_instr *intr)
    814 {
    815    intr->num_components *= 2;
    816    intr->dest.ssa.bit_size = 32;
    817    intr->dest.ssa.num_components *= 2;
    818    nir_intrinsic_set_dest_type(intr, nir_type_float32);
    819    return NIR_LOWER_INSTR_PROGRESS;
    820 }
    821 
    822 nir_ssa_def *
    823 Lower64BitToVec2::load_64_to_vec2(nir_intrinsic_instr *intr)
    824 {
    825    intr->num_components *= 2;
    826    intr->dest.ssa.bit_size = 32;
    827    intr->dest.ssa.num_components *= 2;
    828    nir_intrinsic_set_component(intr, nir_intrinsic_component(intr) * 2);
    829    return NIR_LOWER_INSTR_PROGRESS;
    830 }
    831 
    832 nir_ssa_def *
    833 Lower64BitToVec2::load_ssbo_64_to_vec2(nir_intrinsic_instr *intr)
    834 {
    835    intr->num_components *= 2;
    836    intr->dest.ssa.bit_size = 32;
    837    intr->dest.ssa.num_components *= 2;
    838    return NIR_LOWER_INSTR_PROGRESS;
    839 }
    840 
    841 static bool store_64bit_intr(nir_src *src, void *state)
    842 {
    843    bool *s = (bool *)state;
    844    *s = nir_src_bit_size(*src) == 64;
    845    return !*s;
    846 }
    847 
    848 static bool double2vec2(nir_src *src, void *state)
    849 {
    850    if (nir_src_bit_size(*src) != 64)
    851       return true;
    852 
    853    assert(src->is_ssa);
    854    src->ssa->bit_size = 32;
    855    src->ssa->num_components *= 2;
    856    return true;
    857 }
    858 
    859 bool
    860 r600_nir_64_to_vec2(nir_shader *sh)
    861 {
    862    vector<nir_instr*> intr64bit;
    863    nir_foreach_function(function, sh) {
    864       if (function->impl) {
    865          nir_builder b;
    866          nir_builder_init(&b, function->impl);
    867 
    868          nir_foreach_block(block, function->impl) {
    869             nir_foreach_instr_safe(instr, block) {
    870                switch (instr->type) {
    871                case nir_instr_type_alu: {
    872                   bool success = false;
    873                   nir_foreach_src(instr, store_64bit_intr, &success);
    874                   if (success)
    875                      intr64bit.push_back(instr);
    876                   break;
    877                }
    878                case nir_instr_type_intrinsic: {
    879                   auto ir = nir_instr_as_intrinsic(instr);
    880                   switch (ir->intrinsic) {
    881                   case nir_intrinsic_store_output:
    882                   case nir_intrinsic_store_ssbo: {
    883                      bool success = false;
    884                      nir_foreach_src(instr, store_64bit_intr, &success);
    885                      if (success) {
    886                         auto wm = nir_intrinsic_write_mask(ir);
    887                         nir_intrinsic_set_write_mask(ir, (wm == 1) ? 3 : 0xf);
    888                         ir->num_components *= 2;
    889                      }
    890                      break;
    891                   }
    892                   default:
    893                      ;
    894                   }
    895                }
    896                default:
    897                   ;
    898                }
    899             }
    900          }
    901       }
    902    }
    903 
    904    bool result = Lower64BitToVec2().run(sh);
    905 
    906    if (result || !intr64bit.empty()) {
    907 
    908       for(auto&& instr: intr64bit) {
    909          if (instr->type == nir_instr_type_alu) {
    910             auto alu = nir_instr_as_alu(instr);
    911             auto alu_info = nir_op_infos[alu->op];
    912             for (unsigned i = 0; i < alu_info.num_inputs; ++i) {
    913                int swizzle[NIR_MAX_VEC_COMPONENTS] = {0};
    914                for (unsigned k = 0; k < NIR_MAX_VEC_COMPONENTS / 2; k++) {
    915                   if (!nir_alu_instr_channel_used(alu, i, k)) {
    916                      continue;
    917                   }
    918 
    919                   switch (alu->op) {
    920                   case nir_op_unpack_64_2x32_split_x:
    921                      swizzle[2 * k] = alu->src[i].swizzle[k] * 2;
    922                      alu->op = nir_op_mov;
    923                      break;
    924                   case nir_op_unpack_64_2x32_split_y:
    925                      swizzle[2 * k] = alu->src[i].swizzle[k] * 2 + 1;
    926                      alu->op = nir_op_mov;
    927                      break;
    928                   case nir_op_unpack_64_2x32:
    929                      alu->op = nir_op_mov;
    930                      break;
    931                   case nir_op_bcsel:
    932                      if (i == 0) {
    933                         swizzle[2 * k] = swizzle[2 * k + 1] = alu->src[i].swizzle[k] * 2;
    934                         break;
    935                      }
    936                      FALLTHROUGH;
    937                   default:
    938                      swizzle[2 * k] = alu->src[i].swizzle[k] * 2;
    939                      swizzle[2 * k + 1] = alu->src[i].swizzle[k] * 2 + 1;
    940                   }
    941                }
    942                for (unsigned k = 0; k < NIR_MAX_VEC_COMPONENTS; ++k) {
    943                   alu->src[i].swizzle[k] = swizzle[k];
    944                }
    945             }
    946          } else
    947             nir_foreach_src(instr, double2vec2, nullptr);
    948       }
    949       result = true;
    950    }
    951 
    952    return result;
    953 }
    954 
    955 using std::map;
    956 using std::vector;
    957 using std::pair;
    958 
    959 class StoreMerger {
    960 public:
    961    StoreMerger(nir_shader *shader);
    962    void collect_stores();
    963    bool combine();
    964    void combine_one_slot(vector<nir_intrinsic_instr*>& stores);
    965 
    966    using StoreCombos = map<unsigned, vector<nir_intrinsic_instr*>>;
    967 
    968    StoreCombos m_stores;
    969    nir_shader *sh;
    970 };
    971 
    972 StoreMerger::StoreMerger(nir_shader *shader):
    973    sh(shader)
    974 {
    975 }
    976 
    977 
    978 void StoreMerger::collect_stores()
    979 {
    980    unsigned vertex = 0;
    981    nir_foreach_function(function, sh) {
    982       if (function->impl) {
    983          nir_foreach_block(block, function->impl) {
    984             nir_foreach_instr_safe(instr, block) {
    985                if (instr->type != nir_instr_type_intrinsic)
    986                   continue;
    987 
    988                auto ir = nir_instr_as_intrinsic(instr);
    989                if (ir->intrinsic == nir_intrinsic_emit_vertex ||
    990                    ir->intrinsic == nir_intrinsic_emit_vertex_with_counter) {
    991                   ++vertex;
    992                   continue;
    993                }
    994                if (ir->intrinsic != nir_intrinsic_store_output)
    995                   continue;
    996 
    997                unsigned index = nir_intrinsic_base(ir) + 64 * vertex +
    998                                 8 * 64 * nir_intrinsic_io_semantics(ir).gs_streams;
    999                m_stores[index].push_back(ir);
   1000             }
   1001          }
   1002       }
   1003    }
   1004 }
   1005 
   1006 bool StoreMerger::combine()
   1007 {
   1008    bool progress = false;
   1009    for(auto&& i : m_stores) {
   1010       if (i.second.size() < 2)
   1011          continue;
   1012 
   1013       combine_one_slot(i.second);
   1014       progress = true;
   1015    }
   1016    return progress;
   1017 }
   1018 
   1019 void StoreMerger::combine_one_slot(vector<nir_intrinsic_instr*>& stores)
   1020 {
   1021    nir_ssa_def *srcs[4] = {nullptr};
   1022 
   1023    nir_builder b;
   1024    nir_builder_init(&b, nir_shader_get_entrypoint(sh));
   1025    auto last_store = *stores.rbegin();
   1026 
   1027    b.cursor = nir_before_instr(&last_store->instr);
   1028 
   1029    unsigned comps = 0;
   1030    unsigned writemask = 0;
   1031    unsigned first_comp = 4;
   1032    for (auto&& store : stores) {
   1033       int cmp = nir_intrinsic_component(store);
   1034       for (unsigned i = 0; i < nir_src_num_components(store->src[0]); ++i, ++comps) {
   1035          unsigned out_comp = i + cmp;
   1036          srcs[out_comp] = nir_channel(&b, store->src[0].ssa, i);
   1037          writemask |= 1 << out_comp;
   1038          if (first_comp > out_comp)
   1039             first_comp = out_comp;
   1040       }
   1041    }
   1042 
   1043    auto new_src = nir_vec(&b, srcs, comps);
   1044 
   1045    nir_instr_rewrite_src(&last_store->instr, &last_store->src[0], nir_src_for_ssa(new_src));
   1046    last_store->num_components = comps;
   1047    nir_intrinsic_set_component(last_store, first_comp);
   1048    nir_intrinsic_set_write_mask(last_store, writemask);
   1049 
   1050    for (auto i = stores.begin(); i != stores.end() - 1; ++i)
   1051       nir_instr_remove(&(*i)->instr);
   1052 }
   1053 
   1054 bool r600_merge_vec2_stores(nir_shader *shader)
   1055 {
   1056    r600::StoreMerger merger(shader);
   1057    merger.collect_stores();
   1058    return merger.combine();
   1059 }
   1060 
   1061 } // end namespace r600
   1062 
   1063 
   1064