2 * Copyright 2012 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * Christian König <christian.koenig@amd.com>
27 #include "util/u_memory.h"
28 #include "radeonsi_pipe.h"
36 static uint32_t si_translate_blend_function(int blend_func
)
40 return V_028780_COMB_DST_PLUS_SRC
;
41 case PIPE_BLEND_SUBTRACT
:
42 return V_028780_COMB_SRC_MINUS_DST
;
43 case PIPE_BLEND_REVERSE_SUBTRACT
:
44 return V_028780_COMB_DST_MINUS_SRC
;
46 return V_028780_COMB_MIN_DST_SRC
;
48 return V_028780_COMB_MAX_DST_SRC
;
50 R600_ERR("Unknown blend function %d\n", blend_func
);
57 static uint32_t si_translate_blend_factor(int blend_fact
)
60 case PIPE_BLENDFACTOR_ONE
:
61 return V_028780_BLEND_ONE
;
62 case PIPE_BLENDFACTOR_SRC_COLOR
:
63 return V_028780_BLEND_SRC_COLOR
;
64 case PIPE_BLENDFACTOR_SRC_ALPHA
:
65 return V_028780_BLEND_SRC_ALPHA
;
66 case PIPE_BLENDFACTOR_DST_ALPHA
:
67 return V_028780_BLEND_DST_ALPHA
;
68 case PIPE_BLENDFACTOR_DST_COLOR
:
69 return V_028780_BLEND_DST_COLOR
;
70 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
71 return V_028780_BLEND_SRC_ALPHA_SATURATE
;
72 case PIPE_BLENDFACTOR_CONST_COLOR
:
73 return V_028780_BLEND_CONSTANT_COLOR
;
74 case PIPE_BLENDFACTOR_CONST_ALPHA
:
75 return V_028780_BLEND_CONSTANT_ALPHA
;
76 case PIPE_BLENDFACTOR_ZERO
:
77 return V_028780_BLEND_ZERO
;
78 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
79 return V_028780_BLEND_ONE_MINUS_SRC_COLOR
;
80 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
81 return V_028780_BLEND_ONE_MINUS_SRC_ALPHA
;
82 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
83 return V_028780_BLEND_ONE_MINUS_DST_ALPHA
;
84 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
85 return V_028780_BLEND_ONE_MINUS_DST_COLOR
;
86 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
87 return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR
;
88 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
89 return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA
;
90 case PIPE_BLENDFACTOR_SRC1_COLOR
:
91 return V_028780_BLEND_SRC1_COLOR
;
92 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
93 return V_028780_BLEND_SRC1_ALPHA
;
94 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
95 return V_028780_BLEND_INV_SRC1_COLOR
;
96 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
97 return V_028780_BLEND_INV_SRC1_ALPHA
;
99 R600_ERR("Bad blend factor %d not supported!\n", blend_fact
);
106 static void *si_create_blend_state(struct pipe_context
*ctx
,
107 const struct pipe_blend_state
*state
)
109 struct si_state_blend
*blend
= CALLOC_STRUCT(si_state_blend
);
110 struct si_pm4_state
*pm4
= &blend
->pm4
;
112 uint32_t color_control
;
117 color_control
= S_028808_MODE(V_028808_CB_NORMAL
);
118 if (state
->logicop_enable
) {
119 color_control
|= S_028808_ROP3(state
->logicop_func
| (state
->logicop_func
<< 4));
121 color_control
|= S_028808_ROP3(0xcc);
123 si_pm4_set_reg(pm4
, R_028808_CB_COLOR_CONTROL
, color_control
);
125 si_pm4_set_reg(pm4
, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0
, ~0);
126 si_pm4_set_reg(pm4
, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1
, ~0);
128 blend
->cb_target_mask
= 0;
129 for (int i
= 0; i
< 8; i
++) {
130 /* state->rt entries > 0 only written if independent blending */
131 const int j
= state
->independent_blend_enable
? i
: 0;
133 unsigned eqRGB
= state
->rt
[j
].rgb_func
;
134 unsigned srcRGB
= state
->rt
[j
].rgb_src_factor
;
135 unsigned dstRGB
= state
->rt
[j
].rgb_dst_factor
;
136 unsigned eqA
= state
->rt
[j
].alpha_func
;
137 unsigned srcA
= state
->rt
[j
].alpha_src_factor
;
138 unsigned dstA
= state
->rt
[j
].alpha_dst_factor
;
140 unsigned blend_cntl
= 0;
142 /* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */
143 blend
->cb_target_mask
|= state
->rt
[j
].colormask
<< (4 * i
);
145 if (!state
->rt
[j
].blend_enable
) {
146 si_pm4_set_reg(pm4
, R_028780_CB_BLEND0_CONTROL
+ i
* 4, blend_cntl
);
150 blend_cntl
|= S_028780_ENABLE(1);
151 blend_cntl
|= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB
));
152 blend_cntl
|= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB
));
153 blend_cntl
|= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB
));
155 if (srcA
!= srcRGB
|| dstA
!= dstRGB
|| eqA
!= eqRGB
) {
156 blend_cntl
|= S_028780_SEPARATE_ALPHA_BLEND(1);
157 blend_cntl
|= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA
));
158 blend_cntl
|= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA
));
159 blend_cntl
|= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA
));
161 si_pm4_set_reg(pm4
, R_028780_CB_BLEND0_CONTROL
+ i
* 4, blend_cntl
);
167 static void si_bind_blend_state(struct pipe_context
*ctx
, void *state
)
169 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
170 si_pm4_bind_state(rctx
, blend
, (struct si_state_blend
*)state
);
173 static void si_delete_blend_state(struct pipe_context
*ctx
, void *state
)
175 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
176 si_pm4_delete_state(rctx
, blend
, (struct si_state_blend
*)state
);
179 void si_init_state_functions(struct r600_context
*rctx
)
181 rctx
->context
.create_blend_state
= si_create_blend_state
;
182 rctx
->context
.bind_blend_state
= si_bind_blend_state
;
183 rctx
->context
.delete_blend_state
= si_delete_blend_state
;