v3d: fix blending for mixed RT formats

Blending configuration needs to be adapted in case the RT format does
not have an alpha channel. This is handled so far correctly.

But when we have two RT, one with alpha and other without it, we need
to split the blend configuration, so one is adapted and the other not.

Otherwise we would be changing the blend config for the wrong RT.

Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16747>
This commit is contained in:
Juan A. Suarez Romero
2022-05-27 13:12:11 +02:00
committed by Marge Bot
parent 836ce97f5e
commit 4357dff4e9
2 changed files with 32 additions and 12 deletions

View File

@@ -198,7 +198,6 @@ spec@ext_framebuffer_blit@fbo-blit-check-limits,Fail
spec@ext_framebuffer_multisample@blit-mismatched-formats,Fail
spec@ext_framebuffer_multisample@interpolation 2 centroid-edges,Fail
spec@ext_framebuffer_multisample@interpolation 4 centroid-edges,Fail
spec@ext_framebuffer_object@fbo-blending-format-quirks,Fail
spec@ext_framebuffer_object@getteximage-formats init-by-clear-and-render,Fail
spec@ext_framebuffer_object@getteximage-formats init-by-rendering,Fail
spec@ext_gpu_shader4@execution@texelfetch@fs-texelfetch-isampler1darray,Fail

View File

@@ -277,7 +277,8 @@ translate_colormask(struct v3d_context *v3d, uint32_t colormask, int rt)
static void
emit_rt_blend(struct v3d_context *v3d, struct v3d_job *job,
struct pipe_blend_state *blend, int rt)
struct pipe_blend_state *blend, int rt, uint8_t rt_mask,
bool blend_dst_alpha_one)
{
struct pipe_rt_blend_state *rtblend = &blend->rt[rt];
@@ -289,10 +290,7 @@ emit_rt_blend(struct v3d_context *v3d, struct v3d_job *job,
cl_emit(&job->bcl, BLEND_CFG, config) {
#if V3D_VERSION >= 40
if (blend->independent_blend_enable)
config.render_target_mask = 1 << rt;
else
config.render_target_mask = (1 << V3D_MAX_DRAW_BUFFERS) - 1;
config.render_target_mask = rt_mask;
#else
assert(rt == 0);
#endif
@@ -300,18 +298,18 @@ emit_rt_blend(struct v3d_context *v3d, struct v3d_job *job,
config.color_blend_mode = rtblend->rgb_func;
config.color_blend_dst_factor =
v3d_factor(rtblend->rgb_dst_factor,
v3d->blend_dst_alpha_one);
blend_dst_alpha_one);
config.color_blend_src_factor =
v3d_factor(rtblend->rgb_src_factor,
v3d->blend_dst_alpha_one);
blend_dst_alpha_one);
config.alpha_blend_mode = rtblend->alpha_func;
config.alpha_blend_dst_factor =
v3d_factor(rtblend->alpha_dst_factor,
v3d->blend_dst_alpha_one);
blend_dst_alpha_one);
config.alpha_blend_src_factor =
v3d_factor(rtblend->alpha_src_factor,
v3d->blend_dst_alpha_one);
blend_dst_alpha_one);
}
}
@@ -627,9 +625,32 @@ v3dX(emit_state)(struct pipe_context *pctx)
if (blend->base.independent_blend_enable) {
for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++)
emit_rt_blend(v3d, job, &blend->base, i);
emit_rt_blend(v3d, job, &blend->base, i,
(1 << i),
v3d->blend_dst_alpha_one & (1 << i));
} else if (v3d->blend_dst_alpha_one &&
util_bitcount(v3d->blend_dst_alpha_one) < job->nr_cbufs) {
/* Even if we don't have independent per-RT
* blending, we may have a combination of RT
* formats were some RTs have an alpha channel
* and others don't. Since this affects how
* blending is performed, we also need to emit
* independent blend configurations in this
* case: one for RTs with alpha and one for
* RTs without.
*/
emit_rt_blend(v3d, job, &blend->base, 0,
((1 << V3D_MAX_DRAW_BUFFERS) - 1) &
v3d->blend_dst_alpha_one,
true);
emit_rt_blend(v3d, job, &blend->base, 0,
((1 << V3D_MAX_DRAW_BUFFERS) - 1) &
~v3d->blend_dst_alpha_one,
false);
} else {
emit_rt_blend(v3d, job, &blend->base, 0);
emit_rt_blend(v3d, job, &blend->base, 0,
(1 << V3D_MAX_DRAW_BUFFERS) - 1,
v3d->blend_dst_alpha_one);
}
}
}