From d2a09f3dd3e97f1439300855edfa34db1b998506 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 11 Mar 2022 16:11:16 -0600 Subject: [PATCH] bifrost: Implement fine and coarse derivatives We leave the undecorated ops as fine so we don't disturb panfrost. For coarse derivatives, we use a lane ID of 0 for the first lane and 1 or 2 for the second depending on axis. This ensures that coarse derivatives are quad-uniform. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/panfrost/bifrost/bifrost_compile.c | 42 ++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index b811e1f..0ebe8d9 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -2140,16 +2140,50 @@ bi_emit_alu(bi_builder *b, nir_alu_instr *instr) } case nir_op_fddx: - case nir_op_fddy: { - unsigned axis = instr->op == nir_op_fddx ? 1 : 2; - bi_index lane1 = bi_lshift_and_i32(b, + case nir_op_fddy: + case nir_op_fddx_coarse: + case nir_op_fddy_coarse: + case nir_op_fddx_fine: + case nir_op_fddy_fine: { + unsigned axis; + switch (instr->op) { + case nir_op_fddx: + case nir_op_fddx_coarse: + case nir_op_fddx_fine: + axis = 1; + break; + case nir_op_fddy: + case nir_op_fddy_coarse: + case nir_op_fddy_fine: + axis = 2; + break; + default: + unreachable("Invalid derivative op"); + } + + bi_index lane1, lane2; + switch (instr->op) { + case nir_op_fddx: + case nir_op_fddx_fine: + case nir_op_fddy: + case nir_op_fddy_fine: + lane1 = bi_lshift_and_i32(b, bi_fau(BIR_FAU_LANE_ID, false), bi_imm_u32(0x3 & ~axis), bi_imm_u8(0)); - bi_index lane2 = bi_iadd_u32(b, lane1, + lane2 = bi_iadd_u32(b, lane1, bi_imm_u32(axis), false); + break; + case nir_op_fddx_coarse: + case nir_op_fddy_coarse: + lane1 = bi_imm_u32(0); + lane2 = bi_imm_u32(axis); + break; + default: + unreachable("Invalid derivative op"); + } bi_index left, right; -- 2.7.4