[Mesa-dev] [RFC 15/16] nir: Consider float precision when deciding opcode

Topi Pohjolainen topi.pohjolainen at intel.com
Fri May 15 02:39:42 PDT 2015


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/glsl/nir/glsl_to_nir.cpp | 61 +++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 26 deletions(-)

diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp
index 4cb250a..b4777aa 100644
--- a/src/glsl/nir/glsl_to_nir.cpp
+++ b/src/glsl/nir/glsl_to_nir.cpp
@@ -888,6 +888,10 @@ nir_visitor::emit(nir_op op, unsigned dest_size, nir_src src1,
    (type) == GLSL_TYPE_FLOAT ? nir_op_f ## suffix : \
                                nir_op_u ## suffix
 
+#define OP_FLT(type, suffix)                       \
+   (type) == GLSL_TYPE_HALF ? nir_op_h ## suffix : \
+                              nir_op_f ## suffix
+
 void
 nir_visitor::visit(ir_expression *ir)
 {
@@ -1047,19 +1051,19 @@ nir_visitor::visit(ir_expression *ir)
       instr = emit(OP_FLT_INT(types[0], abs), dest_size, srcs);
       break;
    case ir_unop_saturate:
-      assert(types[0] == GLSL_TYPE_FLOAT);
-      instr = emit(nir_op_fsat, dest_size, srcs);
+      assert(types[0] == GLSL_TYPE_HALF || types[0] == GLSL_TYPE_FLOAT);
+      instr = emit(OP_FLT(types[0], sat), dest_size, srcs);
       break;
    case ir_unop_sign:
       instr = emit(OP_FLT_INT(types[0], sign), dest_size, srcs);
       break;
-   case ir_unop_rcp:  emit(nir_op_frcp, dest_size, srcs);  break;
-   case ir_unop_rsq:  emit(nir_op_frsq, dest_size, srcs);  break;
-   case ir_unop_sqrt: emit(nir_op_fsqrt, dest_size, srcs); break;
+   case ir_unop_rcp: emit(OP_FLT(types[0], rcp), dest_size, srcs); break;
+   case ir_unop_rsq: emit(OP_FLT(types[0], rsq), dest_size, srcs); break;
+   case ir_unop_sqrt: emit(OP_FLT(types[0], sqrt), dest_size, srcs); break;
    case ir_unop_exp:  unreachable("ir_unop_exp should have been lowered");
    case ir_unop_log:  unreachable("ir_unop_log should have been lowered");
-   case ir_unop_exp2: emit(nir_op_fexp2, dest_size, srcs); break;
-   case ir_unop_log2: emit(nir_op_flog2, dest_size, srcs); break;
+   case ir_unop_exp2: emit(OP_FLT(types[0], exp2), dest_size, srcs); break;
+   case ir_unop_log2: emit(OP_FLT(types[0], log2), dest_size, srcs); break;
    case ir_unop_i2f:
       emit(supports_ints ? nir_op_i2f : nir_op_fmov, dest_size, srcs);
       break;
@@ -1069,11 +1073,11 @@ nir_visitor::visit(ir_expression *ir)
    case ir_unop_b2f:
       emit(supports_ints ? nir_op_b2f : nir_op_fmov, dest_size, srcs);
       break;
-   case ir_unop_f2i:  emit(nir_op_f2i, dest_size, srcs);   break;
-   case ir_unop_f2u:  emit(nir_op_f2u, dest_size, srcs);   break;
-   case ir_unop_f2b:  emit(nir_op_f2b, dest_size, srcs);   break;
-   case ir_unop_i2b:  emit(nir_op_i2b, dest_size, srcs);   break;
-   case ir_unop_b2i:  emit(nir_op_b2i, dest_size, srcs);   break;
+   case ir_unop_f2i: emit(OP_FLT(types[0], 2i), dest_size, srcs); break;
+   case ir_unop_f2u: emit(OP_FLT(types[0], 2u), dest_size, srcs); break;
+   case ir_unop_f2b: emit(OP_FLT(types[0], 2b), dest_size, srcs); break;
+   case ir_unop_i2b: emit(nir_op_i2b, dest_size, srcs);   break;
+   case ir_unop_b2i: emit(nir_op_b2i, dest_size, srcs);   break;
    case ir_unop_i2u:
    case ir_unop_u2i:
    case ir_unop_bitcast_i2f:
@@ -1101,19 +1105,24 @@ nir_visitor::visit(ir_expression *ir)
          unreachable("not reached");
       }
       break;
-   case ir_unop_trunc: emit(nir_op_ftrunc, dest_size, srcs); break;
-   case ir_unop_ceil:  emit(nir_op_fceil,  dest_size, srcs); break;
-   case ir_unop_floor: emit(nir_op_ffloor, dest_size, srcs); break;
-   case ir_unop_fract: emit(nir_op_ffract, dest_size, srcs); break;
-   case ir_unop_round_even: emit(nir_op_fround_even, dest_size, srcs); break;
-   case ir_unop_sin:   emit(nir_op_fsin,   dest_size, srcs); break;
-   case ir_unop_cos:   emit(nir_op_fcos,   dest_size, srcs); break;
-   case ir_unop_dFdx:        emit(nir_op_fddx,        dest_size, srcs); break;
-   case ir_unop_dFdy:        emit(nir_op_fddy,        dest_size, srcs); break;
-   case ir_unop_dFdx_fine:   emit(nir_op_fddx_fine,   dest_size, srcs); break;
-   case ir_unop_dFdy_fine:   emit(nir_op_fddy_fine,   dest_size, srcs); break;
-   case ir_unop_dFdx_coarse: emit(nir_op_fddx_coarse, dest_size, srcs); break;
-   case ir_unop_dFdy_coarse: emit(nir_op_fddy_coarse, dest_size, srcs); break;
+   case ir_unop_trunc: emit(OP_FLT(types[0], trunc), dest_size, srcs); break;
+   case ir_unop_ceil:  emit(OP_FLT(types[0], ceil), dest_size, srcs); break;
+   case ir_unop_floor: emit(OP_FLT(types[0], floor), dest_size, srcs); break;
+   case ir_unop_fract: emit(OP_FLT(types[0], fract), dest_size, srcs); break;
+   case ir_unop_round_even:
+      emit(OP_FLT(types[0], round_even), dest_size, srcs); break;
+   case ir_unop_sin: emit(OP_FLT(types[0], sin), dest_size, srcs); break;
+   case ir_unop_cos: emit(OP_FLT(types[0], cos), dest_size, srcs); break;
+   case ir_unop_dFdx: emit(OP_FLT(types[0], ddx), dest_size, srcs); break;
+   case ir_unop_dFdy: emit(OP_FLT(types[0], ddy), dest_size, srcs); break;
+   case ir_unop_dFdx_fine:
+      emit(OP_FLT(types[0], ddx_fine), dest_size, srcs); break;
+   case ir_unop_dFdy_fine:
+      emit(OP_FLT(types[0], ddy_fine), dest_size, srcs); break;
+   case ir_unop_dFdx_coarse:
+      emit(OP_FLT(types[0], ddx_coarse), dest_size, srcs); break;
+   case ir_unop_dFdy_coarse:
+      emit(OP_FLT(types[0], ddy_coarse), dest_size, srcs); break;
    case ir_unop_pack_snorm_2x16:
       emit(nir_op_pack_snorm_2x16, dest_size, srcs);
       break;
@@ -1289,7 +1298,7 @@ nir_visitor::visit(ir_expression *ir)
             op = nir_op_ushr;
          break;
       case ir_binop_pow:
-         op = nir_op_fpow;
+         op = OP_FLT(out_type, pow);
          break;
 
       default:
-- 
1.9.3



More information about the mesa-dev mailing list