diff --git a/src/panfrost/bifrost/bi_pack.c b/src/panfrost/bifrost/bi_pack.c index 204affa06f5..977363e4894 100644 --- a/src/panfrost/bifrost/bi_pack.c +++ b/src/panfrost/bifrost/bi_pack.c @@ -701,6 +701,10 @@ bi_pack_add_special(bi_clause *clause, bi_instruction *ins, bi_registers *regs) return pan_pack_add_cube_ssel(clause, ins, regs); case BI_SPECIAL_CUBE_TSEL: return pan_pack_add_cube_tsel(clause, ins, regs); + case BI_SPECIAL_CLPER_V6: + return pan_pack_add_clper_v6_i32(clause, ins, regs); + case BI_SPECIAL_CLPER_V7: + return pan_pack_add_clper_v7_i32(clause, ins, regs); default: unreachable("Unknown special op"); } diff --git a/src/panfrost/bifrost/bi_print.c b/src/panfrost/bifrost/bi_print.c index a97366bbba6..c00f2180b27 100644 --- a/src/panfrost/bifrost/bi_print.c +++ b/src/panfrost/bifrost/bi_print.c @@ -211,6 +211,8 @@ bi_special_op_name(enum bi_special_op op) case BI_SPECIAL_CUBEFACE2: return "cubeface2"; case BI_SPECIAL_CUBE_SSEL: return "cube_ssel"; case BI_SPECIAL_CUBE_TSEL: return "cube_tsel"; + case BI_SPECIAL_CLPER_V6: return "clper_v6"; + case BI_SPECIAL_CLPER_V7: return "clper_v7"; default: return "invalid"; } } diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index d51294cf2b9..22cc615ba2b 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -241,6 +241,10 @@ enum bi_special_op { BI_SPECIAL_CUBEFACE2, BI_SPECIAL_CUBE_SSEL, BI_SPECIAL_CUBE_TSEL, + + /* Cross-lane permute, used to implement dFd{x,y} */ + BI_SPECIAL_CLPER_V6, + BI_SPECIAL_CLPER_V7, }; struct bi_bitwise { @@ -259,6 +263,46 @@ struct bi_texture { bool compute_lod; }; +enum bi_clper_lane_op_mod { + BI_CLPER_LANE_OP_MOD_NONE, + BI_CLPER_LANE_OP_MOD_XOR, + BI_CLPER_LANE_OP_MOD_ACCUMULATE, + BI_CLPER_LANE_OP_MOD_SHIFT, +}; + +enum bi_subgroup_sz { + BI_CLPER_SUBGROUP_SZ_2, + BI_CLPER_SUBGROUP_SZ_4, + BI_CLPER_SUBGROUP_SZ_8, +}; + +enum bi_clper_inactive_res { + BI_CLPER_INACTIVE_RES_ZERO, + BI_CLPER_INACTIVE_RES_UMAX, + BI_CLPER_INACTIVE_RES_I1, + BI_CLPER_INACTIVE_RES_V2I1, + BI_CLPER_INACTIVE_RES_SMIN, + BI_CLPER_INACTIVE_RES_SMAX, + BI_CLPER_INACTIVE_RES_V2SMIN, + BI_CLPER_INACTIVE_RES_V2SMAX, + BI_CLPER_INACTIVE_RES_V4SMIN, + BI_CLPER_INACTIVE_RES_V4SMAX, + BI_CLPER_INACTIVE_RES_F1, + BI_CLPER_INACTIVE_RES_V2F1, + BI_CLPER_INACTIVE_RES_INFN, + BI_CLPER_INACTIVE_RES_INF, + BI_CLPER_INACTIVE_RES_V2INFN, + BI_CLPER_INACTIVE_RES_V2INF, +}; + +struct bi_special { + struct { + enum bi_clper_lane_op_mod lane_op_mod; + enum bi_clper_inactive_res inactive_res; + } clper; + enum bi_subgroup_sz subgroup_sz; +}; + typedef struct { struct list_head link; /* Must be first */ enum bi_class type; @@ -355,6 +399,7 @@ typedef struct { struct bi_bitwise bitwise; struct bi_texture texture; + struct bi_special special; }; } bi_instruction; diff --git a/src/panfrost/bifrost/gen_pack.py b/src/panfrost/bifrost/gen_pack.py index d9d31fd57d5..03c2f0401f1 100644 --- a/src/panfrost/bifrost/gen_pack.py +++ b/src/panfrost/bifrost/gen_pack.py @@ -284,6 +284,13 @@ modifier_map = { # For +LD_VAR, infer sample from load_vary.interp_mode "sample": lambda a,b,c,d: 'ins->load_vary.interp_mode', + # +CLPER + "lane_op": lambda a,b,c,d: 'ins->special.clper.lane_op_mod', + "inactive_result": lambda a,b,c,d: 'ins->special.clper.inactive_res', + + # +CLPER and +WMASK + "subgroup": lambda a,b,c,d: 'ins->special.subgroup_sz', + # We don't support these in the IR yet (TODO) "saturate": lambda a,b,c,d: '0', # clamp to min/max int "mask": lambda a,b,c,d: '0', # clz(~0) = ~0 @@ -304,9 +311,6 @@ modifier_map = { "bytes2": lambda a,b,c,d: '0', # NIR shifts are in bits "result_word": lambda a,b,c,d: '0', # 32-bit only shifts for now (TODO) "source": lambda a,b,c,d: '7', # cycle_counter for LD_GCLK - "lane_op": lambda a,b,c,d: '0', # CLPER none - "subgroup": lambda a,b,c,d: '1', # CLPER subgroup4 - "inactive_result": lambda a,b,c,d: '0', # CLPER zero "threads": lambda a,b,c,d: '0', # IMULD odd "combine": lambda a,b,c,d: '0', # BRANCHC any "format": lambda a,b,c,d: '1', # LEA_TEX_IMM u32