ir3: add support for 64-bit image atomics

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39932>
This commit is contained in:
Job Noorman 2026-04-11 14:02:11 +02:00 committed by Marge Bot
parent b7b66d3efd
commit 0eab11b67f
2 changed files with 10 additions and 6 deletions

View file

@ -383,7 +383,7 @@ emit_intrinsic_atomic_image(struct ir3_context *ctx, nir_intrinsic_instr *intr)
* destination in RA (i.e. must be allocated to the same vec2/vec3
* register) and then immediately extract the first component.
*/
dummy = create_immed(b, 0);
dummy = intr->def.bit_size == 64 ? ir3_64b_immed(b, 0) : create_immed(b, 0);
src0 = ir3_create_collect(b, coords, ncoords);
if (op == nir_atomic_op_cmpxchg) {
@ -394,7 +394,7 @@ emit_intrinsic_atomic_image(struct ir3_context *ctx, nir_intrinsic_instr *intr)
}
atomic = emit_atomic(b, op, ibo, src0, src1);
atomic->cat6.iim_val = 1;
atomic->cat6.iim_val = intr->def.bit_size == 64 ? 2 : 1;
atomic->cat6.d = ncoords;
atomic->cat6.type = ir3_get_type_for_image_intrinsic(intr);
atomic->cat6.typed = true;
@ -408,9 +408,7 @@ emit_intrinsic_atomic_image(struct ir3_context *ctx, nir_intrinsic_instr *intr)
atomic->dsts[0]->wrmask = src1->dsts[0]->wrmask;
ir3_reg_tie(atomic->dsts[0], atomic->srcs[2]);
ir3_handle_nonuniform(atomic, intr);
struct ir3_instruction *split;
ir3_split_dest(b, &split, atomic, 0, 1);
return split;
return ir3_split_off_scalar(b, atomic, intr->def.bit_size);
}
static void

View file

@ -98,6 +98,9 @@ ir3_get_type_for_image_intrinsic(const nir_intrinsic_instr *instr)
{
const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
int bit_size = info->has_dest ? instr->def.bit_size : nir_src_bit_size(instr->src[3]);
assert(bit_size != 64 ||
instr->intrinsic == nir_intrinsic_bindless_image_atomic ||
instr->intrinsic == nir_intrinsic_bindless_image_atomic_swap);
nir_alu_type type = nir_type_uint;
switch (instr->intrinsic) {
@ -132,10 +135,13 @@ ir3_get_type_for_image_intrinsic(const nir_intrinsic_instr *instr)
switch (type) {
case nir_type_uint:
return bit_size == 16 ? TYPE_U16 : TYPE_U32;
return (bit_size == 16 ? TYPE_U16
: (bit_size == 32 ? TYPE_U32 : TYPE_ATOMIC_U64));
case nir_type_int:
assert(bit_size != 64);
return bit_size == 16 ? TYPE_S16 : TYPE_S32;
case nir_type_float:
assert(bit_size != 64);
return bit_size == 16 ? TYPE_F16 : TYPE_F32;
default:
UNREACHABLE("bad type");