From 6beac11868c3656d37e383238ec007d0bcead0fa Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 18 Aug 2020 17:51:22 -0400 Subject: [PATCH] panfrost: Honour load_dest/opaque flags Let's split them out and work out the metadata at CSO time. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Tomeu Vizoso Part-of: --- src/gallium/drivers/panfrost/pan_blend.h | 10 ++++++-- src/gallium/drivers/panfrost/pan_blend_cso.c | 26 ++++++++++++-------- src/gallium/drivers/panfrost/pan_cmdstream.c | 12 +++++---- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_blend.h b/src/gallium/drivers/panfrost/pan_blend.h index 22993dd94a9..a37d571c7d6 100644 --- a/src/gallium/drivers/panfrost/pan_blend.h +++ b/src/gallium/drivers/panfrost/pan_blend.h @@ -80,6 +80,9 @@ struct panfrost_blend_rt { /* Mask of blend color components read */ unsigned constant_mask; + /* Properties of the blend mode */ + bool opaque, load_dest, no_colour; + /* Regardless of fixed-function blending, this is a map of pipe_format * to panfrost_blend_shader */ @@ -99,8 +102,11 @@ struct panfrost_blend_final { /* Set for a shader, clear for an equation */ bool is_shader; - /* Clear if the destination needs to be loaded from the tilebuffer */ - bool no_blending; + /* Set if this is the replace mode */ + bool opaque; + + /* Set if destination is loaded */ + bool load_dest; /* Set if the colour mask is 0x0 (nothing is written) */ bool no_colour; diff --git a/src/gallium/drivers/panfrost/pan_blend_cso.c b/src/gallium/drivers/panfrost/pan_blend_cso.c index 1d0b2bad5c9..d600292e8a0 100644 --- a/src/gallium/drivers/panfrost/pan_blend_cso.c +++ b/src/gallium/drivers/panfrost/pan_blend_cso.c @@ -27,6 +27,7 @@ #include #include "util/u_memory.h" +#include "gallium/auxiliary/util/u_blend.h" #include "pan_blend_shaders.h" #include "pan_blending.h" #include "pan_bo.h" @@ -118,6 +119,7 @@ panfrost_create_blend_state(struct pipe_context *pipe, /* Logic ops are always shader */ if (blend->logicop_enable) { + rt->load_dest = true; continue; } @@ -127,10 +129,17 @@ panfrost_create_blend_state(struct pipe_context *pipe, &rt->equation, &rt->constant_mask); - /* Regardless if that works, we also need to initialize - * the blend shaders */ + if (rt->has_fixed_function) { + rt->opaque = + (rt->equation.rgb_mode == 0x122) && + (rt->equation.alpha_mode == 0x122) && + (rt->equation.color_mask == 0xf); + } - rt->shaders = _mesa_hash_table_u64_create(so); + rt->load_dest = util_blend_uses_dest(pipe) + || pipe.colormask != 0xF; + + rt->no_colour = pipe.colormask == 0x0; } return so; @@ -230,17 +239,13 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti) &constant, ctx->blend_color.color, rt->constant_mask)) { - bool no_blending = - (rt->equation.rgb_mode == 0x122) && - (rt->equation.alpha_mode == 0x122) && - (rt->equation.color_mask == 0xf); - struct panfrost_blend_final final = { .equation = { .equation = &rt->equation, .constant = constant }, - .no_blending = no_blending, + .load_dest = rt->load_dest, + .opaque = rt->opaque, .no_colour = (rt->equation.color_mask == 0x0) }; @@ -273,7 +278,8 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti) .work_count = shader->work_count, .first_tag = shader->first_tag, .gpu = bo->gpu, - } + }, + .load_dest = rt->load_dest, }; return final; diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index f57d240748a..33a7b7abd3d 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -615,7 +615,7 @@ panfrost_frag_meta_blend_update(struct panfrost_context *ctx, } SET_BIT(fragmeta->unknown2_3, MALI_CAN_DISCARD, - !blend[0].no_blending || fs->can_discard); + blend[0].load_dest); batch->draws |= PIPE_CLEAR_COLOR0; return; @@ -625,7 +625,7 @@ panfrost_frag_meta_blend_update(struct panfrost_context *ctx, bool no_blend = true; for (unsigned i = 0; i < rt_count; ++i) - no_blend &= (blend[i].no_blending | blend[i].no_colour); + no_blend &= (!blend[i].load_dest | blend[i].no_colour); SET_BIT(fragmeta->bifrost1.unk1, MALI_BIFROST_EARLY_Z, !fs->can_discard && !fs->writes_depth && no_blend); @@ -652,13 +652,15 @@ panfrost_emit_blend(struct panfrost_batch *batch, void *rts, unsigned flags = 0; pan_pack(&flags, BLEND_FLAGS, cfg) { - if (blend[i].no_colour) + if (blend[i].no_colour) { + cfg.enable = false; break; + } batch->draws |= (PIPE_CLEAR_COLOR0 << i); cfg.srgb = util_format_is_srgb(batch->key.cbufs[i]->format); - cfg.load_destination = !blend[i].no_blending; /* XXX */ + cfg.load_destination = blend[i].load_dest; cfg.dither_disable = !batch->ctx->blend->base.dither; if (!(dev->quirks & IS_BIFROST)) @@ -693,7 +695,7 @@ panfrost_emit_blend(struct panfrost_batch *batch, void *rts, * mode (equivalent to rgb_mode = alpha_mode = * x122, colour mask = 0xF). 0x1a allows * blending. */ - brts[i].unk2 = blend[i].no_blending ? 0x19 : 0x1a; + brts[i].unk2 = blend[i].opaque ? 0x19 : 0x1a; brts[i].shader_type = fs->blend_types[i]; } -- 2.30.2