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
;
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
,
111 softpipe
->cbuf_cache
[softpipe
->current_cbuf
],
113 float (*quadColor
)[4] = quad
->outputs
.color
;
116 /* get/swizzle dest colors */
117 for (j
= 0; j
< QUAD_SIZE
; j
++) {
118 int x
= (quad
->x0
& (TILE_SIZE
-1)) + (j
& 1);
119 int y
= (quad
->y0
& (TILE_SIZE
-1)) + (j
>> 1);
120 for (i
= 0; i
< 4; i
++) {
121 dest
[i
][j
] = tile
->data
.color
[y
][x
][i
];
125 /* convert to ubyte */
126 for (j
= 0; j
< 4; j
++) { /* loop over R,G,B,A channels */
127 UNCLAMPED_FLOAT_TO_UBYTE(dst
[j
][0], dest
[j
][0]); /* P0 */
128 UNCLAMPED_FLOAT_TO_UBYTE(dst
[j
][1], dest
[j
][1]); /* P1 */
129 UNCLAMPED_FLOAT_TO_UBYTE(dst
[j
][2], dest
[j
][2]); /* P2 */
130 UNCLAMPED_FLOAT_TO_UBYTE(dst
[j
][3], dest
[j
][3]); /* P3 */
132 UNCLAMPED_FLOAT_TO_UBYTE(src
[j
][0], quadColor
[j
][0]); /* P0 */
133 UNCLAMPED_FLOAT_TO_UBYTE(src
[j
][1], quadColor
[j
][1]); /* P1 */
134 UNCLAMPED_FLOAT_TO_UBYTE(src
[j
][2], quadColor
[j
][2]); /* P2 */
135 UNCLAMPED_FLOAT_TO_UBYTE(src
[j
][3], quadColor
[j
][3]); /* P3 */
138 switch (softpipe
->blend
->logicop_func
) {
139 case PIPE_LOGICOP_CLEAR
:
140 for (j
= 0; j
< 4; j
++)
143 case PIPE_LOGICOP_NOR
:
144 for (j
= 0; j
< 4; j
++)
145 res4
[j
] = ~(src4
[j
] | dst4
[j
]);
147 case PIPE_LOGICOP_AND_INVERTED
:
148 for (j
= 0; j
< 4; j
++)
149 res4
[j
] = ~src4
[j
] & dst4
[j
];
151 case PIPE_LOGICOP_COPY_INVERTED
:
152 for (j
= 0; j
< 4; j
++)
155 case PIPE_LOGICOP_AND_REVERSE
:
156 for (j
= 0; j
< 4; j
++)
157 res4
[j
] = src4
[j
] & ~dst4
[j
];
159 case PIPE_LOGICOP_INVERT
:
160 for (j
= 0; j
< 4; j
++)
163 case PIPE_LOGICOP_XOR
:
164 for (j
= 0; j
< 4; j
++)
165 res4
[j
] = dst4
[j
] ^ src4
[j
];
167 case PIPE_LOGICOP_NAND
:
168 for (j
= 0; j
< 4; j
++)
169 res4
[j
] = ~(src4
[j
] & dst4
[j
]);
171 case PIPE_LOGICOP_AND
:
172 for (j
= 0; j
< 4; j
++)
173 res4
[j
] = src4
[j
] & dst4
[j
];
175 case PIPE_LOGICOP_EQUIV
:
176 for (j
= 0; j
< 4; j
++)
177 res4
[j
] = ~(src4
[j
] ^ dst4
[j
]);
179 case PIPE_LOGICOP_NOOP
:
180 for (j
= 0; j
< 4; j
++)
183 case PIPE_LOGICOP_OR_INVERTED
:
184 for (j
= 0; j
< 4; j
++)
185 res4
[j
] = ~src4
[j
] | dst4
[j
];
187 case PIPE_LOGICOP_COPY
:
188 for (j
= 0; j
< 4; j
++)
191 case PIPE_LOGICOP_OR_REVERSE
:
192 for (j
= 0; j
< 4; j
++)
193 res4
[j
] = src4
[j
] | ~dst4
[j
];
195 case PIPE_LOGICOP_OR
:
196 for (j
= 0; j
< 4; j
++)
197 res4
[j
] = src4
[j
] | dst4
[j
];
199 case PIPE_LOGICOP_SET
:
200 for (j
= 0; j
< 4; j
++)
207 for (j
= 0; j
< 4; j
++) {
208 quadColor
[j
][0] = UBYTE_TO_FLOAT(res
[j
][0]);
209 quadColor
[j
][1] = UBYTE_TO_FLOAT(res
[j
][1]);
210 quadColor
[j
][2] = UBYTE_TO_FLOAT(res
[j
][2]);
211 quadColor
[j
][3] = UBYTE_TO_FLOAT(res
[j
][3]);
214 /* pass quad to next stage */
215 qs
->next
->run(qs
->next
, quad
);
222 blend_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
224 struct softpipe_context
*softpipe
= qs
->softpipe
;
225 static const float zero
[4] = { 0, 0, 0, 0 };
226 static const float one
[4] = { 1, 1, 1, 1 };
227 float source
[4][QUAD_SIZE
], dest
[4][QUAD_SIZE
];
228 struct softpipe_cached_tile
*tile
229 = sp_get_cached_tile(softpipe
,
230 softpipe
->cbuf_cache
[softpipe
->current_cbuf
],
232 float (*quadColor
)[4] = quad
->outputs
.color
;
235 if (softpipe
->blend
->logicop_enable
) {
236 logicop_quad(qs
, quad
);
240 /* get/swizzle dest colors */
241 for (j
= 0; j
< QUAD_SIZE
; j
++) {
242 int x
= (quad
->x0
& (TILE_SIZE
-1)) + (j
& 1);
243 int y
= (quad
->y0
& (TILE_SIZE
-1)) + (j
>> 1);
244 for (i
= 0; i
< 4; i
++) {
245 dest
[i
][j
] = tile
->data
.color
[y
][x
][i
];
250 * Compute src/first term RGB
252 switch (softpipe
->blend
->rgb_src_factor
) {
253 case PIPE_BLENDFACTOR_ONE
:
254 VEC4_COPY(source
[0], quadColor
[0]); /* R */
255 VEC4_COPY(source
[1], quadColor
[1]); /* G */
256 VEC4_COPY(source
[2], quadColor
[2]); /* B */
258 case PIPE_BLENDFACTOR_SRC_COLOR
:
259 VEC4_MUL(source
[0], quadColor
[0], quadColor
[0]); /* R */
260 VEC4_MUL(source
[1], quadColor
[1], quadColor
[1]); /* G */
261 VEC4_MUL(source
[2], quadColor
[2], quadColor
[2]); /* B */
263 case PIPE_BLENDFACTOR_SRC_ALPHA
:
265 const float *alpha
= quadColor
[3];
266 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
267 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
268 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
271 case PIPE_BLENDFACTOR_DST_COLOR
:
272 VEC4_MUL(source
[0], quadColor
[0], dest
[0]); /* R */
273 VEC4_MUL(source
[1], quadColor
[1], dest
[1]); /* G */
274 VEC4_MUL(source
[2], quadColor
[2], dest
[2]); /* B */
276 case PIPE_BLENDFACTOR_DST_ALPHA
:
278 const float *alpha
= dest
[3];
279 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
280 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
281 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
284 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
286 const float *alpha
= quadColor
[3];
288 VEC4_SUB(diff
, one
, dest
[3]);
289 VEC4_MIN(source
[0], alpha
, diff
); /* R */
290 VEC4_MIN(source
[1], alpha
, diff
); /* G */
291 VEC4_MIN(source
[2], alpha
, diff
); /* B */
294 case PIPE_BLENDFACTOR_CONST_COLOR
:
297 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[0]); /* R */
298 VEC4_MUL(source
[0], quadColor
[0], comp
); /* R */
299 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[1]); /* G */
300 VEC4_MUL(source
[1], quadColor
[1], comp
); /* G */
301 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[2]); /* B */
302 VEC4_MUL(source
[2], quadColor
[2], comp
); /* B */
305 case PIPE_BLENDFACTOR_CONST_ALPHA
:
308 VEC4_SCALAR(alpha
, softpipe
->blend_color
.color
[3]);
309 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
310 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
311 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
314 case PIPE_BLENDFACTOR_SRC1_COLOR
:
315 assert(0); /* to do */
317 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
318 assert(0); /* to do */
320 case PIPE_BLENDFACTOR_ZERO
:
321 VEC4_COPY(source
[0], zero
); /* R */
322 VEC4_COPY(source
[1], zero
); /* G */
323 VEC4_COPY(source
[2], zero
); /* B */
325 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
328 VEC4_SUB(inv_comp
, one
, quadColor
[0]); /* R */
329 VEC4_MUL(source
[0], quadColor
[0], inv_comp
); /* R */
330 VEC4_SUB(inv_comp
, one
, quadColor
[1]); /* G */
331 VEC4_MUL(source
[1], quadColor
[1], inv_comp
); /* G */
332 VEC4_SUB(inv_comp
, one
, quadColor
[2]); /* B */
333 VEC4_MUL(source
[2], quadColor
[2], inv_comp
); /* B */
336 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
339 VEC4_SUB(inv_alpha
, one
, quadColor
[3]);
340 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
341 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
342 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
345 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
348 VEC4_SUB(inv_alpha
, one
, dest
[3]);
349 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
350 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
351 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
354 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
357 VEC4_SUB(inv_comp
, one
, dest
[0]); /* R */
358 VEC4_MUL(source
[0], quadColor
[0], inv_comp
); /* R */
359 VEC4_SUB(inv_comp
, one
, dest
[1]); /* G */
360 VEC4_MUL(source
[1], quadColor
[1], inv_comp
); /* G */
361 VEC4_SUB(inv_comp
, one
, dest
[2]); /* B */
362 VEC4_MUL(source
[2], quadColor
[2], inv_comp
); /* B */
365 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
369 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
370 VEC4_MUL(source
[0], quadColor
[0], inv_comp
);
372 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
373 VEC4_MUL(source
[1], quadColor
[1], inv_comp
);
375 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
376 VEC4_MUL(source
[2], quadColor
[2], inv_comp
);
379 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
382 VEC4_SCALAR(inv_alpha
, 1.0f
- softpipe
->blend_color
.color
[3]);
383 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
384 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
385 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
388 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
389 assert(0); /* to do */
391 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
392 assert(0); /* to do */
399 * Compute src/first term A
401 switch (softpipe
->blend
->alpha_src_factor
) {
402 case PIPE_BLENDFACTOR_ONE
:
403 VEC4_COPY(source
[3], quadColor
[3]); /* A */
405 case PIPE_BLENDFACTOR_SRC_COLOR
:
407 case PIPE_BLENDFACTOR_SRC_ALPHA
:
409 const float *alpha
= quadColor
[3];
410 VEC4_MUL(source
[3], quadColor
[3], alpha
); /* A */
413 case PIPE_BLENDFACTOR_DST_COLOR
:
415 case PIPE_BLENDFACTOR_DST_ALPHA
:
416 VEC4_MUL(source
[3], quadColor
[3], dest
[3]); /* A */
418 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
420 const float *alpha
= quadColor
[3];
422 VEC4_SUB(diff
, one
, dest
[3]);
423 VEC4_MIN(source
[3], alpha
, diff
); /* A */
426 case PIPE_BLENDFACTOR_CONST_COLOR
:
428 case PIPE_BLENDFACTOR_CONST_ALPHA
:
431 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
432 VEC4_MUL(source
[3], quadColor
[3], comp
); /* A */
435 case PIPE_BLENDFACTOR_ZERO
:
436 VEC4_COPY(source
[3], zero
); /* A */
438 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
440 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
443 VEC4_SUB(inv_alpha
, one
, quadColor
[3]);
444 VEC4_MUL(source
[3], quadColor
[3], inv_alpha
); /* A */
447 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
449 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
452 VEC4_SUB(inv_alpha
, one
, dest
[3]);
453 VEC4_MUL(source
[3], quadColor
[3], inv_alpha
); /* A */
456 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
458 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
462 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
463 VEC4_MUL(source
[3], quadColor
[3], inv_comp
);
472 * Compute dest/second term RGB
474 switch (softpipe
->blend
->rgb_dst_factor
) {
475 case PIPE_BLENDFACTOR_ONE
:
476 /* dest = dest * 1 NO-OP, leave dest as-is */
478 case PIPE_BLENDFACTOR_SRC_COLOR
:
479 VEC4_MUL(dest
[0], dest
[0], quadColor
[0]); /* R */
480 VEC4_MUL(dest
[1], dest
[1], quadColor
[1]); /* G */
481 VEC4_MUL(dest
[2], dest
[2], quadColor
[2]); /* B */
483 case PIPE_BLENDFACTOR_SRC_ALPHA
:
484 VEC4_MUL(dest
[0], dest
[0], quadColor
[3]); /* R * A */
485 VEC4_MUL(dest
[1], dest
[1], quadColor
[3]); /* G * A */
486 VEC4_MUL(dest
[2], dest
[2], quadColor
[3]); /* B * A */
488 case PIPE_BLENDFACTOR_DST_ALPHA
:
489 VEC4_MUL(dest
[0], dest
[0], dest
[3]); /* R * A */
490 VEC4_MUL(dest
[1], dest
[1], dest
[3]); /* G * A */
491 VEC4_MUL(dest
[2], dest
[2], dest
[3]); /* B * A */
493 case PIPE_BLENDFACTOR_DST_COLOR
:
494 VEC4_MUL(dest
[0], dest
[0], dest
[0]); /* R */
495 VEC4_MUL(dest
[1], dest
[1], dest
[1]); /* G */
496 VEC4_MUL(dest
[2], dest
[2], dest
[2]); /* B */
498 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
499 assert(0); /* illegal */
501 case PIPE_BLENDFACTOR_CONST_COLOR
:
504 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[0]); /* R */
505 VEC4_MUL(dest
[0], dest
[0], comp
); /* R */
506 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[1]); /* G */
507 VEC4_MUL(dest
[1], dest
[1], comp
); /* G */
508 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[2]); /* B */
509 VEC4_MUL(dest
[2], dest
[2], comp
); /* B */
512 case PIPE_BLENDFACTOR_CONST_ALPHA
:
515 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
516 VEC4_MUL(dest
[0], dest
[0], comp
); /* R */
517 VEC4_MUL(dest
[1], dest
[1], comp
); /* G */
518 VEC4_MUL(dest
[2], dest
[2], comp
); /* B */
521 case PIPE_BLENDFACTOR_ZERO
:
522 VEC4_COPY(dest
[0], zero
); /* R */
523 VEC4_COPY(dest
[1], zero
); /* G */
524 VEC4_COPY(dest
[2], zero
); /* B */
526 case PIPE_BLENDFACTOR_SRC1_COLOR
:
527 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
528 /* XXX what are these? */
531 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
534 VEC4_SUB(inv_comp
, one
, quadColor
[0]); /* R */
535 VEC4_MUL(dest
[0], inv_comp
, dest
[0]); /* R */
536 VEC4_SUB(inv_comp
, one
, quadColor
[1]); /* G */
537 VEC4_MUL(dest
[1], inv_comp
, dest
[1]); /* G */
538 VEC4_SUB(inv_comp
, one
, quadColor
[2]); /* B */
539 VEC4_MUL(dest
[2], inv_comp
, dest
[2]); /* B */
542 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
544 float one_minus_alpha
[QUAD_SIZE
];
545 VEC4_SUB(one_minus_alpha
, one
, quadColor
[3]);
546 VEC4_MUL(dest
[0], dest
[0], one_minus_alpha
); /* R */
547 VEC4_MUL(dest
[1], dest
[1], one_minus_alpha
); /* G */
548 VEC4_MUL(dest
[2], dest
[2], one_minus_alpha
); /* B */
551 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
554 VEC4_SUB(inv_comp
, one
, quadColor
[3]); /* A */
555 VEC4_MUL(dest
[0], inv_comp
, dest
[0]); /* R */
556 VEC4_MUL(dest
[1], inv_comp
, dest
[1]); /* G */
557 VEC4_MUL(dest
[2], inv_comp
, dest
[2]); /* B */
560 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
563 VEC4_SUB(inv_comp
, one
, dest
[0]); /* R */
564 VEC4_MUL(dest
[0], dest
[0], inv_comp
); /* R */
565 VEC4_SUB(inv_comp
, one
, dest
[1]); /* G */
566 VEC4_MUL(dest
[1], dest
[1], inv_comp
); /* G */
567 VEC4_SUB(inv_comp
, one
, dest
[2]); /* B */
568 VEC4_MUL(dest
[2], dest
[2], inv_comp
); /* B */
571 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
575 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
576 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
578 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
579 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
581 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
582 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
585 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
588 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
589 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
590 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
591 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
594 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
595 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
596 /* XXX what are these? */
604 * Compute dest/second term A
606 switch (softpipe
->blend
->alpha_dst_factor
) {
607 case PIPE_BLENDFACTOR_ONE
:
608 /* dest = dest * 1 NO-OP, leave dest as-is */
610 case PIPE_BLENDFACTOR_SRC_COLOR
:
612 case PIPE_BLENDFACTOR_SRC_ALPHA
:
613 VEC4_MUL(dest
[3], dest
[3], quadColor
[3]); /* A * A */
615 case PIPE_BLENDFACTOR_DST_COLOR
:
617 case PIPE_BLENDFACTOR_DST_ALPHA
:
618 VEC4_MUL(dest
[3], dest
[3], dest
[3]); /* A */
620 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
621 assert(0); /* illegal */
623 case PIPE_BLENDFACTOR_CONST_COLOR
:
625 case PIPE_BLENDFACTOR_CONST_ALPHA
:
628 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
629 VEC4_MUL(dest
[3], dest
[3], comp
); /* A */
632 case PIPE_BLENDFACTOR_ZERO
:
633 VEC4_COPY(dest
[3], zero
); /* A */
635 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
637 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
639 float one_minus_alpha
[QUAD_SIZE
];
640 VEC4_SUB(one_minus_alpha
, one
, quadColor
[3]);
641 VEC4_MUL(dest
[3], dest
[3], one_minus_alpha
); /* A */
644 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
646 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
649 VEC4_SUB(inv_comp
, one
, dest
[3]); /* A */
650 VEC4_MUL(dest
[3], inv_comp
, dest
[3]); /* A */
653 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
655 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
658 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
659 VEC4_MUL(dest
[3], dest
[3], inv_comp
);
669 switch (softpipe
->blend
->rgb_func
) {
671 VEC4_ADD(quadColor
[0], source
[0], dest
[0]); /* R */
672 VEC4_ADD(quadColor
[1], source
[1], dest
[1]); /* G */
673 VEC4_ADD(quadColor
[2], source
[2], dest
[2]); /* B */
675 case PIPE_BLEND_SUBTRACT
:
676 VEC4_SUB(quadColor
[0], source
[0], dest
[0]); /* R */
677 VEC4_SUB(quadColor
[1], source
[1], dest
[1]); /* G */
678 VEC4_SUB(quadColor
[2], source
[2], dest
[2]); /* B */
680 case PIPE_BLEND_REVERSE_SUBTRACT
:
681 VEC4_SUB(quadColor
[0], dest
[0], source
[0]); /* R */
682 VEC4_SUB(quadColor
[1], dest
[1], source
[1]); /* G */
683 VEC4_SUB(quadColor
[2], dest
[2], source
[2]); /* B */
686 VEC4_MIN(quadColor
[0], source
[0], dest
[0]); /* R */
687 VEC4_MIN(quadColor
[1], source
[1], dest
[1]); /* G */
688 VEC4_MIN(quadColor
[2], source
[2], dest
[2]); /* B */
691 VEC4_MAX(quadColor
[0], source
[0], dest
[0]); /* R */
692 VEC4_MAX(quadColor
[1], source
[1], dest
[1]); /* G */
693 VEC4_MAX(quadColor
[2], source
[2], dest
[2]); /* B */
702 switch (softpipe
->blend
->alpha_func
) {
704 VEC4_ADD(quadColor
[3], source
[3], dest
[3]); /* A */
706 case PIPE_BLEND_SUBTRACT
:
707 VEC4_SUB(quadColor
[3], source
[3], dest
[3]); /* A */
709 case PIPE_BLEND_REVERSE_SUBTRACT
:
710 VEC4_SUB(quadColor
[3], dest
[3], source
[3]); /* A */
713 VEC4_MIN(quadColor
[3], source
[3], dest
[3]); /* A */
716 VEC4_MAX(quadColor
[3], source
[3], dest
[3]); /* A */
722 /* pass blended quad to next stage */
723 qs
->next
->run(qs
->next
, quad
);
727 static void blend_begin(struct quad_stage
*qs
)
729 qs
->next
->begin(qs
->next
);
733 static void blend_destroy(struct quad_stage
*qs
)
739 struct quad_stage
*sp_quad_blend_stage( struct softpipe_context
*softpipe
)
741 struct quad_stage
*stage
= CALLOC_STRUCT(quad_stage
);
743 stage
->softpipe
= softpipe
;
744 stage
->begin
= blend_begin
;
745 stage
->run
= blend_quad
;
746 stage
->destroy
= blend_destroy
;