#include "etnaviv_blend.h"
#include "etnaviv_context.h"
+#include "etnaviv_screen.h"
#include "etnaviv_translate.h"
+#include "hw/common.xml.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
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;
if (!co)
return NULL;
* - NOT source factor is ONE and destination factor ZERO for both rgb and
* alpha (which would mean that blending is effectively disabled)
*/
- co->enable = rt0->blend_enable &&
+ alpha_enable = rt0->blend_enable &&
!(rt0->rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
rt0->rgb_dst_factor == PIPE_BLENDFACTOR_ZERO &&
rt0->alpha_src_factor == PIPE_BLENDFACTOR_ONE &&
* - NOT source factor is equal to destination factor for both rgb abd
* alpha (which would effectively that mean alpha is not separate)
*/
- bool separate_alpha = co->enable &&
+ bool separate_alpha = alpha_enable &&
!(rt0->rgb_src_factor == rt0->alpha_src_factor &&
rt0->rgb_dst_factor == rt0->alpha_dst_factor);
- if (co->enable) {
+ if (alpha_enable) {
co->PE_ALPHA_CONFIG =
VIVS_PE_ALPHA_CONFIG_BLEND_ENABLE_COLOR |
COND(separate_alpha, VIVS_PE_ALPHA_CONFIG_BLEND_SEPARATE_ALPHA) |
co->PE_ALPHA_CONFIG = 0;
}
+ logicop_enable = so->logicop_enable &&
+ VIV_FEATURE(ctx->screen, chipMinorFeatures2, LOGIC_OP);
+
co->PE_LOGIC_OP =
- VIVS_PE_LOGIC_OP_OP(so->logicop_enable ? so->logicop_func : LOGIC_OP_COPY) |
+ VIVS_PE_LOGIC_OP_OP(logicop_enable ? so->logicop_func : LOGIC_OP_COPY) |
0x000E4000 /* ??? */;
+ co->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
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;
if (pfb->cbufs[0] &&
- translate_rs_format_rb_swap(pfb->cbufs[0]->texture->format)) {
+ translate_rs_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 the complete render target is written, set full_overwrite:
- * - The color mask is 1111
- * - No blending is used
+ * - The color mask covers all channels of the render target
+ * - No blending or logicop is used
*/
- bool full_overwrite = (rt0->colormask == 0xf) && !blend->enable;
+ if (pfb->cbufs[0])
+ desc = util_format_description(pfb->cbufs[0]->format);
+ bool full_overwrite = !pfb->cbufs[0] || ((blend->fo_allowed &&
+ util_format_colormask_full(desc, colormask)));
blend->PE_COLOR_FORMAT =
VIVS_PE_COLOR_FORMAT_COMPONENTS(colormask) |
COND(full_overwrite, VIVS_PE_COLOR_FORMAT_OVERWRITE);
return true;
}
+
+void
+etna_set_blend_color(struct pipe_context *pctx, const struct pipe_blend_color *bc)
+{
+ struct etna_context *ctx = etna_context(pctx);
+ struct compiled_blend_color *cs = &ctx->blend_color;
+
+ memcpy(cs->color, bc->color, sizeof(float) * 4);
+
+ ctx->dirty |= ETNA_DIRTY_BLEND_COLOR;
+}
+
+bool
+etna_update_blend_color(struct etna_context *ctx)
+{
+ struct pipe_framebuffer_state *pfb = &ctx->framebuffer_s;
+ struct compiled_blend_color *cs = &ctx->blend_color;
+
+ if (pfb->cbufs[0] &&
+ translate_rs_format_rb_swap(pfb->cbufs[0]->format)) {
+ cs->PE_ALPHA_BLEND_COLOR =
+ VIVS_PE_ALPHA_BLEND_COLOR_R(etna_cfloat_to_uint8(cs->color[2])) |
+ VIVS_PE_ALPHA_BLEND_COLOR_G(etna_cfloat_to_uint8(cs->color[1])) |
+ VIVS_PE_ALPHA_BLEND_COLOR_B(etna_cfloat_to_uint8(cs->color[0])) |
+ VIVS_PE_ALPHA_BLEND_COLOR_A(etna_cfloat_to_uint8(cs->color[3]));
+ } else {
+ cs->PE_ALPHA_BLEND_COLOR =
+ VIVS_PE_ALPHA_BLEND_COLOR_R(etna_cfloat_to_uint8(cs->color[0])) |
+ VIVS_PE_ALPHA_BLEND_COLOR_G(etna_cfloat_to_uint8(cs->color[1])) |
+ VIVS_PE_ALPHA_BLEND_COLOR_B(etna_cfloat_to_uint8(cs->color[2])) |
+ VIVS_PE_ALPHA_BLEND_COLOR_A(etna_cfloat_to_uint8(cs->color[3]));
+ }
+
+ return true;
+}