diff --git a/src/freedreno/ir3/ir3_a6xx.c b/src/freedreno/ir3/ir3_a6xx.c index 62e4e944672..badc964f367 100644 --- a/src/freedreno/ir3/ir3_a6xx.c +++ b/src/freedreno/ir3/ir3_a6xx.c @@ -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 diff --git a/src/freedreno/ir3/ir3_image.c b/src/freedreno/ir3/ir3_image.c index fb311b6b7d5..093fd53f3f5 100644 --- a/src/freedreno/ir3/ir3_image.c +++ b/src/freedreno/ir3/ir3_image.c @@ -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");