[Mesa-dev] [WIP 09/25] i965/fs: Generator support for converting double to float

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


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

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index ab45d3d..4a173db 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -926,6 +926,8 @@ enum opcode {
    FS_OPCODE_INTERPOLATE_AT_SAMPLE,
    FS_OPCODE_INTERPOLATE_AT_SHARED_OFFSET,
    FS_OPCODE_INTERPOLATE_AT_PER_SLOT_OFFSET,
+   FS_OPCODE_D2F_CONVERT,
+   FS_OPCODE_D2F_MOV_LOW_32BITS,
 
    VS_OPCODE_URB_WRITE,
    VS_OPCODE_PULL_CONSTANT_LOAD,
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index c2010c0..21c9660 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -1968,6 +1968,51 @@ fs_generator::generate_code(const cfg_t *cfg)
                                            GEN7_PIXEL_INTERPOLATOR_LOC_PER_SLOT_OFFSET);
          break;
 
+      case FS_OPCODE_D2F_CONVERT:
+         /*
+          * Conversion from double to single precision writes 64 bits per
+          * element leaving the upper 32 bits undefined. Hence there has to be
+          * first a separate conversion followed by copy from the lower 32-bits
+          * to the final destination.
+          * In addition, hardware can write only half the amount of channels
+          * whenever double precision operands are involved. Therefore we
+          * need wide enough intermediate, fill it with two separate
+          * converting moves and emit a single instruction copying every second
+          * 32-bit doubleword.
+          */
+         assert(brw->gen >= 7);
+         assert(inst->sources == 1);
+         assert(dst.type == BRW_REGISTER_TYPE_DF);
+         assert(src[0].type == BRW_REGISTER_TYPE_DF);
+
+         /* Now tell the hardware a conversion is needed - treat the
+          * destination as two single precision floats. Convert exec_width / 2
+          * values with two moves each writing exec_width / 2 many 64-bit
+          * channels.
+          */
+         dst.type = BRW_REGISTER_TYPE_F;
+         brw_MOV(p, dst, src[0]);
+         dst.nr += (dispatch_width / 8);
+         if (src[0].file == GRF && src[0].width > 1)
+            src[0].nr += (dispatch_width / 8);
+         brw_MOV(p, dst, src[0]);
+         break;
+
+      case FS_OPCODE_D2F_MOV_LOW_32BITS:
+         assert(brw->gen >= 7);
+         assert(inst->sources == 1);
+         assert(dst.type == BRW_REGISTER_TYPE_F);
+         assert(src[0].type == BRW_REGISTER_TYPE_DF);
+         /* Tell the hardware that there are in fact single precision floats
+          * but that each occupies 64-bits.
+          */
+         src[0].type = BRW_REGISTER_TYPE_F;
+         src[0].width = BRW_WIDTH_4;
+         src[0].hstride = BRW_HORIZONTAL_STRIDE_2;
+         src[0].vstride = BRW_VERTICAL_STRIDE_8;
+         brw_MOV(p, dst, src[0]);
+         break;
+
       default:
 	 if (inst->opcode < (int) ARRAY_SIZE(opcode_descs)) {
 	    _mesa_problem(ctx, "Unsupported opcode `%s' in FS",
-- 
1.8.3.1



More information about the mesa-dev mailing list