[Mesa-dev] [PATCH v3 20/44] spirv/nir: add rounding mode support for floating-point conversions

Samuel Iglesias Gonsálvez siglesias at igalia.com
Wed Feb 6 10:44:49 UTC 2019


v2:
- Fixed bug in rounding modes for conversion ops, it was not considering
the rounding mode of the destination data type.

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
---
 src/compiler/nir/nir.h       | 16 ++++++++++++++++
 src/compiler/spirv/vtn_alu.c | 14 +++++++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index cbc5bcff7d3..d57cabfcfa1 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -943,6 +943,22 @@ nir_is_rounding_mode_rtz(unsigned execution_mode, unsigned bit_size)
    return false;
 }
 
+static inline nir_rounding_mode
+nir_get_rounding_mode_from_float_controls(unsigned execution_mode,
+                                          nir_alu_type type)
+{
+   if (nir_alu_type_get_base_type(type) != nir_type_float)
+      return nir_rounding_mode_undef;
+
+   unsigned bit_size = nir_alu_type_get_type_size(type);
+   if (nir_is_rounding_mode_rtz(execution_mode, bit_size))
+      return nir_rounding_mode_rtz;
+   if (nir_is_rounding_mode_rtne(execution_mode, bit_size))
+      return nir_rounding_mode_rtne;
+
+   return nir_rounding_mode_undef;
+}
+
 typedef enum {
    NIR_OP_IS_COMMUTATIVE = (1 << 0),
    NIR_OP_IS_ASSOCIATIVE = (1 << 1),
diff --git a/src/compiler/spirv/vtn_alu.c b/src/compiler/spirv/vtn_alu.c
index f910630acfb..848fbbdb07c 100644
--- a/src/compiler/spirv/vtn_alu.c
+++ b/src/compiler/spirv/vtn_alu.c
@@ -329,7 +329,12 @@ vtn_nir_alu_op_for_spirv_opcode(struct vtn_builder *b,
       }
       src_type |= src_bit_size;
       dst_type |= dst_bit_size;
-      return nir_type_conversion_op(src_type, dst_type, nir_rounding_mode_undef);
+      unsigned float_controls =
+         b->shader->info.shader_float_controls_execution_mode;
+      nir_rounding_mode rounding_mode =
+         nir_get_rounding_mode_from_float_controls(float_controls,
+                                                   dst_type);
+      return nir_type_conversion_op(src_type, dst_type, rounding_mode);
    }
    /* Derivatives: */
    case SpvOpDPdx:         return nir_op_fddx;
@@ -589,8 +594,15 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
       nir_alu_type src_alu_type = nir_get_nir_type_for_glsl_type(vtn_src[0]->type);
       nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(type);
       nir_rounding_mode rounding_mode = nir_rounding_mode_undef;
+      unsigned float_controls = b->shader->info.shader_float_controls_execution_mode;
 
       vtn_foreach_decoration(b, val, handle_rounding_mode, &rounding_mode);
+
+      if (rounding_mode == nir_rounding_mode_undef && float_controls) {
+         rounding_mode =
+            nir_get_rounding_mode_from_float_controls(float_controls,
+                                                      src_alu_type);
+      }
       nir_op op = nir_type_conversion_op(src_alu_type, dst_alu_type, rounding_mode);
 
       val->ssa->def = nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL);
-- 
2.19.1



More information about the mesa-dev mailing list