mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
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:
parent
d7590efd25
commit
3943adbd91
3 changed files with 90 additions and 61 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue