Home | History | Annotate | Line # | Download | only in sfn
      1 /* -*- mesa-c++  -*-
      2  *
      3  * Copyright (c) 2019 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 #include "nir_builder.h"
     29 
     30 #include "../r600_pipe.h"
     31 #include "../r600_shader.h"
     32 
     33 #include "sfn_instruction_tex.h"
     34 
     35 #include "sfn_shader_vertex.h"
     36 #include "sfn_shader_fragment.h"
     37 #include "sfn_shader_geometry.h"
     38 #include "sfn_shader_compute.h"
     39 #include "sfn_shader_tcs.h"
     40 #include "sfn_shader_tess_eval.h"
     41 #include "sfn_nir_lower_fs_out_to_vector.h"
     42 #include "sfn_ir_to_assembly.h"
     43 #include "sfn_nir_lower_alu.h"
     44 
     45 #include <vector>
     46 
     47 namespace r600 {
     48 
     49 using std::vector;
     50 
     51 
     52 NirLowerInstruction::NirLowerInstruction():
     53 	b(nullptr)
     54 {
     55 
     56 }
     57 
     58 bool NirLowerInstruction::filter_instr(const nir_instr *instr, const void *data)
     59 {
     60    auto me = reinterpret_cast<const NirLowerInstruction*>(data);
     61    return me->filter(instr);
     62 }
     63 
     64 nir_ssa_def *NirLowerInstruction::lower_instr(nir_builder *b, nir_instr *instr, void *data)
     65 {
     66    auto me = reinterpret_cast<NirLowerInstruction*>(data);
     67    me->set_builder(b);
     68    return me->lower(instr);
     69 }
     70 
     71 bool NirLowerInstruction::run(nir_shader *shader)
     72 {
     73    return nir_shader_lower_instructions(shader,
     74                                         filter_instr,
     75                                         lower_instr,
     76                                         (void *)this);
     77 }
     78 
     79 
     80 ShaderFromNir::ShaderFromNir():sh(nullptr),
     81    chip_class(CLASS_UNKNOWN),
     82    m_current_if_id(0),
     83    m_current_loop_id(0),
     84    scratch_size(0)
     85 {
     86 }
     87 
     88 bool ShaderFromNir::lower(const nir_shader *shader, r600_pipe_shader *pipe_shader,
     89                           r600_pipe_shader_selector *sel, r600_shader_key& key,
     90                           struct r600_shader* gs_shader, enum chip_class _chip_class)
     91 {
     92    sh = shader;
     93    chip_class = _chip_class;
     94    assert(sh);
     95 
     96    switch (shader->info.stage) {
     97    case MESA_SHADER_VERTEX:
     98       impl.reset(new VertexShaderFromNir(pipe_shader, *sel, key, gs_shader, chip_class));
     99       break;
    100    case MESA_SHADER_TESS_CTRL:
    101       sfn_log << SfnLog::trans << "Start TCS\n";
    102       impl.reset(new TcsShaderFromNir(pipe_shader, *sel, key, chip_class));
    103       break;
    104    case MESA_SHADER_TESS_EVAL:
    105       sfn_log << SfnLog::trans << "Start TESS_EVAL\n";
    106       impl.reset(new TEvalShaderFromNir(pipe_shader, *sel, key, gs_shader, chip_class));
    107       break;
    108    case MESA_SHADER_GEOMETRY:
    109       sfn_log << SfnLog::trans << "Start GS\n";
    110       impl.reset(new GeometryShaderFromNir(pipe_shader, *sel, key, chip_class));
    111       break;
    112    case MESA_SHADER_FRAGMENT:
    113       sfn_log << SfnLog::trans << "Start FS\n";
    114       impl.reset(new FragmentShaderFromNir(*shader, pipe_shader->shader, *sel, key, chip_class));
    115       break;
    116    case MESA_SHADER_COMPUTE:
    117       sfn_log << SfnLog::trans << "Start CS\n";
    118       impl.reset(new ComputeShaderFromNir(pipe_shader, *sel, key, chip_class));
    119       break;
    120    default:
    121       return false;
    122    }
    123 
    124    sfn_log << SfnLog::trans << "Process declarations\n";
    125    if (!process_declaration())
    126       return false;
    127 
    128    // at this point all functions should be inlined
    129    const nir_function *func = reinterpret_cast<const nir_function *>(exec_list_get_head_const(&sh->functions));
    130 
    131    sfn_log << SfnLog::trans << "Scan shader\n";
    132 
    133    if (sfn_log.has_debug_flag(SfnLog::instr))
    134       nir_print_shader(const_cast<nir_shader *>(shader), stderr);
    135 
    136    nir_foreach_block(block, func->impl) {
    137       nir_foreach_instr(instr, block) {
    138          if (!impl->scan_instruction(instr)) {
    139             fprintf(stderr, "Unhandled sysvalue access ");
    140             nir_print_instr(instr, stderr);
    141             fprintf(stderr, "\n");
    142             return false;
    143          }
    144       }
    145    }
    146 
    147    sfn_log << SfnLog::trans << "Reserve registers\n";
    148    if (!impl->allocate_reserved_registers()) {
    149       return false;
    150    }
    151 
    152    ValuePool::array_list arrays;
    153    sfn_log << SfnLog::trans << "Allocate local registers\n";
    154    foreach_list_typed(nir_register, reg, node, &func->impl->registers) {
    155       impl->allocate_local_register(*reg, arrays);
    156    }
    157 
    158    sfn_log << SfnLog::trans << "Emit shader start\n";
    159    impl->allocate_arrays(arrays);
    160 
    161    impl->emit_shader_start();
    162 
    163    sfn_log << SfnLog::trans << "Process shader \n";
    164    foreach_list_typed(nir_cf_node, node, node, &func->impl->body) {
    165       if (!process_cf_node(node))
    166          return false;
    167    }
    168 
    169    // Add optimizations here
    170    sfn_log << SfnLog::trans << "Finalize\n";
    171    impl->finalize();
    172 
    173    impl->get_array_info(pipe_shader->shader);
    174 
    175    if (!sfn_log.has_debug_flag(SfnLog::nomerge)) {
    176       sfn_log << SfnLog::trans << "Merge registers\n";
    177       impl->remap_registers();
    178    }
    179 
    180    sfn_log << SfnLog::trans << "Finished translating to R600 IR\n";
    181    return true;
    182 }
    183 
    184 Shader ShaderFromNir::shader() const
    185 {
    186    return Shader{impl->m_output, impl->get_temp_registers()};
    187 }
    188 
    189 
    190 bool ShaderFromNir::process_cf_node(nir_cf_node *node)
    191 {
    192    SFN_TRACE_FUNC(SfnLog::flow, "CF");
    193    switch (node->type) {
    194    case nir_cf_node_block:
    195       return process_block(nir_cf_node_as_block(node));
    196    case nir_cf_node_if:
    197       return process_if(nir_cf_node_as_if(node));
    198    case nir_cf_node_loop:
    199       return process_loop(nir_cf_node_as_loop(node));
    200    default:
    201       return false;
    202    }
    203 }
    204 
    205 bool ShaderFromNir::process_if(nir_if *if_stmt)
    206 {
    207    SFN_TRACE_FUNC(SfnLog::flow, "IF");
    208 
    209    if (!impl->emit_if_start(m_current_if_id, if_stmt))
    210       return false;
    211 
    212    int if_id = m_current_if_id++;
    213    m_if_stack.push(if_id);
    214 
    215    foreach_list_typed(nir_cf_node, n, node, &if_stmt->then_list)
    216          if (!process_cf_node(n)) return false;
    217 
    218    if (!if_stmt->then_list.is_empty()) {
    219       if (!impl->emit_else_start(if_id))
    220          return false;
    221 
    222       foreach_list_typed(nir_cf_node, n, node, &if_stmt->else_list)
    223             if (!process_cf_node(n)) return false;
    224    }
    225 
    226    if (!impl->emit_ifelse_end(if_id))
    227       return false;
    228 
    229    m_if_stack.pop();
    230    return true;
    231 }
    232 
    233 bool ShaderFromNir::process_loop(nir_loop *node)
    234 {
    235    SFN_TRACE_FUNC(SfnLog::flow, "LOOP");
    236    int loop_id = m_current_loop_id++;
    237 
    238    if (!impl->emit_loop_start(loop_id))
    239       return false;
    240 
    241    foreach_list_typed(nir_cf_node, n, node, &node->body)
    242          if (!process_cf_node(n)) return false;
    243 
    244    if (!impl->emit_loop_end(loop_id))
    245       return false;
    246 
    247    return true;
    248 }
    249 
    250 bool ShaderFromNir::process_block(nir_block *block)
    251 {
    252    SFN_TRACE_FUNC(SfnLog::flow, "BLOCK");
    253    nir_foreach_instr(instr, block) {
    254       int r = emit_instruction(instr);
    255       if (!r) {
    256          sfn_log << SfnLog::err << "R600: Unsupported instruction: "
    257                  << *instr << "\n";
    258          return false;
    259       }
    260    }
    261    return true;
    262 }
    263 
    264 
    265 ShaderFromNir::~ShaderFromNir()
    266 {
    267 }
    268 
    269 pipe_shader_type ShaderFromNir::processor_type() const
    270 {
    271    return impl->m_processor_type;
    272 }
    273 
    274 
    275 bool ShaderFromNir::emit_instruction(nir_instr *instr)
    276 {
    277    assert(impl);
    278 
    279    sfn_log << SfnLog::instr << "Read instruction " << *instr << "\n";
    280 
    281    switch (instr->type) {
    282    case nir_instr_type_alu:
    283       return impl->emit_alu_instruction(instr);
    284    case nir_instr_type_deref:
    285       return impl->emit_deref_instruction(nir_instr_as_deref(instr));
    286    case nir_instr_type_intrinsic:
    287       return impl->emit_intrinsic_instruction(nir_instr_as_intrinsic(instr));
    288    case nir_instr_type_load_const: /* const values are loaded when needed */
    289       return true;
    290    case nir_instr_type_tex:
    291       return impl->emit_tex_instruction(instr);
    292    case nir_instr_type_jump:
    293       return impl->emit_jump_instruction(nir_instr_as_jump(instr));
    294    default:
    295       fprintf(stderr, "R600: %s: ShaderFromNir Unsupported instruction: type %d:'", __func__, instr->type);
    296       nir_print_instr(instr, stderr);
    297       fprintf(stderr, "'\n");
    298       return false;
    299    case nir_instr_type_ssa_undef:
    300       return impl->create_undef(nir_instr_as_ssa_undef(instr));
    301       return true;
    302    }
    303 }
    304 
    305 bool ShaderFromNir::process_declaration()
    306 {
    307    impl->set_shader_info(sh);
    308 
    309    if (!impl->scan_inputs_read(sh))
    310       return false;
    311 
    312    // scan declarations
    313    nir_foreach_variable_with_modes(variable, sh, nir_var_uniform |
    314                                                  nir_var_mem_ubo |
    315                                                  nir_var_mem_ssbo) {
    316       if (!impl->process_uniforms(variable)) {
    317          fprintf(stderr, "R600: error parsing outputs variable %s\n", variable->name);
    318          return false;
    319       }
    320    }
    321 
    322    return true;
    323 }
    324 
    325 const std::vector<InstructionBlock>& ShaderFromNir::shader_ir() const
    326 {
    327    assert(impl);
    328    return impl->m_output;
    329 }
    330 
    331 
    332 AssemblyFromShader::~AssemblyFromShader()
    333 {
    334 }
    335 
    336 bool AssemblyFromShader::lower(const std::vector<InstructionBlock>& ir)
    337 {
    338    return do_lower(ir);
    339 }
    340 
    341 static void
    342 r600_nir_lower_scratch_address_impl(nir_builder *b, nir_intrinsic_instr *instr)
    343 {
    344    b->cursor = nir_before_instr(&instr->instr);
    345 
    346    int address_index = 0;
    347    int align;
    348 
    349    if (instr->intrinsic == nir_intrinsic_store_scratch) {
    350       align  = instr->src[0].ssa->num_components;
    351       address_index = 1;
    352    } else{
    353       align = instr->dest.ssa.num_components;
    354    }
    355 
    356    nir_ssa_def *address = instr->src[address_index].ssa;
    357    nir_ssa_def *new_address = nir_ishr(b, address,  nir_imm_int(b, 4 * align));
    358 
    359    nir_instr_rewrite_src(&instr->instr, &instr->src[address_index],
    360                          nir_src_for_ssa(new_address));
    361 }
    362 
    363 bool r600_lower_scratch_addresses(nir_shader *shader)
    364 {
    365    bool progress = false;
    366    nir_foreach_function(function, shader) {
    367       nir_builder build;
    368       nir_builder_init(&build, function->impl);
    369 
    370       nir_foreach_block(block, function->impl) {
    371          nir_foreach_instr(instr, block) {
    372             if (instr->type != nir_instr_type_intrinsic)
    373                continue;
    374             nir_intrinsic_instr *op = nir_instr_as_intrinsic(instr);
    375             if (op->intrinsic != nir_intrinsic_load_scratch &&
    376                 op->intrinsic != nir_intrinsic_store_scratch)
    377                continue;
    378             r600_nir_lower_scratch_address_impl(&build, op);
    379             progress = true;
    380          }
    381       }
    382    }
    383    return progress;
    384 }
    385 
    386 static void
    387 insert_uniform_sorted(struct exec_list *var_list, nir_variable *new_var)
    388 {
    389    nir_foreach_variable_in_list(var, var_list) {
    390       if (var->data.binding > new_var->data.binding ||
    391           (var->data.binding == new_var->data.binding &&
    392            var->data.offset > new_var->data.offset)) {
    393          exec_node_insert_node_before(&var->node, &new_var->node);
    394          return;
    395       }
    396    }
    397    exec_list_push_tail(var_list, &new_var->node);
    398 }
    399 
    400 void sort_uniforms(nir_shader *shader)
    401 {
    402    struct exec_list new_list;
    403    exec_list_make_empty(&new_list);
    404 
    405    nir_foreach_uniform_variable_safe(var, shader) {
    406       exec_node_remove(&var->node);
    407       insert_uniform_sorted(&new_list, var);
    408    }
    409    exec_list_append(&shader->variables, &new_list);
    410 }
    411 
    412 static void
    413 insert_fsoutput_sorted(struct exec_list *var_list, nir_variable *new_var)
    414 {
    415 
    416    nir_foreach_variable_in_list(var, var_list) {
    417       if (var->data.location > new_var->data.location ||
    418           (var->data.location == new_var->data.location &&
    419            var->data.index > new_var->data.index)) {
    420          exec_node_insert_node_before(&var->node, &new_var->node);
    421          return;
    422       }
    423    }
    424 
    425    exec_list_push_tail(var_list, &new_var->node);
    426 }
    427 
    428 void sort_fsoutput(nir_shader *shader)
    429 {
    430    struct exec_list new_list;
    431    exec_list_make_empty(&new_list);
    432 
    433    nir_foreach_shader_out_variable_safe(var, shader) {
    434       exec_node_remove(&var->node);
    435       insert_fsoutput_sorted(&new_list, var);
    436    }
    437 
    438    unsigned driver_location = 0;
    439    nir_foreach_variable_in_list(var, &new_list)
    440       var->data.driver_location = driver_location++;
    441 
    442    exec_list_append(&shader->variables, &new_list);
    443 }
    444 
    445 }
    446 
    447 static nir_intrinsic_op
    448 r600_map_atomic(nir_intrinsic_op op)
    449 {
    450    switch (op) {
    451    case nir_intrinsic_atomic_counter_read_deref:
    452       return nir_intrinsic_atomic_counter_read;
    453    case nir_intrinsic_atomic_counter_inc_deref:
    454       return nir_intrinsic_atomic_counter_inc;
    455    case nir_intrinsic_atomic_counter_pre_dec_deref:
    456       return nir_intrinsic_atomic_counter_pre_dec;
    457    case nir_intrinsic_atomic_counter_post_dec_deref:
    458       return nir_intrinsic_atomic_counter_post_dec;
    459    case nir_intrinsic_atomic_counter_add_deref:
    460       return nir_intrinsic_atomic_counter_add;
    461    case nir_intrinsic_atomic_counter_min_deref:
    462       return nir_intrinsic_atomic_counter_min;
    463    case nir_intrinsic_atomic_counter_max_deref:
    464       return nir_intrinsic_atomic_counter_max;
    465    case nir_intrinsic_atomic_counter_and_deref:
    466       return nir_intrinsic_atomic_counter_and;
    467    case nir_intrinsic_atomic_counter_or_deref:
    468       return nir_intrinsic_atomic_counter_or;
    469    case nir_intrinsic_atomic_counter_xor_deref:
    470       return nir_intrinsic_atomic_counter_xor;
    471    case nir_intrinsic_atomic_counter_exchange_deref:
    472       return nir_intrinsic_atomic_counter_exchange;
    473    case nir_intrinsic_atomic_counter_comp_swap_deref:
    474       return nir_intrinsic_atomic_counter_comp_swap;
    475    default:
    476       return nir_num_intrinsics;
    477    }
    478 }
    479 
    480 static bool
    481 r600_lower_deref_instr(nir_builder *b, nir_instr *instr_, UNUSED void *cb_data)
    482 {
    483    if (instr_->type != nir_instr_type_intrinsic)
    484       return false;
    485 
    486    nir_intrinsic_instr *instr = nir_instr_as_intrinsic(instr_);
    487 
    488    nir_intrinsic_op op = r600_map_atomic(instr->intrinsic);
    489    if (nir_num_intrinsics == op)
    490       return false;
    491 
    492    nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
    493    nir_variable *var = nir_deref_instr_get_variable(deref);
    494 
    495    if (var->data.mode != nir_var_uniform &&
    496        var->data.mode != nir_var_mem_ssbo &&
    497        var->data.mode != nir_var_mem_shared)
    498       return false; /* atomics passed as function arguments can't be lowered */
    499 
    500    const unsigned idx = var->data.binding;
    501 
    502    b->cursor = nir_before_instr(&instr->instr);
    503 
    504    nir_ssa_def *offset = nir_imm_int(b, var->data.index);
    505    for (nir_deref_instr *d = deref; d->deref_type != nir_deref_type_var;
    506         d = nir_deref_instr_parent(d)) {
    507       assert(d->deref_type == nir_deref_type_array);
    508       assert(d->arr.index.is_ssa);
    509 
    510       unsigned array_stride = 1;
    511       if (glsl_type_is_array(d->type))
    512          array_stride *= glsl_get_aoa_size(d->type);
    513 
    514       offset = nir_iadd(b, offset, nir_imul(b, d->arr.index.ssa,
    515                                             nir_imm_int(b, array_stride)));
    516    }
    517 
    518    /* Since the first source is a deref and the first source in the lowered
    519     * instruction is the offset, we can just swap it out and change the
    520     * opcode.
    521     */
    522    instr->intrinsic = op;
    523    nir_instr_rewrite_src(&instr->instr, &instr->src[0],
    524                          nir_src_for_ssa(offset));
    525    nir_intrinsic_set_base(instr, idx);
    526 
    527    nir_deref_instr_remove_if_unused(deref);
    528 
    529    return true;
    530 }
    531 
    532 static bool
    533 r600_nir_lower_atomics(nir_shader *shader)
    534 {
    535    /* First re-do the offsets, in Hardware we start at zero for each new
    536     * binding, and we use an offset of one per counter */
    537    int current_binding = -1;
    538    int current_offset = 0;
    539    nir_foreach_variable_with_modes(var, shader, nir_var_uniform) {
    540       if (!var->type->contains_atomic())
    541          continue;
    542 
    543       if (current_binding == (int)var->data.binding) {
    544          var->data.index = current_offset;
    545          current_offset += var->type->atomic_size() / ATOMIC_COUNTER_SIZE;
    546       } else {
    547          current_binding = var->data.binding;
    548          var->data.index = 0;
    549          current_offset = var->type->atomic_size() / ATOMIC_COUNTER_SIZE;
    550       }
    551    }
    552 
    553    return nir_shader_instructions_pass(shader, r600_lower_deref_instr,
    554                                        nir_metadata_block_index |
    555                                        nir_metadata_dominance,
    556                                        NULL);
    557 }
    558 using r600::r600_nir_lower_int_tg4;
    559 using r600::r600_lower_scratch_addresses;
    560 using r600::r600_lower_fs_out_to_vector;
    561 using r600::r600_lower_ubo_to_align16;
    562 
    563 int
    564 r600_glsl_type_size(const struct glsl_type *type, bool is_bindless)
    565 {
    566    return glsl_count_vec4_slots(type, false, is_bindless);
    567 }
    568 
    569 void
    570 r600_get_natural_size_align_bytes(const struct glsl_type *type,
    571                                   unsigned *size, unsigned *align)
    572 {
    573    if (type->base_type != GLSL_TYPE_ARRAY) {
    574       *align = 1;
    575       *size = 1;
    576    } else {
    577       unsigned elem_size, elem_align;
    578       glsl_get_natural_size_align_bytes(type->fields.array,
    579                                         &elem_size, &elem_align);
    580       *align = 1;
    581       *size = type->length;
    582    }
    583 }
    584 
    585 static bool
    586 r600_lower_shared_io_impl(nir_function *func)
    587 {
    588    nir_builder b;
    589    nir_builder_init(&b, func->impl);
    590 
    591    bool progress = false;
    592    nir_foreach_block(block, func->impl) {
    593       nir_foreach_instr_safe(instr, block) {
    594 
    595          if (instr->type != nir_instr_type_intrinsic)
    596             continue;
    597 
    598          nir_intrinsic_instr *op = nir_instr_as_intrinsic(instr);
    599          if (op->intrinsic != nir_intrinsic_load_shared &&
    600              op->intrinsic != nir_intrinsic_store_shared)
    601             continue;
    602 
    603          b.cursor = nir_before_instr(instr);
    604 
    605          if (op->intrinsic == nir_intrinsic_load_shared) {
    606             nir_ssa_def *addr = op->src[0].ssa;
    607 
    608             switch (nir_dest_num_components(op->dest)) {
    609             case 2: {
    610                auto addr2 = nir_iadd_imm(&b, addr, 4);
    611                addr = nir_vec2(&b, addr, addr2);
    612                break;
    613             }
    614             case 3: {
    615                auto addr2 = nir_iadd(&b, addr, nir_imm_ivec2(&b, 4, 8));
    616                addr = nir_vec3(&b, addr,
    617                                nir_channel(&b, addr2, 0),
    618                                nir_channel(&b, addr2, 1));
    619                break;
    620             }
    621             case 4: {
    622                addr = nir_iadd(&b, addr, nir_imm_ivec4(&b, 0, 4, 8, 12));
    623                break;
    624             }
    625             }
    626 
    627             auto load = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_local_shared_r600);
    628             load->num_components = nir_dest_num_components(op->dest);
    629             load->src[0] = nir_src_for_ssa(addr);
    630             nir_ssa_dest_init(&load->instr, &load->dest,
    631                               load->num_components, 32, NULL);
    632             nir_ssa_def_rewrite_uses(&op->dest.ssa, &load->dest.ssa);
    633             nir_builder_instr_insert(&b, &load->instr);
    634          } else {
    635             nir_ssa_def *addr = op->src[1].ssa;
    636             for (int i = 0; i < 2; ++i) {
    637                unsigned test_mask = (0x3 << 2 * i);
    638                if (!(nir_intrinsic_write_mask(op) & test_mask))
    639                   continue;
    640 
    641                auto store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_store_local_shared_r600);
    642                unsigned writemask = nir_intrinsic_write_mask(op) & test_mask;
    643                nir_intrinsic_set_write_mask(store, writemask);
    644                store->src[0] = nir_src_for_ssa(op->src[0].ssa);
    645                store->num_components = store->src[0].ssa->num_components;
    646                bool start_even = (writemask & (1u << (2 * i)));
    647 
    648                auto addr2 = nir_iadd(&b, addr, nir_imm_int(&b, 8 * i + (start_even ? 0 : 4)));
    649                store->src[1] = nir_src_for_ssa(addr2);
    650 
    651                nir_builder_instr_insert(&b, &store->instr);
    652             }
    653          }
    654          nir_instr_remove(instr);
    655          progress = true;
    656       }
    657    }
    658    return progress;
    659 }
    660 
    661 static bool
    662 r600_lower_shared_io(nir_shader *nir)
    663 {
    664 	bool progress=false;
    665 	nir_foreach_function(function, nir) {
    666 		if (function->impl &&
    667 			 r600_lower_shared_io_impl(function))
    668 			progress = true;
    669 	}
    670 	return progress;
    671 }
    672 
    673 
    674 static nir_ssa_def *
    675 r600_lower_fs_pos_input_impl(nir_builder *b, nir_instr *instr, void *_options)
    676 {
    677    auto old_ir = nir_instr_as_intrinsic(instr);
    678    auto load = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_input);
    679    nir_ssa_dest_init(&load->instr, &load->dest,
    680                      old_ir->dest.ssa.num_components, old_ir->dest.ssa.bit_size, NULL);
    681    nir_intrinsic_set_io_semantics(load, nir_intrinsic_io_semantics(old_ir));
    682 
    683    nir_intrinsic_set_base(load, nir_intrinsic_base(old_ir));
    684    nir_intrinsic_set_component(load, nir_intrinsic_component(old_ir));
    685    nir_intrinsic_set_dest_type(load, nir_type_float32);
    686    load->num_components = old_ir->num_components;
    687    load->src[0] = old_ir->src[1];
    688    nir_builder_instr_insert(b, &load->instr);
    689    return &load->dest.ssa;
    690 }
    691 
    692 bool r600_lower_fs_pos_input_filter(const nir_instr *instr, const void *_options)
    693 {
    694    if (instr->type != nir_instr_type_intrinsic)
    695       return false;
    696 
    697    auto ir = nir_instr_as_intrinsic(instr);
    698    if (ir->intrinsic != nir_intrinsic_load_interpolated_input)
    699       return false;
    700 
    701    return nir_intrinsic_io_semantics(ir).location == VARYING_SLOT_POS;
    702 }
    703 
    704 /* Strip the interpolator specification, it is not needed and irritates */
    705 bool r600_lower_fs_pos_input(nir_shader *shader)
    706 {
    707    return nir_shader_lower_instructions(shader,
    708                                         r600_lower_fs_pos_input_filter,
    709                                         r600_lower_fs_pos_input_impl,
    710                                         nullptr);
    711 };
    712 
    713 static bool
    714 optimize_once(nir_shader *shader, bool vectorize)
    715 {
    716    bool progress = false;
    717    NIR_PASS(progress, shader, nir_lower_vars_to_ssa);
    718    NIR_PASS(progress, shader, nir_copy_prop);
    719    NIR_PASS(progress, shader, nir_opt_dce);
    720    NIR_PASS(progress, shader, nir_opt_algebraic);
    721    NIR_PASS(progress, shader, nir_opt_constant_folding);
    722    NIR_PASS(progress, shader, nir_opt_copy_prop_vars);
    723    if (vectorize)
    724       NIR_PASS(progress, shader, nir_opt_vectorize, NULL, NULL);
    725 
    726    NIR_PASS(progress, shader, nir_opt_remove_phis);
    727 
    728    if (nir_opt_trivial_continues(shader)) {
    729            progress = true;
    730            NIR_PASS(progress, shader, nir_copy_prop);
    731            NIR_PASS(progress, shader, nir_opt_dce);
    732    }
    733 
    734    NIR_PASS(progress, shader, nir_opt_if, false);
    735    NIR_PASS(progress, shader, nir_opt_dead_cf);
    736    NIR_PASS(progress, shader, nir_opt_cse);
    737    NIR_PASS(progress, shader, nir_opt_peephole_select, 200, true, true);
    738 
    739    NIR_PASS(progress, shader, nir_opt_conditional_discard);
    740    NIR_PASS(progress, shader, nir_opt_dce);
    741    NIR_PASS(progress, shader, nir_opt_undef);
    742    return progress;
    743 }
    744 
    745 bool has_saturate(const nir_function *func)
    746 {
    747    nir_foreach_block(block, func->impl) {
    748       nir_foreach_instr(instr, block) {
    749          if (instr->type == nir_instr_type_alu) {
    750             auto alu = nir_instr_as_alu(instr);
    751             if (alu->dest.saturate)
    752                return true;
    753          }
    754       }
    755    }
    756    return false;
    757 }
    758 
    759 extern "C"
    760 bool r600_lower_to_scalar_instr_filter(const nir_instr *instr, const void *)
    761 {
    762    if (instr->type != nir_instr_type_alu)
    763       return true;
    764 
    765    auto alu = nir_instr_as_alu(instr);
    766    switch (alu->op) {
    767    case nir_op_bany_fnequal3:
    768    case nir_op_bany_fnequal4:
    769    case nir_op_ball_fequal3:
    770    case nir_op_ball_fequal4:
    771    case nir_op_bany_inequal3:
    772    case nir_op_bany_inequal4:
    773    case nir_op_ball_iequal3:
    774    case nir_op_ball_iequal4:
    775    case nir_op_fdot2:
    776    case nir_op_fdot3:
    777    case nir_op_fdot4:
    778    case nir_op_cube_r600:
    779       return false;
    780    case nir_op_bany_fnequal2:
    781    case nir_op_ball_fequal2:
    782    case nir_op_bany_inequal2:
    783    case nir_op_ball_iequal2:
    784       return nir_src_bit_size(alu->src[0].src) != 64;
    785    default:
    786       return true;
    787    }
    788 }
    789 
    790 int r600_shader_from_nir(struct r600_context *rctx,
    791                          struct r600_pipe_shader *pipeshader,
    792                          r600_shader_key *key)
    793 {
    794    char filename[4000];
    795    struct r600_pipe_shader_selector *sel = pipeshader->selector;
    796 
    797    bool lower_64bit = ((sel->nir->options->lower_int64_options ||
    798                         sel->nir->options->lower_doubles_options) &&
    799                        (sel->nir->info.bit_sizes_float | sel->nir->info.bit_sizes_int) & 64);
    800 
    801    r600::ShaderFromNir convert;
    802 
    803    if (rctx->screen->b.debug_flags & DBG_PREOPT_IR) {
    804       fprintf(stderr, "PRE-OPT-NIR-----------.------------------------------\n");
    805       nir_print_shader(sel->nir, stderr);
    806       fprintf(stderr, "END PRE-OPT-NIR--------------------------------------\n\n");
    807    }
    808 
    809    r600::sort_uniforms(sel->nir);
    810 
    811    /* Cayman seems very crashy about accessing images that don't exists or are
    812     * accessed out of range, this lowering seems to help (but it can also be
    813     * another problem */
    814    if (sel->nir->info.num_images > 0 && rctx->b.chip_class == CAYMAN)
    815        NIR_PASS_V(sel->nir, r600_legalize_image_load_store);
    816 
    817    NIR_PASS_V(sel->nir, nir_lower_vars_to_ssa);
    818    NIR_PASS_V(sel->nir, nir_lower_regs_to_ssa);
    819    nir_lower_idiv_options idiv_options = {0};
    820    idiv_options.imprecise_32bit_lowering = sel->nir->info.stage != MESA_SHADER_COMPUTE;
    821    idiv_options.allow_fp16 = true;
    822 
    823    NIR_PASS_V(sel->nir, nir_lower_idiv, &idiv_options);
    824    NIR_PASS_V(sel->nir, r600_nir_lower_trigen);
    825    NIR_PASS_V(sel->nir, nir_lower_phis_to_scalar, false);
    826 
    827    if (lower_64bit)
    828       NIR_PASS_V(sel->nir, nir_lower_int64);
    829    while(optimize_once(sel->nir, false));
    830 
    831    NIR_PASS_V(sel->nir, r600_lower_shared_io);
    832    NIR_PASS_V(sel->nir, r600_nir_lower_atomics);
    833 
    834    struct nir_lower_tex_options lower_tex_options = {0};
    835    lower_tex_options.lower_txp = ~0u;
    836    lower_tex_options.lower_txf_offset = true;
    837 
    838    NIR_PASS_V(sel->nir, nir_lower_tex, &lower_tex_options);
    839    NIR_PASS_V(sel->nir, r600::r600_nir_lower_txl_txf_array_or_cube);
    840    NIR_PASS_V(sel->nir, r600::r600_nir_lower_cube_to_2darray);
    841 
    842    NIR_PASS_V(sel->nir, r600_nir_lower_pack_unpack_2x16);
    843 
    844    if (sel->nir->info.stage == MESA_SHADER_VERTEX)
    845       NIR_PASS_V(sel->nir, r600_vectorize_vs_inputs);
    846 
    847    if (sel->nir->info.stage == MESA_SHADER_FRAGMENT) {
    848       NIR_PASS_V(sel->nir, nir_lower_fragcoord_wtrans);
    849       NIR_PASS_V(sel->nir, r600_lower_fs_out_to_vector);
    850    }
    851 
    852    nir_variable_mode io_modes = nir_var_uniform | nir_var_shader_in;
    853 
    854    //if (sel->nir->info.stage != MESA_SHADER_FRAGMENT)
    855       io_modes |= nir_var_shader_out;
    856 
    857    if (sel->nir->info.stage == MESA_SHADER_FRAGMENT) {
    858 
    859       /* Lower IO to temporaries late, because otherwise we get into trouble
    860        * with the glsl 4.40 interpolateAt swizzle tests. There seems to be a bug
    861        * somewhere that results in the input alweas reading from the same temp
    862        * regardless of interpolation when the lowering is done early */
    863       NIR_PASS_V(sel->nir, nir_lower_io_to_temporaries, nir_shader_get_entrypoint(sel->nir),
    864               true, true);
    865 
    866       /* Since we're doing nir_lower_io_to_temporaries late, we need
    867        * to lower all the copy_deref's introduced by
    868        * lower_io_to_temporaries before calling nir_lower_io.
    869        */
    870       NIR_PASS_V(sel->nir, nir_split_var_copies);
    871       NIR_PASS_V(sel->nir, nir_lower_var_copies);
    872       NIR_PASS_V(sel->nir, nir_lower_global_vars_to_local);
    873    }
    874 
    875    NIR_PASS_V(sel->nir, nir_lower_io, io_modes, r600_glsl_type_size,
    876                  nir_lower_io_lower_64bit_to_32);
    877 
    878    if (sel->nir->info.stage == MESA_SHADER_FRAGMENT)
    879       NIR_PASS_V(sel->nir, r600_lower_fs_pos_input);
    880 
    881    /**/
    882    if (lower_64bit)
    883       NIR_PASS_V(sel->nir, nir_lower_indirect_derefs, nir_var_function_temp, 10);
    884 
    885    NIR_PASS_V(sel->nir, nir_opt_constant_folding);
    886    NIR_PASS_V(sel->nir, nir_io_add_const_offset_to_base, io_modes);
    887 
    888    NIR_PASS_V(sel->nir, nir_lower_alu_to_scalar, r600_lower_to_scalar_instr_filter, NULL);
    889    NIR_PASS_V(sel->nir, nir_lower_phis_to_scalar, false);
    890    if (lower_64bit)
    891       NIR_PASS_V(sel->nir, r600::r600_nir_split_64bit_io);
    892    NIR_PASS_V(sel->nir, nir_lower_alu_to_scalar, r600_lower_to_scalar_instr_filter, NULL);
    893    NIR_PASS_V(sel->nir, nir_lower_phis_to_scalar, false);
    894    NIR_PASS_V(sel->nir, nir_lower_alu_to_scalar, r600_lower_to_scalar_instr_filter, NULL);
    895    NIR_PASS_V(sel->nir, nir_copy_prop);
    896    NIR_PASS_V(sel->nir, nir_opt_dce);
    897 
    898    auto sh = nir_shader_clone(sel->nir, sel->nir);
    899 
    900    if (sh->info.stage == MESA_SHADER_TESS_CTRL ||
    901        sh->info.stage == MESA_SHADER_TESS_EVAL ||
    902        (sh->info.stage == MESA_SHADER_VERTEX && key->vs.as_ls)) {
    903       auto prim_type = sh->info.stage == MESA_SHADER_TESS_EVAL ?
    904                           sh->info.tess.primitive_mode: key->tcs.prim_mode;
    905       NIR_PASS_V(sh, r600_lower_tess_io, static_cast<pipe_prim_type>(prim_type));
    906    }
    907 
    908    if (sh->info.stage == MESA_SHADER_TESS_CTRL)
    909       NIR_PASS_V(sh, r600_append_tcs_TF_emission,
    910                  (pipe_prim_type)key->tcs.prim_mode);
    911 
    912    if (sh->info.stage == MESA_SHADER_TESS_EVAL)
    913       NIR_PASS_V(sh, r600_lower_tess_coord,
    914                  static_cast<pipe_prim_type>(sh->info.tess.primitive_mode));
    915 
    916    NIR_PASS_V(sh, nir_lower_ubo_vec4);
    917    if (lower_64bit)
    918       NIR_PASS_V(sh, r600::r600_nir_64_to_vec2);
    919 
    920    /* Lower to scalar to let some optimization work out better */
    921    while(optimize_once(sh, false));
    922 
    923    NIR_PASS_V(sh, r600::r600_merge_vec2_stores);
    924 
    925    NIR_PASS_V(sh, nir_remove_dead_variables, nir_var_shader_in, NULL);
    926    NIR_PASS_V(sh, nir_remove_dead_variables,  nir_var_shader_out, NULL);
    927 
    928 
    929    NIR_PASS_V(sh, nir_lower_vars_to_scratch,
    930               nir_var_function_temp,
    931               40,
    932               r600_get_natural_size_align_bytes);
    933 
    934    while (optimize_once(sh, true));
    935 
    936    NIR_PASS_V(sh, nir_lower_bool_to_int32);
    937    NIR_PASS_V(sh, r600_nir_lower_int_tg4);
    938    NIR_PASS_V(sh, nir_opt_algebraic_late);
    939 
    940    if (sh->info.stage == MESA_SHADER_FRAGMENT)
    941       r600::sort_fsoutput(sh);
    942 
    943    NIR_PASS_V(sh, nir_lower_locals_to_regs);
    944 
    945    //NIR_PASS_V(sh, nir_opt_algebraic);
    946    //NIR_PASS_V(sh, nir_copy_prop);
    947    NIR_PASS_V(sh, nir_lower_to_source_mods,
    948 	      (nir_lower_to_source_mods_flags)(nir_lower_float_source_mods |
    949 					       nir_lower_64bit_source_mods));
    950    NIR_PASS_V(sh, nir_convert_from_ssa, true);
    951    NIR_PASS_V(sh, nir_opt_dce);
    952 
    953    if ((rctx->screen->b.debug_flags & DBG_NIR_PREFERRED) &&
    954        (rctx->screen->b.debug_flags & DBG_ALL_SHADERS)) {
    955       fprintf(stderr, "-- NIR --------------------------------------------------------\n");
    956       struct nir_function *func = (struct nir_function *)exec_list_get_head(&sh->functions);
    957       nir_index_ssa_defs(func->impl);
    958       nir_print_shader(sh, stderr);
    959       fprintf(stderr, "-- END --------------------------------------------------------\n");
    960    }
    961 
    962    memset(&pipeshader->shader, 0, sizeof(r600_shader));
    963    pipeshader->scratch_space_needed = sh->scratch_size;
    964 
    965    if (sh->info.stage == MESA_SHADER_TESS_EVAL ||
    966        sh->info.stage == MESA_SHADER_VERTEX ||
    967        sh->info.stage == MESA_SHADER_GEOMETRY) {
    968       pipeshader->shader.clip_dist_write |= ((1 << sh->info.clip_distance_array_size) - 1);
    969       pipeshader->shader.cull_dist_write = ((1 << sh->info.cull_distance_array_size) - 1)
    970                                            << sh->info.clip_distance_array_size;
    971       pipeshader->shader.cc_dist_mask = (1 <<  (sh->info.cull_distance_array_size +
    972                                                 sh->info.clip_distance_array_size)) - 1;
    973    }
    974 
    975    struct r600_shader* gs_shader = nullptr;
    976    if (rctx->gs_shader)
    977       gs_shader = &rctx->gs_shader->current->shader;
    978    r600_screen *rscreen = rctx->screen;
    979 
    980    bool r = convert.lower(sh, pipeshader, sel, *key, gs_shader, rscreen->b.chip_class);
    981    if (!r || rctx->screen->b.debug_flags & DBG_ALL_SHADERS) {
    982       static int shnr = 0;
    983 
    984       snprintf(filename, 4000, "nir-%s_%d.inc", sh->info.name, shnr++);
    985 
    986       if (access(filename, F_OK) == -1) {
    987          FILE *f = fopen(filename, "w");
    988 
    989          if (f) {
    990             fprintf(f, "const char *shader_blob_%s = {\nR\"(", sh->info.name);
    991             nir_print_shader(sh, f);
    992             fprintf(f, ")\";\n");
    993             fclose(f);
    994          }
    995       }
    996       if (!r)
    997          return -2;
    998    }
    999 
   1000    auto shader = convert.shader();
   1001 
   1002    r600_bytecode_init(&pipeshader->shader.bc, rscreen->b.chip_class, rscreen->b.family,
   1003                       rscreen->has_compressed_msaa_texturing);
   1004 
   1005    r600::sfn_log << r600::SfnLog::shader_info
   1006                  << "pipeshader->shader.processor_type = "
   1007                  << pipeshader->shader.processor_type << "\n";
   1008 
   1009    pipeshader->shader.bc.type = pipeshader->shader.processor_type;
   1010    pipeshader->shader.bc.isa = rctx->isa;
   1011 
   1012    r600::AssemblyFromShaderLegacy afs(&pipeshader->shader, key);
   1013    if (!afs.lower(shader.m_ir)) {
   1014       R600_ERR("%s: Lowering to assembly failed\n", __func__);
   1015       return -1;
   1016    }
   1017 
   1018    if (sh->info.stage == MESA_SHADER_GEOMETRY) {
   1019       r600::sfn_log << r600::SfnLog::shader_info << "Geometry shader, create copy shader\n";
   1020       generate_gs_copy_shader(rctx, pipeshader, &sel->so);
   1021       assert(pipeshader->gs_copy_shader);
   1022    } else {
   1023       r600::sfn_log << r600::SfnLog::shader_info << "This is not a Geometry shader\n";
   1024    }
   1025    if (pipeshader->shader.bc.ngpr < 6)
   1026       pipeshader->shader.bc.ngpr = 6;
   1027 
   1028    return 0;
   1029 }
   1030