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
, softpipe
->cbuf_cache
[0],
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
];
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 */
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 */
136 switch (softpipe
->blend
->logicop_func
) {
137 case PIPE_LOGICOP_CLEAR
:
138 for (j
= 0; j
< 4; j
++)
141 case PIPE_LOGICOP_NOR
:
142 for (j
= 0; j
< 4; j
++)
143 res4
[j
] = ~(src4
[j
] | dst4
[j
]);
145 case PIPE_LOGICOP_AND_INVERTED
:
146 for (j
= 0; j
< 4; j
++)
147 res4
[j
] = ~src4
[j
] & dst4
[j
];
149 case PIPE_LOGICOP_COPY_INVERTED
:
150 for (j
= 0; j
< 4; j
++)
153 case PIPE_LOGICOP_AND_REVERSE
:
154 for (j
= 0; j
< 4; j
++)
155 res4
[j
] = src4
[j
] & ~dst4
[j
];
157 case PIPE_LOGICOP_INVERT
:
158 for (j
= 0; j
< 4; j
++)
161 case PIPE_LOGICOP_XOR
:
162 for (j
= 0; j
< 4; j
++)
163 res4
[j
] = dst4
[j
] ^ src4
[j
];
165 case PIPE_LOGICOP_NAND
:
166 for (j
= 0; j
< 4; j
++)
167 res4
[j
] = ~(src4
[j
] & dst4
[j
]);
169 case PIPE_LOGICOP_AND
:
170 for (j
= 0; j
< 4; j
++)
171 res4
[j
] = src4
[j
] & dst4
[j
];
173 case PIPE_LOGICOP_EQUIV
:
174 for (j
= 0; j
< 4; j
++)
175 res4
[j
] = ~(src4
[j
] ^ dst4
[j
]);
177 case PIPE_LOGICOP_NOOP
:
178 for (j
= 0; j
< 4; j
++)
181 case PIPE_LOGICOP_OR_INVERTED
:
182 for (j
= 0; j
< 4; j
++)
183 res4
[j
] = ~src4
[j
] | dst4
[j
];
185 case PIPE_LOGICOP_COPY
:
186 for (j
= 0; j
< 4; j
++)
189 case PIPE_LOGICOP_OR_REVERSE
:
190 for (j
= 0; j
< 4; j
++)
191 res4
[j
] = src4
[j
] | ~dst4
[j
];
193 case PIPE_LOGICOP_OR
:
194 for (j
= 0; j
< 4; j
++)
195 res4
[j
] = src4
[j
] | dst4
[j
];
197 case PIPE_LOGICOP_SET
:
198 for (j
= 0; j
< 4; j
++)
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]);
212 /* pass quad to next stage */
213 qs
->next
->run(qs
->next
, quad
);
220 blend_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
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],
231 if (softpipe
->blend
->logicop_enable
) {
232 logicop_quad(qs
, quad
);
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
];
246 * Compute src/first term RGB
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 */
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 */
259 case PIPE_BLENDFACTOR_SRC_ALPHA
:
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 */
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 */
272 case PIPE_BLENDFACTOR_DST_ALPHA
:
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 */
280 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
282 const float *alpha
= quad
->outputs
.color
[3];
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 */
290 case PIPE_BLENDFACTOR_CONST_COLOR
:
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 */
301 case PIPE_BLENDFACTOR_CONST_ALPHA
:
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 */
310 case PIPE_BLENDFACTOR_SRC1_COLOR
:
311 assert(0); /* to do */
313 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
314 assert(0); /* to do */
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 */
321 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
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 */
332 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
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 */
341 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
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 */
350 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
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 */
361 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
365 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
366 VEC4_MUL(source
[0], quad
->outputs
.color
[0], inv_comp
);
368 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
369 VEC4_MUL(source
[1], quad
->outputs
.color
[1], inv_comp
);
371 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
372 VEC4_MUL(source
[2], quad
->outputs
.color
[2], inv_comp
);
375 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
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 */
384 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
385 assert(0); /* to do */
387 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
388 assert(0); /* to do */
395 * Compute src/first term A
397 switch (softpipe
->blend
->alpha_src_factor
) {
398 case PIPE_BLENDFACTOR_ONE
:
399 VEC4_COPY(source
[3], quad
->outputs
.color
[3]); /* A */
401 case PIPE_BLENDFACTOR_SRC_COLOR
:
403 case PIPE_BLENDFACTOR_SRC_ALPHA
:
405 const float *alpha
= quad
->outputs
.color
[3];
406 VEC4_MUL(source
[3], quad
->outputs
.color
[3], alpha
); /* A */
409 case PIPE_BLENDFACTOR_DST_COLOR
:
411 case PIPE_BLENDFACTOR_DST_ALPHA
:
412 VEC4_MUL(source
[3], quad
->outputs
.color
[3], dest
[3]); /* A */
414 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
416 const float *alpha
= quad
->outputs
.color
[3];
418 VEC4_SUB(diff
, one
, dest
[3]);
419 VEC4_MIN(source
[3], alpha
, diff
); /* A */
422 case PIPE_BLENDFACTOR_CONST_COLOR
:
424 case PIPE_BLENDFACTOR_CONST_ALPHA
:
427 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
428 VEC4_MUL(source
[3], quad
->outputs
.color
[3], comp
); /* A */
431 case PIPE_BLENDFACTOR_ZERO
:
432 VEC4_COPY(source
[3], zero
); /* A */
434 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
436 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
439 VEC4_SUB(inv_alpha
, one
, quad
->outputs
.color
[3]);
440 VEC4_MUL(source
[3], quad
->outputs
.color
[3], inv_alpha
); /* A */
443 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
445 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
448 VEC4_SUB(inv_alpha
, one
, dest
[3]);
449 VEC4_MUL(source
[3], quad
->outputs
.color
[3], inv_alpha
); /* A */
452 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
454 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
458 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
459 VEC4_MUL(source
[3], quad
->outputs
.color
[3], inv_comp
);
468 * Compute dest/second term RGB
470 switch (softpipe
->blend
->rgb_dst_factor
) {
471 case PIPE_BLENDFACTOR_ONE
:
472 /* dest = dest * 1 NO-OP, leave dest as-is */
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 */
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 */
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 */
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 */
494 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
495 assert(0); /* illegal */
497 case PIPE_BLENDFACTOR_CONST_COLOR
:
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 */
508 case PIPE_BLENDFACTOR_CONST_ALPHA
:
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 */
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 */
522 case PIPE_BLENDFACTOR_SRC1_COLOR
:
523 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
524 /* XXX what are these? */
527 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
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 */
538 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
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 */
547 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
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 */
556 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
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 */
567 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
571 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[0]);
572 VEC4_MUL(dest
[0], dest
[0], inv_comp
);
574 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[1]);
575 VEC4_MUL(dest
[1], dest
[1], inv_comp
);
577 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[2]);
578 VEC4_MUL(dest
[2], dest
[2], inv_comp
);
581 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
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
);
590 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
591 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
592 /* XXX what are these? */
600 * Compute dest/second term A
602 switch (softpipe
->blend
->alpha_dst_factor
) {
603 case PIPE_BLENDFACTOR_ONE
:
604 /* dest = dest * 1 NO-OP, leave dest as-is */
606 case PIPE_BLENDFACTOR_SRC_COLOR
:
608 case PIPE_BLENDFACTOR_SRC_ALPHA
:
609 VEC4_MUL(dest
[3], dest
[3], quad
->outputs
.color
[3]); /* A * A */
611 case PIPE_BLENDFACTOR_DST_COLOR
:
613 case PIPE_BLENDFACTOR_DST_ALPHA
:
614 VEC4_MUL(dest
[3], dest
[3], dest
[3]); /* A */
616 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
617 assert(0); /* illegal */
619 case PIPE_BLENDFACTOR_CONST_COLOR
:
621 case PIPE_BLENDFACTOR_CONST_ALPHA
:
624 VEC4_SCALAR(comp
, softpipe
->blend_color
.color
[3]); /* A */
625 VEC4_MUL(dest
[3], dest
[3], comp
); /* A */
628 case PIPE_BLENDFACTOR_ZERO
:
629 VEC4_COPY(dest
[3], zero
); /* A */
631 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
633 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
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 */
640 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
642 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
645 VEC4_SUB(inv_comp
, one
, dest
[3]); /* A */
646 VEC4_MUL(dest
[3], inv_comp
, dest
[3]); /* A */
649 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
651 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
654 VEC4_SCALAR(inv_comp
, 1.0f
- softpipe
->blend_color
.color
[3]);
655 VEC4_MUL(dest
[3], dest
[3], inv_comp
);
665 switch (softpipe
->blend
->rgb_func
) {
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 */
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 */
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 */
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 */
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 */
698 switch (softpipe
->blend
->alpha_func
) {
700 VEC4_ADD(quad
->outputs
.color
[3], source
[3], dest
[3]); /* A */
702 case PIPE_BLEND_SUBTRACT
:
703 VEC4_SUB(quad
->outputs
.color
[3], source
[3], dest
[3]); /* A */
705 case PIPE_BLEND_REVERSE_SUBTRACT
:
706 VEC4_SUB(quad
->outputs
.color
[3], dest
[3], source
[3]); /* A */
709 VEC4_MIN(quad
->outputs
.color
[3], source
[3], dest
[3]); /* A */
712 VEC4_MAX(quad
->outputs
.color
[3], source
[3], dest
[3]); /* A */
718 /* pass blended quad to next stage */
719 qs
->next
->run(qs
->next
, quad
);
723 static void blend_begin(struct quad_stage
*qs
)
726 qs
->next
->begin(qs
->next
);
730 static void blend_destroy(struct quad_stage
*qs
)
736 struct quad_stage
*sp_quad_blend_stage( struct softpipe_context
*softpipe
)
738 struct quad_stage
*stage
= CALLOC_STRUCT(quad_stage
);
740 stage
->softpipe
= softpipe
;
741 stage
->begin
= blend_begin
;
742 stage
->run
= blend_quad
;
743 stage
->destroy
= blend_destroy
;