aco/lower_to_hw: support saturating fp8 conversions

Sadly amd only made this behavior controlable with global state.
We add a new pseudo opcode for this purpose and change FP16_OVFL
for each instruction. Ideally we would only do it once for clauses
and after ilp scheduling, but this can be improved in the future.

Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35434>
This commit is contained in:
Georg Lehmann
2025-06-06 16:42:39 +02:00
committed by Marge Bot
parent 65650cfef8
commit 3a45802514
2 changed files with 15 additions and 0 deletions
@@ -2926,6 +2926,20 @@ lower_to_hw_instr(Program* program)
ctx.instructions.emplace_back(std::move(instr));
emit_set_mode(bld, block->fp_mode, set_round, false);
} else if (instr->opcode == aco_opcode::p_v_cvt_pk_fp8_f32_ovfl) {
/* FP8/BF8 uses FP16_OVFL(1) to clamp to max finite result. Temporarily set it for the
* instruction.
* "((size - 1) << 11 | (offset << 6) | register" (MODE is encoded as register 1, we
* want to set a single bit at offset 23)
*/
bld.sopk(aco_opcode::s_setreg_imm32_b32, Operand::literal32(1),
(0 << 11) | (23 << 6) | 1);
instr->opcode = aco_opcode::v_cvt_pk_fp8_f32;
ctx.instructions.emplace_back(std::move(instr));
bld.sopk(aco_opcode::s_setreg_imm32_b32, Operand::literal32(0),
(0 << 11) | (23 << 6) | 1);
} else if (instr->isMIMG() && instr->mimg().strict_wqm) {
lower_image_sample(&ctx, instr);
ctx.instructions.emplace_back(std::move(instr));
+1
View File
@@ -1448,6 +1448,7 @@ VOP3 = {
("v_permlane16_var_b32", dst(U32), src(U32, U32), op(gfx12=0x30f)),
("v_permlanex16_var_b32", dst(U32), src(U32, U32), op(gfx12=0x310)),
("v_cvt_pk_fp8_f32", dst(PkF8), src(F32, F32), op(gfx12=0x369)),
("p_v_cvt_pk_fp8_f32_ovfl", dst(PkF8), src(F32, F32), op(-1)),
("v_cvt_pk_bf8_f32", dst(PkBF8), src(F32, F32), op(gfx12=0x36a)),
("v_cvt_sr_fp8_f32", dst(F8), src(F32, U32), op(gfx12=0x36b)),
("v_cvt_sr_bf8_f32", dst(BF8), src(F32, U32), op(gfx12=0x36c)),