pan/bi: Handle special ops in NIR->BIR
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 10 Mar 2020 01:20:20 +0000 (21:20 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 10 Mar 2020 19:25:59 +0000 (19:25 +0000)
Only on supported GPUs at the moment; for older Bifrost that don't
support these, I'm not sure yet where the right place to do the lowering
is. NIR algebraic rules would be "nice" but probably impractical -- but
it wouldn't be hard to do it directly in BIR (as a lowering pass or
alternative implementation).

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4139>

src/panfrost/bifrost/bifrost_compile.c

index b02089e69861c30b694b53436fe85f9268e2c376..8dccb16bbe6fe4fd466e4cde06647ed5eaac29b5 100644 (file)
@@ -270,6 +270,12 @@ bi_class_for_nir_alu(nir_op op)
         case nir_op_mov:
                 return BI_MOV;
 
+        case nir_op_frcp:
+        case nir_op_frsq:
+        case nir_op_fsin:
+        case nir_op_fcos:
+                return BI_SPECIAL;
+
         default:
                 unreachable("Unknown ALU op");
         }
@@ -286,6 +292,9 @@ emit_alu(bi_context *ctx, nir_alu_instr *instr)
                         | nir_dest_bit_size(instr->dest.dest),
         };
 
+        /* TODO: Implement lowering of special functions for older Bifrost */
+        assert((alu.type != BI_SPECIAL) || !(ctx->quirks & BIFROST_NO_FAST_OP));
+
         if (instr->dest.dest.is_ssa) {
                 /* Construct a writemask */
                 unsigned bits_per_comp = instr->dest.dest.ssa.bit_size;
@@ -349,6 +358,18 @@ emit_alu(bi_context *ctx, nir_alu_instr *instr)
         case nir_op_umax:
                 alu.op.minmax = BI_MINMAX_MAX; /* MINMAX */
                 break;
+        case nir_op_frcp:
+                alu.op.special = BI_SPECIAL_FRCP;
+                break;
+        case nir_op_frsq:
+                alu.op.special = BI_SPECIAL_FRSQ;
+                break;
+        case nir_op_fsin:
+                alu.op.special = BI_SPECIAL_FSIN;
+                break;
+        case nir_op_fcos:
+                alu.op.special = BI_SPECIAL_FCOS;
+                break;
         default:
                 break;
         }