<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Oct 12, 2017 at 11:37 AM, Jose Maria Casanova Crespo <span dir="ltr"><<a href="mailto:jmcasanova@igalia.com" target="_blank">jmcasanova@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">nir_type_conversion enables new operations to handle rounding modes to<br>
convert to fp16 values. Two new opcodes are enabled nir_op_f2f16_rtne<br>
and nir_op_f2f16_rtz.<br>
<br>
The undefined behaviour doesn't has any effect and uses the original<br>
nir_op_f2f16 operation.<br>
<br>
v2: Indentation fixed (Jason Ekstrand)<br>
---<br>
 src/compiler/glsl/glsl_to_nir.<wbr>cpp |  3 ++-<br>
 src/compiler/nir/nir.h            |  3 ++-<br>
 src/compiler/nir/nir_opcodes.<wbr>py   | 10 ++++++++--<br>
 src/compiler/nir/nir_opcodes_<wbr>c.py | 15 ++++++++++++++-<br>
 src/compiler/spirv/vtn_alu.c      |  2 +-<br>
 5 files changed, 27 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/src/compiler/glsl/glsl_to_<wbr>nir.cpp b/src/compiler/glsl/glsl_to_<wbr>nir.cpp<br>
index 9f25e30678..5738979b19 100644<br>
--- a/src/compiler/glsl/glsl_to_<wbr>nir.cpp<br>
+++ b/src/compiler/glsl/glsl_to_<wbr>nir.cpp<br>
@@ -1575,7 +1575,8 @@ nir_visitor::visit(ir_<wbr>expression *ir)<br>
    case ir_unop_u642i64: {<br>
       nir_alu_type src_type = nir_get_nir_type_for_glsl_<wbr>base_type(types[0]);<br>
       nir_alu_type dst_type = nir_get_nir_type_for_glsl_<wbr>base_type(out_type);<br>
-      result = nir_build_alu(&b, nir_type_conversion_op(src_<wbr>type, dst_type),<br>
+      result = nir_build_alu(&b, nir_type_conversion_op(src_<wbr>type, dst_type,<br>
+                                 nir_rounding_mode_undef),<br>
                                  srcs[0], NULL, NULL, NULL);<br>
       /* b2i and b2f don't have fixed bit-size versions so the builder will<br>
        * just assume 32 and we have to fix it up here.<br>
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
index fb269fcb28..93f0d52804 100644<br>
--- a/src/compiler/nir/nir.h<br>
+++ b/src/compiler/nir/nir.h<br>
@@ -753,7 +753,8 @@ nir_get_nir_type_for_glsl_<wbr>type(const struct glsl_type *type)<br>
    return nir_get_nir_type_for_glsl_<wbr>base_type(glsl_get_base_type(<wbr>type));<br>
 }<br>
<br>
-nir_op nir_type_conversion_op(nir_<wbr>alu_type src, nir_alu_type dst);<br>
+nir_op nir_type_conversion_op(nir_<wbr>alu_type src, nir_alu_type dst,<br>
+                              nir_rounding_mode rnd);<br>
<br>
 typedef enum {<br>
    NIR_OP_IS_COMMUTATIVE = (1 << 0),<br>
diff --git a/src/compiler/nir/nir_<wbr>opcodes.py b/src/compiler/nir/nir_<wbr>opcodes.py<br>
index 06ae820c3e..0abc34f037 100644<br>
--- a/src/compiler/nir/nir_<wbr>opcodes.py<br>
+++ b/src/compiler/nir/nir_<wbr>opcodes.py<br>
@@ -179,8 +179,14 @@ for src_t in [tint, tuint, tfloat]:<br>
       else:<br>
          bit_sizes = [8, 16, 32, 64]<br>
       for bit_size in bit_sizes:<br>
-         unop_convert("{0}2{1}{2}".<wbr>format(src_t[0], dst_t[0], bit_size),<br>
-                      dst_t + str(bit_size), src_t, "src0")<br>
+          if bit_size == 16 and dst_t == tfloat and src_t == tfloat:<br>
+              rnd_modes = ['rtne', 'rtz']<br>
+              for rnd_mode in rnd_modes:<br>
+                  unop_convert("{0}2{1}{2}_{3}".<wbr>format(src_t[0], dst_t[0],<br>
+                                                       bit_size, rnd_mode),<br>
+                               dst_t + str(bit_size), src_t, "src0")<br>
+          unop_convert("{0}2{1}{2}".<wbr>format(src_t[0], dst_t[0], bit_size),<br>
+                       dst_t + str(bit_size), src_t, "src0")<br>
<br>
 # We'll hand-code the to/from bool conversion opcodes.  Because bool doesn't<br>
 # have multiple bit-sizes, we can always infer the size from the other type.<br>
diff --git a/src/compiler/nir/nir_<wbr>opcodes_c.py b/src/compiler/nir/nir_<wbr>opcodes_c.py<br>
index 02bb4738ed..95a76ea39f 100644<br>
--- a/src/compiler/nir/nir_<wbr>opcodes_c.py<br>
+++ b/src/compiler/nir/nir_<wbr>opcodes_c.py<br>
@@ -30,7 +30,7 @@ template = Template("""<br>
 #include "nir.h"<br>
<br>
 nir_op<br>
-nir_type_conversion_op(nir_<wbr>alu_type src, nir_alu_type dst)<br>
+nir_type_conversion_op(nir_<wbr>alu_type src, nir_alu_type dst, nir_rounding_mode rnd)<br>
 {<br>
    nir_alu_type src_base = (nir_alu_type) nir_alu_type_get_base_type(<wbr>src);<br>
    nir_alu_type dst_base = (nir_alu_type) nir_alu_type_get_base_type(<wbr>dst);<br>
@@ -64,7 +64,20 @@ nir_type_conversion_op(nir_<wbr>alu_type src, nir_alu_type dst)<br>
                switch (dst_bit_size) {<br>
 %                 for dst_bits in [16, 32, 64]:<br>
                   case ${dst_bits}:<br>
+%                    if src_t == 'float' and dst_t == 'float' and dst_bits == 16:<br>
+                     switch(rnd) {<br>
+%                       for rnd_t in ['rtne', 'rtz']:<br>
+                        case nir_rounding_mode_${rnd_t}:<br>
+                           return ${'nir_op_{0}2{1}{2}_{3}'.<wbr>format(src_t[0], dst_t[0],<br>
+                                                                   dst_bits, rnd_t)};<br>
+%                       endfor<br>
+                        default:<br>
+                           return ${'nir_op_{0}2{1}{2}'.format(<wbr>src_t[0], dst_t[0],<br>
+                                                               dst_bits)};<br></blockquote><div><br></div><div>I commented on an earlier version of this series that having a default here makes me nervous.  Someone will pass a rounding mode in for a double->float conversion or pass in a rounding mode of nir_rounding_mode_ru and we'll happily ignore it.  I'd be more comfortable if _undefined had an explicit case and the default was unreachable()<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+                     }<br>
+%                    else:<br>
                      return ${'nir_op_{0}2{1}{2}'.format(<wbr>src_t[0], dst_t[0], dst_bits)};<br></blockquote><div><br></div><div>and an assert(rnd == nir_rounding_mode_undefined) here<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+%                    endif<br>
 %                 endfor<br>
                   default:<br>
                      unreachable("Invalid nir alu bit size");<br>
diff --git a/src/compiler/spirv/vtn_alu.c b/src/compiler/spirv/vtn_alu.c<br>
index ecf9cbc34d..7ec30b8a63 100644<br>
--- a/src/compiler/spirv/vtn_alu.c<br>
+++ b/src/compiler/spirv/vtn_alu.c<br>
@@ -355,7 +355,7 @@ vtn_nir_alu_op_for_spirv_<wbr>opcode(SpvOp opcode, bool *swap,<br>
    case SpvOpConvertUToF:<br>
    case SpvOpSConvert:<br>
    case SpvOpFConvert:<br>
-      return nir_type_conversion_op(src, dst);<br>
+      return nir_type_conversion_op(src, dst, nir_rounding_mode_undef);<br>
<br>
    /* Derivatives: */<br>
    case SpvOpDPdx:         return nir_op_fddx;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.13.6<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>