mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
pan/bi: Rewrite conversion packing
To support roundmodes and other goodies. Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4539>
This commit is contained in:
parent
0b000c54c0
commit
8cfe660326
2 changed files with 89 additions and 63 deletions
|
|
@ -749,49 +749,80 @@ bi_pack_fma_convert(bi_instruction *ins, struct bi_registers *regs)
|
|||
nir_alu_type to_base = nir_alu_type_get_base_type(ins->dest_type);
|
||||
unsigned to_size = nir_alu_type_get_type_size(ins->dest_type);
|
||||
bool to_unsigned = to_base == nir_type_uint;
|
||||
bool to_float = to_base == nir_type_float;
|
||||
|
||||
/* Sanity check */
|
||||
assert((from_base != to_base) || (from_size != to_size));
|
||||
assert((MAX2(from_size, to_size) / MIN2(from_size, to_size)) <= 2);
|
||||
|
||||
if (from_size == 16 && to_size == 16) {
|
||||
/* f2i_i2f16 */
|
||||
unreachable("i16 not yet implemented");
|
||||
} else if (from_size == 32 && to_size == 32) {
|
||||
unsigned op = 0;
|
||||
/* f32 to f16 is special */
|
||||
if (from_size == 32 && to_size == 16 && from_base == nir_type_float && to_base == from_base) {
|
||||
/* TODO: second vectorized source? */
|
||||
struct bifrost_fma_2src pack = {
|
||||
.src0 = bi_get_src(ins, regs, 0, true),
|
||||
.src1 = BIFROST_SRC_STAGE, /* 0 */
|
||||
.op = BIFROST_FMA_FLOAT32_TO_16
|
||||
};
|
||||
|
||||
if (from_base == nir_type_float) {
|
||||
op = BIFROST_FMA_FLOAT32_TO_INT(to_unsigned);
|
||||
} else {
|
||||
op = BIFROST_FMA_INT_TO_FLOAT32(from_unsigned);
|
||||
}
|
||||
|
||||
return bi_pack_fma_1src(ins, regs, op);
|
||||
} else if (from_size == 16 && to_size == 32) {
|
||||
bool from_y = ins->swizzle[0][0];
|
||||
|
||||
if (from_base == nir_type_float) {
|
||||
return bi_pack_fma_1src(ins, regs,
|
||||
BIFROST_FMA_FLOAT16_TO_32(from_y));
|
||||
} else {
|
||||
unreachable("i16 not yet implemented");
|
||||
}
|
||||
} else if (from_size == 32 && to_size == 16) {
|
||||
if (from_base == nir_type_float) {
|
||||
/* TODO: second vectorized source? */
|
||||
struct bifrost_fma_2src pack = {
|
||||
.src0 = bi_get_src(ins, regs, 0, true),
|
||||
.src1 = BIFROST_SRC_STAGE, /* 0 */
|
||||
.op = BIFROST_FMA_FLOAT32_TO_16
|
||||
};
|
||||
|
||||
RETURN_PACKED(pack);
|
||||
} else {
|
||||
unreachable("i16 not yet implemented");
|
||||
}
|
||||
RETURN_PACKED(pack);
|
||||
}
|
||||
|
||||
unreachable("Unknown convert");
|
||||
/* Otherwise, figure out the mode */
|
||||
unsigned op = 0;
|
||||
|
||||
if (from_size == 16 && to_size == 32) {
|
||||
unsigned component = ins->swizzle[0][0];
|
||||
assert(component <= 1);
|
||||
|
||||
if (from_base == nir_type_float)
|
||||
op = BIFROST_CONVERT_5(component);
|
||||
else
|
||||
op = BIFROST_CONVERT_4(from_unsigned, component, to_float);
|
||||
} else {
|
||||
unsigned mode = 0;
|
||||
unsigned swizzle = (from_size == 16) ? bi_swiz16(ins, 0) : 0;
|
||||
bool is_unsigned = from_unsigned;
|
||||
|
||||
if (from_base == nir_type_float) {
|
||||
assert(to_base != nir_type_float);
|
||||
is_unsigned = to_unsigned;
|
||||
|
||||
if (from_size == 32 && to_size == 32)
|
||||
mode = BIFROST_CONV_F32_TO_I32;
|
||||
else if (from_size == 16 && to_size == 16)
|
||||
mode = BIFROST_CONV_F16_TO_I16;
|
||||
else
|
||||
unreachable("Invalid float conversion");
|
||||
} else {
|
||||
assert(to_base == nir_type_float);
|
||||
assert(from_size == to_size);
|
||||
|
||||
if (to_size == 32)
|
||||
mode = BIFROST_CONV_I32_TO_F32;
|
||||
else if (to_size == 16)
|
||||
mode = BIFROST_CONV_I16_TO_F16;
|
||||
else
|
||||
unreachable("Invalid int conversion");
|
||||
}
|
||||
|
||||
/* Fixup swizzle for 32-bit only modes */
|
||||
|
||||
if (mode == BIFROST_CONV_I32_TO_F32)
|
||||
swizzle = 0b11;
|
||||
else if (mode == BIFROST_CONV_F32_TO_I32)
|
||||
swizzle = 0b10;
|
||||
|
||||
op = BIFROST_CONVERT(is_unsigned, ins->roundmode, swizzle, mode);
|
||||
|
||||
/* Unclear what the top bit is for... maybe 16-bit related */
|
||||
bool mode2 = mode == BIFROST_CONV_F16_TO_I16;
|
||||
bool mode6 = mode == BIFROST_CONV_I16_TO_F16;
|
||||
|
||||
if (!(mode2 || mode6))
|
||||
op |= 0x100;
|
||||
}
|
||||
|
||||
return bi_pack_fma_1src(ins, regs, BIFROST_FMA_CONVERT | op);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
|
|
|
|||
|
|
@ -333,39 +333,34 @@ struct bifrost_shift_add {
|
|||
unsigned op : 7;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BIFROST_FMA_INT16_TO_32 (0xe0198 >> 3)
|
||||
|
||||
struct bifrost_fma_int16_to_32 {
|
||||
unsigned src0 : 3;
|
||||
unsigned is_unsigned : 1;
|
||||
unsigned swizzle : 1;
|
||||
unsigned to_float : 1;
|
||||
unsigned op : 17;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* We could combine but it's easier to just use FMA_ONE_SRC */
|
||||
#define BIFROST_FMA_FLOAT16_TO_32(y) (0xe01a2 | ((y) ? 1 : 0))
|
||||
|
||||
/* Two sources for vectorization */
|
||||
#define BIFROST_FMA_FLOAT32_TO_16 (0xdd000 >> 3)
|
||||
|
||||
/* Again we could combine but easier to just ONE_SRC with an
|
||||
* argumnt for unsignedness */
|
||||
#define BIFROST_FMA_FLOAT32_TO_INT(u) (0xe0136 | ((u) ? 1 : 0))
|
||||
#define BIFROST_FMA_INT_TO_FLOAT32(u) (0xe0178 | ((u) ? 1 : 0))
|
||||
enum bifrost_convert_mode {
|
||||
BIFROST_CONV_UNK0 = 0,
|
||||
BIFROST_CONV_F32_TO_I32 = 1,
|
||||
BIFROST_CONV_F16_TO_I16 = 2,
|
||||
BIFROST_CONV_I32_TO_F32 = 3,
|
||||
BIFROST_CONV_I16_TO_X32 = 4,
|
||||
BIFROST_CONV_F16_TO_F32 = 5,
|
||||
BIFROST_CONV_I16_TO_F16 = 6,
|
||||
BIFROST_CONV_UNK7 = 7
|
||||
};
|
||||
|
||||
/* Used for f2i16 and i2f16 */
|
||||
#define BIFROST_FMA_F2I16 (0xe00)
|
||||
/* i16 to x32 */
|
||||
#define BIFROST_CONVERT_4(is_unsigned, component, to_float) \
|
||||
((is_unsigned & 1) | ((component & 1) << 1) | ((to_float & 1) << 2) | \
|
||||
((0x3) << 3) | ((4) << 5) | 0x100)
|
||||
|
||||
struct bifrost_fma_f2i_i2f16 {
|
||||
unsigned src0 : 3;
|
||||
unsigned is_unsigned : 1;
|
||||
unsigned direction : 2; /* 00 for i2f, 11 for f2i */
|
||||
unsigned swizzle : 2;
|
||||
unsigned unk : 2; /* always 10 */
|
||||
unsigned direction_2 : 1; /* 0 for f2i, 1 for i2f */
|
||||
unsigned op : 12;
|
||||
} __attribute__((packed));
|
||||
/* f16 to f32 */
|
||||
#define BIFROST_CONVERT_5(component) \
|
||||
((component & 1) | ((1) << 1) | ((5) << 5) | 0x100)
|
||||
|
||||
/* Other conversions */
|
||||
#define BIFROST_CONVERT(is_unsigned, roundmode, swizzle, mode) \
|
||||
((is_unsigned & 1) | ((roundmode & 3) << 1) | ((swizzle & 3) << 3) | ((mode & 7) << 5))
|
||||
|
||||
#define BIFROST_FMA_CONVERT (0xe0000)
|
||||
|
||||
enum bifrost_ldst_type {
|
||||
BIFROST_LDST_F16 = 0,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue