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"
38 #include "sp_surface.h"
39 #include "sp_tile_cache.h"
40 #include "sp_quad_pipe.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 /** Add and limit result to ceiling of 1.0 */
76 #define VEC4_ADD_SAT(R, A, B) \
78 R[0] = A[0] + B[0]; if (R[0] > 1.0f) R[0] = 1.0f; \
79 R[1] = A[1] + B[1]; if (R[1] > 1.0f) R[1] = 1.0f; \
80 R[2] = A[2] + B[2]; if (R[2] > 1.0f) R[2] = 1.0f; \
81 R[3] = A[3] + B[3]; if (R[3] > 1.0f) R[3] = 1.0f; \
84 /** Subtract and limit result to floor of 0.0 */
85 #define VEC4_SUB_SAT(R, A, B) \
87 R[0] = A[0] - B[0]; if (R[0] < 0.0f) R[0] = 0.0f; \
88 R[1] = A[1] - B[1]; if (R[1] < 0.0f) R[1] = 0.0f; \
89 R[2] = A[2] - B[2]; if (R[2] < 0.0f) R[2] = 0.0f; \
90 R[3] = A[3] - B[3]; if (R[3] < 0.0f) R[3] = 0.0f; \
93 #define VEC4_MUL(R, A, B) \
101 #define VEC4_MIN(R, A, B) \
103 R[0] = (A[0] < B[0]) ? A[0] : B[0]; \
104 R[1] = (A[1] < B[1]) ? A[1] : B[1]; \
105 R[2] = (A[2] < B[2]) ? A[2] : B[2]; \
106 R[3] = (A[3] < B[3]) ? A[3] : B[3]; \
109 #define VEC4_MAX(R, A, B) \
111 R[0] = (A[0] > B[0]) ? A[0] : B[0]; \
112 R[1] = (A[1] > B[1]) ? A[1] : B[1]; \
113 R[2] = (A[2] > B[2]) ? A[2] : B[2]; \
114 R[3] = (A[3] > B[3]) ? A[3] : B[3]; \
120 logicop_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
122 struct softpipe_context
*softpipe
= qs
->softpipe
;
125 /* loop over colorbuffer outputs */
126 for (cbuf
= 0; cbuf
< softpipe
->framebuffer
.nr_cbufs
; cbuf
++) {
127 float dest
[4][QUAD_SIZE
];
128 ubyte src
[4][4], dst
[4][4], res
[4][4];
129 uint
*src4
= (uint
*) src
;
130 uint
*dst4
= (uint
*) dst
;
131 uint
*res4
= (uint
*) res
;
132 struct softpipe_cached_tile
*
133 tile
= sp_get_cached_tile(softpipe
,
134 softpipe
->cbuf_cache
[cbuf
],
135 quad
->input
.x0
, quad
->input
.y0
);
136 float (*quadColor
)[4] = quad
->output
.color
[cbuf
];
139 /* get/swizzle dest colors */
140 for (j
= 0; j
< QUAD_SIZE
; j
++) {
141 int x
= (quad
->input
.x0
& (TILE_SIZE
-1)) + (j
& 1);
142 int y
= (quad
->input
.y0
& (TILE_SIZE
-1)) + (j
>> 1);
143 for (i
= 0; i
< 4; i
++) {
144 dest
[i
][j
] = tile
->data
.color
[y
][x
][i
];
148 /* convert to ubyte */
149 for (j
= 0; j
< 4; j
++) { /* loop over R,G,B,A channels */
150 dst
[j
][0] = float_to_ubyte(dest
[j
][0]); /* P0 */
151 dst
[j
][1] = float_to_ubyte(dest
[j
][1]); /* P1 */
152 dst
[j
][2] = float_to_ubyte(dest
[j
][2]); /* P2 */
153 dst
[j
][3] = float_to_ubyte(dest
[j
][3]); /* P3 */
155 src
[j
][0] = float_to_ubyte(quadColor
[j
][0]); /* P0 */
156 src
[j
][1] = float_to_ubyte(quadColor
[j
][1]); /* P1 */
157 src
[j
][2] = float_to_ubyte(quadColor
[j
][2]); /* P2 */
158 src
[j
][3] = float_to_ubyte(quadColor
[j
][3]); /* P3 */
161 switch (softpipe
->blend
->logicop_func
) {
162 case PIPE_LOGICOP_CLEAR
:
163 for (j
= 0; j
< 4; j
++)
166 case PIPE_LOGICOP_NOR
:
167 for (j
= 0; j
< 4; j
++)
168 res4
[j
] = ~(src4
[j
] | dst4
[j
]);
170 case PIPE_LOGICOP_AND_INVERTED
:
171 for (j
= 0; j
< 4; j
++)
172 res4
[j
] = ~src4
[j
] & dst4
[j
];
174 case PIPE_LOGICOP_COPY_INVERTED
:
175 for (j
= 0; j
< 4; j
++)
178 case PIPE_LOGICOP_AND_REVERSE
:
179 for (j
= 0; j
< 4; j
++)
180 res4
[j
] = src4
[j
] & ~dst4
[j
];
182 case PIPE_LOGICOP_INVERT
:
183 for (j
= 0; j
< 4; j
++)
186 case PIPE_LOGICOP_XOR
:
187 for (j
= 0; j
< 4; j
++)
188 res4
[j
] = dst4
[j
] ^ src4
[j
];
190 case PIPE_LOGICOP_NAND
:
191 for (j
= 0; j
< 4; j
++)
192 res4
[j
] = ~(src4
[j
] & dst4
[j
]);
194 case PIPE_LOGICOP_AND
:
195 for (j
= 0; j
< 4; j
++)
196 res4
[j
] = src4
[j
] & dst4
[j
];
198 case PIPE_LOGICOP_EQUIV
:
199 for (j
= 0; j
< 4; j
++)
200 res4
[j
] = ~(src4
[j
] ^ dst4
[j
]);
202 case PIPE_LOGICOP_NOOP
:
203 for (j
= 0; j
< 4; j
++)
206 case PIPE_LOGICOP_OR_INVERTED
:
207 for (j
= 0; j
< 4; j
++)
208 res4
[j
] = ~src4
[j
] | dst4
[j
];
210 case PIPE_LOGICOP_COPY
:
211 for (j
= 0; j
< 4; j
++)
214 case PIPE_LOGICOP_OR_REVERSE
:
215 for (j
= 0; j
< 4; j
++)
216 res4
[j
] = src4
[j
] | ~dst4
[j
];
218 case PIPE_LOGICOP_OR
:
219 for (j
= 0; j
< 4; j
++)
220 res4
[j
] = src4
[j
] | dst4
[j
];
222 case PIPE_LOGICOP_SET
:
223 for (j
= 0; j
< 4; j
++)
230 for (j
= 0; j
< 4; j
++) {
231 quadColor
[j
][0] = ubyte_to_float(res
[j
][0]);
232 quadColor
[j
][1] = ubyte_to_float(res
[j
][1]);
233 quadColor
[j
][2] = ubyte_to_float(res
[j
][2]);
234 quadColor
[j
][3] = ubyte_to_float(res
[j
][3]);
238 /* pass quad to next stage */
239 qs
->next
->run(qs
->next
, quad
);
246 blend_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
248 static const float zero
[4] = { 0, 0, 0, 0 };
249 static const float one
[4] = { 1, 1, 1, 1 };
251 struct softpipe_context
*softpipe
= qs
->softpipe
;
254 if (softpipe
->blend
->logicop_enable
) {
255 logicop_quad(qs
, quad
);
259 /* loop over colorbuffer outputs */
260 for (cbuf
= 0; cbuf
< softpipe
->framebuffer
.nr_cbufs
; cbuf
++) {
261 float source
[4][QUAD_SIZE
], dest
[4][QUAD_SIZE
];
262 struct softpipe_cached_tile
*tile
263 = sp_get_cached_tile(softpipe
,
264 softpipe
->cbuf_cache
[cbuf
],
265 quad
->input
.x0
, quad
->input
.y0
);
266 float (*quadColor
)[4] = quad
->output
.color
[cbuf
];
269 /* get/swizzle dest colors */
270 for (j
= 0; j
< QUAD_SIZE
; j
++) {
271 int x
= (quad
->input
.x0
& (TILE_SIZE
-1)) + (j
& 1);
272 int y
= (quad
->input
.y0
& (TILE_SIZE
-1)) + (j
>> 1);
273 for (i
= 0; i
< 4; i
++) {
274 dest
[i
][j
] = tile
->data
.color
[y
][x
][i
];
279 * Compute src/first term RGB
281 switch (softpipe
->blend
->rgb_src_factor
) {
282 case PIPE_BLENDFACTOR_ONE
:
283 VEC4_COPY(source
[0], quadColor
[0]); /* R */
284 VEC4_COPY(source
[1], quadColor
[1]); /* G */
285 VEC4_COPY(source
[2], quadColor
[2]); /* B */
287 case PIPE_BLENDFACTOR_SRC_COLOR
:
288 VEC4_MUL(source
[0], quadColor
[0], quadColor
[0]); /* R */
289 VEC4_MUL(source
[1], quadColor
[1], quadColor
[1]); /* G */
290 VEC4_MUL(source
[2], quadColor
[2], quadColor
[2]); /* B */
292 case PIPE_BLENDFACTOR_SRC_ALPHA
:
294 const float *alpha
= quadColor
[3];
295 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
296 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
297 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
300 case PIPE_BLENDFACTOR_DST_COLOR
:
301 VEC4_MUL(source
[0], quadColor
[0], dest
[0]); /* R */
302 VEC4_MUL(source
[1], quadColor
[1], dest
[1]); /* G */
303 VEC4_MUL(source
[2], quadColor
[2], dest
[2]); /* B */
305 case PIPE_BLENDFACTOR_DST_ALPHA
:
307 const float *alpha
= dest
[3];
308 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
309 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
310 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
313 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
315 const float *alpha
= quadColor
[3];
316 float diff
[4], temp
[4];
317 VEC4_SUB(diff
, one
, dest
[3]);
318 VEC4_MIN(temp
, alpha
, diff
);
319 VEC4_MUL(source
[0], quadColor
[0], temp
); /* R */
320 VEC4_MUL(source
[1], quadColor
[1], temp
); /* G */
321 VEC4_MUL(source
[2], quadColor
[2], temp
); /* B */
324 case PIPE_BLENDFACTOR_CONST_COLOR
:
327 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[0]); /* R */
328 VEC4_MUL(source
[0], quadColor
[0], comp
); /* R */
329 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[1]); /* G */
330 VEC4_MUL(source
[1], quadColor
[1], comp
); /* G */
331 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[2]); /* B */
332 VEC4_MUL(source
[2], quadColor
[2], comp
); /* B */
335 case PIPE_BLENDFACTOR_CONST_ALPHA
:
338 VEC4_SCALAR(alpha
, softpipe
->blend_color
.color
[3]);
339 VEC4_MUL(source
[0], quadColor
[0], alpha
); /* R */
340 VEC4_MUL(source
[1], quadColor
[1], alpha
); /* G */
341 VEC4_MUL(source
[2], quadColor
[2], alpha
); /* B */
344 case PIPE_BLENDFACTOR_SRC1_COLOR
:
345 assert(0); /* to do */
347 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
348 assert(0); /* to do */
350 case PIPE_BLENDFACTOR_ZERO
:
351 VEC4_COPY(source
[0], zero
); /* R */
352 VEC4_COPY(source
[1], zero
); /* G */
353 VEC4_COPY(source
[2], zero
); /* B */
355 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
358 VEC4_SUB(inv_comp
, one
, quadColor
[0]); /* R */
359 VEC4_MUL(source
[0], quadColor
[0], inv_comp
); /* R */
360 VEC4_SUB(inv_comp
, one
, quadColor
[1]); /* G */
361 VEC4_MUL(source
[1], quadColor
[1], inv_comp
); /* G */
362 VEC4_SUB(inv_comp
, one
, quadColor
[2]); /* B */
363 VEC4_MUL(source
[2], quadColor
[2], inv_comp
); /* B */
366 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
369 VEC4_SUB(inv_alpha
, one
, quadColor
[3]);
370 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
371 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
372 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
375 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
378 VEC4_SUB(inv_alpha
, one
, dest
[3]);
379 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
380 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
381 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
384 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
387 VEC4_SUB(inv_comp
, one
, dest
[0]); /* R */
388 VEC4_MUL(source
[0], quadColor
[0], inv_comp
); /* R */
389 VEC4_SUB(inv_comp
, one
, dest
[1]); /* G */
390 VEC4_MUL(source
[1], quadColor
[1], inv_comp
); /* G */
391 VEC4_SUB(inv_comp
, one
, dest
[2]); /* B */
392 VEC4_MUL(source
[2], quadColor
[2], inv_comp
); /* B */
395 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
399 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
400 VEC4_MUL(source
[0], quadColor
[0], inv_comp
);
402 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
403 VEC4_MUL(source
[1], quadColor
[1], inv_comp
);
405 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
406 VEC4_MUL(source
[2], quadColor
[2], inv_comp
);
409 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
412 VEC4_SCALAR(inv_alpha
, 1.0f
- softpipe
->blend_color
.color
[3]);
413 VEC4_MUL(source
[0], quadColor
[0], inv_alpha
); /* R */
414 VEC4_MUL(source
[1], quadColor
[1], inv_alpha
); /* G */
415 VEC4_MUL(source
[2], quadColor
[2], inv_alpha
); /* B */
418 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
419 assert(0); /* to do */
421 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
422 assert(0); /* to do */
429 * Compute src/first term A
431 switch (softpipe
->blend
->alpha_src_factor
) {
432 case PIPE_BLENDFACTOR_ONE
:
433 VEC4_COPY(source
[3], quadColor
[3]); /* A */
435 case PIPE_BLENDFACTOR_SRC_COLOR
:
437 case PIPE_BLENDFACTOR_SRC_ALPHA
:
439 const float *alpha
= quadColor
[3];
440 VEC4_MUL(source
[3], quadColor
[3], alpha
); /* A */
443 case PIPE_BLENDFACTOR_DST_COLOR
:
445 case PIPE_BLENDFACTOR_DST_ALPHA
:
446 VEC4_MUL(source
[3], quadColor
[3], dest
[3]); /* A */
448 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
449 /* multiply alpha by 1.0 */
450 VEC4_COPY(source
[3], quadColor
[3]); /* A */
452 case PIPE_BLENDFACTOR_CONST_COLOR
:
454 case PIPE_BLENDFACTOR_CONST_ALPHA
:
457 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
458 VEC4_MUL(source
[3], quadColor
[3], comp
); /* A */
461 case PIPE_BLENDFACTOR_ZERO
:
462 VEC4_COPY(source
[3], zero
); /* A */
464 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
466 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
469 VEC4_SUB(inv_alpha
, one
, quadColor
[3]);
470 VEC4_MUL(source
[3], quadColor
[3], inv_alpha
); /* A */
473 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
475 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
478 VEC4_SUB(inv_alpha
, one
, dest
[3]);
479 VEC4_MUL(source
[3], quadColor
[3], inv_alpha
); /* A */
482 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
484 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
488 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
489 VEC4_MUL(source
[3], quadColor
[3], inv_comp
);
498 * Compute dest/second term RGB
500 switch (softpipe
->blend
->rgb_dst_factor
) {
501 case PIPE_BLENDFACTOR_ONE
:
502 /* dest = dest * 1 NO-OP, leave dest as-is */
504 case PIPE_BLENDFACTOR_SRC_COLOR
:
505 VEC4_MUL(dest
[0], dest
[0], quadColor
[0]); /* R */
506 VEC4_MUL(dest
[1], dest
[1], quadColor
[1]); /* G */
507 VEC4_MUL(dest
[2], dest
[2], quadColor
[2]); /* B */
509 case PIPE_BLENDFACTOR_SRC_ALPHA
:
510 VEC4_MUL(dest
[0], dest
[0], quadColor
[3]); /* R * A */
511 VEC4_MUL(dest
[1], dest
[1], quadColor
[3]); /* G * A */
512 VEC4_MUL(dest
[2], dest
[2], quadColor
[3]); /* B * A */
514 case PIPE_BLENDFACTOR_DST_ALPHA
:
515 VEC4_MUL(dest
[0], dest
[0], dest
[3]); /* R * A */
516 VEC4_MUL(dest
[1], dest
[1], dest
[3]); /* G * A */
517 VEC4_MUL(dest
[2], dest
[2], dest
[3]); /* B * A */
519 case PIPE_BLENDFACTOR_DST_COLOR
:
520 VEC4_MUL(dest
[0], dest
[0], dest
[0]); /* R */
521 VEC4_MUL(dest
[1], dest
[1], dest
[1]); /* G */
522 VEC4_MUL(dest
[2], dest
[2], dest
[2]); /* B */
524 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
525 assert(0); /* illegal */
527 case PIPE_BLENDFACTOR_CONST_COLOR
:
530 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[0]); /* R */
531 VEC4_MUL(dest
[0], dest
[0], comp
); /* R */
532 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[1]); /* G */
533 VEC4_MUL(dest
[1], dest
[1], comp
); /* G */
534 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[2]); /* B */
535 VEC4_MUL(dest
[2], dest
[2], comp
); /* B */
538 case PIPE_BLENDFACTOR_CONST_ALPHA
:
541 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
542 VEC4_MUL(dest
[0], dest
[0], comp
); /* R */
543 VEC4_MUL(dest
[1], dest
[1], comp
); /* G */
544 VEC4_MUL(dest
[2], dest
[2], comp
); /* B */
547 case PIPE_BLENDFACTOR_ZERO
:
548 VEC4_COPY(dest
[0], zero
); /* R */
549 VEC4_COPY(dest
[1], zero
); /* G */
550 VEC4_COPY(dest
[2], zero
); /* B */
552 case PIPE_BLENDFACTOR_SRC1_COLOR
:
553 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
554 /* XXX what are these? */
557 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
560 VEC4_SUB(inv_comp
, one
, quadColor
[0]); /* R */
561 VEC4_MUL(dest
[0], inv_comp
, dest
[0]); /* R */
562 VEC4_SUB(inv_comp
, one
, quadColor
[1]); /* G */
563 VEC4_MUL(dest
[1], inv_comp
, dest
[1]); /* G */
564 VEC4_SUB(inv_comp
, one
, quadColor
[2]); /* B */
565 VEC4_MUL(dest
[2], inv_comp
, dest
[2]); /* B */
568 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
570 float one_minus_alpha
[QUAD_SIZE
];
571 VEC4_SUB(one_minus_alpha
, one
, quadColor
[3]);
572 VEC4_MUL(dest
[0], dest
[0], one_minus_alpha
); /* R */
573 VEC4_MUL(dest
[1], dest
[1], one_minus_alpha
); /* G */
574 VEC4_MUL(dest
[2], dest
[2], one_minus_alpha
); /* B */
577 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
580 VEC4_SUB(inv_comp
, one
, dest
[3]); /* A */
581 VEC4_MUL(dest
[0], inv_comp
, dest
[0]); /* R */
582 VEC4_MUL(dest
[1], inv_comp
, dest
[1]); /* G */
583 VEC4_MUL(dest
[2], inv_comp
, dest
[2]); /* B */
586 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
589 VEC4_SUB(inv_comp
, one
, dest
[0]); /* R */
590 VEC4_MUL(dest
[0], dest
[0], inv_comp
); /* R */
591 VEC4_SUB(inv_comp
, one
, dest
[1]); /* G */
592 VEC4_MUL(dest
[1], dest
[1], inv_comp
); /* G */
593 VEC4_SUB(inv_comp
, one
, dest
[2]); /* B */
594 VEC4_MUL(dest
[2], dest
[2], inv_comp
); /* B */
597 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
601 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
602 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
604 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
605 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
607 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
608 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
611 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
614 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
615 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
616 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
617 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
620 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
621 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
622 /* XXX what are these? */
630 * Compute dest/second term A
632 switch (softpipe
->blend
->alpha_dst_factor
) {
633 case PIPE_BLENDFACTOR_ONE
:
634 /* dest = dest * 1 NO-OP, leave dest as-is */
636 case PIPE_BLENDFACTOR_SRC_COLOR
:
638 case PIPE_BLENDFACTOR_SRC_ALPHA
:
639 VEC4_MUL(dest
[3], dest
[3], quadColor
[3]); /* A * A */
641 case PIPE_BLENDFACTOR_DST_COLOR
:
643 case PIPE_BLENDFACTOR_DST_ALPHA
:
644 VEC4_MUL(dest
[3], dest
[3], dest
[3]); /* A */
646 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
647 assert(0); /* illegal */
649 case PIPE_BLENDFACTOR_CONST_COLOR
:
651 case PIPE_BLENDFACTOR_CONST_ALPHA
:
654 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
655 VEC4_MUL(dest
[3], dest
[3], comp
); /* A */
658 case PIPE_BLENDFACTOR_ZERO
:
659 VEC4_COPY(dest
[3], zero
); /* A */
661 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
663 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
665 float one_minus_alpha
[QUAD_SIZE
];
666 VEC4_SUB(one_minus_alpha
, one
, quadColor
[3]);
667 VEC4_MUL(dest
[3], dest
[3], one_minus_alpha
); /* A */
670 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
672 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
675 VEC4_SUB(inv_comp
, one
, dest
[3]); /* A */
676 VEC4_MUL(dest
[3], inv_comp
, dest
[3]); /* A */
679 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
681 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
684 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
685 VEC4_MUL(dest
[3], dest
[3], inv_comp
);
695 switch (softpipe
->blend
->rgb_func
) {
697 VEC4_ADD_SAT(quadColor
[0], source
[0], dest
[0]); /* R */
698 VEC4_ADD_SAT(quadColor
[1], source
[1], dest
[1]); /* G */
699 VEC4_ADD_SAT(quadColor
[2], source
[2], dest
[2]); /* B */
701 case PIPE_BLEND_SUBTRACT
:
702 VEC4_SUB_SAT(quadColor
[0], source
[0], dest
[0]); /* R */
703 VEC4_SUB_SAT(quadColor
[1], source
[1], dest
[1]); /* G */
704 VEC4_SUB_SAT(quadColor
[2], source
[2], dest
[2]); /* B */
706 case PIPE_BLEND_REVERSE_SUBTRACT
:
707 VEC4_SUB_SAT(quadColor
[0], dest
[0], source
[0]); /* R */
708 VEC4_SUB_SAT(quadColor
[1], dest
[1], source
[1]); /* G */
709 VEC4_SUB_SAT(quadColor
[2], dest
[2], source
[2]); /* B */
712 VEC4_MIN(quadColor
[0], source
[0], dest
[0]); /* R */
713 VEC4_MIN(quadColor
[1], source
[1], dest
[1]); /* G */
714 VEC4_MIN(quadColor
[2], source
[2], dest
[2]); /* B */
717 VEC4_MAX(quadColor
[0], source
[0], dest
[0]); /* R */
718 VEC4_MAX(quadColor
[1], source
[1], dest
[1]); /* G */
719 VEC4_MAX(quadColor
[2], source
[2], dest
[2]); /* B */
728 switch (softpipe
->blend
->alpha_func
) {
730 VEC4_ADD_SAT(quadColor
[3], source
[3], dest
[3]); /* A */
732 case PIPE_BLEND_SUBTRACT
:
733 VEC4_SUB_SAT(quadColor
[3], source
[3], dest
[3]); /* A */
735 case PIPE_BLEND_REVERSE_SUBTRACT
:
736 VEC4_SUB_SAT(quadColor
[3], dest
[3], source
[3]); /* A */
739 VEC4_MIN(quadColor
[3], source
[3], dest
[3]); /* A */
742 VEC4_MAX(quadColor
[3], source
[3], dest
[3]); /* A */
750 /* pass blended quad to next stage */
751 qs
->next
->run(qs
->next
, quad
);
755 static void blend_begin(struct quad_stage
*qs
)
757 qs
->next
->begin(qs
->next
);
761 static void blend_destroy(struct quad_stage
*qs
)
767 struct quad_stage
*sp_quad_blend_stage( struct softpipe_context
*softpipe
)
769 struct quad_stage
*stage
= CALLOC_STRUCT(quad_stage
);
771 stage
->softpipe
= softpipe
;
772 stage
->begin
= blend_begin
;
773 stage
->run
= blend_quad
;
774 stage
->destroy
= blend_destroy
;