mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-03 11:30:21 +01:00
r600: fix evergreen gds atomic_counter_comp_swap
This change fixes the gds implementation of atomic_counter_comp_swap which requires three arguments. This update is based on4e3b43f180"r600/atomic: fix ATOMCAS instruction." which was the tgsi implementation. Note: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36554 is required for this change to work properly on cayman. This change was tested on palm, cypress and barts. Here is the test fixed: khr-gl4[5-6]/shader_atomic_counter_ops_tests/shaderatomiccounteropsexchangetestcase: fail pass Cc: mesa-stable Signed-off-by: Patrick Lerda <patrick9876@free.fr> Reviewed-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36254> (cherry picked from commit521b848ea8)
This commit is contained in:
parent
c1ed51bae5
commit
1f4ae92921
3 changed files with 61 additions and 2 deletions
|
|
@ -6634,7 +6634,7 @@
|
|||
"description": "r600: fix evergreen gds atomic_counter_comp_swap",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null,
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -87,8 +87,9 @@ GDSInstr::emit_atomic_counter(nir_intrinsic_instr *intr, Shader& shader)
|
|||
case nir_intrinsic_atomic_counter_min:
|
||||
case nir_intrinsic_atomic_counter_or:
|
||||
case nir_intrinsic_atomic_counter_xor:
|
||||
case nir_intrinsic_atomic_counter_comp_swap:
|
||||
return emit_atomic_op2(intr, shader);
|
||||
case nir_intrinsic_atomic_counter_comp_swap:
|
||||
return emit_atomic_counter_comp_swap(intr, shader);
|
||||
case nir_intrinsic_atomic_counter_read:
|
||||
case nir_intrinsic_atomic_counter_post_dec:
|
||||
return emit_atomic_read(intr, shader);
|
||||
|
|
@ -353,6 +354,63 @@ GDSInstr::emit_atomic_pre_dec(nir_intrinsic_instr *instr, Shader& shader)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GDSInstr::emit_atomic_counter_comp_swap(nir_intrinsic_instr *instr, Shader& shader)
|
||||
{
|
||||
auto& vf = shader.value_factory();
|
||||
bool read_result = !list_is_empty(&instr->def.uses);
|
||||
|
||||
ESDOp op =
|
||||
read_result ? get_opcode(instr->intrinsic) : get_opcode_wo(instr->intrinsic);
|
||||
|
||||
if (DS_OP_INVALID == op)
|
||||
return false;
|
||||
|
||||
auto [offset, uav_id] = shader.evaluate_resource_offset(instr, 0);
|
||||
|
||||
offset += nir_intrinsic_base(instr);
|
||||
|
||||
auto dest = read_result ? vf.dest(instr->def, 0, pin_free) : nullptr;
|
||||
|
||||
if (uav_id != nullptr)
|
||||
shader.set_flag(Shader::sh_indirect_atomic);
|
||||
|
||||
GDSInstr *ir = nullptr;
|
||||
|
||||
if (shader.chip_class() < ISA_CC_CAYMAN) {
|
||||
auto tmp = vf.temp_vec4(pin_group, {4, 1, 2, 7});
|
||||
|
||||
shader.emit_instruction(
|
||||
new AluInstr(op1_mov, tmp[1], vf.src(instr->src[1], 0), AluInstr::write));
|
||||
shader.emit_instruction(
|
||||
new AluInstr(op1_mov, tmp[2], vf.src(instr->src[2], 0), AluInstr::write));
|
||||
|
||||
ir = new GDSInstr(op, dest, tmp, offset, uav_id);
|
||||
} else {
|
||||
auto tmp = vf.temp_vec4(pin_group, {0, 1, 2, 7});
|
||||
|
||||
if (uav_id)
|
||||
shader.emit_instruction(new AluInstr(op3_muladd_uint24,
|
||||
tmp[0],
|
||||
uav_id,
|
||||
vf.literal(4),
|
||||
vf.literal(4 * offset),
|
||||
AluInstr::write));
|
||||
else
|
||||
shader.emit_instruction(
|
||||
new AluInstr(op1_mov, tmp[0], vf.literal(4 * offset), AluInstr::write));
|
||||
|
||||
shader.emit_instruction(
|
||||
new AluInstr(op1_mov, tmp[1], vf.src(instr->src[1], 0), AluInstr::write));
|
||||
shader.emit_instruction(
|
||||
new AluInstr(op1_mov, tmp[2], vf.src(instr->src[2], 0), AluInstr::write));
|
||||
|
||||
ir = new GDSInstr(op, dest, tmp, 0, nullptr);
|
||||
}
|
||||
shader.emit_instruction(ir);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GDSInstr::update_indirect_addr(PRegister old_reg, PRegister addr)
|
||||
{
|
||||
(void)old_reg;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ private:
|
|||
static bool emit_atomic_op2(nir_intrinsic_instr *intr, Shader& shader);
|
||||
static bool emit_atomic_inc(nir_intrinsic_instr *intr, Shader& shader);
|
||||
static bool emit_atomic_pre_dec(nir_intrinsic_instr *intr, Shader& shader);
|
||||
static bool emit_atomic_counter_comp_swap(nir_intrinsic_instr *intr, Shader& shader);
|
||||
|
||||
void do_print(std::ostream& os) const override;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue