1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
33 #include "pipe/p_defines.h"
34 #include "util/u_math.h"
35 #include "util/u_memory.h"
36 #include "sp_context.h"
37 #include "sp_headers.h"
38 #include "sp_surface.h"
39 #include "sp_tile_cache.h"
43 #define VEC4_COPY(DST, SRC) \
51 #define VEC4_SCALAR(DST, SRC) \
59 #define VEC4_ADD(R, A, B) \
67 #define VEC4_SUB(R, A, B) \
75 #define VEC4_MUL(R, A, B) \
83 #define VEC4_MIN(R, A, B) \
85 R[0] = (A[0] < B[0]) ? A[0] : B[0]; \
86 R[1] = (A[1] < B[1]) ? A[1] : B[1]; \
87 R[2] = (A[2] < B[2]) ? A[2] : B[2]; \
88 R[3] = (A[3] < B[3]) ? A[3] : B[3]; \
91 #define VEC4_MAX(R, A, B) \
93 R[0] = (A[0] > B[0]) ? A[0] : B[0]; \
94 R[1] = (A[1] > B[1]) ? A[1] : B[1]; \
95 R[2] = (A[2] > B[2]) ? A[2] : B[2]; \
96 R[3] = (A[3] > B[3]) ? A[3] : B[3]; \
102 logicop_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
104 struct softpipe_context
*softpipe
= qs
->softpipe
;
107 /* loop over colorbuffer outputs */
108 for (cbuf
= 0; cbuf
< softpipe
->framebuffer
.num_cbufs
; cbuf
++) {
109 float dest
[4][QUAD_SIZE
];
110 ubyte src
[4][4], dst
[4][4], res
[4][4];
111 uint
*src4
= (uint
*) src
;
112 uint
*dst4
= (uint
*) dst
;
113 uint
*res4
= (uint
*) res
;
114 struct softpipe_cached_tile
*
115 tile
= sp_get_cached_tile(softpipe
,
116 softpipe
->cbuf_cache
[cbuf
],
117 quad
->input
.x0
, quad
->input
.y0
);
118 float (*quadColor
)[4] = quad
->output
.color
[cbuf
];
121 /* get/swizzle dest colors */
122 for (j
= 0; j
< QUAD_SIZE
; j
++) {
123 int x
= (quad
->input
.x0
& (TILE_SIZE
-1)) + (j
& 1);
124 int y
= (quad
->input
.y0
& (TILE_SIZE
-1)) + (j
>> 1);
125 for (i
= 0; i
< 4; i
++) {
126 dest
[i
][j
] = tile
->data
.color
[y
][x
][i
];
130 /* convert to ubyte */
131 for (j
= 0; j
< 4; j
++) { /* loop over R,G,B,A channels */
132 dst
[j
][0] = float_to_ubyte(dest
[j
][0]); /* P0 */
133 dst
[j
][1] = float_to_ubyte(dest
[j
][1]); /* P1 */
134 dst
[j
][2] = float_to_ubyte(dest
[j
][2]); /* P2 */
135 dst
[j
][3] = float_to_ubyte(dest
[j
][3]); /* P3 */
137 src
[j
][0] = float_to_ubyte(quadColor
[j
][0]); /* P0 */
138 src
[j
][1] = float_to_ubyte(quadColor
[j
][1]); /* P1 */
139 src
[j
][2] = float_to_ubyte(quadColor
[j
][2]); /* P2 */
140 src
[j
][3] = float_to_ubyte(quadColor
[j
][3]); /* P3 */
143 switch (softpipe
->blend
->logicop_func
) {
144 case PIPE_LOGICOP_CLEAR
:
145 for (j
= 0; j
< 4; j
++)
148 case PIPE_LOGICOP_NOR
:
149 for (j
= 0; j
< 4; j
++)
150 res4
[j
] = ~(src4
[j
] | dst4
[j
]);
152 case PIPE_LOGICOP_AND_INVERTED
:
153 for (j
= 0; j
< 4; j
++)
154 res4
[j
] = ~src4
[j
] & dst4
[j
];
156 case PIPE_LOGICOP_COPY_INVERTED
:
157 for (j
= 0; j
< 4; j
++)
160 case PIPE_LOGICOP_AND_REVERSE
:
161 for (j
= 0; j
< 4; j
++)
162 res4
[j
] = src4
[j
] & ~dst4
[j
];
164 case PIPE_LOGICOP_INVERT
:
165 for (j
= 0; j
< 4; j
++)
168 case PIPE_LOGICOP_XOR
:
169 for (j
= 0; j
< 4; j
++)
170 res4
[j
] = dst4
[j
] ^ src4
[j
];
172 case PIPE_LOGICOP_NAND
:
173 for (j
= 0; j
< 4; j
++)
174 res4
[j
] = ~(src4
[j
] & dst4
[j
]);
176 case PIPE_LOGICOP_AND
:
177 for (j
= 0; j
< 4; j
++)
178 res4
[j
] = src4
[j
] & dst4
[j
];
180 case PIPE_LOGICOP_EQUIV
:
181 for (j
= 0; j
< 4; j
++)
182 res4
[j
] = ~(src4
[j
] ^ dst4
[j
]);
184 case PIPE_LOGICOP_NOOP
:
185 for (j
= 0; j
< 4; j
++)
188 case PIPE_LOGICOP_OR_INVERTED
:
189 for (j
= 0; j
< 4; j
++)
190 res4
[j
] = ~src4
[j
] | dst4
[j
];
192 case PIPE_LOGICOP_COPY
:
193 for (j
= 0; j
< 4; j
++)
196 case PIPE_LOGICOP_OR_REVERSE
:
197 for (j
= 0; j
< 4; j
++)
198 res4
[j
] = src4
[j
] | ~dst4
[j
];
200 case PIPE_LOGICOP_OR
:
201 for (j
= 0; j
< 4; j
++)
202 res4
[j
] = src4
[j
] | dst4
[j
];
204 case PIPE_LOGICOP_SET
:
205 for (j
= 0; j
< 4; j
++)
212 for (j
= 0; j
< 4; j
++) {
213 quadColor
[j
][0] = ubyte_to_float(res
[j
][0]);
214 quadColor
[j
][1] = ubyte_to_float(res
[j
][1]);
215 quadColor
[j
][2] = ubyte_to_float(res
[j
][2]);
216 quadColor
[j
][3] = ubyte_to_float(res
[j
][3]);
220 /* pass quad to next stage */
221 qs
->next
->run(qs
->next
, quad
);
228 blend_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
230 static const float zero
[4] = { 0, 0, 0, 0 };
231 static const float one
[4] = { 1, 1, 1, 1 };
233 struct softpipe_context
*softpipe
= qs
->softpipe
;
236 if (softpipe
->blend
->logicop_enable
) {
237 logicop_quad(qs
, quad
);
241 /* loop over colorbuffer outputs */
242 for (cbuf
= 0; cbuf
< softpipe
->framebuffer
.num_cbufs
; cbuf
++) {
243 float source
[4][QUAD_SIZE
], dest
[4][QUAD_SIZE
];
244 struct softpipe_cached_tile
*tile
245 = sp_get_cached_tile(softpipe
,
246 softpipe
->cbuf_cache
[cbuf
],
247 quad
->input
.x0
, quad
->input
.y0
);
248 float (*quadColor
)[4] = quad
->output
.color
[cbuf
];
251 /* get/swizzle dest colors */
252 for (j
= 0; j
< QUAD_SIZE
; j
++) {
253 int x
= (quad
->input
.x0
& (TILE_SIZE
-1)) + (j
& 1);
254 int y
= (quad
->input
.y0
& (TILE_SIZE
-1)) + (j
>> 1);
255 for (i
= 0; i
< 4; i
++) {
256 dest
[i
][j
] = tile
->data
.color
[y
][x
][i
];
261 * Compute src/first term RGB
263 switch (softpipe
->blend
->rgb_src_factor
) {
264 case PIPE_BLENDFACTOR_ONE
:
265 VEC4_COPY(source
[0], quadColor
[0]); /* R */
266 VEC4_COPY(source
[1], quadColor
[1]); /* G */
267 VEC4_COPY(source
[2], quadColor
[2]); /* B */
269 case PIPE_BLENDFACTOR_SRC_COLOR
:
270 VEC4_MUL(source
[0], quadColor
[0], quadColor
[0]); /* R */
271 VEC4_MUL(source
[1], quadColor
[1], quadColor
[1]); /* G */
272 VEC4_MUL(source
[2], quadColor
[2], quadColor
[2]); /* B */
274 case PIPE_BLENDFACTOR_SRC_ALPHA
:
276 const float *alpha
= quadColor
[3];
277 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
278 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
279 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
282 case PIPE_BLENDFACTOR_DST_COLOR
:
283 VEC4_MUL(source
[0], quadColor
[0], dest
[0]); /* R */
284 VEC4_MUL(source
[1], quadColor
[1], dest
[1]); /* G */
285 VEC4_MUL(source
[2], quadColor
[2], dest
[2]); /* B */
287 case PIPE_BLENDFACTOR_DST_ALPHA
:
289 const float *alpha
= dest
[3];
290 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
291 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
292 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
295 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
297 const float *alpha
= quadColor
[3];
298 float diff
[4], temp
[4];
299 VEC4_SUB(diff
, one
, dest
[3]);
300 VEC4_MIN(temp
, alpha
, diff
);
301 VEC4_MUL(source
[0], quadColor
[0], temp
); /* R */
302 VEC4_MUL(source
[1], quadColor
[1], temp
); /* G */
303 VEC4_MUL(source
[2], quadColor
[2], temp
); /* B */
306 case PIPE_BLENDFACTOR_CONST_COLOR
:
309 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[0]); /* R */
310 VEC4_MUL(source
[0], quadColor
[0], comp
); /* R */
311 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[1]); /* G */
312 VEC4_MUL(source
[1], quadColor
[1], comp
); /* G */
313 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[2]); /* B */
314 VEC4_MUL(source
[2], quadColor
[2], comp
); /* B */
317 case PIPE_BLENDFACTOR_CONST_ALPHA
:
320 VEC4_SCALAR(alpha
, softpipe
->blend_color
.color
[3]);
321 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
322 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
323 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
326 case PIPE_BLENDFACTOR_SRC1_COLOR
:
327 assert(0); /* to do */
329 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
330 assert(0); /* to do */
332 case PIPE_BLENDFACTOR_ZERO
:
333 VEC4_COPY(source
[0], zero
); /* R */
334 VEC4_COPY(source
[1], zero
); /* G */
335 VEC4_COPY(source
[2], zero
); /* B */
337 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
340 VEC4_SUB(inv_comp
, one
, quadColor
[0]); /* R */
341 VEC4_MUL(source
[0], quadColor
[0], inv_comp
); /* R */
342 VEC4_SUB(inv_comp
, one
, quadColor
[1]); /* G */
343 VEC4_MUL(source
[1], quadColor
[1], inv_comp
); /* G */
344 VEC4_SUB(inv_comp
, one
, quadColor
[2]); /* B */
345 VEC4_MUL(source
[2], quadColor
[2], inv_comp
); /* B */
348 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
351 VEC4_SUB(inv_alpha
, one
, quadColor
[3]);
352 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
353 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
354 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
357 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
360 VEC4_SUB(inv_alpha
, one
, dest
[3]);
361 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
362 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
363 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
366 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
369 VEC4_SUB(inv_comp
, one
, dest
[0]); /* R */
370 VEC4_MUL(source
[0], quadColor
[0], inv_comp
); /* R */
371 VEC4_SUB(inv_comp
, one
, dest
[1]); /* G */
372 VEC4_MUL(source
[1], quadColor
[1], inv_comp
); /* G */
373 VEC4_SUB(inv_comp
, one
, dest
[2]); /* B */
374 VEC4_MUL(source
[2], quadColor
[2], inv_comp
); /* B */
377 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
381 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
382 VEC4_MUL(source
[0], quadColor
[0], inv_comp
);
384 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
385 VEC4_MUL(source
[1], quadColor
[1], inv_comp
);
387 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
388 VEC4_MUL(source
[2], quadColor
[2], inv_comp
);
391 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
394 VEC4_SCALAR(inv_alpha
, 1.0f
- softpipe
->blend_color
.color
[3]);
395 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
396 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
397 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
400 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
401 assert(0); /* to do */
403 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
404 assert(0); /* to do */
411 * Compute src/first term A
413 switch (softpipe
->blend
->alpha_src_factor
) {
414 case PIPE_BLENDFACTOR_ONE
:
415 VEC4_COPY(source
[3], quadColor
[3]); /* A */
417 case PIPE_BLENDFACTOR_SRC_COLOR
:
419 case PIPE_BLENDFACTOR_SRC_ALPHA
:
421 const float *alpha
= quadColor
[3];
422 VEC4_MUL(source
[3], quadColor
[3], alpha
); /* A */
425 case PIPE_BLENDFACTOR_DST_COLOR
:
427 case PIPE_BLENDFACTOR_DST_ALPHA
:
428 VEC4_MUL(source
[3], quadColor
[3], dest
[3]); /* A */
430 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
431 /* multiply alpha by 1.0 */
432 VEC4_COPY(source
[3], quadColor
[3]); /* A */
434 case PIPE_BLENDFACTOR_CONST_COLOR
:
436 case PIPE_BLENDFACTOR_CONST_ALPHA
:
439 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
440 VEC4_MUL(source
[3], quadColor
[3], comp
); /* A */
443 case PIPE_BLENDFACTOR_ZERO
:
444 VEC4_COPY(source
[3], zero
); /* A */
446 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
448 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
451 VEC4_SUB(inv_alpha
, one
, quadColor
[3]);
452 VEC4_MUL(source
[3], quadColor
[3], inv_alpha
); /* A */
455 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
457 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
460 VEC4_SUB(inv_alpha
, one
, dest
[3]);
461 VEC4_MUL(source
[3], quadColor
[3], inv_alpha
); /* A */
464 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
466 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
470 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
471 VEC4_MUL(source
[3], quadColor
[3], inv_comp
);
480 * Compute dest/second term RGB
482 switch (softpipe
->blend
->rgb_dst_factor
) {
483 case PIPE_BLENDFACTOR_ONE
:
484 /* dest = dest * 1 NO-OP, leave dest as-is */
486 case PIPE_BLENDFACTOR_SRC_COLOR
:
487 VEC4_MUL(dest
[0], dest
[0], quadColor
[0]); /* R */
488 VEC4_MUL(dest
[1], dest
[1], quadColor
[1]); /* G */
489 VEC4_MUL(dest
[2], dest
[2], quadColor
[2]); /* B */
491 case PIPE_BLENDFACTOR_SRC_ALPHA
:
492 VEC4_MUL(dest
[0], dest
[0], quadColor
[3]); /* R * A */
493 VEC4_MUL(dest
[1], dest
[1], quadColor
[3]); /* G * A */
494 VEC4_MUL(dest
[2], dest
[2], quadColor
[3]); /* B * A */
496 case PIPE_BLENDFACTOR_DST_ALPHA
:
497 VEC4_MUL(dest
[0], dest
[0], dest
[3]); /* R * A */
498 VEC4_MUL(dest
[1], dest
[1], dest
[3]); /* G * A */
499 VEC4_MUL(dest
[2], dest
[2], dest
[3]); /* B * A */
501 case PIPE_BLENDFACTOR_DST_COLOR
:
502 VEC4_MUL(dest
[0], dest
[0], dest
[0]); /* R */
503 VEC4_MUL(dest
[1], dest
[1], dest
[1]); /* G */
504 VEC4_MUL(dest
[2], dest
[2], dest
[2]); /* B */
506 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
507 assert(0); /* illegal */
509 case PIPE_BLENDFACTOR_CONST_COLOR
:
512 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[0]); /* R */
513 VEC4_MUL(dest
[0], dest
[0], comp
); /* R */
514 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[1]); /* G */
515 VEC4_MUL(dest
[1], dest
[1], comp
); /* G */
516 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[2]); /* B */
517 VEC4_MUL(dest
[2], dest
[2], comp
); /* B */
520 case PIPE_BLENDFACTOR_CONST_ALPHA
:
523 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
524 VEC4_MUL(dest
[0], dest
[0], comp
); /* R */
525 VEC4_MUL(dest
[1], dest
[1], comp
); /* G */
526 VEC4_MUL(dest
[2], dest
[2], comp
); /* B */
529 case PIPE_BLENDFACTOR_ZERO
:
530 VEC4_COPY(dest
[0], zero
); /* R */
531 VEC4_COPY(dest
[1], zero
); /* G */
532 VEC4_COPY(dest
[2], zero
); /* B */
534 case PIPE_BLENDFACTOR_SRC1_COLOR
:
535 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
536 /* XXX what are these? */
539 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
542 VEC4_SUB(inv_comp
, one
, quadColor
[0]); /* R */
543 VEC4_MUL(dest
[0], inv_comp
, dest
[0]); /* R */
544 VEC4_SUB(inv_comp
, one
, quadColor
[1]); /* G */
545 VEC4_MUL(dest
[1], inv_comp
, dest
[1]); /* G */
546 VEC4_SUB(inv_comp
, one
, quadColor
[2]); /* B */
547 VEC4_MUL(dest
[2], inv_comp
, dest
[2]); /* B */
550 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
552 float one_minus_alpha
[QUAD_SIZE
];
553 VEC4_SUB(one_minus_alpha
, one
, quadColor
[3]);
554 VEC4_MUL(dest
[0], dest
[0], one_minus_alpha
); /* R */
555 VEC4_MUL(dest
[1], dest
[1], one_minus_alpha
); /* G */
556 VEC4_MUL(dest
[2], dest
[2], one_minus_alpha
); /* B */
559 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
562 VEC4_SUB(inv_comp
, one
, dest
[3]); /* A */
563 VEC4_MUL(dest
[0], inv_comp
, dest
[0]); /* R */
564 VEC4_MUL(dest
[1], inv_comp
, dest
[1]); /* G */
565 VEC4_MUL(dest
[2], inv_comp
, dest
[2]); /* B */
568 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
571 VEC4_SUB(inv_comp
, one
, dest
[0]); /* R */
572 VEC4_MUL(dest
[0], dest
[0], inv_comp
); /* R */
573 VEC4_SUB(inv_comp
, one
, dest
[1]); /* G */
574 VEC4_MUL(dest
[1], dest
[1], inv_comp
); /* G */
575 VEC4_SUB(inv_comp
, one
, dest
[2]); /* B */
576 VEC4_MUL(dest
[2], dest
[2], inv_comp
); /* B */
579 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
583 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
584 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
586 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
587 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
589 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
590 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
593 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
596 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
597 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
598 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
599 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
602 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
603 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
604 /* XXX what are these? */
612 * Compute dest/second term A
614 switch (softpipe
->blend
->alpha_dst_factor
) {
615 case PIPE_BLENDFACTOR_ONE
:
616 /* dest = dest * 1 NO-OP, leave dest as-is */
618 case PIPE_BLENDFACTOR_SRC_COLOR
:
620 case PIPE_BLENDFACTOR_SRC_ALPHA
:
621 VEC4_MUL(dest
[3], dest
[3], quadColor
[3]); /* A * A */
623 case PIPE_BLENDFACTOR_DST_COLOR
:
625 case PIPE_BLENDFACTOR_DST_ALPHA
:
626 VEC4_MUL(dest
[3], dest
[3], dest
[3]); /* A */
628 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
629 assert(0); /* illegal */
631 case PIPE_BLENDFACTOR_CONST_COLOR
:
633 case PIPE_BLENDFACTOR_CONST_ALPHA
:
636 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
637 VEC4_MUL(dest
[3], dest
[3], comp
); /* A */
640 case PIPE_BLENDFACTOR_ZERO
:
641 VEC4_COPY(dest
[3], zero
); /* A */
643 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
645 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
647 float one_minus_alpha
[QUAD_SIZE
];
648 VEC4_SUB(one_minus_alpha
, one
, quadColor
[3]);
649 VEC4_MUL(dest
[3], dest
[3], one_minus_alpha
); /* A */
652 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
654 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
657 VEC4_SUB(inv_comp
, one
, dest
[3]); /* A */
658 VEC4_MUL(dest
[3], inv_comp
, dest
[3]); /* A */
661 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
663 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
666 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
667 VEC4_MUL(dest
[3], dest
[3], inv_comp
);
677 switch (softpipe
->blend
->rgb_func
) {
679 VEC4_ADD(quadColor
[0], source
[0], dest
[0]); /* R */
680 VEC4_ADD(quadColor
[1], source
[1], dest
[1]); /* G */
681 VEC4_ADD(quadColor
[2], source
[2], dest
[2]); /* B */
683 case PIPE_BLEND_SUBTRACT
:
684 VEC4_SUB(quadColor
[0], source
[0], dest
[0]); /* R */
685 VEC4_SUB(quadColor
[1], source
[1], dest
[1]); /* G */
686 VEC4_SUB(quadColor
[2], source
[2], dest
[2]); /* B */
688 case PIPE_BLEND_REVERSE_SUBTRACT
:
689 VEC4_SUB(quadColor
[0], dest
[0], source
[0]); /* R */
690 VEC4_SUB(quadColor
[1], dest
[1], source
[1]); /* G */
691 VEC4_SUB(quadColor
[2], dest
[2], source
[2]); /* B */
694 VEC4_MIN(quadColor
[0], source
[0], dest
[0]); /* R */
695 VEC4_MIN(quadColor
[1], source
[1], dest
[1]); /* G */
696 VEC4_MIN(quadColor
[2], source
[2], dest
[2]); /* B */
699 VEC4_MAX(quadColor
[0], source
[0], dest
[0]); /* R */
700 VEC4_MAX(quadColor
[1], source
[1], dest
[1]); /* G */
701 VEC4_MAX(quadColor
[2], source
[2], dest
[2]); /* B */
710 switch (softpipe
->blend
->alpha_func
) {
712 VEC4_ADD(quadColor
[3], source
[3], dest
[3]); /* A */
714 case PIPE_BLEND_SUBTRACT
:
715 VEC4_SUB(quadColor
[3], source
[3], dest
[3]); /* A */
717 case PIPE_BLEND_REVERSE_SUBTRACT
:
718 VEC4_SUB(quadColor
[3], dest
[3], source
[3]); /* A */
721 VEC4_MIN(quadColor
[3], source
[3], dest
[3]); /* A */
724 VEC4_MAX(quadColor
[3], source
[3], dest
[3]); /* A */
732 /* pass blended quad to next stage */
733 qs
->next
->run(qs
->next
, quad
);
737 static void blend_begin(struct quad_stage
*qs
)
739 qs
->next
->begin(qs
->next
);
743 static void blend_destroy(struct quad_stage
*qs
)
749 struct quad_stage
*sp_quad_blend_stage( struct softpipe_context
*softpipe
)
751 struct quad_stage
*stage
= CALLOC_STRUCT(quad_stage
);
753 stage
->softpipe
= softpipe
;
754 stage
->begin
= blend_begin
;
755 stage
->run
= blend_quad
;
756 stage
->destroy
= blend_destroy
;