diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index 32b54c8d14f..f5753e8ca37 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -1809,6 +1809,22 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr) } break; } + case nir_op_iadd_sat: { + Temp src0 = get_alu_src(ctx, instr->src[0]); + Temp src1 = as_vgpr(ctx, get_alu_src(ctx, instr->src[1])); + if (dst.regClass() == v2b) { + Instruction* add_instr = + bld.vop3(aco_opcode::v_add_i16, Definition(dst), src0, src1).instr; + add_instr->vop3().clamp = 1; + } else if (dst.regClass() == v1) { + Instruction* add_instr = + bld.vop3(aco_opcode::v_add_i32, Definition(dst), src0, src1).instr; + add_instr->vop3().clamp = 1; + } else { + isel_err(&instr->instr, "Unimplemented NIR instr bit size"); + } + break; + } case nir_op_uadd_carry: { Temp src0 = get_alu_src(ctx, instr->src[0]); Temp src1 = get_alu_src(ctx, instr->src[1]); diff --git a/src/amd/compiler/aco_instruction_selection_setup.cpp b/src/amd/compiler/aco_instruction_selection_setup.cpp index 28ce8223e94..5371628d7ac 100644 --- a/src/amd/compiler/aco_instruction_selection_setup.cpp +++ b/src/amd/compiler/aco_instruction_selection_setup.cpp @@ -593,7 +593,8 @@ init_context(isel_context* ctx, nir_shader* shader) case nir_op_frexp_exp: case nir_op_cube_face_index_amd: case nir_op_cube_face_coord_amd: - case nir_op_sad_u8x4: type = RegType::vgpr; break; + case nir_op_sad_u8x4: + case nir_op_iadd_sat: type = RegType::vgpr; break; case nir_op_f2i16: case nir_op_f2u16: case nir_op_f2i32: diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 3b01545ed6d..414ede8a173 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -3224,6 +3224,9 @@ lower_bit_size_callback(const nir_instr *instr, void *_) case nir_op_uadd_sat: return (bit_size == 8 || !(chip >= GFX8 && nir_dest_is_divergent(alu->dest.dest))) ? 32 : 0; + case nir_op_iadd_sat: + return bit_size == 8 || !nir_dest_is_divergent(alu->dest.dest) ? 32 : 0; + default: return 0; } diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index 5952f95d4c3..0b9d3d82835 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -81,6 +81,7 @@ radv_get_nir_options(struct radv_physical_device *device) .lower_fpow = true, .lower_mul_2x32_64 = true, .lower_rotate = true, + .lower_iadd_sat = device->rad_info.chip_class <= GFX8, .has_fsub = true, .has_isub = true, .use_scoped_barrier = true,