From 9efec45b0cd8bdd39c2ef50e5ab4dee447724a5c Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Wed, 17 Mar 2021 21:39:47 +0200 Subject: [PATCH] ir3: disallow .sat on SEL instructions Saturation is unsupported on SEL instructions. Fixes main menu rendering in Genshin Impact. Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/ir3/instr-a3xx.h | 20 ++++++++++++++++++++ src/freedreno/ir3/ir3_compiler_nir.c | 7 ++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index 36ae363877e..9eb4ea66f85 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -1040,6 +1040,26 @@ static inline bool instr_sat(instr_t *instr) } } +static inline bool is_sat_compatible(opc_t opc) +{ + /* TODO probably opc_cat==4 is ok too */ + if (opc_cat(opc) != 2 && opc_cat(opc) != 3) + return false; + + switch (opc) { + case OPC_BARY_F: + case OPC_SEL_B16: + case OPC_SEL_B32: + case OPC_SEL_S16: + case OPC_SEL_S32: + case OPC_SEL_F16: + case OPC_SEL_F32: + return false; + default: + return true; + } +} + /* We can probably drop the gpu_id arg, but keeping it for now so we can * assert if we see something we think should be new encoding on an older * gpu. diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 815da33119a..38a4aba3b4e 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -433,13 +433,10 @@ emit_alu(struct ir3_context *ctx, nir_alu_instr *alu) * NOTE: a3xx definitely seen not working with flat bary.f. Same test * uses ldlv on a4xx+, so not definitive. Seems rare enough to apply * everywhere. - * - * TODO probably opc_cat==4 is ok too */ if (alu->src[0].src.is_ssa && - src[0]->opc != OPC_BARY_F && - (list_length(&alu->src[0].src.ssa->uses) == 1) && - ((opc_cat(src[0]->opc) == 2) || (opc_cat(src[0]->opc) == 3))) { + is_sat_compatible(src[0]->opc) && + (list_length(&alu->src[0].src.ssa->uses) == 1)) { src[0]->flags |= IR3_INSTR_SAT; dst[0] = ir3_MOV(b, src[0], dst_type); } else {