panfrost: Move blend properties to CSO create

Fixes: 93824b6451 ("panfrost: Move the blend logic out of the gallium driver")
Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10869>
This commit is contained in:
Alyssa Rosenzweig 2021-05-14 12:55:49 -04:00 committed by Marge Bot
parent d7590efd25
commit 3943adbd91
3 changed files with 90 additions and 61 deletions

View file

@ -66,6 +66,7 @@ panfrost_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
struct panfrost_context *ctx = pan_context(pipe);
struct panfrost_device *dev = pan_device(pipe->screen);
struct panfrost_blend_state *so = rzalloc(ctx, struct panfrost_blend_state);
so->base = *blend;
@ -76,24 +77,44 @@ panfrost_create_blend_state(struct pipe_context *pipe,
for (unsigned c = 0; c < so->pan.rt_count; ++c) {
unsigned g = blend->independent_blend_enable ? c : 0;
const struct pipe_rt_blend_state *pipe = &blend->rt[g];
struct pan_blend_equation *equation = &so->pan.rts[c].equation;
const struct pipe_rt_blend_state pipe = blend->rt[g];
struct pan_blend_equation equation;
equation->color_mask = pipe->colormask;
equation->blend_enable = pipe->blend_enable;
if (!equation->blend_enable)
continue;
equation.color_mask = pipe.colormask;
equation.blend_enable = pipe.blend_enable;
equation->rgb_func = util_blend_func_to_shader(pipe->rgb_func);
equation->rgb_src_factor = util_blend_factor_to_shader(pipe->rgb_src_factor);
equation->rgb_invert_src_factor = util_blend_factor_is_inverted(pipe->rgb_src_factor);
equation->rgb_dst_factor = util_blend_factor_to_shader(pipe->rgb_dst_factor);
equation->rgb_invert_dst_factor = util_blend_factor_is_inverted(pipe->rgb_dst_factor);
equation->alpha_func = util_blend_func_to_shader(pipe->alpha_func);
equation->alpha_src_factor = util_blend_factor_to_shader(pipe->alpha_src_factor);
equation->alpha_invert_src_factor = util_blend_factor_is_inverted(pipe->alpha_src_factor);
equation->alpha_dst_factor = util_blend_factor_to_shader(pipe->alpha_dst_factor);
equation->alpha_invert_dst_factor = util_blend_factor_is_inverted(pipe->alpha_dst_factor);
if (pipe.blend_enable) {
equation.rgb_func = util_blend_func_to_shader(pipe.rgb_func);
equation.rgb_src_factor = util_blend_factor_to_shader(pipe.rgb_src_factor);
equation.rgb_invert_src_factor = util_blend_factor_is_inverted(pipe.rgb_src_factor);
equation.rgb_dst_factor = util_blend_factor_to_shader(pipe.rgb_dst_factor);
equation.rgb_invert_dst_factor = util_blend_factor_is_inverted(pipe.rgb_dst_factor);
equation.alpha_func = util_blend_func_to_shader(pipe.alpha_func);
equation.alpha_src_factor = util_blend_factor_to_shader(pipe.alpha_src_factor);
equation.alpha_invert_src_factor = util_blend_factor_is_inverted(pipe.alpha_src_factor);
equation.alpha_dst_factor = util_blend_factor_to_shader(pipe.alpha_dst_factor);
equation.alpha_invert_dst_factor = util_blend_factor_is_inverted(pipe.alpha_dst_factor);
}
/* Determine some common properties */
unsigned constant_mask = pan_blend_constant_mask(equation);
so->info[c] = (struct pan_blend_info) {
.no_colour = (equation.color_mask == 0),
.opaque = pan_blend_is_opaque(equation),
.constant_mask = constant_mask,
/* TODO: check the dest for the logicop */
.load_dest = blend->logicop_enable ||
pan_blend_reads_dest(equation),
/* Could this possibly be fixed-function? */
.fixed_function = !blend->logicop_enable &&
pan_blend_can_fixed_function(equation) &&
(!constant_mask ||
pan_blend_supports_constant(dev->arch, c))
};
so->pan.rts[c].equation = equation;
}
return so;
@ -145,20 +166,20 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti, struc
/* First, we'll try fixed function, matching equation and constant */
const struct pan_blend_equation eq = pan_blend.rts[rti].equation;
unsigned constant_mask = pan_blend_constant_mask(eq);
bool ff = blend->info[rti].fixed_function;
bool ff = pan_blend_can_fixed_function(eq);
ff &= pan_blend_is_homogenous_constant(constant_mask, ctx->blend_color.color);
ff &= (pan_blend_supports_constant(dev->arch, rti) || !constant_mask);
ff &= !pan_blend.logicop_enable;
/* Not all formats are blendable, check if this one is */
ff &= panfrost_blendable_formats[fmt].internal;
/* There are hazards around constants, check that */
ff &= pan_blend_is_homogenous_constant(blend->info[rti].constant_mask,
ctx->blend_color.color);
if (ff) {
struct panfrost_blend_final final = {
.load_dest = pan_blend_reads_dest(pan_blend.rts[rti].equation),
.equation.constant = pan_blend_get_constant(constant_mask, ctx->blend_color.color),
.opaque = pan_blend_is_opaque(pan_blend.rts[rti].equation),
.no_colour = pan_blend.rts[rti].equation.color_mask == 0,
.equation.constant = pan_blend_get_constant(
blend->info[rti].constant_mask,
ctx->blend_color.color),
};
pan_blend_to_fixed_function_equation(eq, &final.equation.equation);
@ -204,8 +225,6 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti, struc
.first_tag = shader->first_tag,
.gpu = (*bo)->ptr.gpu + *shader_offset,
},
.load_dest = pan_blend.logicop_enable ||
pan_blend_reads_dest(pan_blend.rts[rti].equation),
};
*shader_offset += shader->binary.size;

View file

@ -69,9 +69,18 @@ struct panfrost_blend_equation_final {
float constant;
};
struct pan_blend_info {
unsigned constant_mask : 4;
bool fixed_function : 1;
bool no_colour : 1;
bool load_dest : 1;
bool opaque : 1;
};
struct panfrost_blend_state {
struct pipe_blend_state base;
struct pan_blend_state pan;
struct pan_blend_info info[PIPE_MAX_COLOR_BUFS];
};
/* Container for a final blend state, specialized to constants and a
@ -81,15 +90,6 @@ struct panfrost_blend_final {
/* Set for a shader, clear for an equation */
bool is_shader;
/* 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;
union {
struct panfrost_blend_shader_final shader;
struct panfrost_blend_equation_final equation;

View file

@ -260,7 +260,7 @@ void panfrost_sampler_desc_init_bifrost(const struct pipe_sampler_state *cso,
static bool
panfrost_fs_required(
struct panfrost_shader_state *fs,
struct panfrost_blend_final *blend,
struct panfrost_blend_state *blend,
struct pipe_framebuffer_state *state)
{
/* If we generally have side effects */
@ -269,7 +269,7 @@ panfrost_fs_required(
/* If colour is written we need to execute */
for (unsigned i = 0; i < state->nr_cbufs; ++i) {
if (!blend[i].no_colour && state->cbufs[i])
if (state->cbufs[i] && !blend->info[i].no_colour)
return true;
}
@ -308,8 +308,10 @@ panfrost_emit_bifrost_blend(struct panfrost_batch *batch,
void *rts)
{
unsigned rt_count = batch->key.nr_cbufs;
const struct panfrost_device *dev = pan_device(batch->ctx->base.screen);
struct panfrost_shader_state *fs = panfrost_get_shader_state(batch->ctx, PIPE_SHADER_FRAGMENT);
struct panfrost_context *ctx = batch->ctx;
const struct panfrost_blend_state *so = ctx->blend;
const struct panfrost_device *dev = pan_device(ctx->base.screen);
struct panfrost_shader_state *fs = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
/* Always have at least one render target for depth-only passes */
for (unsigned i = 0; i < MAX2(rt_count, 1); ++i) {
@ -324,14 +326,16 @@ panfrost_emit_bifrost_blend(struct panfrost_batch *batch,
}
pan_pack(rts + i * MALI_BLEND_LENGTH, BLEND, cfg) {
if (blend[i].no_colour) {
struct pan_blend_info info = so->info[i];
if (info.no_colour) {
cfg.enable = false;
} else {
cfg.srgb = util_format_is_srgb(batch->key.cbufs[i]->format);
cfg.load_destination = blend[i].load_dest;
cfg.load_destination = info.load_dest;
cfg.round_to_fb_precision = !batch->ctx->blend->base.dither;
cfg.alpha_to_one = batch->ctx->blend->base.alpha_to_one;
cfg.round_to_fb_precision = !ctx->blend->base.dither;
cfg.alpha_to_one = ctx->blend->base.alpha_to_one;
}
if (blend[i].is_shader) {
@ -367,10 +371,9 @@ panfrost_emit_bifrost_blend(struct panfrost_batch *batch,
constant <<= 16 - chan_size;
cfg.bifrost.constant = constant;
if (blend[i].opaque)
cfg.bifrost.internal.mode = MALI_BIFROST_BLEND_MODE_OPAQUE;
else
cfg.bifrost.internal.mode = MALI_BIFROST_BLEND_MODE_FIXED_FUNCTION;
cfg.bifrost.internal.mode = info.opaque ?
MALI_BIFROST_BLEND_MODE_OPAQUE :
MALI_BIFROST_BLEND_MODE_FIXED_FUNCTION;
/* If we want the conversion to work properly,
* num_comps must be set to 4
@ -392,6 +395,8 @@ panfrost_emit_midgard_blend(struct panfrost_batch *batch,
void *rts)
{
unsigned rt_count = batch->key.nr_cbufs;
struct panfrost_context *ctx = batch->ctx;
const struct panfrost_blend_state *so = ctx->blend;
/* Always have at least one render target for depth-only passes */
for (unsigned i = 0; i < MAX2(rt_count, 1); ++i) {
@ -411,15 +416,17 @@ panfrost_emit_midgard_blend(struct panfrost_batch *batch,
}
pan_pack(rts + i * MALI_BLEND_LENGTH, BLEND, cfg) {
if (blend[i].no_colour) {
struct pan_blend_info info = so->info[i];
if (info.no_colour) {
cfg.enable = false;
continue;
}
cfg.srgb = util_format_is_srgb(batch->key.cbufs[i]->format);
cfg.load_destination = blend[i].load_dest;
cfg.round_to_fb_precision = !batch->ctx->blend->base.dither;
cfg.alpha_to_one = batch->ctx->blend->base.alpha_to_one;
cfg.load_destination = info.load_dest;
cfg.round_to_fb_precision = !ctx->blend->base.dither;
cfg.alpha_to_one = ctx->blend->base.alpha_to_one;
cfg.midgard.blend_shader = blend[i].is_shader;
if (blend[i].is_shader) {
cfg.midgard.shader_pc = blend[i].shader.gpu | blend[i].shader.first_tag;
@ -436,6 +443,7 @@ panfrost_emit_blend(struct panfrost_batch *batch, void *rts,
struct panfrost_blend_final *blend)
{
const struct panfrost_device *dev = pan_device(batch->ctx->base.screen);
struct panfrost_blend_state *so = batch->ctx->blend;
if (pan_is_bifrost(dev))
panfrost_emit_bifrost_blend(batch, blend, rts);
@ -443,7 +451,7 @@ panfrost_emit_blend(struct panfrost_batch *batch, void *rts,
panfrost_emit_midgard_blend(batch, blend, rts);
for (unsigned i = 0; i < batch->key.nr_cbufs; ++i) {
if (!blend[i].no_colour && batch->key.cbufs[i]) {
if (!so->info[i].no_colour && batch->key.cbufs[i]) {
batch->draws |= (PIPE_CLEAR_COLOR0 << i);
batch->resolve |= (PIPE_CLEAR_COLOR0 << i);
}
@ -457,9 +465,10 @@ panfrost_prepare_bifrost_fs_state(struct panfrost_context *ctx,
{
const struct panfrost_device *dev = pan_device(ctx->base.screen);
struct panfrost_shader_state *fs = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
bool alpha_to_coverage = ctx->blend->base.alpha_to_coverage;
struct panfrost_blend_state *so = ctx->blend;
bool alpha_to_coverage = so->base.alpha_to_coverage;
if (!panfrost_fs_required(fs, blend, &ctx->pipe_framebuffer)) {
if (!panfrost_fs_required(fs, so, &ctx->pipe_framebuffer)) {
state->properties.bifrost.shader_modifies_coverage = true;
state->properties.bifrost.allow_forward_pixel_to_kill = true;
state->properties.bifrost.allow_forward_pixel_to_be_killed = true;
@ -475,7 +484,7 @@ panfrost_prepare_bifrost_fs_state(struct panfrost_context *ctx,
for (unsigned i = 0; i < ctx->pipe_framebuffer.nr_cbufs; ++i) {
if (ctx->pipe_framebuffer.cbufs[i]) {
rt_mask |= (1 << i);
blend_reads_dest |= blend[i].load_dest;
blend_reads_dest |= so->info[i].load_dest;
}
}
@ -505,7 +514,7 @@ panfrost_prepare_midgard_fs_state(struct panfrost_context *ctx,
unsigned rt_count = ctx->pipe_framebuffer.nr_cbufs;
bool alpha_to_coverage = ctx->blend->base.alpha_to_coverage;
if (!panfrost_fs_required(fs, blend, &ctx->pipe_framebuffer)) {
if (!panfrost_fs_required(fs, ctx->blend, &ctx->pipe_framebuffer)) {
state->shader.shader = 0x1;
state->properties.midgard.work_register_count = 1;
state->properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
@ -548,12 +557,13 @@ panfrost_prepare_midgard_fs_state(struct panfrost_context *ctx,
}
if (dev->quirks & MIDGARD_SFBD && ctx->pipe_framebuffer.nr_cbufs > 0) {
state->multisample_misc.sfbd_load_destination = blend[0].load_dest;
struct panfrost_blend_state *so = ctx->blend;
state->multisample_misc.sfbd_load_destination = so->info[0].load_dest;
state->multisample_misc.sfbd_blend_shader = blend[0].is_shader;
state->stencil_mask_misc.sfbd_write_enable = !blend[0].no_colour;
state->stencil_mask_misc.sfbd_write_enable = !so->info[0].no_colour;
state->stencil_mask_misc.sfbd_srgb = util_format_is_srgb(ctx->pipe_framebuffer.cbufs[0]->format);
state->stencil_mask_misc.sfbd_dither_disable = !ctx->blend->base.dither;
state->stencil_mask_misc.sfbd_alpha_to_one = ctx->blend->base.alpha_to_one;
state->stencil_mask_misc.sfbd_dither_disable = !so->base.dither;
state->stencil_mask_misc.sfbd_alpha_to_one = so->base.alpha_to_one;
if (blend[0].is_shader) {
state->sfbd_blend_shader = blend[0].shader.gpu |