Remove remnants of 'intel' from active state tracker code.
[mesa.git] / src / mesa / pipe / softpipe / sp_quad_blend.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /**
29 * quad blending
30 * \author Brian Paul
31 */
32
33 #include "pipe/p_defines.h"
34 #include "pipe/p_util.h"
35 #include "sp_context.h"
36 #include "sp_headers.h"
37 #include "sp_surface.h"
38 #include "sp_tile_cache.h"
39 #include "sp_quad.h"
40
41
42 #define VEC4_COPY(DST, SRC) \
43 do { \
44 DST[0] = SRC[0]; \
45 DST[1] = SRC[1]; \
46 DST[2] = SRC[2]; \
47 DST[3] = SRC[3]; \
48 } while(0)
49
50 #define VEC4_SCALAR(DST, SRC) \
51 do { \
52 DST[0] = SRC; \
53 DST[1] = SRC; \
54 DST[2] = SRC; \
55 DST[3] = SRC; \
56 } while(0)
57
58 #define VEC4_ADD(R, A, B) \
59 do { \
60 R[0] = A[0] + B[0]; \
61 R[1] = A[1] + B[1]; \
62 R[2] = A[2] + B[2]; \
63 R[3] = A[3] + B[3]; \
64 } while (0)
65
66 #define VEC4_SUB(R, A, B) \
67 do { \
68 R[0] = A[0] - B[0]; \
69 R[1] = A[1] - B[1]; \
70 R[2] = A[2] - B[2]; \
71 R[3] = A[3] - B[3]; \
72 } while (0)
73
74 #define VEC4_MUL(R, A, B) \
75 do { \
76 R[0] = A[0] * B[0]; \
77 R[1] = A[1] * B[1]; \
78 R[2] = A[2] * B[2]; \
79 R[3] = A[3] * B[3]; \
80 } while (0)
81
82 #define VEC4_MIN(R, A, B) \
83 do { \
84 R[0] = (A[0] < B[0]) ? A[0] : B[0]; \
85 R[1] = (A[1] < B[1]) ? A[1] : B[1]; \
86 R[2] = (A[2] < B[2]) ? A[2] : B[2]; \
87 R[3] = (A[3] < B[3]) ? A[3] : B[3]; \
88 } while (0)
89
90 #define VEC4_MAX(R, A, B) \
91 do { \
92 R[0] = (A[0] > B[0]) ? A[0] : B[0]; \
93 R[1] = (A[1] > B[1]) ? A[1] : B[1]; \
94 R[2] = (A[2] > B[2]) ? A[2] : B[2]; \
95 R[3] = (A[3] > B[3]) ? A[3] : B[3]; \
96 } while (0)
97
98
99
100 static void
101 logicop_quad(struct quad_stage *qs, struct quad_header *quad)
102 {
103 struct softpipe_context *softpipe = qs->softpipe;
104 float dest[4][QUAD_SIZE];
105 ubyte src[4][4], dst[4][4], res[4][4];
106 uint *src4 = (uint *) src;
107 uint *dst4 = (uint *) dst;
108 uint *res4 = (uint *) res;
109 struct softpipe_cached_tile *
110 tile = sp_get_cached_tile(softpipe, softpipe->cbuf_cache[0],
111 quad->x0, quad->y0);
112 uint i, j;
113
114 /* get/swizzle dest colors */
115 for (j = 0; j < QUAD_SIZE; j++) {
116 int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1);
117 int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1);
118 for (i = 0; i < 4; i++) {
119 dest[i][j] = tile->data.color[y][x][i];
120 }
121 }
122
123 /* convert to ubyte */
124 for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
125 UNCLAMPED_FLOAT_TO_UBYTE(dst[j][0], dest[j][0]); /* P0 */
126 UNCLAMPED_FLOAT_TO_UBYTE(dst[j][1], dest[j][1]); /* P1 */
127 UNCLAMPED_FLOAT_TO_UBYTE(dst[j][2], dest[j][2]); /* P2 */
128 UNCLAMPED_FLOAT_TO_UBYTE(dst[j][3], dest[j][3]); /* P3 */
129
130 UNCLAMPED_FLOAT_TO_UBYTE(src[j][0], quad->outputs.color[j][0]); /* P0 */
131 UNCLAMPED_FLOAT_TO_UBYTE(src[j][1], quad->outputs.color[j][1]); /* P1 */
132 UNCLAMPED_FLOAT_TO_UBYTE(src[j][2], quad->outputs.color[j][2]); /* P2 */
133 UNCLAMPED_FLOAT_TO_UBYTE(src[j][3], quad->outputs.color[j][3]); /* P3 */
134 }
135
136 switch (softpipe->blend->logicop_func) {
137 case PIPE_LOGICOP_CLEAR:
138 for (j = 0; j < 4; j++)
139 res4[j] = 0;
140 break;
141 case PIPE_LOGICOP_NOR:
142 for (j = 0; j < 4; j++)
143 res4[j] = ~(src4[j] | dst4[j]);
144 break;
145 case PIPE_LOGICOP_AND_INVERTED:
146 for (j = 0; j < 4; j++)
147 res4[j] = ~src4[j] & dst4[j];
148 break;
149 case PIPE_LOGICOP_COPY_INVERTED:
150 for (j = 0; j < 4; j++)
151 res4[j] = ~src4[j];
152 break;
153 case PIPE_LOGICOP_AND_REVERSE:
154 for (j = 0; j < 4; j++)
155 res4[j] = src4[j] & ~dst4[j];
156 break;
157 case PIPE_LOGICOP_INVERT:
158 for (j = 0; j < 4; j++)
159 res4[j] = ~dst4[j];
160 break;
161 case PIPE_LOGICOP_XOR:
162 for (j = 0; j < 4; j++)
163 res4[j] = dst4[j] ^ src4[j];
164 break;
165 case PIPE_LOGICOP_NAND:
166 for (j = 0; j < 4; j++)
167 res4[j] = ~(src4[j] & dst4[j]);
168 break;
169 case PIPE_LOGICOP_AND:
170 for (j = 0; j < 4; j++)
171 res4[j] = src4[j] & dst4[j];
172 break;
173 case PIPE_LOGICOP_EQUIV:
174 for (j = 0; j < 4; j++)
175 res4[j] = ~(src4[j] ^ dst4[j]);
176 break;
177 case PIPE_LOGICOP_NOOP:
178 for (j = 0; j < 4; j++)
179 res4[j] = dst4[j];
180 break;
181 case PIPE_LOGICOP_OR_INVERTED:
182 for (j = 0; j < 4; j++)
183 res4[j] = ~src4[j] | dst4[j];
184 break;
185 case PIPE_LOGICOP_COPY:
186 for (j = 0; j < 4; j++)
187 res4[j] = src4[j];
188 break;
189 case PIPE_LOGICOP_OR_REVERSE:
190 for (j = 0; j < 4; j++)
191 res4[j] = src4[j] | ~dst4[j];
192 break;
193 case PIPE_LOGICOP_OR:
194 for (j = 0; j < 4; j++)
195 res4[j] = src4[j] | dst4[j];
196 break;
197 case PIPE_LOGICOP_SET:
198 for (j = 0; j < 4; j++)
199 res4[j] = ~0;
200 break;
201 default:
202 assert(0);
203 }
204
205 for (j = 0; j < 4; j++) {
206 quad->outputs.color[j][0] = UBYTE_TO_FLOAT(res[j][0]);
207 quad->outputs.color[j][1] = UBYTE_TO_FLOAT(res[j][1]);
208 quad->outputs.color[j][2] = UBYTE_TO_FLOAT(res[j][2]);
209 quad->outputs.color[j][3] = UBYTE_TO_FLOAT(res[j][3]);
210 }
211
212 /* pass quad to next stage */
213 qs->next->run(qs->next, quad);
214 }
215
216
217
218
219 static void
220 blend_quad(struct quad_stage *qs, struct quad_header *quad)
221 {
222 struct softpipe_context *softpipe = qs->softpipe;
223 static const float zero[4] = { 0, 0, 0, 0 };
224 static const float one[4] = { 1, 1, 1, 1 };
225 float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
226 struct softpipe_cached_tile *tile
227 = sp_get_cached_tile(softpipe, softpipe->cbuf_cache[0],
228 quad->x0, quad->y0);
229 uint i, j;
230
231 if (softpipe->blend->logicop_enable) {
232 logicop_quad(qs, quad);
233 return;
234 }
235
236 /* get/swizzle dest colors */
237 for (j = 0; j < QUAD_SIZE; j++) {
238 int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1);
239 int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1);
240 for (i = 0; i < 4; i++) {
241 dest[i][j] = tile->data.color[y][x][i];
242 }
243 }
244
245 /*
246 * Compute src/first term RGB
247 */
248 switch (softpipe->blend->rgb_src_factor) {
249 case PIPE_BLENDFACTOR_ONE:
250 VEC4_COPY(source[0], quad->outputs.color[0]); /* R */
251 VEC4_COPY(source[1], quad->outputs.color[1]); /* G */
252 VEC4_COPY(source[2], quad->outputs.color[2]); /* B */
253 break;
254 case PIPE_BLENDFACTOR_SRC_COLOR:
255 VEC4_MUL(source[0], quad->outputs.color[0], quad->outputs.color[0]); /* R */
256 VEC4_MUL(source[1], quad->outputs.color[1], quad->outputs.color[1]); /* G */
257 VEC4_MUL(source[2], quad->outputs.color[2], quad->outputs.color[2]); /* B */
258 break;
259 case PIPE_BLENDFACTOR_SRC_ALPHA:
260 {
261 const float *alpha = quad->outputs.color[3];
262 VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */
263 VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */
264 VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */
265 }
266 break;
267 case PIPE_BLENDFACTOR_DST_COLOR:
268 VEC4_MUL(source[0], quad->outputs.color[0], dest[0]); /* R */
269 VEC4_MUL(source[1], quad->outputs.color[1], dest[1]); /* G */
270 VEC4_MUL(source[2], quad->outputs.color[2], dest[2]); /* B */
271 break;
272 case PIPE_BLENDFACTOR_DST_ALPHA:
273 {
274 const float *alpha = dest[3];
275 VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */
276 VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */
277 VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */
278 }
279 break;
280 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
281 {
282 const float *alpha = quad->outputs.color[3];
283 float diff[4];
284 VEC4_SUB(diff, one, dest[3]);
285 VEC4_MIN(source[0], alpha, diff); /* R */
286 VEC4_MIN(source[1], alpha, diff); /* G */
287 VEC4_MIN(source[2], alpha, diff); /* B */
288 }
289 break;
290 case PIPE_BLENDFACTOR_CONST_COLOR:
291 {
292 float comp[4];
293 VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
294 VEC4_MUL(source[0], quad->outputs.color[0], comp); /* R */
295 VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
296 VEC4_MUL(source[1], quad->outputs.color[1], comp); /* G */
297 VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
298 VEC4_MUL(source[2], quad->outputs.color[2], comp); /* B */
299 }
300 break;
301 case PIPE_BLENDFACTOR_CONST_ALPHA:
302 {
303 float alpha[4];
304 VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
305 VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */
306 VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */
307 VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */
308 }
309 break;
310 case PIPE_BLENDFACTOR_SRC1_COLOR:
311 assert(0); /* to do */
312 break;
313 case PIPE_BLENDFACTOR_SRC1_ALPHA:
314 assert(0); /* to do */
315 break;
316 case PIPE_BLENDFACTOR_ZERO:
317 VEC4_COPY(source[0], zero); /* R */
318 VEC4_COPY(source[1], zero); /* G */
319 VEC4_COPY(source[2], zero); /* B */
320 break;
321 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
322 {
323 float inv_comp[4];
324 VEC4_SUB(inv_comp, one, quad->outputs.color[0]); /* R */
325 VEC4_MUL(source[0], quad->outputs.color[0], inv_comp); /* R */
326 VEC4_SUB(inv_comp, one, quad->outputs.color[1]); /* G */
327 VEC4_MUL(source[1], quad->outputs.color[1], inv_comp); /* G */
328 VEC4_SUB(inv_comp, one, quad->outputs.color[2]); /* B */
329 VEC4_MUL(source[2], quad->outputs.color[2], inv_comp); /* B */
330 }
331 break;
332 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
333 {
334 float inv_alpha[4];
335 VEC4_SUB(inv_alpha, one, quad->outputs.color[3]);
336 VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */
337 VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */
338 VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */
339 }
340 break;
341 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
342 {
343 float inv_alpha[4];
344 VEC4_SUB(inv_alpha, one, dest[3]);
345 VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */
346 VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */
347 VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */
348 }
349 break;
350 case PIPE_BLENDFACTOR_INV_DST_COLOR:
351 {
352 float inv_comp[4];
353 VEC4_SUB(inv_comp, one, dest[0]); /* R */
354 VEC4_MUL(source[0], quad->outputs.color[0], inv_comp); /* R */
355 VEC4_SUB(inv_comp, one, dest[1]); /* G */
356 VEC4_MUL(source[1], quad->outputs.color[1], inv_comp); /* G */
357 VEC4_SUB(inv_comp, one, dest[2]); /* B */
358 VEC4_MUL(source[2], quad->outputs.color[2], inv_comp); /* B */
359 }
360 break;
361 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
362 {
363 float inv_comp[4];
364 /* R */
365 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
366 VEC4_MUL(source[0], quad->outputs.color[0], inv_comp);
367 /* G */
368 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
369 VEC4_MUL(source[1], quad->outputs.color[1], inv_comp);
370 /* B */
371 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
372 VEC4_MUL(source[2], quad->outputs.color[2], inv_comp);
373 }
374 break;
375 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
376 {
377 float inv_alpha[4];
378 VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
379 VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */
380 VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */
381 VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */
382 }
383 break;
384 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
385 assert(0); /* to do */
386 break;
387 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
388 assert(0); /* to do */
389 break;
390 default:
391 abort();
392 }
393
394 /*
395 * Compute src/first term A
396 */
397 switch (softpipe->blend->alpha_src_factor) {
398 case PIPE_BLENDFACTOR_ONE:
399 VEC4_COPY(source[3], quad->outputs.color[3]); /* A */
400 break;
401 case PIPE_BLENDFACTOR_SRC_COLOR:
402 /* fall-through */
403 case PIPE_BLENDFACTOR_SRC_ALPHA:
404 {
405 const float *alpha = quad->outputs.color[3];
406 VEC4_MUL(source[3], quad->outputs.color[3], alpha); /* A */
407 }
408 break;
409 case PIPE_BLENDFACTOR_DST_COLOR:
410 /* fall-through */
411 case PIPE_BLENDFACTOR_DST_ALPHA:
412 VEC4_MUL(source[3], quad->outputs.color[3], dest[3]); /* A */
413 break;
414 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
415 {
416 const float *alpha = quad->outputs.color[3];
417 float diff[4];
418 VEC4_SUB(diff, one, dest[3]);
419 VEC4_MIN(source[3], alpha, diff); /* A */
420 }
421 break;
422 case PIPE_BLENDFACTOR_CONST_COLOR:
423 /* fall-through */
424 case PIPE_BLENDFACTOR_CONST_ALPHA:
425 {
426 float comp[4];
427 VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
428 VEC4_MUL(source[3], quad->outputs.color[3], comp); /* A */
429 }
430 break;
431 case PIPE_BLENDFACTOR_ZERO:
432 VEC4_COPY(source[3], zero); /* A */
433 break;
434 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
435 /* fall-through */
436 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
437 {
438 float inv_alpha[4];
439 VEC4_SUB(inv_alpha, one, quad->outputs.color[3]);
440 VEC4_MUL(source[3], quad->outputs.color[3], inv_alpha); /* A */
441 }
442 break;
443 case PIPE_BLENDFACTOR_INV_DST_COLOR:
444 /* fall-through */
445 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
446 {
447 float inv_alpha[4];
448 VEC4_SUB(inv_alpha, one, dest[3]);
449 VEC4_MUL(source[3], quad->outputs.color[3], inv_alpha); /* A */
450 }
451 break;
452 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
453 /* fall-through */
454 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
455 {
456 float inv_comp[4];
457 /* A */
458 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
459 VEC4_MUL(source[3], quad->outputs.color[3], inv_comp);
460 }
461 break;
462 default:
463 abort();
464 }
465
466
467 /*
468 * Compute dest/second term RGB
469 */
470 switch (softpipe->blend->rgb_dst_factor) {
471 case PIPE_BLENDFACTOR_ONE:
472 /* dest = dest * 1 NO-OP, leave dest as-is */
473 break;
474 case PIPE_BLENDFACTOR_SRC_COLOR:
475 VEC4_MUL(dest[0], dest[0], quad->outputs.color[0]); /* R */
476 VEC4_MUL(dest[1], dest[1], quad->outputs.color[1]); /* G */
477 VEC4_MUL(dest[2], dest[2], quad->outputs.color[2]); /* B */
478 break;
479 case PIPE_BLENDFACTOR_SRC_ALPHA:
480 VEC4_MUL(dest[0], dest[0], quad->outputs.color[3]); /* R * A */
481 VEC4_MUL(dest[1], dest[1], quad->outputs.color[3]); /* G * A */
482 VEC4_MUL(dest[2], dest[2], quad->outputs.color[3]); /* B * A */
483 break;
484 case PIPE_BLENDFACTOR_DST_ALPHA:
485 VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
486 VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
487 VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
488 break;
489 case PIPE_BLENDFACTOR_DST_COLOR:
490 VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
491 VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
492 VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
493 break;
494 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
495 assert(0); /* illegal */
496 break;
497 case PIPE_BLENDFACTOR_CONST_COLOR:
498 {
499 float comp[4];
500 VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
501 VEC4_MUL(dest[0], dest[0], comp); /* R */
502 VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
503 VEC4_MUL(dest[1], dest[1], comp); /* G */
504 VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
505 VEC4_MUL(dest[2], dest[2], comp); /* B */
506 }
507 break;
508 case PIPE_BLENDFACTOR_CONST_ALPHA:
509 {
510 float comp[4];
511 VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
512 VEC4_MUL(dest[0], dest[0], comp); /* R */
513 VEC4_MUL(dest[1], dest[1], comp); /* G */
514 VEC4_MUL(dest[2], dest[2], comp); /* B */
515 }
516 break;
517 case PIPE_BLENDFACTOR_ZERO:
518 VEC4_COPY(dest[0], zero); /* R */
519 VEC4_COPY(dest[1], zero); /* G */
520 VEC4_COPY(dest[2], zero); /* B */
521 break;
522 case PIPE_BLENDFACTOR_SRC1_COLOR:
523 case PIPE_BLENDFACTOR_SRC1_ALPHA:
524 /* XXX what are these? */
525 assert(0);
526 break;
527 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
528 {
529 float inv_comp[4];
530 VEC4_SUB(inv_comp, one, quad->outputs.color[0]); /* R */
531 VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
532 VEC4_SUB(inv_comp, one, quad->outputs.color[1]); /* G */
533 VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
534 VEC4_SUB(inv_comp, one, quad->outputs.color[2]); /* B */
535 VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
536 }
537 break;
538 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
539 {
540 float one_minus_alpha[QUAD_SIZE];
541 VEC4_SUB(one_minus_alpha, one, quad->outputs.color[3]);
542 VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
543 VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
544 VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
545 }
546 break;
547 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
548 {
549 float inv_comp[4];
550 VEC4_SUB(inv_comp, one, quad->outputs.color[3]); /* A */
551 VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
552 VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
553 VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
554 }
555 break;
556 case PIPE_BLENDFACTOR_INV_DST_COLOR:
557 {
558 float inv_comp[4];
559 VEC4_SUB(inv_comp, one, dest[0]); /* R */
560 VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
561 VEC4_SUB(inv_comp, one, dest[1]); /* G */
562 VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
563 VEC4_SUB(inv_comp, one, dest[2]); /* B */
564 VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
565 }
566 break;
567 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
568 {
569 float inv_comp[4];
570 /* R */
571 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
572 VEC4_MUL(dest[0], dest[0], inv_comp);
573 /* G */
574 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
575 VEC4_MUL(dest[1], dest[1], inv_comp);
576 /* B */
577 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
578 VEC4_MUL(dest[2], dest[2], inv_comp);
579 }
580 break;
581 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
582 {
583 float inv_comp[4];
584 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
585 VEC4_MUL(dest[0], dest[0], inv_comp);
586 VEC4_MUL(dest[1], dest[1], inv_comp);
587 VEC4_MUL(dest[2], dest[2], inv_comp);
588 }
589 break;
590 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
591 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
592 /* XXX what are these? */
593 assert(0);
594 break;
595 default:
596 assert(0);
597 }
598
599 /*
600 * Compute dest/second term A
601 */
602 switch (softpipe->blend->alpha_dst_factor) {
603 case PIPE_BLENDFACTOR_ONE:
604 /* dest = dest * 1 NO-OP, leave dest as-is */
605 break;
606 case PIPE_BLENDFACTOR_SRC_COLOR:
607 /* fall-through */
608 case PIPE_BLENDFACTOR_SRC_ALPHA:
609 VEC4_MUL(dest[3], dest[3], quad->outputs.color[3]); /* A * A */
610 break;
611 case PIPE_BLENDFACTOR_DST_COLOR:
612 /* fall-through */
613 case PIPE_BLENDFACTOR_DST_ALPHA:
614 VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
615 break;
616 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
617 assert(0); /* illegal */
618 break;
619 case PIPE_BLENDFACTOR_CONST_COLOR:
620 /* fall-through */
621 case PIPE_BLENDFACTOR_CONST_ALPHA:
622 {
623 float comp[4];
624 VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
625 VEC4_MUL(dest[3], dest[3], comp); /* A */
626 }
627 break;
628 case PIPE_BLENDFACTOR_ZERO:
629 VEC4_COPY(dest[3], zero); /* A */
630 break;
631 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
632 /* fall-through */
633 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
634 {
635 float one_minus_alpha[QUAD_SIZE];
636 VEC4_SUB(one_minus_alpha, one, quad->outputs.color[3]);
637 VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
638 }
639 break;
640 case PIPE_BLENDFACTOR_INV_DST_COLOR:
641 /* fall-through */
642 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
643 {
644 float inv_comp[4];
645 VEC4_SUB(inv_comp, one, dest[3]); /* A */
646 VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
647 }
648 break;
649 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
650 /* fall-through */
651 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
652 {
653 float inv_comp[4];
654 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
655 VEC4_MUL(dest[3], dest[3], inv_comp);
656 }
657 break;
658 default:
659 assert(0);
660 }
661
662 /*
663 * Combine RGB terms
664 */
665 switch (softpipe->blend->rgb_func) {
666 case PIPE_BLEND_ADD:
667 VEC4_ADD(quad->outputs.color[0], source[0], dest[0]); /* R */
668 VEC4_ADD(quad->outputs.color[1], source[1], dest[1]); /* G */
669 VEC4_ADD(quad->outputs.color[2], source[2], dest[2]); /* B */
670 break;
671 case PIPE_BLEND_SUBTRACT:
672 VEC4_SUB(quad->outputs.color[0], source[0], dest[0]); /* R */
673 VEC4_SUB(quad->outputs.color[1], source[1], dest[1]); /* G */
674 VEC4_SUB(quad->outputs.color[2], source[2], dest[2]); /* B */
675 break;
676 case PIPE_BLEND_REVERSE_SUBTRACT:
677 VEC4_SUB(quad->outputs.color[0], dest[0], source[0]); /* R */
678 VEC4_SUB(quad->outputs.color[1], dest[1], source[1]); /* G */
679 VEC4_SUB(quad->outputs.color[2], dest[2], source[2]); /* B */
680 break;
681 case PIPE_BLEND_MIN:
682 VEC4_MIN(quad->outputs.color[0], source[0], dest[0]); /* R */
683 VEC4_MIN(quad->outputs.color[1], source[1], dest[1]); /* G */
684 VEC4_MIN(quad->outputs.color[2], source[2], dest[2]); /* B */
685 break;
686 case PIPE_BLEND_MAX:
687 VEC4_MAX(quad->outputs.color[0], source[0], dest[0]); /* R */
688 VEC4_MAX(quad->outputs.color[1], source[1], dest[1]); /* G */
689 VEC4_MAX(quad->outputs.color[2], source[2], dest[2]); /* B */
690 break;
691 default:
692 assert(0);
693 }
694
695 /*
696 * Combine A terms
697 */
698 switch (softpipe->blend->alpha_func) {
699 case PIPE_BLEND_ADD:
700 VEC4_ADD(quad->outputs.color[3], source[3], dest[3]); /* A */
701 break;
702 case PIPE_BLEND_SUBTRACT:
703 VEC4_SUB(quad->outputs.color[3], source[3], dest[3]); /* A */
704 break;
705 case PIPE_BLEND_REVERSE_SUBTRACT:
706 VEC4_SUB(quad->outputs.color[3], dest[3], source[3]); /* A */
707 break;
708 case PIPE_BLEND_MIN:
709 VEC4_MIN(quad->outputs.color[3], source[3], dest[3]); /* A */
710 break;
711 case PIPE_BLEND_MAX:
712 VEC4_MAX(quad->outputs.color[3], source[3], dest[3]); /* A */
713 break;
714 default:
715 abort();
716 }
717
718 /* pass blended quad to next stage */
719 qs->next->run(qs->next, quad);
720 }
721
722
723 static void blend_begin(struct quad_stage *qs)
724 {
725 if (qs->next)
726 qs->next->begin(qs->next);
727 }
728
729
730 static void blend_destroy(struct quad_stage *qs)
731 {
732 FREE( qs );
733 }
734
735
736 struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe )
737 {
738 struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
739
740 stage->softpipe = softpipe;
741 stage->begin = blend_begin;
742 stage->run = blend_quad;
743 stage->destroy = blend_destroy;
744
745 return stage;
746 }