radeonsi: move blender to new state handling
[mesa.git] / src / gallium / drivers / radeonsi / si_state.c
1 /*
2 * Copyright 2012 Advanced Micro Devices, Inc.
3 *
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:
10 *
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
13 * Software.
14 *
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.
22 *
23 * Authors:
24 * Christian König <christian.koenig@amd.com>
25 */
26
27 #include "util/u_memory.h"
28 #include "radeonsi_pipe.h"
29 #include "si_state.h"
30 #include "sid.h"
31
32 /*
33 * Blender functions
34 */
35
36 static uint32_t si_translate_blend_function(int blend_func)
37 {
38 switch (blend_func) {
39 case PIPE_BLEND_ADD:
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;
45 case PIPE_BLEND_MIN:
46 return V_028780_COMB_MIN_DST_SRC;
47 case PIPE_BLEND_MAX:
48 return V_028780_COMB_MAX_DST_SRC;
49 default:
50 R600_ERR("Unknown blend function %d\n", blend_func);
51 assert(0);
52 break;
53 }
54 return 0;
55 }
56
57 static uint32_t si_translate_blend_factor(int blend_fact)
58 {
59 switch (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;
98 default:
99 R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
100 assert(0);
101 break;
102 }
103 return 0;
104 }
105
106 static void *si_create_blend_state(struct pipe_context *ctx,
107 const struct pipe_blend_state *state)
108 {
109 struct si_state_blend *blend = CALLOC_STRUCT(si_state_blend);
110 struct si_pm4_state *pm4 = &blend->pm4;
111
112 uint32_t color_control;
113
114 if (blend == NULL)
115 return NULL;
116
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));
120 } else {
121 color_control |= S_028808_ROP3(0xcc);
122 }
123 si_pm4_set_reg(pm4, R_028808_CB_COLOR_CONTROL, color_control);
124
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);
127
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;
132
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;
139
140 unsigned blend_cntl = 0;
141
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);
144
145 if (!state->rt[j].blend_enable) {
146 si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
147 continue;
148 }
149
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));
154
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));
160 }
161 si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
162 }
163
164 return blend;
165 }
166
167 static void si_bind_blend_state(struct pipe_context *ctx, void *state)
168 {
169 struct r600_context *rctx = (struct r600_context *)ctx;
170 si_pm4_bind_state(rctx, blend, (struct si_state_blend *)state);
171 }
172
173 static void si_delete_blend_state(struct pipe_context *ctx, void *state)
174 {
175 struct r600_context *rctx = (struct r600_context *)ctx;
176 si_pm4_delete_state(rctx, blend, (struct si_state_blend *)state);
177 }
178
179 void si_init_state_functions(struct r600_context *rctx)
180 {
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;
184 }