s_blend.c revision f431a3fb4dc1bf860203d79e54657e3a62bc50df
1f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul/* $Id: s_blend.c,v 1.8 2001/07/13 20:07:37 brianp Exp $ */
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
4e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
5e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Version:  3.5
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
16e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
26e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
27e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
28e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
29e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "glheader.h"
30e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "context.h"
31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "macros.h"
32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alphabuf.h"
34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h"
35cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
36e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_pb.h"
37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
40cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#if defined(USE_MMX_ASM)
41cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "X86/mmx.h"
42cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "X86/common_x86_asm.h"
43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define _BLENDAPI _ASMAPI
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#else
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define _BLENDAPI
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
48cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Common transparency blending mode.
51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
54e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                    GLchan rgba[][4], CONST GLchan dest[][4] )
55e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
56e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
57e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
58e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA);
59e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA);
60e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
61e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
62e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
63e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
64e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         const GLint t = rgba[i][ACOMP];  /* t in [0, CHAN_MAX] */
65e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (t == 0) {
66e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* 0% alpha */
67e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][RCOMP] = dest[i][RCOMP];
68e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][GCOMP] = dest[i][GCOMP];
69e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][BCOMP] = dest[i][BCOMP];
70e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][ACOMP] = dest[i][ACOMP];
71e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
72e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (t == CHAN_MAX) {
73e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* 100% alpha, no-op */
74e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
75e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
76e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#if 0
77e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This is pretty close, but Glean complains */
78e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint s = CHAN_MAX - t;
79e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s + 1) >> 8;
80e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s + 1) >> 8;
81e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s + 1) >> 8;
82e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s + 1) >> 8;
83e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#elif 0
84e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This is slower but satisfies Glean */
85e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint s = CHAN_MAX - t;
86e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) / 255;
87e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) / 255;
88e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) / 255;
89e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) / 255;
90e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#else
91e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#if CHAN_BITS == 8
92e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This satisfies Glean and should be reasonably fast */
93e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* Contributed by Nathan Hand */
94e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define DIV255(X)  (((X) << 8) + (X) + 256) >> 16
95e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint s = CHAN_MAX - t;
96e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint r = DIV255(rgba[i][RCOMP] * t + dest[i][RCOMP] * s);
97e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint g = DIV255(rgba[i][GCOMP] * t + dest[i][GCOMP] * s);
98e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint b = DIV255(rgba[i][BCOMP] * t + dest[i][BCOMP] * s);
99e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint a = DIV255(rgba[i][ACOMP] * t + dest[i][ACOMP] * s);
100e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef DIV255
10101915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul#elif CHAN_BITS == 16
10201915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat tt = (GLfloat) t / CHAN_MAXF;
10301915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat s = 1.0 - tt;
10401915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLint r = (GLint) (rgba[i][RCOMP] * tt + dest[i][RCOMP] * s);
10501915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLint g = (GLint) (rgba[i][GCOMP] * tt + dest[i][GCOMP] * s);
10601915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLint b = (GLint) (rgba[i][BCOMP] * tt + dest[i][BCOMP] * s);
10701915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLint a = (GLint) (rgba[i][ACOMP] * tt + dest[i][ACOMP] * s);
10801915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul#else /* CHAN_BITS == 32 */
10901915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat tt = (GLfloat) t / CHAN_MAXF;
11001915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat s = 1.0 - tt;
11101915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat r = rgba[i][RCOMP] * tt + dest[i][RCOMP] * s;
11201915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat g = rgba[i][GCOMP] * tt + dest[i][GCOMP] * s;
11301915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat b = rgba[i][BCOMP] * tt + dest[i][BCOMP] * s;
11401915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat a = rgba[i][ACOMP] * tt + dest[i][ACOMP] * s;
115e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
117e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(r <= CHAN_MAX);
118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(g <= CHAN_MAX);
119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(b <= CHAN_MAX);
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(a <= CHAN_MAX);
121e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][RCOMP] = (GLchan) r;
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][GCOMP] = (GLchan) g;
123e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][BCOMP] = (GLchan) b;
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][ACOMP] = (GLchan) a;
125e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
128e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
129e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
130e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
131e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
132e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
133e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add src and dest.
134e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
135e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
137e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
138e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
139e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
140e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
141e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
142e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
143e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
144e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
145e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
146e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
147e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
148e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
149e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
150e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
151e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MIN2( r, CHAN_MAX );
152e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MIN2( g, CHAN_MAX );
153e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MIN2( b, CHAN_MAX );
154e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAX );
155e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
156e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
157e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
158e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
159e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
160e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
161e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
162e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Blend min function  (for GL_EXT_blend_minmax)
163e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
164e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
165e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
166e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
167e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
168e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
169e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_MIN_EXT);
170e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
171e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
172e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
173e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
174e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
175e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
176e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
177e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
178e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
179e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
180e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
181e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
182e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
183e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
184e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
185e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Blend max function  (for GL_EXT_blend_minmax)
186e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
187e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
188e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
189e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
190e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
191e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
192e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_MAX_EXT);
193e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
194e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
195e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
196e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
197e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
198e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
199e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
200e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
201e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
202e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
203e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
204e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
205e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
206e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
207e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
208e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Modulate:  result = src * dest
209e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
210e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
211e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
212e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                GLchan rgba[][4], CONST GLchan dest[][4] )
213e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
214e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
215e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
216e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
217e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
218e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
219f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#if CHAN_TYPE == GL_FLOAT
220f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP];
221f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
222f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
223f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
224f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#else
225e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint r = (rgba[i][RCOMP] * dest[i][RCOMP]) >> 8;
226e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint g = (rgba[i][GCOMP] * dest[i][GCOMP]) >> 8;
227e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint b = (rgba[i][BCOMP] * dest[i][BCOMP]) >> 8;
228e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint a = (rgba[i][ACOMP] * dest[i][ACOMP]) >> 8;
229e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) r;
230e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) g;
231e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) b;
232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) a;
233f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#endif
234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
238e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
240e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * General case blend pixels.
242e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Input:  n - number of pixels
243e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *         mask - the usual write mask
244e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * In/Out:  rgba - the incoming and modified pixels
245e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Input:  dest - the pixels from the dest color buffer
246e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
247e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
248e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
249e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               GLchan rgba[][4], CONST GLchan dest[][4] )
250e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
251e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat rscale = 1.0F / CHAN_MAXF;
252e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat gscale = 1.0F / CHAN_MAXF;
253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat bscale = 1.0F / CHAN_MAXF;
254e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat ascale = 1.0F / CHAN_MAXF;
255e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
256e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
257e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
258e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
259e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint Rs, Gs, Bs, As;  /* Source colors */
260e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint Rd, Gd, Bd, Ad;  /* Dest colors */
261e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat sR, sG, sB, sA;  /* Source scaling */
262e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat dR, dG, dB, dA;  /* Dest scaling */
263e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat r, g, b, a;
264e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
265e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source Color */
266e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Rs = rgba[i][RCOMP];
267e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Gs = rgba[i][GCOMP];
268e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Bs = rgba[i][BCOMP];
269e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         As = rgba[i][ACOMP];
270e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
271e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Frame buffer color */
272e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Rd = dest[i][RCOMP];
273e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Gd = dest[i][GCOMP];
274e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Bd = dest[i][BCOMP];
275e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Ad = dest[i][ACOMP];
276e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
277e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source RGB factor */
278e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendSrcRGB) {
279e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
280e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 0.0F;
281e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
283e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F;
284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
285e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR:
286e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = (GLfloat) Rd * rscale;
287e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = (GLfloat) Gd * gscale;
288e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = (GLfloat) Bd * bscale;
289e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
290e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR:
291e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - (GLfloat) Rd * rscale;
292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - (GLfloat) Gd * gscale;
293e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - (GLfloat) Bd * bscale;
294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
295e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
296e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) As * ascale;
297e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) 1.0F - (GLfloat) As * ascale;
300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) Ad * ascale;
303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA_SATURATE:
308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               if (As < CHAN_MAX - Ad) {
309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  sR = sG = sB = (GLfloat) As * ascale;
310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = ctx->Color.BlendColor[0];
317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = ctx->Color.BlendColor[1];
318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = ctx->Color.BlendColor[2];
319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
320e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - ctx->Color.BlendColor[0];
322e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - ctx->Color.BlendColor[1];
323e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - ctx->Color.BlendColor[2];
324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
325e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = ctx->Color.BlendColor[3];
327e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
328e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
331e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR: /* GL_NV_blend_square */
332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = (GLfloat) Rs * rscale;
333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = (GLfloat) Gs * gscale;
334e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = (GLfloat) Bs * bscale;
335e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
336e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
337e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - (GLfloat) Rs * rscale;
338e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - (GLfloat) Gs * gscale;
339e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - (GLfloat) Bs * bscale;
340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
342e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
34308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend source RGB factor in do_blend");
344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	       return;
345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
346e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
347e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source Alpha factor */
348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendSrcA) {
349e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 0.0F;
351e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
352e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
353e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F;
354e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR:
356e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) Ad * ascale;
357e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
358e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR:
359e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) Ad * ascale;
360e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
361e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
362e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) As * ascale;
363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) 1.0F - (GLfloat) As * ascale;
366e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
367e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
368e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA =(GLfloat) Ad * ascale;
369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
370e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
371e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) Ad * ascale;
372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
373e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA_SATURATE:
374e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0;
375e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
376e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
377e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = ctx->Color.BlendColor[3];
378e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - ctx->Color.BlendColor[3];
381e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
382e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = ctx->Color.BlendColor[3];
384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - ctx->Color.BlendColor[3];
387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
388e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR: /* GL_NV_blend_square */
389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) As * ascale;
390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
391e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
392e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) As * ascale;
393e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
394e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
395e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
396e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 0.0F;
39708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend source A factor in do_blend");
398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
399e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
400e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Dest RGB factor */
401e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendDstRGB) {
402e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
403e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 0.0F;
404e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
405e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F;
407e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
408e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR:
409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = (GLfloat) Rs * rscale;
410e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = (GLfloat) Gs * gscale;
411e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = (GLfloat) Bs * bscale;
412e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
413e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR:
414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - (GLfloat) Rs * rscale;
415e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - (GLfloat) Gs * gscale;
416e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - (GLfloat) Bs * bscale;
417e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
419e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) As * ascale;
420e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
421e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
422e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) 1.0F - (GLfloat) As * ascale;
423e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
424e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
425e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) Ad * ascale;
426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
427e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
428e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F - (GLfloat) Ad * ascale;
429e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
430e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
431e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = ctx->Color.BlendColor[0];
432e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = ctx->Color.BlendColor[1];
433e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = ctx->Color.BlendColor[2];
434e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
435e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
436e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - ctx->Color.BlendColor[0];
437e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - ctx->Color.BlendColor[1];
438e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - ctx->Color.BlendColor[2];
439e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
440e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
441e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = ctx->Color.BlendColor[3];
442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
444e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
445e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
446e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR: /* GL_NV_blend_square */
447e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = (GLfloat) Rd * rscale;
448e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = (GLfloat) Gd * gscale;
449e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = (GLfloat) Bd * bscale;
450e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
451e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
452e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - (GLfloat) Rd * rscale;
453e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - (GLfloat) Gd * gscale;
454e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - (GLfloat) Bd * bscale;
455e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
456e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
457e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
458e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 0.0F;
45908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend dest RGB factor in do_blend");
460e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Dest Alpha factor */
463e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendDstA) {
464e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
465e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 0.0F;
466e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
467e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
468e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F;
469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
470e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR:
471e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) As * ascale;
472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
473e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR:
474e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) As * ascale;
475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
476e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
477e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) As * ascale;
478e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
479e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
480e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) 1.0F - (GLfloat) As * ascale;
481e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
482e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
483e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) Ad * ascale;
484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
485e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) Ad * ascale;
487e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
489e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = ctx->Color.BlendColor[3];
490e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
492e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - ctx->Color.BlendColor[3];
493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = ctx->Color.BlendColor[3];
496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - ctx->Color.BlendColor[3];
499e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
500e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR: /* GL_NV_blend_square */
501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) Ad * ascale;
502e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) Ad * ascale;
505e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
506e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
508e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 0.0F;
50908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend dest A factor in do_blend");
510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	       return;
511e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
512e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
513e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Due to round-off problems we have to clamp against zero. */
514e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Optimization: we don't have to do this for all src & dst factors */
515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dA < 0.0F)  dA = 0.0F;
516e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dR < 0.0F)  dR = 0.0F;
517e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dG < 0.0F)  dG = 0.0F;
518e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dB < 0.0F)  dB = 0.0F;
519e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sA < 0.0F)  sA = 0.0F;
520e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sR < 0.0F)  sR = 0.0F;
521e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sG < 0.0F)  sG = 0.0F;
522e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sB < 0.0F)  sB = 0.0F;
523e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
524e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sR <= 1.0 );
525e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sG <= 1.0 );
526e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sB <= 1.0 );
527e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sA <= 1.0 );
528e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dR <= 1.0 );
529e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dG <= 1.0 );
530e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dB <= 1.0 );
531e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dA <= 1.0 );
532e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
533e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* compute blended color */
534e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
535e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rs * sR + Rd * dR + 0.5F;
536e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gs * sG + Gd * dG + 0.5F;
537e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bs * sB + Bd * dB + 0.5F;
538e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = As * sA + Ad * dA + 0.5F;
539e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
541e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rs * sR - Rd * dR + 0.5F;
542e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gs * sG - Gd * dG + 0.5F;
543e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bs * sB - Bd * dB + 0.5F;
544e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = As * sA - Ad * dA + 0.5F;
545e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
546e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
547e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rd * dR - Rs * sR + 0.5F;
548e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gd * dG - Gs * sG + 0.5F;
549e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bd * dB - Bs * sB + 0.5F;
550e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = Ad * dA - As * sA + 0.5F;
551e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
552e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
553e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* should never get here */
554e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = g = b = a = 0.0F;  /* silence uninitialized var warning */
55508836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
556e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
557e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
558e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* final clamping */
559e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) (GLint) CLAMP( r, 0.0F, CHAN_MAXF );
560e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) (GLint) CLAMP( g, 0.0F, CHAN_MAXF );
561e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) (GLint) CLAMP( b, 0.0F, CHAN_MAXF );
562e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) (GLint) CLAMP( a, 0.0F, CHAN_MAXF );
563e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
564e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
565e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
566e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
567e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
568e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
569e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
570e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
571e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
572e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Analyze current blending parameters to pick fastest blending function.
573e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Result: the ctx->Color.BlendFunc pointer is updated.
574e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
575cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwellvoid _swrast_choose_blend_func( GLcontext *ctx )
576e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
577e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum eq = ctx->Color.BlendEquation;
578e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum srcRGB = ctx->Color.BlendSrcRGB;
579e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum dstRGB = ctx->Color.BlendDstRGB;
580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum srcA = ctx->Color.BlendSrcA;
581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum dstA = ctx->Color.BlendDstA;
582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
583e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (srcRGB != srcA || dstRGB != dstA) {
584cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
585e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
586e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA
58722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	    && dstRGB==GL_ONE_MINUS_SRC_ALPHA)
588cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   {
589cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#if defined(USE_MMX_ASM)
590cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      if ( cpu_has_mmx ) {
591865322f931197c5c73c57b366b64300894565dabBrian Paul	 SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency;
592cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      }
593cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      else
594cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#endif
595cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	 SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency;
596e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
597e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) {
598cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_add;
599e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
601cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	     && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
602cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	    ||
603cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	    ((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
604cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	     && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
605cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate;
606e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_MIN_EXT) {
608cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_min;
609e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
610e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_MAX_EXT) {
611cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_max;
612e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
613e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
614cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
615e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
616e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
617e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
618e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
619e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
621e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the blending operator to a span of pixels.
622e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Input:  n - number of pixels in span
623e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *         x, y - location of leftmost pixel in span in window coords.
624e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *         mask - boolean mask indicating which pixels to blend.
625e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * In/Out:  rgba - pixel values
626e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
627e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
628e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
629e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  GLchan rgba[][4], const GLubyte mask[] )
630e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
631e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLchan dest[MAX_WIDTH][4];
632e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
633e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Check if device driver can do the work */
634e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Color.BlendEquation==GL_LOGIC_OP &&
635e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       !ctx->Color.ColorLogicOpEnabled) {
636e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      return;
637e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
638e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Read span of current frame buffer pixels */
64008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul   _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
641e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
64222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   SWRAST_CONTEXT(ctx)->BlendFunc( ctx, n, mask, rgba,
64301915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul				   (const GLchan (*)[4]) dest );
644e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
645e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
646e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
647e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
648e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
649e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the blending operator to an array of pixels.
650e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Input:  n - number of pixels in span
651e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *         x, y - array of pixel locations
652e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *         mask - boolean mask indicating which pixels to blend.
653e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * In/Out:  rgba - pixel values
654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
655e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
656e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell_mesa_blend_pixels( GLcontext *ctx,
657e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                    GLuint n, const GLint x[], const GLint y[],
658e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                    GLchan rgba[][4], const GLubyte mask[] )
659e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
660cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
661e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLchan dest[PB_SIZE][4];
662e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
663e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Check if device driver can do the work */
664e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Color.BlendEquation==GL_LOGIC_OP &&
665e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       !ctx->Color.ColorLogicOpEnabled) {
666e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      return;
667e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
668e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
669e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Read pixels from current color buffer */
670709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
671cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   if (swrast->_RasterMask & ALPHABUF_BIT) {
672e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
673e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
674e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
675cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   swrast->BlendFunc( ctx, n, mask, rgba, (const GLchan (*)[4])dest );
676e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
677