From bfc1f0f017db6bd11a558237c9a4ebeacf73f5ba Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 29 Jun 2016 13:07:35 +0200 Subject: [PATCH] i965/vec4: add helpers for conversions to/from doubles Use these helpers to implement d2f and f2d. We will reuse these helpers when we implement things like d2i or i2d as well. v2: - Rename the helpers (Matt) Reviewed-by: Matt Turner --- src/mesa/drivers/dri/i965/brw_vec4.h | 5 ++ src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 56 ++++++++++++++-------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 625ab9e5e32..396e15844fd 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -315,6 +315,11 @@ public: bool optimize_predicate(nir_alu_instr *instr, enum brw_predicate *predicate); + void emit_conversion_from_double(dst_reg dst, src_reg src, bool saturate, + brw_reg_type single_type); + void emit_conversion_to_double(dst_reg dst, src_reg src, bool saturate, + brw_reg_type single_type); + virtual void emit_nir_code(); virtual void nir_setup_uniforms(); virtual void nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index 78f5218b45f..4aeb8cb48d3 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -1066,6 +1066,36 @@ emit_find_msb_using_lzd(const vec4_builder &bld, inst->src[0].negate = true; } +void +vec4_visitor::emit_conversion_from_double(dst_reg dst, src_reg src, + bool saturate, + brw_reg_type single_type) +{ + dst_reg temp = dst_reg(this, glsl_type::dvec4_type); + emit(MOV(temp, src)); + + dst_reg temp2 = dst_reg(this, glsl_type::dvec4_type); + temp2 = retype(temp2, single_type); + emit(VEC4_OPCODE_FROM_DOUBLE, temp2, src_reg(temp)) + ->size_written = 2 * REG_SIZE; + + vec4_instruction *inst = emit(MOV(dst, src_reg(temp2))); + inst->saturate = saturate; +} + +void +vec4_visitor::emit_conversion_to_double(dst_reg dst, src_reg src, + bool saturate, + brw_reg_type single_type) +{ + dst_reg tmp_dst = dst_reg(src_reg(this, glsl_type::dvec4_type)); + src_reg tmp_src = retype(src_reg(this, glsl_type::vec4_type), single_type); + emit(MOV(dst_reg(tmp_src), retype(src, single_type))); + emit(VEC4_OPCODE_TO_DOUBLE, tmp_dst, tmp_src); + vec4_instruction *inst = emit(MOV(dst, src_reg(tmp_dst))); + inst->saturate = saturate; +} + void vec4_visitor::nir_emit_alu(nir_alu_instr *instr) { @@ -1110,29 +1140,15 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr) inst = emit(MOV(dst, op[0])); break; - case nir_op_d2f: { - dst_reg temp = dst_reg(this, glsl_type::dvec4_type); - emit(MOV(temp, op[0])); - - dst_reg temp2 = dst_reg(this, glsl_type::dvec4_type); - temp2 = retype(temp2, BRW_REGISTER_TYPE_F); - emit(VEC4_OPCODE_FROM_DOUBLE, temp2, src_reg(temp)) - ->size_written = 2 * REG_SIZE; - - vec4_instruction *inst = emit(MOV(dst, src_reg(temp2))); - inst->saturate = instr->dest.saturate; + case nir_op_d2f: + emit_conversion_from_double(dst, op[0], instr->dest.saturate, + BRW_REGISTER_TYPE_F); break; - } - case nir_op_f2d: { - dst_reg tmp_dst = dst_reg(src_reg(this, glsl_type::dvec4_type)); - src_reg tmp_src = src_reg(this, glsl_type::vec4_type); - emit(MOV(dst_reg(tmp_src), retype(op[0], BRW_REGISTER_TYPE_F))); - emit(VEC4_OPCODE_TO_DOUBLE, tmp_dst, tmp_src); - vec4_instruction *inst = emit(MOV(dst, src_reg(tmp_dst))); - inst->saturate = instr->dest.saturate; + case nir_op_f2d: + emit_conversion_to_double(dst, op[0], instr->dest.saturate, + BRW_REGISTER_TYPE_F); break; - } case nir_op_iadd: assert(nir_dest_bit_size(instr->dest.dest) < 64); -- 2.30.2