xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/freedreno/a3xx/fd3_blend.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2013 Rob Clark <[email protected]>
3  * SPDX-License-Identifier: MIT
4  *
5  * Authors:
6  *    Rob Clark <[email protected]>
7  */
8 
9 #include "pipe/p_state.h"
10 #include "util/u_blend.h"
11 #include "util/u_dual_blend.h"
12 #include "util/u_memory.h"
13 #include "util/u_string.h"
14 
15 #include "fd3_blend.h"
16 #include "fd3_context.h"
17 #include "fd3_format.h"
18 
19 static enum a3xx_rb_blend_opcode
blend_func(unsigned func)20 blend_func(unsigned func)
21 {
22    switch (func) {
23    case PIPE_BLEND_ADD:
24       return BLEND_DST_PLUS_SRC;
25    case PIPE_BLEND_MIN:
26       return BLEND_MIN_DST_SRC;
27    case PIPE_BLEND_MAX:
28       return BLEND_MAX_DST_SRC;
29    case PIPE_BLEND_SUBTRACT:
30       return BLEND_SRC_MINUS_DST;
31    case PIPE_BLEND_REVERSE_SUBTRACT:
32       return BLEND_DST_MINUS_SRC;
33    default:
34       DBG("invalid blend func: %x", func);
35       return 0;
36    }
37 }
38 
39 void *
fd3_blend_state_create(struct pipe_context * pctx,const struct pipe_blend_state * cso)40 fd3_blend_state_create(struct pipe_context *pctx,
41                        const struct pipe_blend_state *cso)
42 {
43    struct fd3_blend_stateobj *so;
44    enum a3xx_rop_code rop = ROP_COPY;
45    bool reads_dest = false;
46    int i;
47 
48    if (cso->logicop_enable) {
49       rop = cso->logicop_func; /* maps 1:1 */
50       reads_dest = util_logicop_reads_dest(cso->logicop_func);
51    }
52 
53    so = CALLOC_STRUCT(fd3_blend_stateobj);
54    if (!so)
55       return NULL;
56 
57    so->base = *cso;
58 
59    for (i = 0; i < ARRAY_SIZE(so->rb_mrt); i++) {
60       const struct pipe_rt_blend_state *rt;
61       if (cso->independent_blend_enable)
62          rt = &cso->rt[i];
63       else
64          rt = &cso->rt[0];
65 
66       so->rb_mrt[i].blend_control =
67          A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(
68             fd_blend_factor(rt->rgb_src_factor)) |
69          A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
70          A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(
71             fd_blend_factor(rt->rgb_dst_factor)) |
72          A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(
73             fd_blend_factor(rt->alpha_src_factor)) |
74          A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(
75             blend_func(rt->alpha_func)) |
76          A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(
77             fd_blend_factor(rt->alpha_dst_factor));
78 
79       so->rb_mrt[i].control =
80          A3XX_RB_MRT_CONTROL_ROP_CODE(rop) |
81          A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(rt->colormask);
82 
83       if (rt->blend_enable)
84          so->rb_mrt[i].control |= A3XX_RB_MRT_CONTROL_READ_DEST_ENABLE |
85                                   A3XX_RB_MRT_CONTROL_BLEND |
86                                   A3XX_RB_MRT_CONTROL_BLEND2;
87 
88       if (reads_dest)
89          so->rb_mrt[i].control |= A3XX_RB_MRT_CONTROL_READ_DEST_ENABLE;
90 
91       if (cso->dither)
92          so->rb_mrt[i].control |=
93             A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_ALWAYS);
94    }
95 
96    if (cso->rt[0].blend_enable && util_blend_state_is_dual(cso, 0))
97       so->rb_render_control = A3XX_RB_RENDER_CONTROL_DUAL_COLOR_IN_ENABLE;
98 
99    return so;
100 }
101