mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 12:10:09 +01:00
etnaviv: blend: Add support for MRTs
Adds also the handling of independent_blend_enable that is supported by HALTI5+ GPUs. Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26565>
This commit is contained in:
parent
ec7a962e3a
commit
07cd0f2306
3 changed files with 112 additions and 63 deletions
|
|
@ -38,9 +38,8 @@ etna_blend_state_create(struct pipe_context *pctx,
|
|||
const struct pipe_blend_state *so)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
const struct pipe_rt_blend_state *rt0 = &so->rt[0];
|
||||
struct etna_blend_state *co = CALLOC_STRUCT(etna_blend_state);
|
||||
bool alpha_enable, logicop_enable;
|
||||
bool logicop_enable;
|
||||
|
||||
/* pipe_blend_func happens to match the hardware. */
|
||||
STATIC_ASSERT(PIPE_BLEND_ADD == BLEND_EQ_ADD);
|
||||
|
|
@ -57,41 +56,38 @@ etna_blend_state_create(struct pipe_context *pctx,
|
|||
logicop_enable = so->logicop_enable &&
|
||||
VIV_FEATURE(ctx->screen, ETNA_FEATURE_LOGIC_OP);
|
||||
|
||||
/* Enable blending if
|
||||
* - blend enabled in blend state
|
||||
* - NOT source factor is ONE and destination factor ZERO and eq is ADD for
|
||||
* both rgb and alpha (which mean that blending is effectively disabled)
|
||||
*/
|
||||
alpha_enable = rt0->blend_enable &&
|
||||
!(rt0->rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
|
||||
rt0->rgb_dst_factor == PIPE_BLENDFACTOR_ZERO &&
|
||||
rt0->rgb_func == PIPE_BLEND_ADD &&
|
||||
rt0->alpha_src_factor == PIPE_BLENDFACTOR_ONE &&
|
||||
rt0->alpha_dst_factor == PIPE_BLENDFACTOR_ZERO &&
|
||||
rt0->alpha_func == PIPE_BLEND_ADD);
|
||||
for (unsigned int i = 0; i < so->max_rt + 1; i++) {
|
||||
const struct pipe_rt_blend_state *rt;
|
||||
|
||||
/* Enable separate alpha if
|
||||
* - Blending enabled (see above)
|
||||
* - NOT source/destination factor and eq is same for both rgb and alpha
|
||||
* (which would effectively that mean alpha is not separate), and
|
||||
*/
|
||||
bool separate_alpha = alpha_enable &&
|
||||
!(rt0->rgb_src_factor == rt0->alpha_src_factor &&
|
||||
rt0->rgb_dst_factor == rt0->alpha_dst_factor &&
|
||||
rt0->rgb_func == rt0->alpha_func);
|
||||
if (so->independent_blend_enable)
|
||||
rt = &so->rt[i];
|
||||
else
|
||||
rt = &so->rt[0];
|
||||
|
||||
if (alpha_enable) {
|
||||
co->rt[0].PE_ALPHA_CONFIG =
|
||||
VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_COLOR |
|
||||
COND(separate_alpha, VIVS_PE_ALPHA_CONFIG_BLEND_SEPARATE_ALPHA) |
|
||||
VIVS_PE_ALPHA_CONFIG_SRC_FUNC_COLOR(translate_blend_factor(rt0->rgb_src_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_SRC_FUNC_ALPHA(translate_blend_factor(rt0->alpha_src_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_DST_FUNC_COLOR(translate_blend_factor(rt0->rgb_dst_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_DST_FUNC_ALPHA(translate_blend_factor(rt0->alpha_dst_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_EQ_COLOR(rt0->rgb_func) |
|
||||
VIVS_PE_ALPHA_CONFIG_EQ_ALPHA(rt0->alpha_func);
|
||||
} else {
|
||||
co->rt[0].PE_ALPHA_CONFIG = 0;
|
||||
/* Enable blending if
|
||||
* - blend enabled in blend state
|
||||
* - NOT source factor is ONE and destination factor ZERO and eq is ADD for
|
||||
* both rgb and alpha (which mean that blending is effectively disabled)
|
||||
*/
|
||||
co->rt[i].alpha_enable = rt->blend_enable &&
|
||||
!(rt->rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
|
||||
rt->rgb_dst_factor == PIPE_BLENDFACTOR_ZERO &&
|
||||
rt->rgb_func == PIPE_BLEND_ADD &&
|
||||
rt->alpha_src_factor == PIPE_BLENDFACTOR_ONE &&
|
||||
rt->alpha_dst_factor == PIPE_BLENDFACTOR_ZERO &&
|
||||
rt->alpha_func == PIPE_BLEND_ADD);
|
||||
|
||||
/* Enable separate alpha if
|
||||
* - Blending enabled (see above)
|
||||
* - NOT source/destination factor and eq is same for both rgb and alpha
|
||||
* (which would effectively that mean alpha is not separate), and
|
||||
*/
|
||||
co->rt[i].separate_alpha = co->rt[i].alpha_enable &&
|
||||
!(rt->rgb_src_factor == rt->alpha_src_factor &&
|
||||
rt->rgb_dst_factor == rt->alpha_dst_factor &&
|
||||
rt->rgb_func == rt->alpha_func);
|
||||
|
||||
co->rt[i].fo_allowed = !co->rt[i].alpha_enable && !logicop_enable;
|
||||
}
|
||||
|
||||
co->PE_LOGIC_OP =
|
||||
|
|
@ -99,16 +95,13 @@ etna_blend_state_create(struct pipe_context *pctx,
|
|||
VIVS_PE_LOGIC_OP_DITHER_MODE(3) | /* TODO: related to dithering, sometimes 2 */
|
||||
0x000E4000 /* ??? */;
|
||||
|
||||
co->rt[0].fo_allowed = !alpha_enable && !logicop_enable;
|
||||
|
||||
/* independent_blend_enable not needed: only one rt supported */
|
||||
/* XXX alpha_to_coverage / alpha_to_one? */
|
||||
/* Set dither registers based on dither status. These registers set the
|
||||
* dither pattern,
|
||||
* for now, set the same values as the blob.
|
||||
*/
|
||||
if (so->dither &&
|
||||
(!alpha_enable ||
|
||||
(!co->rt[0].alpha_enable ||
|
||||
VIV_FEATURE(ctx->screen, ETNA_FEATURE_PE_DITHER_FIX))) {
|
||||
co->PE_DITHER[0] = 0x6e4ca280;
|
||||
co->PE_DITHER[1] = 0x5d7f91b3;
|
||||
|
|
@ -126,33 +119,65 @@ etna_update_blend(struct etna_context *ctx)
|
|||
struct pipe_framebuffer_state *pfb = &ctx->framebuffer_s;
|
||||
struct pipe_blend_state *pblend = ctx->blend;
|
||||
struct etna_blend_state *blend = etna_blend_state(pblend);
|
||||
const struct pipe_rt_blend_state *rt0 = &pblend->rt[0];
|
||||
const struct util_format_description *desc;
|
||||
uint32_t colormask;
|
||||
unsigned current_rt = 0;
|
||||
|
||||
if (pfb->cbufs[0] &&
|
||||
translate_pe_format_rb_swap(pfb->cbufs[0]->format)) {
|
||||
colormask = rt0->colormask & (PIPE_MASK_A | PIPE_MASK_G);
|
||||
if (rt0->colormask & PIPE_MASK_R)
|
||||
colormask |= PIPE_MASK_B;
|
||||
if (rt0->colormask & PIPE_MASK_B)
|
||||
colormask |= PIPE_MASK_R;
|
||||
} else {
|
||||
colormask = rt0->colormask;
|
||||
for (unsigned i = 0; i < pfb->nr_cbufs; i++) {
|
||||
if (!pfb->cbufs[i])
|
||||
continue;
|
||||
|
||||
const struct pipe_rt_blend_state *rt;
|
||||
uint32_t colormask;
|
||||
|
||||
if (pblend->independent_blend_enable)
|
||||
rt = &pblend->rt[i];
|
||||
else
|
||||
rt = &pblend->rt[0];
|
||||
|
||||
if (translate_pe_format_rb_swap(pfb->cbufs[i]->format)) {
|
||||
colormask = rt->colormask & (PIPE_MASK_A | PIPE_MASK_G);
|
||||
if (rt->colormask & PIPE_MASK_R)
|
||||
colormask |= PIPE_MASK_B;
|
||||
if (rt->colormask & PIPE_MASK_B)
|
||||
colormask |= PIPE_MASK_R;
|
||||
} else {
|
||||
colormask = rt->colormask;
|
||||
}
|
||||
|
||||
/* If the complete render target is written, set full_overwrite:
|
||||
* - The color mask covers all channels of the render target
|
||||
* - No blending or logicop is used
|
||||
*/
|
||||
const struct util_format_description *desc = util_format_description(pfb->cbufs[i]->format);
|
||||
bool full_overwrite = (blend->rt[i].fo_allowed &&
|
||||
util_format_colormask_full(desc, colormask));
|
||||
|
||||
if (current_rt == 0) {
|
||||
blend->rt[0].PE_COLOR_FORMAT =
|
||||
VIVS_PE_COLOR_FORMAT_COMPONENTS(colormask) |
|
||||
COND(full_overwrite, VIVS_PE_COLOR_FORMAT_OVERWRITE);
|
||||
} else {
|
||||
blend->rt[current_rt].PE_HALTI5_COLORMASK =
|
||||
VIVS_PE_HALTI5_RT_COLORMASK_COMPONENTS(colormask) |
|
||||
COND(full_overwrite, VIVS_PE_HALTI5_RT_COLORMASK_OVERWRITE);
|
||||
}
|
||||
|
||||
if (blend->rt[i].alpha_enable) {
|
||||
blend->rt[current_rt].PE_ALPHA_CONFIG =
|
||||
VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_COLOR |
|
||||
COND(blend->rt[i].separate_alpha, VIVS_PE_ALPHA_CONFIG_BLEND_SEPARATE_ALPHA) |
|
||||
VIVS_PE_ALPHA_CONFIG_SRC_FUNC_COLOR(translate_blend_factor(rt->rgb_src_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_SRC_FUNC_ALPHA(translate_blend_factor(rt->alpha_src_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_DST_FUNC_COLOR(translate_blend_factor(rt->rgb_dst_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_DST_FUNC_ALPHA(translate_blend_factor(rt->alpha_dst_factor)) |
|
||||
VIVS_PE_ALPHA_CONFIG_EQ_COLOR(rt->rgb_func) |
|
||||
VIVS_PE_ALPHA_CONFIG_EQ_ALPHA(rt->alpha_func);
|
||||
} else {
|
||||
blend->rt[current_rt].PE_ALPHA_CONFIG = 0;
|
||||
}
|
||||
|
||||
current_rt++;
|
||||
}
|
||||
|
||||
/* If the complete render target is written, set full_overwrite:
|
||||
* - The color mask covers all channels of the render target
|
||||
* - No blending or logicop is used
|
||||
*/
|
||||
if (pfb->cbufs[0])
|
||||
desc = util_format_description(pfb->cbufs[0]->format);
|
||||
bool full_overwrite = !pfb->cbufs[0] || ((blend->rt[0].fo_allowed &&
|
||||
util_format_colormask_full(desc, colormask)));
|
||||
blend->rt[0].PE_COLOR_FORMAT =
|
||||
VIVS_PE_COLOR_FORMAT_COMPONENTS(colormask) |
|
||||
COND(full_overwrite, VIVS_PE_COLOR_FORMAT_OVERWRITE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ struct etna_context;
|
|||
struct etna_rt_blend_state {
|
||||
uint32_t PE_ALPHA_CONFIG;
|
||||
uint32_t PE_COLOR_FORMAT;
|
||||
uint32_t PE_HALTI5_COLORMASK;
|
||||
bool alpha_enable : 1;
|
||||
bool separate_alpha : 1;
|
||||
bool fo_allowed : 1;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -151,6 +151,27 @@ emit_halti5_only_state(struct etna_context *ctx, int vs_output_count)
|
|||
/*01084*/ EMIT_STATE(PS_VARYING_NUM_COMPONENTS(1), ctx->shader_state.GL_VARYING_NUM_COMPONENTS[1]);
|
||||
/*03888*/ EMIT_STATE(GL_HALTI5_SH_SPECIALS, ctx->shader_state.GL_HALTI5_SH_SPECIALS);
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_BLEND))) {
|
||||
for (int i = 1; i < ctx->framebuffer.num_rt; i++) {
|
||||
const uint8_t rt = i - 1;
|
||||
/*14920*/ EMIT_STATE(PE_HALTI5_RT_COLORMASK(rt), etna_blend_state(ctx->blend)->rt[i].PE_HALTI5_COLORMASK);
|
||||
}
|
||||
for (int i = 1; i < ctx->framebuffer.num_rt; i++) {
|
||||
const uint8_t rt = i - 1;
|
||||
/*14960*/ EMIT_STATE(PE_HALTI5_RT_ALPHA_CONFIG(rt), etna_blend_state(ctx->blend)->rt[i].PE_ALPHA_CONFIG);
|
||||
}
|
||||
}
|
||||
if (unlikely(dirty & (ETNA_DIRTY_BLEND_COLOR))) {
|
||||
for (int i = 1; i < ctx->framebuffer.num_rt; i++) {
|
||||
const uint8_t rt = i - 1;
|
||||
/*14980*/ EMIT_STATE(PE_HALTI5_RT_ALPHA_COLOR_EXT0(rt), ctx->blend_color.rt[i].PE_ALPHA_COLOR_EXT0);
|
||||
}
|
||||
for (int i = 1; i < ctx->framebuffer.num_rt; i++) {
|
||||
const uint8_t rt = i - 1;
|
||||
/*149A0*/ EMIT_STATE(PE_HALTI5_RT_ALPHA_COLOR_EXT1(rt), ctx->blend_color.rt[i].PE_ALPHA_COLOR_EXT1);
|
||||
}
|
||||
}
|
||||
|
||||
etna_coalesce_end(stream, &coalesce);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue