From fa38f821f43961c2bfdc3e9156229d3fd25a6ce4 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 25 Feb 2026 11:27:16 -0800 Subject: [PATCH] intel/mi_builder: add mi_umax2() We're going to use this for indirect copies, as we need to iterate through the indirect buffer checking the copy sizes, then pick the maximum copy size in order to launch the indirect compute shader. Signed-off-by: Paulo Zanoni --- src/intel/common/mi_builder.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/intel/common/mi_builder.h b/src/intel/common/mi_builder.h index b5f4bee4ee4..527e649015f 100644 --- a/src/intel/common/mi_builder.h +++ b/src/intel/common/mi_builder.h @@ -1301,6 +1301,40 @@ mi_udiv32_imm(struct mi_builder *b, struct mi_value N, uint32_t D) } } +/* Finds the maximum between the two specified unsigned numbers. */ +static inline struct mi_value +mi_umax2(struct mi_builder *b, struct mi_value val1, struct mi_value val2) +{ + /* The idea of the alrogithm here is that the value of 'mask' will be + * either 0 or ~0 depending on which number is bigger. Then we use AND + * operations to ensure the smaller value becomes zero and the bigger value + * is preserved, and finally OR both values to the destination (the bigger + * and zero). + * + * In other words: + * mask = val1 < val2 ? 0xFFFFFFFF : 0x0; + * biggest = (val1 & ~mask) | (val2 & mask); + */ + + /* If 'val1' is smaller, 'mask' is ~0, otherwise it's 0. */ + struct mi_value mask = mi_ult(b, mi_value_ref(b, val1), + mi_value_ref(b, val2)); + struct mi_value notmask = mi_ixor(b, mi_value_ref(b, mask), + mi_imm(UINT64_MAX)); + /* If 'val1' is smaller, 'notmask' is 0, so we zero it, otherwise we + * preserve the value by ANDing it with ~0. + */ + struct mi_value val1_or_zero = mi_iand(b, val1, notmask); + /* If 'val2' is smaller, mask is 0, so we zero it, otherwise we preserve + * the value. + */ + struct mi_value val2_or_zero = mi_iand(b, val2, mask); + /* The smaller value was zeroed, the other was preserved, so just OR + * them now. + */ + return mi_ior(b, val1_or_zero, val2_or_zero); +} + #endif /* MI_MATH section */ /* This assumes addresses of strictly more than 32bits (aka. Gfx8+). */