[Mesa-dev] [RFC 25/27] i965/fs: Emit coordinate translation from W to Y-tiling

Topi Pohjolainen topi.pohjolainen at intel.com
Sat Feb 22 01:05:51 PST 2014


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_fs.h           |  2 +
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 69 ++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 2b3ac34..28053da 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -520,6 +520,8 @@ public:
    void denormalize(const fs_reg& unorm,
                     const fs_reg& norm,
                     const fs_reg& range);
+   void translate_norm_w_to_y_tiling(int sampler, fs_reg coord);
+   void translate_unorm_w_to_y_tiling(int sampler, fs_reg coord);
 
    struct gl_fragment_program *fp;
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 10afe5d..e84f0a2 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1627,6 +1627,68 @@ fs_visitor::normalize(const fs_reg& norm,
    emit(MUL(norm, unorm_f, range_inv));
 }
 
+/**
+ * Emit translation of coordinates in W-tiling layout to Y-tiling. In the
+ * latter a tile holds twice as many pixels horizontally and half as few
+ * vertically.
+ * First the dimensions in Y-tiling layout are queried from the hardware. Then
+ * the width is divided and the height in turn multiplied by two in order to
+ * work with matching W-layout dimensions. These are used the translate the
+ * normalized coordinates into screen equivalent which can be then translated
+ * to corresponding screen coordinates in Y-layout. Finally the translated
+ * coordinates are normalized back.
+ */
+void
+fs_visitor::translate_norm_w_to_y_tiling(int sampler, fs_reg coord)
+{
+   fs_reg unorm_x = fs_reg(this, glsl_type::uint_type);
+   fs_reg unorm_y = fs_reg(this, glsl_type::uint_type);
+   fs_reg dst_x = fs_reg(this, glsl_type::uint_type);
+   fs_reg dst_y = fs_reg(this, glsl_type::uint_type);
+   fs_reg res_info = fetch_resinfo(sampler, fs_reg(0));
+
+   denormalize(unorm_x, coord, res_info);
+   emit(SHR(unorm_x, unorm_x, fs_reg(1)));
+   coord.reg_offset++;
+   res_info.reg_offset++;
+
+   denormalize(unorm_y, coord, res_info);
+   emit(SHL(unorm_y, unorm_y, fs_reg(1)));
+
+   emit_translate_w_to_y_tiling(fs_reg(this, glsl_type::uint_type),
+                                fs_reg(this, glsl_type::uint_type),
+                                unorm_x, unorm_y, dst_x, dst_y);
+
+   res_info.reg_offset = 0;
+   coord.reg_offset = 0;
+   normalize(coord, dst_x, res_info);
+   res_info.reg_offset++;
+   coord.reg_offset++;
+   normalize(coord, dst_y, res_info);
+}
+
+void
+fs_visitor::translate_unorm_w_to_y_tiling(int sampler, fs_reg coord)
+{
+   fs_reg unorm_x = fs_reg(this, glsl_type::uint_type);
+   fs_reg unorm_y = fs_reg(this, glsl_type::uint_type);
+   fs_reg dst_x = fs_reg(this, glsl_type::uint_type);
+   fs_reg dst_y = fs_reg(this, glsl_type::uint_type);
+
+   emit(MOV(unorm_x, coord));
+   coord.reg_offset++;
+   emit(MOV(unorm_y, coord));
+
+   emit_translate_w_to_y_tiling(fs_reg(this, glsl_type::uint_type),
+                                fs_reg(this, glsl_type::uint_type),
+                                unorm_x, unorm_y, dst_x, dst_y);
+
+   coord.reg_offset = 0;
+   emit(MOV(coord, dst_x));
+   coord.reg_offset++;
+   emit(MOV(coord, dst_y));
+}
+
 void
 fs_visitor::visit(ir_texture *ir)
 {
@@ -1721,6 +1783,13 @@ fs_visitor::visit(ir_texture *ir)
    default:
       assert(!"Unrecognized texture opcode");
    };
+  
+   if (c->key.tex.translate_y_to_w[sampler]) {
+      if (ir->op == ir_txf)
+         translate_unorm_w_to_y_tiling(sampler, coordinate);
+      else
+         translate_norm_w_to_y_tiling(sampler, coordinate);
+   }
 
    /* Writemasking doesn't eliminate channels on SIMD8 texture
     * samples, so don't worry about them.
-- 
1.8.3.1



More information about the mesa-dev mailing list