nir/opt_vectorize: Add a callback for filtering of vectorizing.
[mesa.git] / src / gallium / drivers / r600 / sfn / sfn_emittexinstruction.cpp
index 4e43becc8be25e8ea3c4f5779f50823f85ce8158..8764d8adeacd6af143dc34b652582af9be252168 100644 (file)
@@ -97,7 +97,10 @@ bool EmitTexInstruction::do_emit(nir_instr* instr)
          return emit_tex_txf_ms(ir, src);
       case nir_texop_query_levels:
          return emit_tex_txs(ir, src, {3,7,7,7});
+      case nir_texop_texture_samples:
+         return emit_tex_texture_samples(ir, src, {3,7,7,7});
       default:
+
          return false;
       }
    }
@@ -393,7 +396,7 @@ bool EmitTexInstruction::emit_buf_txf(nir_tex_instr* instr, TexInputs &src)
 
    auto ir = new FetchInstruction(vc_fetch, no_index_offset, dst, src.coord.reg_i(0), 0,
                                   instr->texture_index +  R600_MAX_CONST_BUFFERS,
-                                  PValue(), bim_none);
+                                  src.texture_offset, bim_none);
    ir->set_flag(vtx_use_const_field);
    emit_instruction(ir);
    return true;
@@ -481,7 +484,8 @@ bool EmitTexInstruction::emit_tex_txf(nir_tex_instr* instr, TexInputs& src)
 
    auto dst = make_dest(*instr);
 
-   emit_instruction(new AluInstruction(op1_mov, src.coord.reg_i(3), src.lod, {alu_write, alu_last_instr}));
+   if (*src.coord.reg_i(3) != *src.lod)
+      emit_instruction(new AluInstruction(op1_mov, src.coord.reg_i(3), src.lod, {alu_write, alu_last_instr}));
 
    auto sampler = get_samplerr_id(instr->sampler_index, src.sampler_deref);
    assert(!sampler.indirect);
@@ -629,12 +633,30 @@ bool EmitTexInstruction::emit_tex_txs(nir_tex_instr* instr, TexInputs& tex_src,
 
 }
 
+bool EmitTexInstruction::emit_tex_texture_samples(nir_tex_instr* instr, TexInputs& src,
+                                                  const std::array<int, 4> &dest_swz)
+{
+   GPRVector dest = vec_from_nir(instr->dest, nir_dest_num_components(instr->dest));
+   GPRVector help{0,{4,4,4,4}};
+
+   auto dyn_offset = PValue();
+   int res_id = R600_MAX_CONST_BUFFERS + instr->sampler_index;
+
+   auto ir = new TexInstruction(TexInstruction::get_nsampled, dest, help,
+                                0, res_id, src.sampler_offset);
+   ir->set_dest_swizzle(dest_swz);
+   emit_instruction(ir);
+   return true;
+}
+
 bool EmitTexInstruction::emit_tex_tg4(nir_tex_instr* instr, TexInputs& src)
 {
    r600::sfn_log << SfnLog::instr << "emit '"
                  << *reinterpret_cast<nir_instr*>(instr)
                  << "' (" << __func__ << ")\n";
 
+   TexInstruction *set_ofs = nullptr;
+
    auto tex_op = TexInstruction::gather4;
 
    if (instr->is_shadow)  {
@@ -658,18 +680,21 @@ bool EmitTexInstruction::emit_tex_tg4(nir_tex_instr* instr, TexInputs& src)
          for (unsigned i = 0; i < instr->coord_components; ++i)
             swizzle[i] = i;
 
-         std::unique_ptr<GPRVector> ofs(vec_from_nir_with_fetch_constant(*src.offset,
-                                                                         ( 1 << instr->coord_components) -1,
-                                                                         swizzle));
+         int noffsets = instr->coord_components;
+         if (instr->is_array)
+            --noffsets;
+
+         auto ofs = vec_from_nir_with_fetch_constant(*src.offset,
+                                                     ( 1 << noffsets) - 1,
+                                                     swizzle);
          GPRVector dummy(0, {7,7,7,7});
          tex_op = (tex_op == TexInstruction::gather4_c) ?
                      TexInstruction::gather4_c_o : TexInstruction::gather4_o;
 
-         auto set_ofs = new TexInstruction(TexInstruction::set_offsets, dummy,
-                                           *ofs, sampler.id,
-                                           sampler.id + R600_MAX_CONST_BUFFERS, src.sampler_offset);
+         set_ofs = new TexInstruction(TexInstruction::set_offsets, dummy,
+                                           ofs, sampler.id,
+                                      sampler.id + R600_MAX_CONST_BUFFERS, src.sampler_offset);
          set_ofs->set_dest_swizzle({7,7,7,7});
-         emit_instruction(set_ofs);
       }
    }
 
@@ -692,6 +717,9 @@ bool EmitTexInstruction::emit_tex_tg4(nir_tex_instr* instr, TexInputs& src)
 
    set_rect_coordinate_flags(instr, irt);
 
+   if (set_ofs)
+      emit_instruction(set_ofs);
+
    emit_instruction(irt);
    return true;
 }
@@ -838,29 +866,25 @@ bool EmitTexInstruction::get_inputs(const nir_tex_instr& instr, TexInputs &src)
          break;
 
       case nir_tex_src_coord: {
-         std::unique_ptr<GPRVector> coord(vec_from_nir_with_fetch_constant(instr.src[i].src,
-                                                                           (1 << instr.coord_components) - 1,
-                                                                           {0,1,2,3}));
-         src.coord = *coord;
-
+         src.coord = vec_from_nir_with_fetch_constant(instr.src[i].src,
+                                                      (1 << instr.coord_components) - 1,
+         {0,1,2,3});
       } break;
       case nir_tex_src_comparator:
          src.comperator = from_nir(instr.src[i], 0);
          break;
       case nir_tex_src_ddx: {
          sfn_log << SfnLog::tex << "Get DDX ";
-         std::unique_ptr<GPRVector> coord(vec_from_nir_with_fetch_constant(instr.src[i].src,
-                                                                           (1 << grad_components) - 1,
-                                                                           swizzle_from_mask(grad_components)));
-         src.ddx = *coord;
+         src.ddx = vec_from_nir_with_fetch_constant(instr.src[i].src,
+                                                    (1 << grad_components) - 1,
+                                                    swizzle_from_comps(grad_components));
          sfn_log << SfnLog::tex << src.ddx << "\n";
       } break;
       case nir_tex_src_ddy:{
          sfn_log << SfnLog::tex << "Get DDY ";
-         std::unique_ptr<GPRVector> coord(vec_from_nir_with_fetch_constant(instr.src[i].src,
-                                                                           (1 << grad_components) - 1,
-                                                                           swizzle_from_mask(grad_components)));
-         src.ddy = *coord;
+         src.ddy = vec_from_nir_with_fetch_constant(instr.src[i].src,
+                                                    (1 << grad_components) - 1,
+                                                    swizzle_from_comps(grad_components));
          sfn_log << SfnLog::tex << src.ddy << "\n";
       }  break;
       case nir_tex_src_lod: