[Mesa-dev] [PATCH 60/78] i965/nir/vec4: Add nir_swizzle_result() method to vec4_visitor

Eduardo Lima Mitev elima at igalia.com
Fri Jun 26 01:07:16 PDT 2015


This is the NIR->vec4 version of vec4_visitor::swizzle_result(). It is
essentially the same code except that we also pass the destination register
as argument, so that the result is MOVed to that register instead of
to vec4_visitor::result, which is what vec4_visitor::swizzle_result() does
and would cause an extra MOV in our case.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89580
---
 src/mesa/drivers/dri/i965/brw_vec4.h       |  3 ++
 src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 57 ++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 34ef0d8..7139eb4 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -412,6 +412,9 @@ public:
    virtual void nir_emit_alu(nir_alu_instr *instr);
    virtual void nir_emit_jump(nir_jump_instr *instr);
    virtual void nir_emit_texture(nir_tex_instr *instr);
+   virtual void nir_swizzle_result(nir_tex_instr *instr, dst_reg dest,
+                                   src_reg orig_val, uint32_t sampler,
+                                   const glsl_type *dest_type);
 
    dst_reg get_nir_dest(nir_dest dest, enum brw_reg_type type);
    dst_reg get_nir_dest(nir_dest dest, nir_alu_type type);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
index 6e9df99..08a70b0 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
@@ -1353,6 +1353,63 @@ shader_opcode_for_nir_opcode(nir_texop nir_opcode)
 }
 
 void
+vec4_visitor::nir_swizzle_result(nir_tex_instr *instr, dst_reg dest,
+                                 src_reg orig_val, uint32_t sampler,
+                                 const glsl_type *dest_type)
+{
+   int s = key->tex.swizzles[sampler];
+
+   dst_reg swizzled_result = dest;
+
+   if (instr->op == nir_texop_query_levels) {
+      /* # levels is in .w */
+      orig_val.swizzle = BRW_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W);
+      emit(MOV(swizzled_result, orig_val));
+      return;
+   }
+
+   if (instr->op == nir_texop_txs || dest_type == glsl_type::float_type ||
+       s == SWIZZLE_NOOP || instr->op == nir_texop_tg4) {
+      emit(MOV(swizzled_result, orig_val));
+      return;
+   }
+
+   int zero_mask = 0, one_mask = 0, copy_mask = 0;
+   int swizzle[4] = {0};
+
+   for (int i = 0; i < 4; i++) {
+      switch (GET_SWZ(s, i)) {
+      case SWIZZLE_ZERO:
+	 zero_mask |= (1 << i);
+	 break;
+      case SWIZZLE_ONE:
+	 one_mask |= (1 << i);
+	 break;
+      default:
+	 copy_mask |= (1 << i);
+	 swizzle[i] = GET_SWZ(s, i);
+	 break;
+      }
+   }
+
+   if (copy_mask) {
+      orig_val.swizzle = BRW_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
+      swizzled_result.writemask = copy_mask;
+      emit(MOV(swizzled_result, orig_val));
+   }
+
+   if (zero_mask) {
+      swizzled_result.writemask = zero_mask;
+      emit(MOV(swizzled_result, src_reg(0.0f)));
+   }
+
+   if (one_mask) {
+      swizzled_result.writemask = one_mask;
+      emit(MOV(swizzled_result, src_reg(1.0f)));
+   }
+}
+
+void
 vec4_visitor::nir_emit_texture(nir_tex_instr *instr)
 {
    /* @TODO: Not yet implemented */
-- 
2.1.4



More information about the mesa-dev mailing list