[Mesa-dev] [PATCH 30/32] i965: Handle F16TO32/F32TO16 with dword src/dst consistently on both back-ends.

Francisco Jerez currojerez at riseup.net
Fri Feb 6 06:43:10 PST 2015


Due to the way it's implemented in hardware, the F16TO32/F32TO16
instructions require the source/destination register to be of some
16-bit type in Align1 mode, while they require it to be some 32-bit
type in Align16 mode (and as an undocumented feature the high 16 bits
of the destination register are zeroed out in the case of the F32TO16
instruction on Gen7).  Make their behaviour consistent so you can
specify a 32 bit register type as source or destination and get
predictable results in the most significant bits no matter what access
mode is being used.
---
 src/mesa/drivers/dri/i965/brw_eu_emit.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 9d2e65d..93cedce 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1134,13 +1134,14 @@ brw_F32TO16(struct brw_compile *p, struct brw_reg dst, struct brw_reg src)
     * an undocumented feature.
     */
    const bool needs_zero_fill = (dst.type == BRW_REGISTER_TYPE_UD &&
-                                 brw->gen >= 8);
+                                 (!align16 || brw->gen >= 8));
    brw_inst *inst;
 
    if (align16) {
       assert(dst.type == BRW_REGISTER_TYPE_UD);
    } else {
-      assert(dst.type == BRW_REGISTER_TYPE_W ||
+      assert(dst.type == BRW_REGISTER_TYPE_UD ||
+             dst.type == BRW_REGISTER_TYPE_W ||
              dst.type == BRW_REGISTER_TYPE_UW ||
              dst.type == BRW_REGISTER_TYPE_HF);
    }
@@ -1178,6 +1179,15 @@ brw_F16TO32(struct brw_compile *p, struct brw_reg dst, struct brw_reg src)
    if (align16) {
       assert(src.type == BRW_REGISTER_TYPE_UD);
    } else {
+      /* From the Ivybridge PRM, Vol4, Part3, Section 6.26 f16to32:
+       *
+       *   Because this instruction does not have a 16-bit floating-point
+       *   type, the source data type must be Word (W). The destination type
+       *   must be F (Float).
+       */
+      if (src.type == BRW_REGISTER_TYPE_UD)
+         src = spread(retype(src, BRW_REGISTER_TYPE_W), 2);
+
       assert(src.type == BRW_REGISTER_TYPE_W ||
              src.type == BRW_REGISTER_TYPE_UW ||
              src.type == BRW_REGISTER_TYPE_HF);
-- 
2.1.3



More information about the mesa-dev mailing list