[5/7] panfrost/midgard: Route new blending intrinsics

Submitted by Alyssa Rosenzweig on May 6, 2019, 2:26 a.m.

Details

Message ID 20190506022611.4954-6-alyssa@rosenzweig.io
State New
Headers show
Series "Blend shaders! (NIR lowering pass)" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Alyssa Rosenzweig May 6, 2019, 2:26 a.m.
To prepare for the new nir_lower_blend pass, we wire up the intrinsics
for tilebuffer reads and constant colour loading.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
---
 .../panfrost/midgard/midgard_compile.c        | 207 +++++++++---------
 1 file changed, 109 insertions(+), 98 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
index 29f3ce7ff71..cf27ed400e5 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c
+++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
@@ -1547,6 +1547,79 @@  emit_sysval_read(compiler_context *ctx, nir_intrinsic_instr *instr)
         emit_uniform_read(ctx, dest, uniform, NULL);
 }
 
+/* Reads RGBA8888 value from the tilebuffer and converts to a RGBA32F register,
+ * using scalar ops functional on earlier Midgard generations. Newer Midgard
+ * generations have faster vectorized reads. This operation is for blend
+ * shaders in particular; reading the tilebuffer from the fragment shader
+ * remains an open problem. */
+
+static void
+emit_fb_read_blend_scalar(compiler_context *ctx, unsigned reg)
+{
+        midgard_instruction ins = m_load_color_buffer_8(reg, 0);
+        ins.load_store.swizzle = 0; /* xxxx */
+
+        /* Read each component sequentially */
+
+        for (unsigned c = 0; c < 4; ++c) {
+                ins.load_store.mask = (1 << c);
+                ins.load_store.unknown = c;
+                emit_mir_instruction(ctx, ins);
+        }
+
+        /* vadd.u2f hr2, zext(hr2), #0 */
+
+        midgard_vector_alu_src alu_src = blank_alu_src;
+        alu_src.mod = midgard_int_zero_extend;
+        alu_src.half = true;
+
+        midgard_instruction u2f = {
+                .type = TAG_ALU_4,
+                .ssa_args = {
+                        .src0 = reg,
+                        .src1 = SSA_UNUSED_0,
+                        .dest = reg,
+                        .inline_constant = true
+                },
+                .alu = {
+                        .op = midgard_alu_op_u2f,
+                        .reg_mode = midgard_reg_mode_16,
+                        .dest_override = midgard_dest_override_none,
+                        .mask = 0xF,
+                        .src1 = vector_alu_srco_unsigned(alu_src),
+                        .src2 = vector_alu_srco_unsigned(blank_alu_src),
+                }
+        };
+
+        emit_mir_instruction(ctx, u2f);
+
+        /* vmul.fmul.sat r1, hr2, #0.00392151 */
+
+        alu_src.mod = 0;
+
+        midgard_instruction fmul = {
+                .type = TAG_ALU_4,
+                .inline_constant = _mesa_float_to_half(1.0 / 255.0),
+                .ssa_args = {
+                        .src0 = reg,
+                        .dest = reg,
+                        .src1 = SSA_UNUSED_0,
+                        .inline_constant = true
+                },
+                .alu = {
+                        .op = midgard_alu_op_fmul,
+                        .reg_mode = midgard_reg_mode_32,
+                        .dest_override = midgard_dest_override_none,
+                        .outmod = midgard_outmod_sat,
+                        .mask = 0xFF,
+                        .src1 = vector_alu_srco_unsigned(alu_src),
+                        .src2 = vector_alu_srco_unsigned(blank_alu_src),
+                }
+        };
+
+        emit_mir_instruction(ctx, fmul);
+}
+
 static void
 emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
 {
@@ -1608,106 +1681,13 @@  emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
                                 ins.load_store.unknown = 0x79e; /* xxx: what is this? */
                         }
 
-                        emit_mir_instruction(ctx, ins);
-                } else if (ctx->is_blend && instr->intrinsic == nir_intrinsic_load_uniform) {
-                        /* Constant encoded as a pinned constant */
-
-                        midgard_instruction ins = v_fmov(SSA_FIXED_REGISTER(REGISTER_CONSTANT), blank_alu_src, reg);
-                        ins.has_constants = true;
-                        ins.has_blend_constant = true;
                         emit_mir_instruction(ctx, ins);
                 } else if (ctx->is_blend) {
-                        /* For blend shaders, a load might be
-                         * translated various ways depending on what
-                         * we're loading. Figure out how this is used */
-
-                        nir_variable *out = NULL;
-
-                        nir_foreach_variable(var, &ctx->nir->inputs) {
-                                int drvloc = var->data.driver_location;
-
-                                if (nir_intrinsic_base(instr) == drvloc) {
-                                        out = var;
-                                        break;
-                                }
-                        }
+                        /* For blend shaders, load the input color, which is
+                         * preloaded to r0 */
 
-                        assert(out);
-
-                        if (out->data.location == VARYING_SLOT_COL0) {
-                                /* Source color preloaded to r0 */
-
-                                midgard_pin_output(ctx, reg, 0);
-                        } else if (out->data.location == VARYING_SLOT_COL1) {
-                                /* Destination color must be read from framebuffer */
-
-                                midgard_instruction ins = m_load_color_buffer_8(reg, 0);
-                                ins.load_store.swizzle = 0; /* xxxx */
-
-                                /* Read each component sequentially */
-
-                                for (int c = 0; c < 4; ++c) {
-                                        ins.load_store.mask = (1 << c);
-                                        ins.load_store.unknown = c;
-                                        emit_mir_instruction(ctx, ins);
-                                }
-
-                                /* vadd.u2f hr2, zext(hr2), #0 */
-
-                                midgard_vector_alu_src alu_src = blank_alu_src;
-                                alu_src.mod = midgard_int_zero_extend;
-                                alu_src.half = true;
-
-                                midgard_instruction u2f = {
-                                        .type = TAG_ALU_4,
-                                        .ssa_args = {
-                                                .src0 = reg,
-                                                .src1 = SSA_UNUSED_0,
-                                                .dest = reg,
-                                                .inline_constant = true
-                                        },
-                                        .alu = {
-                                                .op = midgard_alu_op_u2f,
-                                                .reg_mode = midgard_reg_mode_16,
-                                                .dest_override = midgard_dest_override_none,
-                                                .mask = 0xF,
-                                                .src1 = vector_alu_srco_unsigned(alu_src),
-                                                .src2 = vector_alu_srco_unsigned(blank_alu_src),
-                                        }
-                                };
-
-                                emit_mir_instruction(ctx, u2f);
-
-                                /* vmul.fmul.sat r1, hr2, #0.00392151 */
-
-                                alu_src.mod = 0;
-
-                                midgard_instruction fmul = {
-                                        .type = TAG_ALU_4,
-                                        .inline_constant = _mesa_float_to_half(1.0 / 255.0),
-                                        .ssa_args = {
-                                                .src0 = reg,
-                                                .dest = reg,
-                                                .src1 = SSA_UNUSED_0,
-                                                .inline_constant = true
-                                        },
-                                        .alu = {
-                                                .op = midgard_alu_op_fmul,
-                                                .reg_mode = midgard_reg_mode_32,
-                                                .dest_override = midgard_dest_override_none,
-                                                .outmod = midgard_outmod_sat,
-                                                .mask = 0xFF,
-                                                .src1 = vector_alu_srco_unsigned(alu_src),
-                                                .src2 = vector_alu_srco_unsigned(blank_alu_src),
-                                        }
-                                };
-
-                                emit_mir_instruction(ctx, fmul);
-                        } else {
-                                DBG("Unknown input in blend shader\n");
-                                assert(0);
-                        }
-                } else if (ctx->stage == MESA_SHADER_VERTEX) {
+                        midgard_pin_output(ctx, reg, 0);
+                }  else if (ctx->stage == MESA_SHADER_VERTEX) {
                         midgard_instruction ins = m_load_attr_32(reg, offset);
                         ins.load_store.unknown = 0x1E1E; /* XXX: What is this? */
                         ins.load_store.mask = (1 << instr->num_components) - 1;
@@ -1719,6 +1699,34 @@  emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
 
                 break;
 
+        case nir_intrinsic_load_output:
+                assert(nir_src_is_const(instr->src[0]));
+                reg = nir_dest_index(ctx, &instr->dest);
+
+                if (ctx->is_blend) {
+                        /* TODO: MRT */
+                        emit_fb_read_blend_scalar(ctx, reg);
+                } else {
+                        DBG("Unknown output load\n");
+                        assert(0);
+                }
+
+                break;
+
+        case nir_intrinsic_load_blend_const_color_rgba: {
+                assert(ctx->is_blend);
+                reg = nir_dest_index(ctx, &instr->dest);
+
+                /* Blend constants are embedded directly in the shader and
+                 * patched in, so we use some magic routing */
+
+                midgard_instruction ins = v_fmov(SSA_FIXED_REGISTER(REGISTER_CONSTANT), blank_alu_src, reg);
+                ins.has_constants = true;
+                ins.has_blend_constant = true;
+                emit_mir_instruction(ctx, ins);
+                break;
+        }
+
         case nir_intrinsic_store_output:
                 assert(nir_src_is_const(instr->src[1]) && "no indirect outputs");
 
@@ -1733,7 +1741,10 @@  emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
                          * framebuffer writeout dance. TODO: Defer
                          * writes */
 
-                        midgard_pin_output(ctx, reg, 0);
+                        midgard_instruction move = v_fmov(reg, blank_alu_src, SSA_FIXED_REGISTER(0));
+                        emit_mir_instruction(ctx, move);
+
+                        //midgard_pin_output(ctx, reg, 0);
 
                         /* Save the index we're writing to for later reference
                          * in the epilogue */