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 static void si_set_blend_color(struct pipe_context
*ctx
,
180 const struct pipe_blend_color
*state
)
182 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
183 struct si_pm4_state
*pm4
= CALLOC_STRUCT(si_pm4_state
);
188 si_pm4_set_reg(pm4
, R_028414_CB_BLEND_RED
, fui(state
->color
[0]));
189 si_pm4_set_reg(pm4
, R_028418_CB_BLEND_GREEN
, fui(state
->color
[1]));
190 si_pm4_set_reg(pm4
, R_02841C_CB_BLEND_BLUE
, fui(state
->color
[2]));
191 si_pm4_set_reg(pm4
, R_028420_CB_BLEND_ALPHA
, fui(state
->color
[3]));
193 si_pm4_set_state(rctx
, blend_color
, pm4
);
196 static void si_set_clip_state(struct pipe_context
*ctx
,
197 const struct pipe_clip_state
*state
)
199 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
200 struct si_pm4_state
*pm4
= CALLOC_STRUCT(si_pm4_state
);
205 for (int i
= 0; i
< 6; i
++) {
206 si_pm4_set_reg(pm4
, R_0285BC_PA_CL_UCP_0_X
+ i
* 16,
207 fui(state
->ucp
[i
][0]));
208 si_pm4_set_reg(pm4
, R_0285C0_PA_CL_UCP_0_Y
+ i
* 16,
209 fui(state
->ucp
[i
][1]));
210 si_pm4_set_reg(pm4
, R_0285C4_PA_CL_UCP_0_Z
+ i
* 16,
211 fui(state
->ucp
[i
][2]));
212 si_pm4_set_reg(pm4
, R_0285C8_PA_CL_UCP_0_W
+ i
* 16,
213 fui(state
->ucp
[i
][3]));
216 si_pm4_set_state(rctx
, clip
, pm4
);
219 static void si_set_scissor_state(struct pipe_context
*ctx
,
220 const struct pipe_scissor_state
*state
)
222 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
223 struct si_pm4_state
*pm4
= CALLOC_STRUCT(si_pm4_state
);
229 tl
= S_028240_TL_X(state
->minx
) | S_028240_TL_Y(state
->miny
);
230 br
= S_028244_BR_X(state
->maxx
) | S_028244_BR_Y(state
->maxy
);
231 si_pm4_set_reg(pm4
, R_028210_PA_SC_CLIPRECT_0_TL
, tl
);
232 si_pm4_set_reg(pm4
, R_028214_PA_SC_CLIPRECT_0_BR
, br
);
233 si_pm4_set_reg(pm4
, R_028218_PA_SC_CLIPRECT_1_TL
, tl
);
234 si_pm4_set_reg(pm4
, R_02821C_PA_SC_CLIPRECT_1_BR
, br
);
235 si_pm4_set_reg(pm4
, R_028220_PA_SC_CLIPRECT_2_TL
, tl
);
236 si_pm4_set_reg(pm4
, R_028224_PA_SC_CLIPRECT_2_BR
, br
);
237 si_pm4_set_reg(pm4
, R_028228_PA_SC_CLIPRECT_3_TL
, tl
);
238 si_pm4_set_reg(pm4
, R_02822C_PA_SC_CLIPRECT_3_BR
, br
);
240 si_pm4_set_state(rctx
, scissor
, pm4
);
243 static void si_set_viewport_state(struct pipe_context
*ctx
,
244 const struct pipe_viewport_state
*state
)
246 struct r600_context
*rctx
= (struct r600_context
*)ctx
;
247 struct si_state_viewport
*viewport
= CALLOC_STRUCT(si_state_viewport
);
248 struct si_pm4_state
*pm4
= &viewport
->pm4
;
250 if (viewport
== NULL
)
253 viewport
->viewport
= *state
;
254 si_pm4_set_reg(pm4
, R_0282D0_PA_SC_VPORT_ZMIN_0
, 0x00000000);
255 si_pm4_set_reg(pm4
, R_0282D4_PA_SC_VPORT_ZMAX_0
, 0x3F800000);
256 si_pm4_set_reg(pm4
, R_028350_PA_SC_RASTER_CONFIG
, 0x00000000);
257 si_pm4_set_reg(pm4
, R_02843C_PA_CL_VPORT_XSCALE_0
, fui(state
->scale
[0]));
258 si_pm4_set_reg(pm4
, R_028440_PA_CL_VPORT_XOFFSET_0
, fui(state
->translate
[0]));
259 si_pm4_set_reg(pm4
, R_028444_PA_CL_VPORT_YSCALE_0
, fui(state
->scale
[1]));
260 si_pm4_set_reg(pm4
, R_028448_PA_CL_VPORT_YOFFSET_0
, fui(state
->translate
[1]));
261 si_pm4_set_reg(pm4
, R_02844C_PA_CL_VPORT_ZSCALE_0
, fui(state
->scale
[2]));
262 si_pm4_set_reg(pm4
, R_028450_PA_CL_VPORT_ZOFFSET_0
, fui(state
->translate
[2]));
263 si_pm4_set_reg(pm4
, R_028818_PA_CL_VTE_CNTL
, 0x0000043F);
265 si_pm4_set_state(rctx
, viewport
, viewport
);
268 void si_init_state_functions(struct r600_context
*rctx
)
270 rctx
->context
.create_blend_state
= si_create_blend_state
;
271 rctx
->context
.bind_blend_state
= si_bind_blend_state
;
272 rctx
->context
.delete_blend_state
= si_delete_blend_state
;
273 rctx
->context
.set_blend_color
= si_set_blend_color
;
275 rctx
->context
.set_clip_state
= si_set_clip_state
;
276 rctx
->context
.set_scissor_state
= si_set_scissor_state
;
277 rctx
->context
.set_viewport_state
= si_set_viewport_state
;