xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/freedreno/a5xx/fd5_blend.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2016 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_memory.h"
12 #include "util/u_string.h"
13 
14 #include "fd5_blend.h"
15 #include "fd5_context.h"
16 #include "fd5_format.h"
17 
18 // XXX move somewhere common.. same across a3xx/a4xx/a5xx..
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 *
fd5_blend_state_create(struct pipe_context * pctx,const struct pipe_blend_state * cso)40 fd5_blend_state_create(struct pipe_context *pctx,
41                        const struct pipe_blend_state *cso)
42 {
43    struct fd5_blend_stateobj *so;
44    enum a3xx_rop_code rop = ROP_COPY;
45    bool reads_dest = false;
46    unsigned i, mrt_blend = 0;
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(fd5_blend_stateobj);
54    if (!so)
55       return NULL;
56 
57    so->base = *cso;
58 
59    so->lrz_write = true; /* unless blend enabled for any MRT */
60 
61    for (i = 0; i < ARRAY_SIZE(so->rb_mrt); i++) {
62       const struct pipe_rt_blend_state *rt;
63 
64       if (cso->independent_blend_enable)
65          rt = &cso->rt[i];
66       else
67          rt = &cso->rt[0];
68 
69       so->rb_mrt[i].blend_control =
70          A5XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(
71             fd_blend_factor(rt->rgb_src_factor)) |
72          A5XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
73          A5XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(
74             fd_blend_factor(rt->rgb_dst_factor)) |
75          A5XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(
76             fd_blend_factor(rt->alpha_src_factor)) |
77          A5XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(
78             blend_func(rt->alpha_func)) |
79          A5XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(
80             fd_blend_factor(rt->alpha_dst_factor));
81 
82       so->rb_mrt[i].control =
83          A5XX_RB_MRT_CONTROL_ROP_CODE(rop) |
84          COND(cso->logicop_enable, A5XX_RB_MRT_CONTROL_ROP_ENABLE) |
85          A5XX_RB_MRT_CONTROL_COMPONENT_ENABLE(rt->colormask);
86 
87       if (rt->blend_enable) {
88          so->rb_mrt[i].control |=
89 //               A5XX_RB_MRT_CONTROL_READ_DEST_ENABLE |
90                A5XX_RB_MRT_CONTROL_BLEND | A5XX_RB_MRT_CONTROL_BLEND2;
91          mrt_blend |= (1 << i);
92          so->lrz_write = false;
93       }
94 
95       if (reads_dest) {
96 //         so->rb_mrt[i].control |=
97 //               A5XX_RB_MRT_CONTROL_READ_DEST_ENABLE;
98          mrt_blend |= (1 << i);
99       }
100 
101 //      if (cso->dither)
102 //         so->rb_mrt[i].buf_info |=
103 //               A5XX_RB_MRT_BUF_INFO_DITHER_MODE(DITHER_ALWAYS);
104    }
105 
106    so->rb_blend_cntl =
107       A5XX_RB_BLEND_CNTL_ENABLE_BLEND(mrt_blend) |
108       COND(cso->alpha_to_coverage, A5XX_RB_BLEND_CNTL_ALPHA_TO_COVERAGE) |
109       COND(cso->independent_blend_enable, A5XX_RB_BLEND_CNTL_INDEPENDENT_BLEND);
110    so->sp_blend_cntl =
111       A5XX_SP_BLEND_CNTL_ENABLE_BLEND(mrt_blend) |
112       A5XX_SP_BLEND_CNTL_UNK8 |
113       COND(cso->alpha_to_coverage, A5XX_SP_BLEND_CNTL_ALPHA_TO_COVERAGE);
114 
115    return so;
116 }
117