diff --git a/src/gallium/drivers/panfrost/pan_blend_cso.c b/src/gallium/drivers/panfrost/pan_blend_cso.c index c61da749121..6f481f78f04 100644 --- a/src/gallium/drivers/panfrost/pan_blend_cso.c +++ b/src/gallium/drivers/panfrost/pan_blend_cso.c @@ -115,6 +115,11 @@ panfrost_create_blend_state(struct pipe_context *pipe, so->pan.rts[c].equation = equation; + /* Bifrost needs to know if any render target loads its + * destination in the hot draw path, so precompute this */ + if (so->info[c].load_dest) + so->load_dest_mask |= BITFIELD_BIT(c); + /* Converting equations to Mali style is expensive, do it at * CSO create time instead of draw-time */ if (so->info[c].fixed_function) { diff --git a/src/gallium/drivers/panfrost/pan_blend_cso.h b/src/gallium/drivers/panfrost/pan_blend_cso.h index 2e1d8ec483a..5e7940f5b16 100644 --- a/src/gallium/drivers/panfrost/pan_blend_cso.h +++ b/src/gallium/drivers/panfrost/pan_blend_cso.h @@ -47,6 +47,9 @@ struct panfrost_blend_state { struct pan_blend_state pan; struct pan_blend_info info[PIPE_MAX_COLOR_BUFS]; struct mali_blend_equation_packed equation[PIPE_MAX_COLOR_BUFS]; + + /* info.load presented as a bitfield for draw call hot paths */ + unsigned load_dest_mask : PIPE_MAX_COLOR_BUFS; }; void diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 219b4b75a3b..686b2c349a7 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -495,15 +495,8 @@ panfrost_prepare_bifrost_fs_state(struct panfrost_context *ctx, if (panfrost_fs_required(fs, so, &ctx->pipe_framebuffer)) { /* Track if any colour buffer is reused across draws, either * from reading it directly, or from failing to write it */ - bool blend_reads_dest = false; - unsigned rt_mask = 0; - - for (unsigned i = 0; i < ctx->pipe_framebuffer.nr_cbufs; ++i) { - if (ctx->pipe_framebuffer.cbufs[i]) { - rt_mask |= (1 << i); - blend_reads_dest |= so->info[i].load_dest; - } - } + unsigned rt_mask = ctx->fb_rt_mask; + bool blend_reads_dest = (so->load_dest_mask & rt_mask); state->properties.bifrost.allow_forward_pixel_to_kill = fs->info.fs.can_fpk && diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 260a55ecfe5..96be71738be 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -1379,6 +1379,14 @@ panfrost_set_framebuffer_state(struct pipe_context *pctx, util_copy_framebuffer_state(&ctx->pipe_framebuffer, fb); ctx->batch = NULL; + /* Hot draw call path needs the mask of active render targets */ + ctx->fb_rt_mask = 0; + + for (unsigned i = 0; i < ctx->pipe_framebuffer.nr_cbufs; ++i) { + if (ctx->pipe_framebuffer.cbufs[i]) + ctx->fb_rt_mask |= BITFIELD_BIT(i); + } + /* We may need to generate a new variant if the fragment shader is * keyed to the framebuffer format (due to EXT_framebuffer_fetch) */ struct panfrost_shader_variants *fs = ctx->shader[PIPE_SHADER_FRAGMENT]; diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 470f43801f8..847f2f5eb58 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -195,6 +195,9 @@ struct panfrost_context { enum pipe_render_cond_flag cond_mode; bool is_noop; + + /* Mask of active render targets */ + uint8_t fb_rt_mask; }; /* Corresponds to the CSO */