Module: Mesa
Branch: main
Commit: 10ddbf50bb69baf8b467579a04e99826ce686b20
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=10ddbf50bb69baf8b467579a04e99826ce686b20

Author: Gert Wollny <[email protected]>
Date:   Fri Sep 16 14:55:58 2022 +0200

r600/sfn: lower tg4 to backend in NIR

Signed-off-by: Gert Wollny <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18619>

---

 src/gallium/drivers/r600/sfn/sfn_instr_tex.cpp | 222 ++++++++++++-------------
 src/gallium/drivers/r600/sfn/sfn_instr_tex.h   |   7 +-
 2 files changed, 112 insertions(+), 117 deletions(-)

diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_tex.cpp 
b/src/gallium/drivers/r600/sfn/sfn_instr_tex.cpp
index 945b9a8e6aa..7f190c1b21f 100644
--- a/src/gallium/drivers/r600/sfn/sfn_instr_tex.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_instr_tex.cpp
@@ -350,8 +350,6 @@ bool TexInstr::from_nir(nir_tex_instr *tex, Shader& shader)
          return emit_tex_lod(tex, src, shader);
       case nir_texop_query_levels:
          return emit_tex_txs(tex, src, {3,7,7,7}, shader);
-      case nir_texop_tg4:
-         return emit_tex_tg4(tex, src, shader);
       case nir_texop_texture_samples:
          return emit_tex_texture_samples(tex, src, shader);
       default:
@@ -401,6 +399,57 @@ get_sampler_id(int sampler_id, const nir_variable *deref)
    return result;
 }
 
+void TexInstr::emit_set_gradients(nir_tex_instr* tex, int sampler_id,
+                                  Inputs& src, TexInstr *irt,  Shader& shader)
+{
+   TexInstr *grad[2] = {nullptr, nullptr};
+   RegisterVec4 empty_dst(0, false, {0,0,0,0}, pin_group);
+   grad[0] = new TexInstr(set_gradient_h, empty_dst, {7,7,7,7}, src.ddx,
+                          sampler_id,
+                          sampler_id + R600_MAX_CONST_BUFFERS,
+                          src.sampler_offset);
+   grad[0]->set_rect_coordinate_flags(tex);
+   grad[0]->set_always_keep();
+
+   grad[1] = new TexInstr(set_gradient_v, empty_dst, {7,7,7,7}, src.ddy,
+                          sampler_id, sampler_id + R600_MAX_CONST_BUFFERS,
+                          src.sampler_offset);
+   grad[1]->set_rect_coordinate_flags(tex);
+   grad[1]->set_always_keep();
+   irt->add_prepare_instr(grad[0]);
+   irt->add_prepare_instr(grad[1]);
+   if (shader.last_txd())
+      irt->add_required_instr(shader.last_txd());
+   shader.set_last_txd(irt);
+}
+
+void TexInstr::emit_set_offsets(nir_tex_instr* tex, int sampler_id,
+                                Inputs& src, TexInstr *irt,  Shader& shader)
+{
+   RegisterVec4::Swizzle swizzle = {4,4,4,4};
+   int src_components = tex->coord_components;
+   if (tex->is_array)
+      --src_components;
+
+   for (int i = 0; i < src_components; ++i)
+      swizzle[i] = i;
+
+   int noffsets = tex->coord_components;
+   if (tex->is_array)
+      --noffsets;
+
+   auto ofs = shader.value_factory().src_vec4(*src.offset, pin_group, swizzle);
+   RegisterVec4 empty_dst(0, false, {0,0,0,0}, pin_group);
+
+   auto set_ofs = new TexInstr(TexInstr::set_offsets, empty_dst, {7,7,7,7},
+                               ofs, sampler_id,
+                               sampler_id + R600_MAX_CONST_BUFFERS,
+                               src.sampler_offset);
+   set_ofs->set_always_keep();
+   irt->add_prepare_instr(set_ofs);
+}
+
+
 bool TexInstr::emit_lowered_tex(nir_tex_instr* tex, Inputs& src, Shader& 
shader)
 {
    assert(src.backend1);
@@ -418,8 +467,7 @@ bool TexInstr::emit_lowered_tex(nir_tex_instr* tex, Inputs& 
src, Shader& shader)
    int32_t coord_mask = params[0].i32;
    int32_t flags = params[1].i32;
    int32_t inst_mode = params[2].i32;
-
-   TexInstr *grad[2] = {nullptr, nullptr};
+   uint32_t dst_swz_packed = params[3].u32;
 
    auto dst = vf.dest_vec4(tex->dest, pin_group);
 
@@ -429,29 +477,23 @@ bool TexInstr::emit_lowered_tex(nir_tex_instr* tex, 
Inputs& src, Shader& shader)
 
    auto src_coord = vf.src_vec4(*src.backend1, pin_group, src_swizzle);
 
-   auto irt = new TexInstr(src.opcode, dst, {0,1,2,3},  src_coord, sampler.id,
+   RegisterVec4::Swizzle dst_swz = {0,1,2,3};
+   if (dst_swz_packed) {
+      for (int i = 0; i < 4; ++i) {
+         dst_swz[i] = (dst_swz_packed >> (8 * i)) & 0xff;
+      }
+   }
+   auto irt = new TexInstr(src.opcode, dst, dst_swz,  src_coord, sampler.id,
                            sampler.id + R600_MAX_CONST_BUFFERS,
                            src.sampler_offset);
 
-   if (tex->op == nir_texop_txd) {
-      RegisterVec4 empty_dst(0, false, {0,0,0,0}, pin_group);
-      grad[0] = new TexInstr(set_gradient_h, empty_dst, {7,7,7,7}, src.ddx,
-                             sampler.id,
-                             sampler.id + R600_MAX_CONST_BUFFERS,
-                             src.sampler_offset);
-      grad[0]->set_rect_coordinate_flags(tex);
-      grad[0]->set_always_keep();
+   if (tex->op == nir_texop_txd)
+      emit_set_gradients(tex, sampler.id, src, irt, shader);
 
-      grad[1] = new TexInstr(set_gradient_v, empty_dst, {7,7,7,7}, src.ddy,
-                             sampler.id, sampler.id + R600_MAX_CONST_BUFFERS,
-                             src.sampler_offset);
-      grad[1]->set_rect_coordinate_flags(tex);
-      grad[1]->set_always_keep();
-      irt->add_prepare_instr(grad[0]);
-      irt->add_prepare_instr(grad[1]);
-      if (shader.last_txd())
-         irt->add_required_instr(shader.last_txd());
-      shader.set_last_txd(irt);
+
+   if (!irt->set_coord_offsets(src.offset)) {
+      assert(tex->op == nir_texop_tg4);
+      emit_set_offsets(tex, sampler.id, src, irt, shader);
    }
 
    for (const auto f : TexFlags) {
@@ -459,7 +501,7 @@ bool TexInstr::emit_lowered_tex(nir_tex_instr* tex, Inputs& 
src, Shader& shader)
          irt->set_tex_flag(f);
    }
 
-   irt->set_coord_offsets(src.offset);
+
    irt->set_inst_mode(inst_mode);
 
    shader.emit_instruction(irt);
@@ -575,89 +617,6 @@ bool TexInstr::emit_tex_txs(nir_tex_instr *tex, Inputs& 
src,
    return true;
 }
 
-bool TexInstr::emit_tex_tg4(nir_tex_instr* tex, Inputs& src , Shader& shader)
-{
-   auto& vf = shader.value_factory();
-
-   r600::sfn_log << SfnLog::instr << "emit '"
-              << *reinterpret_cast<nir_instr*>(tex)
-              << "' (" << __func__ << ")\n";
-
-   TexInstr *set_ofs = nullptr;
-
-   auto src_coord = prepare_source(tex, src, shader);
-
-   r600::sfn_log << SfnLog::instr << "emit '"
-                 << *reinterpret_cast<nir_instr*>(tex)
-                 << "' (" << __func__ << ")\n";
-
-   auto dst = vf.dest_vec4(tex->dest, pin_group);
-
-   RegisterVec4 empty_dst(125, false, {7,7,7,7}, pin_group);
-
-   /* pre CAYMAN needs swizzle */
-   auto dest_swizzle = shader.chip_class() <= ISA_CC_EVERGREEN ?
-            RegisterVec4::Swizzle{1, 2, 0, 3} :
-            RegisterVec4::Swizzle{0, 1, 2, 3};
-
-   auto sampler = get_sampler_id(tex->sampler_index, src.sampler_deref);
-   assert(!sampler.indirect && "Indirect sampler selection not yet supported");
-
-   bool literal_offset = false;
-   if (src.offset) {
-      literal_offset =  nir_src_as_const_value(*src.offset) != 0;
-      r600::sfn_log << SfnLog::tex << " really have offsets and they are " <<
-                       (literal_offset ? "l" : "varying") <<
-                       "\n";
-
-      if (!literal_offset) {
-         RegisterVec4::Swizzle swizzle = {4,4,4,4};
-         int src_components = tex->coord_components;
-         if (tex->is_array)
-            --src_components;
-
-         for (int i = 0; i < src_components; ++i)
-            swizzle[i] = i;
-
-         int noffsets = tex->coord_components;
-         if (tex->is_array)
-            --noffsets;
-
-         auto ofs = vf.src_vec4(*src.offset, pin_group, swizzle);
-         RegisterVec4 dummy(0, true, {7,7,7,7});
-
-         set_ofs = new TexInstr(TexInstr::set_offsets, dummy, {7,7,7,7},
-                                ofs, sampler.id,
-                                sampler.id + R600_MAX_CONST_BUFFERS, 
src.sampler_offset);
-      } else {
-         src.opcode = src.opcode == gather4_o ? gather4 : gather4_c;
-      }
-   }
-
-   auto irt = new TexInstr(src.opcode, dst, dest_swizzle, src_coord, 
sampler.id,
-                           sampler.id + R600_MAX_CONST_BUFFERS, 
src.sampler_offset);
-
-   irt->set_gather_comp(tex->component);
-
-   if (tex->is_array)
-      irt->set_tex_flag(z_unnormalized);
-
-   if (literal_offset) {
-      r600::sfn_log << SfnLog::tex << "emit literal offsets\n";
-      irt->set_coord_offsets(src.offset);
-   }
-
-   irt->set_rect_coordinate_flags(tex);
-
-   if (set_ofs) {
-      set_ofs->set_always_keep();
-      irt->add_prepare_instr(set_ofs);
-   }
-
-   shader.emit_instruction(irt);
-   return true;
-}
-
 auto TexInstr::prepare_source(nir_tex_instr *tex, const Inputs& inputs, 
Shader& shader) -> RegisterVec4
 {
    RegisterVec4::Swizzle target{7,7,7,7};
@@ -806,11 +765,12 @@ auto TexInstr::Inputs::get_opcode(const nir_tex_instr& 
instr) -> Opcode
       return get_resinfo;
    case nir_texop_txd:
       return instr.is_shadow ? sample_c_g : sample_g;
-   case nir_texop_tg4:
+   case nir_texop_tg4: {
+      auto var_offset = offset && nir_src_as_const_value(*offset) == nullptr;
       return instr.is_shadow ?
-               (offset ? gather4_c_o : gather4_c) :
-               (offset ? gather4_o : gather4);
-
+               (var_offset ? gather4_c_o : gather4_c) :
+               (var_offset ? gather4_o : gather4);
+   }
    case nir_texop_txf_ms:
       return ld;
    case nir_texop_query_levels:
@@ -860,17 +820,21 @@ RegisterVec4::Swizzle 
TexInstr::Inputs::swizzle_from_ncomps(int comps) const
    return swz;
 }
 
-void TexInstr::set_coord_offsets(nir_src *offset)
+bool TexInstr::set_coord_offsets(nir_src *offset)
 {
    if (!offset)
-      return;
+      return true;
+
+   if (!offset->is_ssa)
+      return false;
 
-   assert(offset->is_ssa);
    auto literal = nir_src_as_const_value(*offset);
-   assert(literal);
+   if (!literal)
+      return false;
 
    for (int i = 0; i < offset->ssa->num_components; ++i)
       set_offset(i, literal[i].i32);
+   return true;
 }
 
 void TexInstr::set_rect_coordinate_flags(nir_tex_instr* instr)
@@ -890,6 +854,7 @@ private:
 
    nir_ssa_def *lower_tex(nir_tex_instr *tex);
    nir_ssa_def *lower_txf(nir_tex_instr *tex);
+   nir_ssa_def *lower_tg4(nir_tex_instr *tex);
    nir_ssa_def *lower_txf_ms(nir_tex_instr *tex);
    nir_ssa_def *lower_txf_ms_direct(nir_tex_instr *tex);
 
@@ -931,6 +896,7 @@ bool LowerTexToBackend::filter(const nir_instr *instr) const
    case nir_texop_txl:
    case nir_texop_txf:
    case nir_texop_txd:
+   case nir_texop_tg4:
    case nir_texop_txf_ms:
       break;
    default:
@@ -953,6 +919,8 @@ nir_ssa_def *LowerTexToBackend::lower(nir_instr *instr)
       return lower_tex(tex);
    case nir_texop_txf:
       return lower_txf(tex);
+   case nir_texop_tg4:
+      return lower_tg4(tex);
    case nir_texop_txf_ms:
       if (m_chip_class < EVERGREEN)
          return lower_txf_ms_direct(tex);
@@ -998,6 +966,30 @@ nir_ssa_def *LowerTexToBackend::lower_txf(nir_tex_instr 
*tex)
    return finalize(tex, backend1, backend2);
 }
 
+nir_ssa_def *LowerTexToBackend::lower_tg4(nir_tex_instr *tex)
+{
+   std::array<nir_ssa_def *, 4> new_coord = {
+      nullptr,
+      nullptr,
+      nullptr,
+      nullptr
+   };
+
+   get_src_coords(tex, new_coord, false);
+   uint32_t dest_swizzle = m_chip_class <= EVERGREEN ?
+                              1 | (2 << 8) | (0 << 16) | (3 << 24) : 0;
+
+   int used_coord_mask = 0;
+   int unnormalized_mask = 0;
+   nir_ssa_def *backend1 = prepare_coord(tex, unnormalized_mask, 
used_coord_mask);
+
+   nir_ssa_def *backend2 = nir_imm_ivec4(b, used_coord_mask,
+                                         unnormalized_mask,
+                                         tex->component,
+                                         dest_swizzle);
+   return finalize(tex, backend1, backend2);
+}
+
 nir_ssa_def *LowerTexToBackend::lower_txf_ms(nir_tex_instr *tex)
 {
    std::array<nir_ssa_def *, 4> new_coord = {
diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_tex.h 
b/src/gallium/drivers/r600/sfn/sfn_instr_tex.h
index 46fabd7f503..9390de940ee 100644
--- a/src/gallium/drivers/r600/sfn/sfn_instr_tex.h
+++ b/src/gallium/drivers/r600/sfn/sfn_instr_tex.h
@@ -174,11 +174,14 @@ private:
    static bool emit_tex_txs(nir_tex_instr *tex, Inputs& src,
                             RegisterVec4::Swizzle dest_swz, Shader& shader);
    static bool emit_tex_lod(nir_tex_instr* tex, Inputs& src, Shader& shader);
-   static bool emit_tex_tg4(nir_tex_instr* instr, Inputs& src , Shader& 
shader);
    static bool emit_tex_texture_samples(nir_tex_instr* instr, Inputs& src, 
Shader& shader);
    static bool emit_lowered_tex(nir_tex_instr* instr, Inputs& src, Shader& 
shader);
+   static void emit_set_gradients(nir_tex_instr* tex, int sampler_id,
+                                  Inputs& src, TexInstr *irt,  Shader& shader);
+   static void emit_set_offsets(nir_tex_instr* tex, int sampler_id,
+                                Inputs& src, TexInstr *irt,  Shader& shader);
 
-   void set_coord_offsets(nir_src *offset);
+   bool set_coord_offsets(nir_src *offset);
    void set_rect_coordinate_flags(nir_tex_instr* instr);
    void add_prepare_instr(TexInstr *ir) {m_prepare_instr.push_back(ir);};
 

Reply via email to