diff --git a/.pick_status.json b/.pick_status.json index 03da6829c7a..dc8a1649c93 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -14,7 +14,7 @@ "description": "r600/sfn: when emitting fp64 op2 groups pre-load values", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "79ca456b4837b3bc21cf9ef3c03c505c4b4909f6", "notes": null diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp index 5344d0653b6..96ebb3c0efd 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp @@ -2101,6 +2101,14 @@ emit_alu_op2_64bit(const nir_alu_instr& alu, int num_emit0 = opcode == op2_mul_64 ? 3 : 1; + std::array,2> tmp; + for (unsigned k = 0; k < alu.def.num_components; ++k) { + tmp[k][0] = shader.emit_load_to_register(value_factory.src64(alu.src[order[0]], k, 1), 0); + tmp[k][1] = shader.emit_load_to_register(value_factory.src64(alu.src[order[1]], k, 1), 1); + tmp[k][2] = shader.emit_load_to_register(value_factory.src64(alu.src[order[0]], k, 0), 2); + tmp[k][3] = shader.emit_load_to_register(value_factory.src64(alu.src[order[1]], k, 0), 3); + } + assert(num_emit0 == 1 || alu.def.num_components == 1); for (unsigned k = 0; k < alu.def.num_components; ++k) { @@ -2111,8 +2119,8 @@ emit_alu_op2_64bit(const nir_alu_instr& alu, ir = new AluInstr(opcode, dest, - value_factory.src64(alu.src[order[0]], k, 1), - value_factory.src64(alu.src[order[1]], k, 1), + tmp[k][0], + tmp[k][1], i < 2 ? AluInstr::write : AluInstr::empty); group->add_instruction(ir); } @@ -2122,8 +2130,8 @@ emit_alu_op2_64bit(const nir_alu_instr& alu, ir = new AluInstr(opcode, dest, - value_factory.src64(alu.src[order[0]], k, 0), - value_factory.src64(alu.src[order[1]], k, 0), + tmp[k][2], + tmp[k][3], i == 1 ? AluInstr::write : AluInstr::empty); group->add_instruction(ir); } diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.cpp b/src/gallium/drivers/r600/sfn/sfn_shader.cpp index 495df1f73b6..2e374bd3301 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader.cpp @@ -938,13 +938,14 @@ lds_op_from_intrinsic(nir_atomic_op op, bool ret) } PRegister -Shader::emit_load_to_register(PVirtualValue src) +Shader::emit_load_to_register(PVirtualValue src, int chan) { assert(src); PRegister dest = src->as_register(); - if (!dest) { - dest = value_factory().temp_register(); + if (!dest || chan >= 0) { + dest = value_factory().temp_register(chan); + dest->set_pin(pin_free); emit_instruction(new AluInstr(op1_mov, dest, src, AluInstr::last_write)); } return dest; diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.h b/src/gallium/drivers/r600/sfn/sfn_shader.h index 8b340ca2649..e60c0da754a 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.h +++ b/src/gallium/drivers/r600/sfn/sfn_shader.h @@ -261,7 +261,7 @@ public: return m_rat_return_address; } - PRegister emit_load_to_register(PVirtualValue src); + PRegister emit_load_to_register(PVirtualValue src, int chan = -1); virtual unsigned image_size_const_offset() { return 0;}