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 "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"
42 #define VEC4_COPY(DST, SRC) \
50 #define VEC4_SCALAR(DST, SRC) \
58 #define VEC4_ADD(R, A, B) \
66 #define VEC4_SUB(R, A, B) \
74 #define VEC4_MUL(R, A, B) \
82 #define VEC4_MIN(R, A, B) \
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]; \
90 #define VEC4_MAX(R, A, B) \
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]; \
101 logicop_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
103 struct softpipe_context
*softpipe
= qs
->softpipe
;
106 /* loop over colorbuffer outputs */
107 for (cbuf
= 0; cbuf
< softpipe
->framebuffer
.num_cbufs
; cbuf
++) {
108 float dest
[4][QUAD_SIZE
];
109 ubyte src
[4][4], dst
[4][4], res
[4][4];
110 uint
*src4
= (uint
*) src
;
111 uint
*dst4
= (uint
*) dst
;
112 uint
*res4
= (uint
*) res
;
113 struct softpipe_cached_tile
*
114 tile
= sp_get_cached_tile(softpipe
,
115 softpipe
->cbuf_cache
[cbuf
],
117 float (*quadColor
)[4] = quad
->outputs
.color
[cbuf
];
120 /* get/swizzle dest colors */
121 for (j
= 0; j
< QUAD_SIZE
; j
++) {
122 int x
= (quad
->x0
& (TILE_SIZE
-1)) + (j
& 1);
123 int y
= (quad
->y0
& (TILE_SIZE
-1)) + (j
>> 1);
124 for (i
= 0; i
< 4; i
++) {
125 dest
[i
][j
] = tile
->data
.color
[y
][x
][i
];
129 /* convert to ubyte */
130 for (j
= 0; j
< 4; j
++) { /* loop over R,G,B,A channels */
131 UNCLAMPED_FLOAT_TO_UBYTE(dst
[j
][0], dest
[j
][0]); /* P0 */
132 UNCLAMPED_FLOAT_TO_UBYTE(dst
[j
][1], dest
[j
][1]); /* P1 */
133 UNCLAMPED_FLOAT_TO_UBYTE(dst
[j
][2], dest
[j
][2]); /* P2 */
134 UNCLAMPED_FLOAT_TO_UBYTE(dst
[j
][3], dest
[j
][3]); /* P3 */
136 UNCLAMPED_FLOAT_TO_UBYTE(src
[j
][0], quadColor
[j
][0]); /* P0 */
137 UNCLAMPED_FLOAT_TO_UBYTE(src
[j
][1], quadColor
[j
][1]); /* P1 */
138 UNCLAMPED_FLOAT_TO_UBYTE(src
[j
][2], quadColor
[j
][2]); /* P2 */
139 UNCLAMPED_FLOAT_TO_UBYTE(src
[j
][3], quadColor
[j
][3]); /* P3 */
142 switch (softpipe
->blend
->logicop_func
) {
143 case PIPE_LOGICOP_CLEAR
:
144 for (j
= 0; j
< 4; j
++)
147 case PIPE_LOGICOP_NOR
:
148 for (j
= 0; j
< 4; j
++)
149 res4
[j
] = ~(src4
[j
] | dst4
[j
]);
151 case PIPE_LOGICOP_AND_INVERTED
:
152 for (j
= 0; j
< 4; j
++)
153 res4
[j
] = ~src4
[j
] & dst4
[j
];
155 case PIPE_LOGICOP_COPY_INVERTED
:
156 for (j
= 0; j
< 4; j
++)
159 case PIPE_LOGICOP_AND_REVERSE
:
160 for (j
= 0; j
< 4; j
++)
161 res4
[j
] = src4
[j
] & ~dst4
[j
];
163 case PIPE_LOGICOP_INVERT
:
164 for (j
= 0; j
< 4; j
++)
167 case PIPE_LOGICOP_XOR
:
168 for (j
= 0; j
< 4; j
++)
169 res4
[j
] = dst4
[j
] ^ src4
[j
];
171 case PIPE_LOGICOP_NAND
:
172 for (j
= 0; j
< 4; j
++)
173 res4
[j
] = ~(src4
[j
] & dst4
[j
]);
175 case PIPE_LOGICOP_AND
:
176 for (j
= 0; j
< 4; j
++)
177 res4
[j
] = src4
[j
] & dst4
[j
];
179 case PIPE_LOGICOP_EQUIV
:
180 for (j
= 0; j
< 4; j
++)
181 res4
[j
] = ~(src4
[j
] ^ dst4
[j
]);
183 case PIPE_LOGICOP_NOOP
:
184 for (j
= 0; j
< 4; j
++)
187 case PIPE_LOGICOP_OR_INVERTED
:
188 for (j
= 0; j
< 4; j
++)
189 res4
[j
] = ~src4
[j
] | dst4
[j
];
191 case PIPE_LOGICOP_COPY
:
192 for (j
= 0; j
< 4; j
++)
195 case PIPE_LOGICOP_OR_REVERSE
:
196 for (j
= 0; j
< 4; j
++)
197 res4
[j
] = src4
[j
] | ~dst4
[j
];
199 case PIPE_LOGICOP_OR
:
200 for (j
= 0; j
< 4; j
++)
201 res4
[j
] = src4
[j
] | dst4
[j
];
203 case PIPE_LOGICOP_SET
:
204 for (j
= 0; j
< 4; j
++)
211 for (j
= 0; j
< 4; j
++) {
212 quadColor
[j
][0] = UBYTE_TO_FLOAT(res
[j
][0]);
213 quadColor
[j
][1] = UBYTE_TO_FLOAT(res
[j
][1]);
214 quadColor
[j
][2] = UBYTE_TO_FLOAT(res
[j
][2]);
215 quadColor
[j
][3] = UBYTE_TO_FLOAT(res
[j
][3]);
219 /* pass quad to next stage */
220 qs
->next
->run(qs
->next
, quad
);
227 blend_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
229 static const float zero
[4] = { 0, 0, 0, 0 };
230 static const float one
[4] = { 1, 1, 1, 1 };
232 struct softpipe_context
*softpipe
= qs
->softpipe
;
235 /* loop over colorbuffer outputs */
236 for (cbuf
= 0; cbuf
< softpipe
->framebuffer
.num_cbufs
; cbuf
++) {
237 float source
[4][QUAD_SIZE
], dest
[4][QUAD_SIZE
];
238 struct softpipe_cached_tile
*tile
239 = sp_get_cached_tile(softpipe
,
240 softpipe
->cbuf_cache
[cbuf
],
242 float (*quadColor
)[4] = quad
->outputs
.color
[cbuf
];
245 if (softpipe
->blend
->logicop_enable
) {
246 logicop_quad(qs
, quad
);
250 /* get/swizzle dest colors */
251 for (j
= 0; j
< QUAD_SIZE
; j
++) {
252 int x
= (quad
->x0
& (TILE_SIZE
-1)) + (j
& 1);
253 int y
= (quad
->y0
& (TILE_SIZE
-1)) + (j
>> 1);
254 for (i
= 0; i
< 4; i
++) {
255 dest
[i
][j
] = tile
->data
.color
[y
][x
][i
];
260 * Compute src/first term RGB
262 switch (softpipe
->blend
->rgb_src_factor
) {
263 case PIPE_BLENDFACTOR_ONE
:
264 VEC4_COPY(source
[0], quadColor
[0]); /* R */
265 VEC4_COPY(source
[1], quadColor
[1]); /* G */
266 VEC4_COPY(source
[2], quadColor
[2]); /* B */
268 case PIPE_BLENDFACTOR_SRC_COLOR
:
269 VEC4_MUL(source
[0], quadColor
[0], quadColor
[0]); /* R */
270 VEC4_MUL(source
[1], quadColor
[1], quadColor
[1]); /* G */
271 VEC4_MUL(source
[2], quadColor
[2], quadColor
[2]); /* B */
273 case PIPE_BLENDFACTOR_SRC_ALPHA
:
275 const float *alpha
= quadColor
[3];
276 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
277 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
278 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
281 case PIPE_BLENDFACTOR_DST_COLOR
:
282 VEC4_MUL(source
[0], quadColor
[0], dest
[0]); /* R */
283 VEC4_MUL(source
[1], quadColor
[1], dest
[1]); /* G */
284 VEC4_MUL(source
[2], quadColor
[2], dest
[2]); /* B */
286 case PIPE_BLENDFACTOR_DST_ALPHA
:
288 const float *alpha
= dest
[3];
289 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
290 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
291 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
294 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
296 const float *alpha
= quadColor
[3];
298 VEC4_SUB(diff
, one
, dest
[3]);
299 VEC4_MIN(source
[0], alpha
, diff
); /* R */
300 VEC4_MIN(source
[1], alpha
, diff
); /* G */
301 VEC4_MIN(source
[2], alpha
, diff
); /* B */
304 case PIPE_BLENDFACTOR_CONST_COLOR
:
307 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[0]); /* R */
308 VEC4_MUL(source
[0], quadColor
[0], comp
); /* R */
309 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[1]); /* G */
310 VEC4_MUL(source
[1], quadColor
[1], comp
); /* G */
311 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[2]); /* B */
312 VEC4_MUL(source
[2], quadColor
[2], comp
); /* B */
315 case PIPE_BLENDFACTOR_CONST_ALPHA
:
318 VEC4_SCALAR(alpha
, softpipe
->blend_color
.color
[3]);
319 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
320 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
321 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
324 case PIPE_BLENDFACTOR_SRC1_COLOR
:
325 assert(0); /* to do */
327 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
328 assert(0); /* to do */
330 case PIPE_BLENDFACTOR_ZERO
:
331 VEC4_COPY(source
[0], zero
); /* R */
332 VEC4_COPY(source
[1], zero
); /* G */
333 VEC4_COPY(source
[2], zero
); /* B */
335 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
338 VEC4_SUB(inv_comp
, one
, quadColor
[0]); /* R */
339 VEC4_MUL(source
[0], quadColor
[0], inv_comp
); /* R */
340 VEC4_SUB(inv_comp
, one
, quadColor
[1]); /* G */
341 VEC4_MUL(source
[1], quadColor
[1], inv_comp
); /* G */
342 VEC4_SUB(inv_comp
, one
, quadColor
[2]); /* B */
343 VEC4_MUL(source
[2], quadColor
[2], inv_comp
); /* B */
346 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
349 VEC4_SUB(inv_alpha
, one
, quadColor
[3]);
350 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
351 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
352 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
355 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
358 VEC4_SUB(inv_alpha
, one
, dest
[3]);
359 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
360 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
361 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
364 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
367 VEC4_SUB(inv_comp
, one
, dest
[0]); /* R */
368 VEC4_MUL(source
[0], quadColor
[0], inv_comp
); /* R */
369 VEC4_SUB(inv_comp
, one
, dest
[1]); /* G */
370 VEC4_MUL(source
[1], quadColor
[1], inv_comp
); /* G */
371 VEC4_SUB(inv_comp
, one
, dest
[2]); /* B */
372 VEC4_MUL(source
[2], quadColor
[2], inv_comp
); /* B */
375 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
379 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
380 VEC4_MUL(source
[0], quadColor
[0], inv_comp
);
382 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
383 VEC4_MUL(source
[1], quadColor
[1], inv_comp
);
385 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
386 VEC4_MUL(source
[2], quadColor
[2], inv_comp
);
389 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
392 VEC4_SCALAR(inv_alpha
, 1.0f
- softpipe
->blend_color
.color
[3]);
393 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
394 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
395 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
398 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
399 assert(0); /* to do */
401 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
402 assert(0); /* to do */
409 * Compute src/first term A
411 switch (softpipe
->blend
->alpha_src_factor
) {
412 case PIPE_BLENDFACTOR_ONE
:
413 VEC4_COPY(source
[3], quadColor
[3]); /* A */
415 case PIPE_BLENDFACTOR_SRC_COLOR
:
417 case PIPE_BLENDFACTOR_SRC_ALPHA
:
419 const float *alpha
= quadColor
[3];
420 VEC4_MUL(source
[3], quadColor
[3], alpha
); /* A */
423 case PIPE_BLENDFACTOR_DST_COLOR
:
425 case PIPE_BLENDFACTOR_DST_ALPHA
:
426 VEC4_MUL(source
[3], quadColor
[3], dest
[3]); /* A */
428 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
430 const float *alpha
= quadColor
[3];
432 VEC4_SUB(diff
, one
, dest
[3]);
433 VEC4_MIN(source
[3], alpha
, diff
); /* A */
436 case PIPE_BLENDFACTOR_CONST_COLOR
:
438 case PIPE_BLENDFACTOR_CONST_ALPHA
:
441 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
442 VEC4_MUL(source
[3], quadColor
[3], comp
); /* A */
445 case PIPE_BLENDFACTOR_ZERO
:
446 VEC4_COPY(source
[3], zero
); /* A */
448 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
450 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
453 VEC4_SUB(inv_alpha
, one
, quadColor
[3]);
454 VEC4_MUL(source
[3], quadColor
[3], inv_alpha
); /* A */
457 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
459 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
462 VEC4_SUB(inv_alpha
, one
, dest
[3]);
463 VEC4_MUL(source
[3], quadColor
[3], inv_alpha
); /* A */
466 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
468 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
472 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
473 VEC4_MUL(source
[3], quadColor
[3], inv_comp
);
482 * Compute dest/second term RGB
484 switch (softpipe
->blend
->rgb_dst_factor
) {
485 case PIPE_BLENDFACTOR_ONE
:
486 /* dest = dest * 1 NO-OP, leave dest as-is */
488 case PIPE_BLENDFACTOR_SRC_COLOR
:
489 VEC4_MUL(dest
[0], dest
[0], quadColor
[0]); /* R */
490 VEC4_MUL(dest
[1], dest
[1], quadColor
[1]); /* G */
491 VEC4_MUL(dest
[2], dest
[2], quadColor
[2]); /* B */
493 case PIPE_BLENDFACTOR_SRC_ALPHA
:
494 VEC4_MUL(dest
[0], dest
[0], quadColor
[3]); /* R * A */
495 VEC4_MUL(dest
[1], dest
[1], quadColor
[3]); /* G * A */
496 VEC4_MUL(dest
[2], dest
[2], quadColor
[3]); /* B * A */
498 case PIPE_BLENDFACTOR_DST_ALPHA
:
499 VEC4_MUL(dest
[0], dest
[0], dest
[3]); /* R * A */
500 VEC4_MUL(dest
[1], dest
[1], dest
[3]); /* G * A */
501 VEC4_MUL(dest
[2], dest
[2], dest
[3]); /* B * A */
503 case PIPE_BLENDFACTOR_DST_COLOR
:
504 VEC4_MUL(dest
[0], dest
[0], dest
[0]); /* R */
505 VEC4_MUL(dest
[1], dest
[1], dest
[1]); /* G */
506 VEC4_MUL(dest
[2], dest
[2], dest
[2]); /* B */
508 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
509 assert(0); /* illegal */
511 case PIPE_BLENDFACTOR_CONST_COLOR
:
514 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[0]); /* R */
515 VEC4_MUL(dest
[0], dest
[0], comp
); /* R */
516 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[1]); /* G */
517 VEC4_MUL(dest
[1], dest
[1], comp
); /* G */
518 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[2]); /* B */
519 VEC4_MUL(dest
[2], dest
[2], comp
); /* B */
522 case PIPE_BLENDFACTOR_CONST_ALPHA
:
525 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
526 VEC4_MUL(dest
[0], dest
[0], comp
); /* R */
527 VEC4_MUL(dest
[1], dest
[1], comp
); /* G */
528 VEC4_MUL(dest
[2], dest
[2], comp
); /* B */
531 case PIPE_BLENDFACTOR_ZERO
:
532 VEC4_COPY(dest
[0], zero
); /* R */
533 VEC4_COPY(dest
[1], zero
); /* G */
534 VEC4_COPY(dest
[2], zero
); /* B */
536 case PIPE_BLENDFACTOR_SRC1_COLOR
:
537 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
538 /* XXX what are these? */
541 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
544 VEC4_SUB(inv_comp
, one
, quadColor
[0]); /* R */
545 VEC4_MUL(dest
[0], inv_comp
, dest
[0]); /* R */
546 VEC4_SUB(inv_comp
, one
, quadColor
[1]); /* G */
547 VEC4_MUL(dest
[1], inv_comp
, dest
[1]); /* G */
548 VEC4_SUB(inv_comp
, one
, quadColor
[2]); /* B */
549 VEC4_MUL(dest
[2], inv_comp
, dest
[2]); /* B */
552 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
554 float one_minus_alpha
[QUAD_SIZE
];
555 VEC4_SUB(one_minus_alpha
, one
, quadColor
[3]);
556 VEC4_MUL(dest
[0], dest
[0], one_minus_alpha
); /* R */
557 VEC4_MUL(dest
[1], dest
[1], one_minus_alpha
); /* G */
558 VEC4_MUL(dest
[2], dest
[2], one_minus_alpha
); /* B */
561 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
564 VEC4_SUB(inv_comp
, one
, dest
[3]); /* A */
565 VEC4_MUL(dest
[0], inv_comp
, dest
[0]); /* R */
566 VEC4_MUL(dest
[1], inv_comp
, dest
[1]); /* G */
567 VEC4_MUL(dest
[2], inv_comp
, dest
[2]); /* B */
570 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
573 VEC4_SUB(inv_comp
, one
, dest
[0]); /* R */
574 VEC4_MUL(dest
[0], dest
[0], inv_comp
); /* R */
575 VEC4_SUB(inv_comp
, one
, dest
[1]); /* G */
576 VEC4_MUL(dest
[1], dest
[1], inv_comp
); /* G */
577 VEC4_SUB(inv_comp
, one
, dest
[2]); /* B */
578 VEC4_MUL(dest
[2], dest
[2], inv_comp
); /* B */
581 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
585 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
586 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
588 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
589 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
591 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
592 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
595 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
598 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
599 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
600 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
601 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
604 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
605 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
606 /* XXX what are these? */
614 * Compute dest/second term A
616 switch (softpipe
->blend
->alpha_dst_factor
) {
617 case PIPE_BLENDFACTOR_ONE
:
618 /* dest = dest * 1 NO-OP, leave dest as-is */
620 case PIPE_BLENDFACTOR_SRC_COLOR
:
622 case PIPE_BLENDFACTOR_SRC_ALPHA
:
623 VEC4_MUL(dest
[3], dest
[3], quadColor
[3]); /* A * A */
625 case PIPE_BLENDFACTOR_DST_COLOR
:
627 case PIPE_BLENDFACTOR_DST_ALPHA
:
628 VEC4_MUL(dest
[3], dest
[3], dest
[3]); /* A */
630 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
631 assert(0); /* illegal */
633 case PIPE_BLENDFACTOR_CONST_COLOR
:
635 case PIPE_BLENDFACTOR_CONST_ALPHA
:
638 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
639 VEC4_MUL(dest
[3], dest
[3], comp
); /* A */
642 case PIPE_BLENDFACTOR_ZERO
:
643 VEC4_COPY(dest
[3], zero
); /* A */
645 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
647 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
649 float one_minus_alpha
[QUAD_SIZE
];
650 VEC4_SUB(one_minus_alpha
, one
, quadColor
[3]);
651 VEC4_MUL(dest
[3], dest
[3], one_minus_alpha
); /* A */
654 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
656 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
659 VEC4_SUB(inv_comp
, one
, dest
[3]); /* A */
660 VEC4_MUL(dest
[3], inv_comp
, dest
[3]); /* A */
663 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
665 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
668 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
669 VEC4_MUL(dest
[3], dest
[3], inv_comp
);
679 switch (softpipe
->blend
->rgb_func
) {
681 VEC4_ADD(quadColor
[0], source
[0], dest
[0]); /* R */
682 VEC4_ADD(quadColor
[1], source
[1], dest
[1]); /* G */
683 VEC4_ADD(quadColor
[2], source
[2], dest
[2]); /* B */
685 case PIPE_BLEND_SUBTRACT
:
686 VEC4_SUB(quadColor
[0], source
[0], dest
[0]); /* R */
687 VEC4_SUB(quadColor
[1], source
[1], dest
[1]); /* G */
688 VEC4_SUB(quadColor
[2], source
[2], dest
[2]); /* B */
690 case PIPE_BLEND_REVERSE_SUBTRACT
:
691 VEC4_SUB(quadColor
[0], dest
[0], source
[0]); /* R */
692 VEC4_SUB(quadColor
[1], dest
[1], source
[1]); /* G */
693 VEC4_SUB(quadColor
[2], dest
[2], source
[2]); /* B */
696 VEC4_MIN(quadColor
[0], source
[0], dest
[0]); /* R */
697 VEC4_MIN(quadColor
[1], source
[1], dest
[1]); /* G */
698 VEC4_MIN(quadColor
[2], source
[2], dest
[2]); /* B */
701 VEC4_MAX(quadColor
[0], source
[0], dest
[0]); /* R */
702 VEC4_MAX(quadColor
[1], source
[1], dest
[1]); /* G */
703 VEC4_MAX(quadColor
[2], source
[2], dest
[2]); /* B */
712 switch (softpipe
->blend
->alpha_func
) {
714 VEC4_ADD(quadColor
[3], source
[3], dest
[3]); /* A */
716 case PIPE_BLEND_SUBTRACT
:
717 VEC4_SUB(quadColor
[3], source
[3], dest
[3]); /* A */
719 case PIPE_BLEND_REVERSE_SUBTRACT
:
720 VEC4_SUB(quadColor
[3], dest
[3], source
[3]); /* A */
723 VEC4_MIN(quadColor
[3], source
[3], dest
[3]); /* A */
726 VEC4_MAX(quadColor
[3], source
[3], dest
[3]); /* A */
734 /* pass blended quad to next stage */
735 qs
->next
->run(qs
->next
, quad
);
739 static void blend_begin(struct quad_stage
*qs
)
741 qs
->next
->begin(qs
->next
);
745 static void blend_destroy(struct quad_stage
*qs
)
751 struct quad_stage
*sp_quad_blend_stage( struct softpipe_context
*softpipe
)
753 struct quad_stage
*stage
= CALLOC_STRUCT(quad_stage
);
755 stage
->softpipe
= softpipe
;
756 stage
->begin
= blend_begin
;
757 stage
->run
= blend_quad
;
758 stage
->destroy
= blend_destroy
;