u_blitter: add a msaa parameter to util_blitter_clear
[mesa.git] / src / gallium / drivers / svga / svga_pipe_blend.c
1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 **********************************************************/
25
26 #include "util/u_inlines.h"
27 #include "pipe/p_defines.h"
28 #include "util/u_math.h"
29 #include "util/u_memory.h"
30 #include "util/u_bitmask.h"
31
32 #include "svga_context.h"
33 #include "svga_hw_reg.h"
34 #include "svga_cmd.h"
35
36
37 static inline unsigned
38 svga_translate_blend_factor(const struct svga_context *svga, unsigned factor)
39 {
40 /* Note: there is no SVGA3D_BLENDOP_[INV]BLENDFACTORALPHA so
41 * we can't translate PIPE_BLENDFACTOR_[INV_]CONST_ALPHA properly.
42 */
43 switch (factor) {
44 case PIPE_BLENDFACTOR_ZERO: return SVGA3D_BLENDOP_ZERO;
45 case PIPE_BLENDFACTOR_SRC_ALPHA: return SVGA3D_BLENDOP_SRCALPHA;
46 case PIPE_BLENDFACTOR_ONE: return SVGA3D_BLENDOP_ONE;
47 case PIPE_BLENDFACTOR_SRC_COLOR: return SVGA3D_BLENDOP_SRCCOLOR;
48 case PIPE_BLENDFACTOR_INV_SRC_COLOR: return SVGA3D_BLENDOP_INVSRCCOLOR;
49 case PIPE_BLENDFACTOR_DST_COLOR: return SVGA3D_BLENDOP_DESTCOLOR;
50 case PIPE_BLENDFACTOR_INV_DST_COLOR: return SVGA3D_BLENDOP_INVDESTCOLOR;
51 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return SVGA3D_BLENDOP_INVSRCALPHA;
52 case PIPE_BLENDFACTOR_DST_ALPHA: return SVGA3D_BLENDOP_DESTALPHA;
53 case PIPE_BLENDFACTOR_INV_DST_ALPHA: return SVGA3D_BLENDOP_INVDESTALPHA;
54 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return SVGA3D_BLENDOP_SRCALPHASAT;
55 case PIPE_BLENDFACTOR_CONST_COLOR: return SVGA3D_BLENDOP_BLENDFACTOR;
56 case PIPE_BLENDFACTOR_INV_CONST_COLOR: return SVGA3D_BLENDOP_INVBLENDFACTOR;
57 case PIPE_BLENDFACTOR_CONST_ALPHA:
58 if (svga_have_vgpu10(svga))
59 return SVGA3D_BLENDOP_BLENDFACTORALPHA;
60 else
61 return SVGA3D_BLENDOP_BLENDFACTOR; /* as close as we can get */
62 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
63 if (svga_have_vgpu10(svga))
64 return SVGA3D_BLENDOP_INVBLENDFACTORALPHA;
65 else
66 return SVGA3D_BLENDOP_INVBLENDFACTOR; /* as close as we can get */
67 case PIPE_BLENDFACTOR_SRC1_COLOR: return SVGA3D_BLENDOP_SRC1COLOR;
68 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: return SVGA3D_BLENDOP_INVSRC1COLOR;
69 case PIPE_BLENDFACTOR_SRC1_ALPHA: return SVGA3D_BLENDOP_SRC1ALPHA;
70 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: return SVGA3D_BLENDOP_INVSRC1ALPHA;
71 case 0: return SVGA3D_BLENDOP_ONE;
72 default:
73 assert(0);
74 return SVGA3D_BLENDOP_ZERO;
75 }
76 }
77
78 static inline unsigned
79 svga_translate_blend_func(unsigned mode)
80 {
81 switch (mode) {
82 case PIPE_BLEND_ADD: return SVGA3D_BLENDEQ_ADD;
83 case PIPE_BLEND_SUBTRACT: return SVGA3D_BLENDEQ_SUBTRACT;
84 case PIPE_BLEND_REVERSE_SUBTRACT: return SVGA3D_BLENDEQ_REVSUBTRACT;
85 case PIPE_BLEND_MIN: return SVGA3D_BLENDEQ_MINIMUM;
86 case PIPE_BLEND_MAX: return SVGA3D_BLENDEQ_MAXIMUM;
87 default:
88 assert(0);
89 return SVGA3D_BLENDEQ_ADD;
90 }
91 }
92
93
94 /**
95 * Define a vgpu10 blend state object for the given
96 * svga blend state.
97 */
98 static void
99 define_blend_state_object(struct svga_context *svga,
100 struct svga_blend_state *bs)
101 {
102 SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS];
103 unsigned try;
104 int i;
105
106 assert(svga_have_vgpu10(svga));
107
108 bs->id = util_bitmask_add(svga->blend_object_id_bm);
109
110 for (i = 0; i < SVGA3D_DX_MAX_RENDER_TARGETS; i++) {
111 perRT[i].blendEnable = bs->rt[i].blend_enable;
112 perRT[i].srcBlend = bs->rt[i].srcblend;
113 perRT[i].destBlend = bs->rt[i].dstblend;
114 perRT[i].blendOp = bs->rt[i].blendeq;
115 perRT[i].srcBlendAlpha = bs->rt[i].srcblend_alpha;
116 perRT[i].destBlendAlpha = bs->rt[i].dstblend_alpha;
117 perRT[i].blendOpAlpha = bs->rt[i].blendeq_alpha;
118 perRT[i].renderTargetWriteMask = bs->rt[i].writemask;
119 perRT[i].logicOpEnable = 0;
120 perRT[i].logicOp = SVGA3D_LOGICOP_COPY;
121 }
122
123 /* Loop in case command buffer is full and we need to flush and retry */
124 for (try = 0; try < 2; try++) {
125 enum pipe_error ret;
126
127 ret = SVGA3D_vgpu10_DefineBlendState(svga->swc,
128 bs->id,
129 bs->alpha_to_coverage,
130 bs->independent_blend_enable,
131 perRT);
132 if (ret == PIPE_OK)
133 return;
134 svga_context_flush(svga, NULL);
135 }
136 }
137
138
139 static void *
140 svga_create_blend_state(struct pipe_context *pipe,
141 const struct pipe_blend_state *templ)
142 {
143 struct svga_context *svga = svga_context(pipe);
144 struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state );
145 unsigned i;
146
147 if (!blend)
148 return NULL;
149
150 /* Find index of first target with blending enabled. If no blending is
151 * enabled at all, first_enabled will be zero.
152 */
153 unsigned first_enabled = 0;
154 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
155 if (templ->rt[i].blend_enable) {
156 first_enabled = i;
157 break;
158 }
159 }
160
161 /* Fill in the per-rendertarget blend state. We currently only
162 * support independent blend enable and colormask per render target.
163 */
164 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
165 /* No way to set this in SVGA3D, and no way to correctly implement it on
166 * top of D3D9 API. Instead we try to simulate with various blend modes.
167 */
168 if (templ->logicop_enable) {
169 switch (templ->logicop_func) {
170 case PIPE_LOGICOP_XOR:
171 case PIPE_LOGICOP_INVERT:
172 blend->need_white_fragments = TRUE;
173 blend->rt[i].blend_enable = TRUE;
174 blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
175 blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE;
176 blend->rt[i].blendeq = SVGA3D_BLENDEQ_SUBTRACT;
177 break;
178 case PIPE_LOGICOP_CLEAR:
179 blend->rt[i].blend_enable = TRUE;
180 blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO;
181 blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
182 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM;
183 break;
184 case PIPE_LOGICOP_COPY:
185 blend->rt[i].blend_enable = FALSE;
186 blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
187 blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
188 blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
189 break;
190 case PIPE_LOGICOP_COPY_INVERTED:
191 blend->rt[i].blend_enable = TRUE;
192 blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
193 blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
194 blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
195 break;
196 case PIPE_LOGICOP_NOOP:
197 blend->rt[i].blend_enable = TRUE;
198 blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO;
199 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
200 blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
201 break;
202 case PIPE_LOGICOP_SET:
203 blend->rt[i].blend_enable = TRUE;
204 blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
205 blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE;
206 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
207 break;
208 case PIPE_LOGICOP_AND:
209 /* Approximate with minimum - works for the 0 & anything case: */
210 blend->rt[i].blend_enable = TRUE;
211 blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR;
212 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
213 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM;
214 break;
215 case PIPE_LOGICOP_AND_REVERSE:
216 blend->rt[i].blend_enable = TRUE;
217 blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR;
218 blend->rt[i].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR;
219 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM;
220 break;
221 case PIPE_LOGICOP_AND_INVERTED:
222 blend->rt[i].blend_enable = TRUE;
223 blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
224 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
225 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM;
226 break;
227 case PIPE_LOGICOP_OR:
228 /* Approximate with maximum - works for the 1 | anything case: */
229 blend->rt[i].blend_enable = TRUE;
230 blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR;
231 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
232 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
233 break;
234 case PIPE_LOGICOP_OR_REVERSE:
235 blend->rt[i].blend_enable = TRUE;
236 blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR;
237 blend->rt[i].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR;
238 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
239 break;
240 case PIPE_LOGICOP_OR_INVERTED:
241 blend->rt[i].blend_enable = TRUE;
242 blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
243 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR;
244 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
245 break;
246 case PIPE_LOGICOP_NAND:
247 case PIPE_LOGICOP_NOR:
248 case PIPE_LOGICOP_EQUIV:
249 /* Fill these in with plausible values */
250 blend->rt[i].blend_enable = FALSE;
251 blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
252 blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
253 blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
254 break;
255 default:
256 assert(0);
257 break;
258 }
259 blend->rt[i].srcblend_alpha = blend->rt[i].srcblend;
260 blend->rt[i].dstblend_alpha = blend->rt[i].dstblend;
261 blend->rt[i].blendeq_alpha = blend->rt[i].blendeq;
262
263 if (templ->logicop_func == PIPE_LOGICOP_XOR) {
264 pipe_debug_message(&svga->debug.callback, CONFORMANCE,
265 "XOR logicop mode has limited support");
266 }
267 else if (templ->logicop_func != PIPE_LOGICOP_COPY) {
268 pipe_debug_message(&svga->debug.callback, CONFORMANCE,
269 "general logicops are not supported");
270 }
271 }
272 else {
273 /* Note: per-target blend terms are only supported for sm4_1
274 * device. For vgpu10 device, the blending terms must be identical
275 * for all targets (this is why we need the first_enabled index).
276 */
277 const unsigned j =
278 svga_have_sm4_1(svga) && templ->independent_blend_enable
279 ? i : first_enabled;
280 if (templ->independent_blend_enable || templ->rt[j].blend_enable) {
281 blend->rt[i].srcblend =
282 svga_translate_blend_factor(svga, templ->rt[j].rgb_src_factor);
283 blend->rt[i].dstblend =
284 svga_translate_blend_factor(svga, templ->rt[j].rgb_dst_factor);
285 blend->rt[i].blendeq =
286 svga_translate_blend_func(templ->rt[j].rgb_func);
287 blend->rt[i].srcblend_alpha =
288 svga_translate_blend_factor(svga, templ->rt[j].alpha_src_factor);
289 blend->rt[i].dstblend_alpha =
290 svga_translate_blend_factor(svga, templ->rt[j].alpha_dst_factor);
291 blend->rt[i].blendeq_alpha =
292 svga_translate_blend_func(templ->rt[j].alpha_func);
293
294 if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend ||
295 blend->rt[i].dstblend_alpha != blend->rt[i].dstblend ||
296 blend->rt[i].blendeq_alpha != blend->rt[i].blendeq) {
297 blend->rt[i].separate_alpha_blend_enable = TRUE;
298 }
299 }
300 else {
301 /* disabled - default blend terms */
302 blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
303 blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
304 blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
305 blend->rt[i].srcblend_alpha = SVGA3D_BLENDOP_ONE;
306 blend->rt[i].dstblend_alpha = SVGA3D_BLENDOP_ZERO;
307 blend->rt[i].blendeq_alpha = SVGA3D_BLENDEQ_ADD;
308 }
309
310 if (templ->independent_blend_enable) {
311 blend->rt[i].blend_enable = templ->rt[i].blend_enable;
312 }
313 else {
314 blend->rt[i].blend_enable = templ->rt[0].blend_enable;
315 }
316 }
317
318 /* Some GL blend modes are not supported by the VGPU9 device (there's
319 * no equivalent of PIPE_BLENDFACTOR_[INV_]CONST_ALPHA).
320 * When we set this flag, we copy the constant blend alpha value
321 * to the R, G, B components.
322 * This works as long as the src/dst RGB blend factors doesn't use
323 * PIPE_BLENDFACTOR_CONST_COLOR and PIPE_BLENDFACTOR_CONST_ALPHA
324 * at the same time. There's no work-around for that.
325 */
326 if (!svga_have_vgpu10(svga)) {
327 if (templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_CONST_ALPHA ||
328 templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_CONST_ALPHA ||
329 templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA ||
330 templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA) {
331 blend->blend_color_alpha = TRUE;
332 }
333 }
334
335 if (templ->independent_blend_enable) {
336 blend->rt[i].writemask = templ->rt[i].colormask;
337 }
338 else {
339 blend->rt[i].writemask = templ->rt[0].colormask;
340 }
341 }
342
343 blend->independent_blend_enable = templ->independent_blend_enable;
344
345 blend->alpha_to_coverage = templ->alpha_to_coverage;
346 blend->alpha_to_one = templ->alpha_to_one;
347
348 if (svga_have_vgpu10(svga)) {
349 define_blend_state_object(svga, blend);
350 }
351
352 svga->hud.num_blend_objects++;
353 SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
354 SVGA_STATS_COUNT_BLENDSTATE);
355
356 return blend;
357 }
358
359
360 static void svga_bind_blend_state(struct pipe_context *pipe,
361 void *blend)
362 {
363 struct svga_context *svga = svga_context(pipe);
364
365 svga->curr.blend = (struct svga_blend_state*)blend;
366 svga->dirty |= SVGA_NEW_BLEND;
367 }
368
369 static void svga_delete_blend_state(struct pipe_context *pipe,
370 void *blend)
371 {
372 struct svga_context *svga = svga_context(pipe);
373 struct svga_blend_state *bs =
374 (struct svga_blend_state *) blend;
375
376 if (svga_have_vgpu10(svga) && bs->id != SVGA3D_INVALID_ID) {
377 enum pipe_error ret;
378
379 ret = SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id);
380 if (ret != PIPE_OK) {
381 svga_context_flush(svga, NULL);
382 ret = SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id);
383 assert(ret == PIPE_OK);
384 }
385
386 if (bs->id == svga->state.hw_draw.blend_id)
387 svga->state.hw_draw.blend_id = SVGA3D_INVALID_ID;
388
389 util_bitmask_clear(svga->blend_object_id_bm, bs->id);
390 bs->id = SVGA3D_INVALID_ID;
391 }
392
393 FREE(blend);
394 svga->hud.num_blend_objects--;
395 }
396
397 static void svga_set_blend_color( struct pipe_context *pipe,
398 const struct pipe_blend_color *blend_color )
399 {
400 struct svga_context *svga = svga_context(pipe);
401
402 svga->curr.blend_color = *blend_color;
403
404 svga->dirty |= SVGA_NEW_BLEND_COLOR;
405 }
406
407
408 void svga_init_blend_functions( struct svga_context *svga )
409 {
410 svga->pipe.create_blend_state = svga_create_blend_state;
411 svga->pipe.bind_blend_state = svga_bind_blend_state;
412 svga->pipe.delete_blend_state = svga_delete_blend_state;
413
414 svga->pipe.set_blend_color = svga_set_blend_color;
415 }