From 983385d319f017c7f1670804ebe642f7b85b071a Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Thu, 16 Jun 2022 09:37:56 +0200 Subject: [PATCH] r600/sfn: support nir_op_mulz and legazy math rules v2: Handle nir_op_ffmaz as well (Georg Lehmann) Closes: #6390 Signed-off-by: Gert Wollny Reviewed-by: Filip Gawin Part-of: --- src/gallium/drivers/r600/r600_pipe_common.c | 5 +++-- src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp | 18 +++++++++++++++--- src/gallium/drivers/r600/sfn/sfn_shader.cpp | 3 +++ src/gallium/drivers/r600/sfn/sfn_shader.h | 1 + 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/r600/r600_pipe_common.c b/src/gallium/drivers/r600/r600_pipe_common.c index 1f6c3a25043..8fba93cae9d 100644 --- a/src/gallium/drivers/r600/r600_pipe_common.c +++ b/src/gallium/drivers/r600/r600_pipe_common.c @@ -1367,7 +1367,6 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen, rscreen->nir_options = nir_options; - if (rscreen->info.family < CHIP_CEDAR) rscreen->nir_options.force_indirect_unrolling_sampler = true; @@ -1411,7 +1410,9 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen, /* TGSI's ifind is reversed from ours, keep it the TGSI way. */ rscreen->nir_options.lower_find_msb_to_reverse = false; - } + } else { + rscreen->nir_options.has_fmulz = true; + } rscreen->nir_options_fs = rscreen->nir_options; rscreen->nir_options_fs.lower_all_io_to_temps = true; diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp index 006a34fbe64..cd4d949059d 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp @@ -1263,7 +1263,13 @@ bool AluInstr::from_nir(nir_alu_instr *alu, Shader& shader) case nir_op_flt: return emit_alu_op2(*alu, op2_setgt_dx10, shader, op2_opt_reverse); case nir_op_fmax: return emit_alu_op2(*alu, op2_max_dx10, shader); case nir_op_fmin: return emit_alu_op2(*alu, op2_min_dx10, shader); - case nir_op_fmul: return emit_alu_op2(*alu, op2_mul_ieee, shader); + + case nir_op_fmul: + if (!shader.has_flag(Shader::sh_legacy_math_rules)) + return emit_alu_op2(*alu, op2_mul_ieee, shader); + FALLTHROUGH; + case nir_op_fmulz: return emit_alu_op2(*alu, op2_mul, shader); + case nir_op_fneg: return emit_alu_op1(*alu, op1_mov, shader, {1 << alu_src0_neg}); case nir_op_fneu32: return emit_alu_op2(*alu, op2_setne_dx10, shader); case nir_op_fneu: return emit_alu_op2(*alu, op2_setne_dx10, shader); @@ -1319,8 +1325,12 @@ bool AluInstr::from_nir(nir_alu_instr *alu, Shader& shader) case nir_op_unpack_half_2x16_split_x: return emit_unpack_32_2x16_split_x(*alu, shader); case nir_op_unpack_half_2x16_split_y: return emit_unpack_32_2x16_split_y(*alu, shader); + case nir_op_ffma: + if (!shader.has_flag(Shader::sh_legacy_math_rules)) + return emit_alu_op3(*alu, op3_muladd_ieee, shader); + FALLTHROUGH; + case nir_op_ffmaz: return emit_alu_op3(*alu, op3_muladd, shader); - case nir_op_ffma: return emit_alu_op3(*alu, op3_muladd_ieee, shader); case nir_op_mov: return emit_alu_op1(*alu, op1_mov, shader); case nir_op_f2i32: return emit_alu_op1(*alu, op1_flt_to_int, shader); case nir_op_vec2: return emit_create_vec(*alu, 2, shader); @@ -2034,7 +2044,9 @@ static bool emit_dot(const nir_alu_instr& alu, int n, Shader& shader) srcs[2 * i + 1] = value_factory.zero(); } - AluInstr *ir = new AluInstr(op2_dot4_ieee, dest, srcs, AluInstr::last_write, 4); + auto op = unlikely(shader.has_flag(Shader::sh_legacy_math_rules)) ? + op2_dot4 : op2_dot4_ieee; + AluInstr *ir = new AluInstr(op, dest, srcs, AluInstr::last_write, 4); if (src0.negate) ir->set_alu_flag(alu_src0_neg); if (src0.abs) ir->set_alu_flag(alu_src0_abs); diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.cpp b/src/gallium/drivers/r600/sfn/sfn_shader.cpp index ca7bcd9b4a9..e72ecadc83b 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader.cpp @@ -430,6 +430,9 @@ bool Shader::process(nir_shader *nir) { m_ssbo_image_offset = nir->info.num_images; + if (nir->info.use_legacy_math_rules) + set_flag(sh_legacy_math_rules); + nir_foreach_uniform_variable(var, nir) scan_uniforms(var); diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.h b/src/gallium/drivers/r600/sfn/sfn_shader.h index daf9484f36b..1392b42cc45 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.h +++ b/src/gallium/drivers/r600/sfn/sfn_shader.h @@ -199,6 +199,7 @@ public: sh_txs_cube_array_comp, sh_indirect_atomic, sh_mem_barrier, + sh_legacy_math_rules, sh_flags_count };