[Mesa-dev] [WIP 13/25] i965/fs: Add pack_double_2x32 virtual opcode

Topi Pohjolainen topi.pohjolainen at intel.com
Thu Oct 16 05:24:25 PDT 2014


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_defines.h        |  1 +
 src/mesa/drivers/dri/i965/brw_fs.h             |  5 ++
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 96 ++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 4a173db..88097b7 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -919,6 +919,7 @@ enum opcode {
    FS_OPCODE_SET_SAMPLE_ID,
    FS_OPCODE_SET_SIMD4X2_OFFSET,
    FS_OPCODE_PACK_HALF_2x16_SPLIT,
+   FS_OPCODE_PACK_DOUBLE_2x32,
    FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X,
    FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y,
    FS_OPCODE_PLACEHOLDER_HALT,
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 8c11c32..66173fe 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -759,6 +759,11 @@ private:
                                         struct brw_reg dst,
                                         struct brw_reg src);
 
+   void generate_pack_double_2x32(fs_inst *inst,
+                                  struct brw_reg dst,
+                                  struct brw_reg hi,
+                                  struct brw_reg lo);
+
    void generate_shader_time_add(fs_inst *inst,
                                  struct brw_reg payload,
                                  struct brw_reg offset,
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index 21c9660..2b20f7c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -1413,6 +1413,98 @@ fs_generator::generate_pack_half_2x16_split(fs_inst *inst,
 }
 
 void
+fs_generator::generate_pack_double_2x32(fs_inst *inst,
+                                        struct brw_reg dst,
+                                        struct brw_reg hi,
+                                        struct brw_reg lo)
+{
+   assert(brw->gen >= 7);
+   assert(dst.type == BRW_REGISTER_TYPE_DF);
+   assert(hi.type == BRW_REGISTER_TYPE_UD);
+   assert(lo.type == BRW_REGISTER_TYPE_UD);
+
+   /**
+    * Double precision floats take 64-bits channel meaning that two registers
+    * are needed to hold 8 elements. The values are constructed in two steps:
+    * first high 32-bits are copied and then the low 32. The destination is
+    * treated as having unsigned type but a horizontal stride telling that two
+    * consecutive channels are 64-bits apart. Both high bits and low bits
+    * require two moves each - hardware allows sources to spand over mulitple
+    * physical registers but destination not. Hence four moves in total are
+    * required.
+    *
+    * TODO: If "hi" and "lo" are both uniforms and in consecutive slots then
+    *       on HSW and newer one could simply omit the copy. The pair of
+    *       32-bit slots could be treated as double precision scalar instead.
+    *       On IVB the copy is still needed but could be done with two
+    *       instructions each moving hi-lo-pairs.
+    */
+   dst.type = BRW_REGISTER_TYPE_UD;
+   dst.width = BRW_WIDTH_4;
+   dst.hstride = BRW_HORIZONTAL_STRIDE_2;
+   dst.vstride = BRW_VERTICAL_STRIDE_8;
+
+   if (!brw_is_scalar(hi)) {
+      assert(hi.hstride == BRW_HORIZONTAL_STRIDE_1);
+      assert(hi.vstride == BRW_VERTICAL_STRIDE_8);
+      hi.width = BRW_WIDTH_4;
+      hi.vstride = BRW_VERTICAL_STRIDE_4;
+   }
+   if (!brw_is_scalar(lo)) {
+      assert(lo.hstride == BRW_HORIZONTAL_STRIDE_1);
+      assert(lo.vstride == BRW_VERTICAL_STRIDE_8);
+      lo.width = BRW_WIDTH_4;
+      lo.vstride = BRW_VERTICAL_STRIDE_4;
+   }
+
+   struct brw_reg dst_2nd_half = dst;
+   ++dst_2nd_half.nr;
+
+   /* In terms of SIMD8:
+    *            +--+--+--+--+--+--+--+--+          +--+--+--+--+--+--+--+--+
+    * dst.reg    |H0|  |H1|  |H2|  |H3|  |   hi.reg |H0|H1|H2|H3|H4|H5|H6|H7|
+    *            +--+--+--+--+--+--+--+--+          +--+--+--+--+--+--+--+--+
+    * dst.reg+1  |  |  |  |  |  |  |  |  |   lo.reg |L0|L1|L2|L3|L4|L5|L6|L7|
+    *            +--+--+--+--+--+--+--+--+          +--+--+--+--+--+--+--+--+
+    */
+   brw_MOV(p, dst, hi);
+
+   /*            +--+--+--+--+--+--+--+--+
+    * dst.reg    |H0|  |H1|  |H2|  |H3|  |
+    *            +--+--+--+--+--+--+--+--+
+    * dst.reg+1  |H4|  |H5|  |H6|  |H7|  |
+    *            +--+--+--+--+--+--+--+--+
+    */
+   if (!brw_is_scalar(hi)) {
+      assert(hi.subnr == 0);
+      hi.subnr = 4 * 4;
+   }
+   brw_MOV(p, dst_2nd_half, hi);
+
+   /*            +--+--+--+--+--+--+--+--+
+    * dst.reg    |H0|L0|H1|L1|H2|L2|H3|L3|
+    *            +--+--+--+--+--+--+--+--+
+    * dst.reg+1  |H4|  |H5|  |H6|  |H7|  |
+    *            +--+--+--+--+--+--+--+--+
+    */
+   dst.subnr += 4;
+   brw_MOV(p, dst, lo);
+
+   /*            +--+--+--+--+--+--+--+--+
+    * dst.reg    |H0|L0|H1|L1|H2|L2|H3|L3|
+    *            +--+--+--+--+--+--+--+--+
+    * dst.reg+1  |H4|L4|H5|L5|H6|L6|H7|L7|
+    *            +--+--+--+--+--+--+--+--+
+    */
+   if (!brw_is_scalar(lo)) {
+      assert(lo.subnr == 0);
+      lo.subnr = 4 * 4;
+   }
+   dst_2nd_half.subnr += 4;
+   brw_MOV(p, dst_2nd_half, lo);
+}
+
+void
 fs_generator::generate_unpack_half_2x16_split(fs_inst *inst,
                                               struct brw_reg dst,
                                               struct brw_reg src)
@@ -1932,6 +2024,10 @@ fs_generator::generate_code(const cfg_t *cfg)
           generate_pack_half_2x16_split(inst, dst, src[0], src[1]);
           break;
 
+      case FS_OPCODE_PACK_DOUBLE_2x32:
+          generate_pack_double_2x32(inst, dst, src[0], src[1]);
+          break;
+
       case FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X:
       case FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y:
          generate_unpack_half_2x16_split(inst, dst, src[0]);
-- 
1.8.3.1



More information about the mesa-dev mailing list