s_blend.c revision 12a1024d9d003afe1212cc48af04dac81c034299
112a1024d9d003afe1212cc48af04dac81c034299Karl Schultz/* $Id: s_blend.c,v 1.13 2002/02/12 16:45:22 kschultz Exp $ */
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
4e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
559235bd5da794557613463bc942de0c634d2d961Brian Paul * Version:  4.1
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Copyright (C) 1999-2002  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_span.h"
37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
39cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#if defined(USE_MMX_ASM)
40cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "X86/mmx.h"
41cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "X86/common_x86_asm.h"
42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define _BLENDAPI _ASMAPI
43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#else
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define _BLENDAPI
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
47cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
4959235bd5da794557613463bc942de0c634d2d961Brian Paul * Special case for glBlendFunc(GL_ZERO, GL_ONE)
5059235bd5da794557613463bc942de0c634d2d961Brian Paul */
5159235bd5da794557613463bc942de0c634d2d961Brian Paulstatic void _BLENDAPI
5259235bd5da794557613463bc942de0c634d2d961Brian Paulblend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[],
5359235bd5da794557613463bc942de0c634d2d961Brian Paul            GLchan rgba[][4], CONST GLchan dest[][4] )
5459235bd5da794557613463bc942de0c634d2d961Brian Paul{
5512a1024d9d003afe1212cc48af04dac81c034299Karl Schultz   GLuint i;
5659235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
5759235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendSrcRGB==GL_ZERO);
5859235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
5959235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) ctx;
6059235bd5da794557613463bc942de0c634d2d961Brian Paul
6159235bd5da794557613463bc942de0c634d2d961Brian Paul   for (i = 0; i < n; i++) {
6259235bd5da794557613463bc942de0c634d2d961Brian Paul      if (mask[i]) {
6359235bd5da794557613463bc942de0c634d2d961Brian Paul         rgba[i][RCOMP] = dest[i][RCOMP];
6459235bd5da794557613463bc942de0c634d2d961Brian Paul         rgba[i][GCOMP] = dest[i][GCOMP];
6559235bd5da794557613463bc942de0c634d2d961Brian Paul         rgba[i][BCOMP] = dest[i][BCOMP];
6659235bd5da794557613463bc942de0c634d2d961Brian Paul         rgba[i][ACOMP] = dest[i][ACOMP];
6759235bd5da794557613463bc942de0c634d2d961Brian Paul      }
6859235bd5da794557613463bc942de0c634d2d961Brian Paul   }
6959235bd5da794557613463bc942de0c634d2d961Brian Paul}
7059235bd5da794557613463bc942de0c634d2d961Brian Paul
7159235bd5da794557613463bc942de0c634d2d961Brian Paul
7259235bd5da794557613463bc942de0c634d2d961Brian Paul/*
7359235bd5da794557613463bc942de0c634d2d961Brian Paul * Special case for glBlendFunc(GL_ONE, GL_ZERO)
7459235bd5da794557613463bc942de0c634d2d961Brian Paul */
7559235bd5da794557613463bc942de0c634d2d961Brian Paulstatic void _BLENDAPI
7659235bd5da794557613463bc942de0c634d2d961Brian Paulblend_replace( GLcontext *ctx, GLuint n, const GLubyte mask[],
7759235bd5da794557613463bc942de0c634d2d961Brian Paul               GLchan rgba[][4], CONST GLchan dest[][4] )
7859235bd5da794557613463bc942de0c634d2d961Brian Paul{
7959235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
8059235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
8159235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendDstRGB==GL_ZERO);
8259235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) ctx;
8359235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) n;
8459235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) mask;
8559235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) rgba;
8659235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) dest;
8759235bd5da794557613463bc942de0c634d2d961Brian Paul}
8859235bd5da794557613463bc942de0c634d2d961Brian Paul
8959235bd5da794557613463bc942de0c634d2d961Brian Paul
9059235bd5da794557613463bc942de0c634d2d961Brian Paul/*
91e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Common transparency blending mode.
92e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
93e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
94e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
95e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                    GLchan rgba[][4], CONST GLchan dest[][4] )
96e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
97e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
98e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
99e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA);
100e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA);
101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
102e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
103e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
104e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
105e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         const GLint t = rgba[i][ACOMP];  /* t in [0, CHAN_MAX] */
106e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (t == 0) {
107e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* 0% alpha */
108e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][RCOMP] = dest[i][RCOMP];
109e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][GCOMP] = dest[i][GCOMP];
110e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][BCOMP] = dest[i][BCOMP];
111e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][ACOMP] = dest[i][ACOMP];
112e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
113e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (t == CHAN_MAX) {
114e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* 100% alpha, no-op */
115e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
117e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#if 0
118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This is pretty close, but Glean complains */
119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint s = CHAN_MAX - t;
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s + 1) >> 8;
121e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s + 1) >> 8;
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s + 1) >> 8;
123e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s + 1) >> 8;
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#elif 0
125e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This is slower but satisfies Glean */
126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint s = CHAN_MAX - t;
127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) / 255;
128e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) / 255;
129e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) / 255;
130e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) / 255;
131e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#else
132e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#if CHAN_BITS == 8
133e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This satisfies Glean and should be reasonably fast */
134e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* Contributed by Nathan Hand */
135e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define DIV255(X)  (((X) << 8) + (X) + 256) >> 16
136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint s = CHAN_MAX - t;
137e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint r = DIV255(rgba[i][RCOMP] * t + dest[i][RCOMP] * s);
138e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint g = DIV255(rgba[i][GCOMP] * t + dest[i][GCOMP] * s);
139e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint b = DIV255(rgba[i][BCOMP] * t + dest[i][BCOMP] * s);
140e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint a = DIV255(rgba[i][ACOMP] * t + dest[i][ACOMP] * s);
141e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef DIV255
14201915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul#elif CHAN_BITS == 16
14301915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat tt = (GLfloat) t / CHAN_MAXF;
14401915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat s = 1.0 - tt;
14501915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLint r = (GLint) (rgba[i][RCOMP] * tt + dest[i][RCOMP] * s);
14601915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLint g = (GLint) (rgba[i][GCOMP] * tt + dest[i][GCOMP] * s);
14701915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLint b = (GLint) (rgba[i][BCOMP] * tt + dest[i][BCOMP] * s);
14801915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLint a = (GLint) (rgba[i][ACOMP] * tt + dest[i][ACOMP] * s);
14901915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul#else /* CHAN_BITS == 32 */
15001915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat tt = (GLfloat) t / CHAN_MAXF;
15101915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat s = 1.0 - tt;
15201915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat r = rgba[i][RCOMP] * tt + dest[i][RCOMP] * s;
15301915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat g = rgba[i][GCOMP] * tt + dest[i][GCOMP] * s;
15401915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat b = rgba[i][BCOMP] * tt + dest[i][BCOMP] * s;
15501915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat a = rgba[i][ACOMP] * tt + dest[i][ACOMP] * s;
156e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
157e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
158e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(r <= CHAN_MAX);
159e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(g <= CHAN_MAX);
160e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(b <= CHAN_MAX);
161e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(a <= CHAN_MAX);
162e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][RCOMP] = (GLchan) r;
163e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][GCOMP] = (GLchan) g;
164e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][BCOMP] = (GLchan) b;
165e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][ACOMP] = (GLchan) a;
166e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
167e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
168e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
169e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
170e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
171e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
172e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
173e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
174e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add src and dest.
175e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
176e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
177e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
178e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
179e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
180e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
181e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
182e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
183e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
184e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
185e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
186e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
187e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
188e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
189e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
190e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
191e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
192e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MIN2( r, CHAN_MAX );
193e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MIN2( g, CHAN_MAX );
194e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MIN2( b, CHAN_MAX );
195e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAX );
196e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
197e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
198e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
199e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
200e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
201e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
202e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
203e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Blend min function  (for GL_EXT_blend_minmax)
204e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
205e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
206e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
207e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
208e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
209e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
210e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_MIN_EXT);
211e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
212e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
213e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
214e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
215e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
216e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
217e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
218e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
219e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
220e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
221e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
222e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
223e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
224e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
225e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
226e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Blend max function  (for GL_EXT_blend_minmax)
227e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
228e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
229e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
230e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
231e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
233e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_MAX_EXT);
234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
238e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
240e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
242e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
243e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
244e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
245e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
246e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
247e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
248e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
249e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Modulate:  result = src * dest
250e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
251e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
252e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                GLchan rgba[][4], CONST GLchan dest[][4] )
254e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
255e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
256e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
257e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
258e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
259e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
260f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#if CHAN_TYPE == GL_FLOAT
261f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP];
262f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
263f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
264f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
265f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#else
266e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint r = (rgba[i][RCOMP] * dest[i][RCOMP]) >> 8;
267e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint g = (rgba[i][GCOMP] * dest[i][GCOMP]) >> 8;
268e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint b = (rgba[i][BCOMP] * dest[i][BCOMP]) >> 8;
269e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint a = (rgba[i][ACOMP] * dest[i][ACOMP]) >> 8;
270e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) r;
271e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) g;
272e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) b;
273e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) a;
274f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#endif
275e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
276e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
277e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
278e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
279e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
280e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
281e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * General case blend pixels.
283e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Input:  n - number of pixels
284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *         mask - the usual write mask
285e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * In/Out:  rgba - the incoming and modified pixels
286e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Input:  dest - the pixels from the dest color buffer
287e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
288e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
289e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
290e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               GLchan rgba[][4], CONST GLchan dest[][4] )
291e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat rscale = 1.0F / CHAN_MAXF;
293e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat gscale = 1.0F / CHAN_MAXF;
294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat bscale = 1.0F / CHAN_MAXF;
295e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat ascale = 1.0F / CHAN_MAXF;
296e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
297e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint Rs, Gs, Bs, As;  /* Source colors */
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint Rd, Gd, Bd, Ad;  /* Dest colors */
302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat sR, sG, sB, sA;  /* Source scaling */
303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat dR, dG, dB, dA;  /* Dest scaling */
304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat r, g, b, a;
305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source Color */
307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Rs = rgba[i][RCOMP];
308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Gs = rgba[i][GCOMP];
309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Bs = rgba[i][BCOMP];
310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         As = rgba[i][ACOMP];
311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Frame buffer color */
313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Rd = dest[i][RCOMP];
314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Gd = dest[i][GCOMP];
315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Bd = dest[i][BCOMP];
316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Ad = dest[i][ACOMP];
317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source RGB factor */
319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendSrcRGB) {
320e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 0.0F;
322e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
323e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F;
325e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR:
327e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = (GLfloat) Rd * rscale;
328e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = (GLfloat) Gd * gscale;
329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = (GLfloat) Bd * bscale;
330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
331e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR:
332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - (GLfloat) Rd * rscale;
333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - (GLfloat) Gd * gscale;
334e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - (GLfloat) Bd * bscale;
335e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
336e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
337e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) As * ascale;
338e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
339e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) 1.0F - (GLfloat) As * ascale;
341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
342e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
343e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) Ad * ascale;
344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
346e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
347e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA_SATURATE:
349e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               if (As < CHAN_MAX - Ad) {
350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  sR = sG = sB = (GLfloat) As * ascale;
351e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
352e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
353e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
354e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
356e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
357e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = ctx->Color.BlendColor[0];
358e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = ctx->Color.BlendColor[1];
359e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = ctx->Color.BlendColor[2];
360e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
361e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
362e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - ctx->Color.BlendColor[0];
363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - ctx->Color.BlendColor[1];
364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - ctx->Color.BlendColor[2];
365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
366e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
367e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = ctx->Color.BlendColor[3];
368e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
370e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
371e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR: /* GL_NV_blend_square */
373e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = (GLfloat) Rs * rscale;
374e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = (GLfloat) Gs * gscale;
375e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = (GLfloat) Bs * bscale;
376e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
377e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
378e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - (GLfloat) Rs * rscale;
379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - (GLfloat) Gs * gscale;
380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - (GLfloat) Bs * bscale;
381e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
382e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
38408836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend source RGB factor in do_blend");
38559235bd5da794557613463bc942de0c634d2d961Brian Paul               return;
386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
388e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source Alpha factor */
389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendSrcA) {
390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
391e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 0.0F;
392e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
393e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
394e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F;
395e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
396e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR:
397e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) Ad * ascale;
398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
399e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR:
400e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) Ad * ascale;
401e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
402e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
403e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) As * ascale;
404e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
405e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) 1.0F - (GLfloat) As * ascale;
407e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
408e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA =(GLfloat) Ad * ascale;
410e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
411e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
412e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) Ad * ascale;
413e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA_SATURATE:
415e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0;
416e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
417e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = ctx->Color.BlendColor[3];
419e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
420e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
421e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - ctx->Color.BlendColor[3];
422e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
423e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
424e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = ctx->Color.BlendColor[3];
425e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
427e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - ctx->Color.BlendColor[3];
428e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
429e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR: /* GL_NV_blend_square */
430e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) As * ascale;
431e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
432e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
433e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) As * ascale;
434e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
435e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
436e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
437e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 0.0F;
43808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend source A factor in do_blend");
439e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
440e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
441e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Dest RGB factor */
442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendDstRGB) {
443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
444e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 0.0F;
445e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
446e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
447e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F;
448e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
449e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR:
450e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = (GLfloat) Rs * rscale;
451e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = (GLfloat) Gs * gscale;
452e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = (GLfloat) Bs * bscale;
453e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
454e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR:
455e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - (GLfloat) Rs * rscale;
456e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - (GLfloat) Gs * gscale;
457e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - (GLfloat) Bs * bscale;
458e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
459e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
460e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) As * ascale;
461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
463e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) 1.0F - (GLfloat) As * ascale;
464e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
465e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
466e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) Ad * ascale;
467e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
468e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F - (GLfloat) Ad * ascale;
470e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
471e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = ctx->Color.BlendColor[0];
473e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = ctx->Color.BlendColor[1];
474e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = ctx->Color.BlendColor[2];
475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
476e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
477e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - ctx->Color.BlendColor[0];
478e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - ctx->Color.BlendColor[1];
479e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - ctx->Color.BlendColor[2];
480e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
481e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
482e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = ctx->Color.BlendColor[3];
483e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
485e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
487e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR: /* GL_NV_blend_square */
488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = (GLfloat) Rd * rscale;
489e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = (GLfloat) Gd * gscale;
490e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = (GLfloat) Bd * bscale;
491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
492e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - (GLfloat) Rd * rscale;
494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - (GLfloat) Gd * gscale;
495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - (GLfloat) Bd * bscale;
496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
499e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 0.0F;
50008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend dest RGB factor in do_blend");
501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
502e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Dest Alpha factor */
504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendDstA) {
505e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
506e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 0.0F;
507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
508e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
509e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F;
510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
511e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR:
512e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) As * ascale;
513e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
514e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR:
515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) As * ascale;
516e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
517e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
518e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) As * ascale;
519e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
520e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
521e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) 1.0F - (GLfloat) As * ascale;
522e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
523e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
524e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) Ad * ascale;
525e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
526e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
527e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) Ad * ascale;
528e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
529e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
530e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = ctx->Color.BlendColor[3];
531e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
532e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
533e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - ctx->Color.BlendColor[3];
534e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
535e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
536e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = ctx->Color.BlendColor[3];
537e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
538e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
539e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - ctx->Color.BlendColor[3];
540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
541e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR: /* GL_NV_blend_square */
542e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) Ad * ascale;
543e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
544e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
545e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) Ad * ascale;
546e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
547e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
548e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
549e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 0.0F;
55008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend dest A factor in do_blend");
55159235bd5da794557613463bc942de0c634d2d961Brian Paul               return;
552e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
553e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
554e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Due to round-off problems we have to clamp against zero. */
555e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Optimization: we don't have to do this for all src & dst factors */
556e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dA < 0.0F)  dA = 0.0F;
557e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dR < 0.0F)  dR = 0.0F;
558e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dG < 0.0F)  dG = 0.0F;
559e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dB < 0.0F)  dB = 0.0F;
560e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sA < 0.0F)  sA = 0.0F;
561e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sR < 0.0F)  sR = 0.0F;
562e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sG < 0.0F)  sG = 0.0F;
563e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sB < 0.0F)  sB = 0.0F;
564e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
565e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sR <= 1.0 );
566e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sG <= 1.0 );
567e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sB <= 1.0 );
568e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sA <= 1.0 );
569e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dR <= 1.0 );
570e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dG <= 1.0 );
571e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dB <= 1.0 );
572e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dA <= 1.0 );
573e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
574e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* compute blended color */
575e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
576e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rs * sR + Rd * dR + 0.5F;
577e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gs * sG + Gd * dG + 0.5F;
578e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bs * sB + Bd * dB + 0.5F;
579e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = As * sA + Ad * dA + 0.5F;
580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rs * sR - Rd * dR + 0.5F;
583e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gs * sG - Gd * dG + 0.5F;
584e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bs * sB - Bd * dB + 0.5F;
585e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = As * sA - Ad * dA + 0.5F;
586e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
587e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
588e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rd * dR - Rs * sR + 0.5F;
589e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gd * dG - Gs * sG + 0.5F;
590e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bd * dB - Bs * sB + 0.5F;
591e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = Ad * dA - As * sA + 0.5F;
592e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
593e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
594e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* should never get here */
595e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = g = b = a = 0.0F;  /* silence uninitialized var warning */
59608836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
597e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
598e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
599e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* final clamping */
600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) (GLint) CLAMP( r, 0.0F, CHAN_MAXF );
601e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) (GLint) CLAMP( g, 0.0F, CHAN_MAXF );
602e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) (GLint) CLAMP( b, 0.0F, CHAN_MAXF );
603e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) (GLint) CLAMP( a, 0.0F, CHAN_MAXF );
604e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
605e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
606e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
608e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
609e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
610e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
611e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
612e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
613e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Analyze current blending parameters to pick fastest blending function.
614e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Result: the ctx->Color.BlendFunc pointer is updated.
615e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
616cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwellvoid _swrast_choose_blend_func( GLcontext *ctx )
617e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
618e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum eq = ctx->Color.BlendEquation;
619e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum srcRGB = ctx->Color.BlendSrcRGB;
620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum dstRGB = ctx->Color.BlendDstRGB;
621e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum srcA = ctx->Color.BlendSrcA;
622e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum dstA = ctx->Color.BlendDstA;
623e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
624e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (srcRGB != srcA || dstRGB != dstA) {
625cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
626e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
627e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA
62859235bd5da794557613463bc942de0c634d2d961Brian Paul            && dstRGB==GL_ONE_MINUS_SRC_ALPHA)
629cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   {
630461b99050811b345e77de01f4610e7c22a259141Brian Paul      /* XXX It looks like the MMX blend code is broken.  Disable for now. */
631461b99050811b345e77de01f4610e7c22a259141Brian Paul#if 0 && defined(USE_MMX_ASM)
632cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      if ( cpu_has_mmx ) {
63359235bd5da794557613463bc942de0c634d2d961Brian Paul         SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency;
634cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      }
635cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      else
636cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#endif
637cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	 SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency;
638e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) {
640cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_add;
641e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
642e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
643cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	     && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
644cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	    ||
645cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	    ((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
646cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	     && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
647cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate;
648e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
649e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_MIN_EXT) {
650cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_min;
651e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
652e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_MAX_EXT) {
653cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_max;
654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
65559235bd5da794557613463bc942de0c634d2d961Brian Paul   else if (eq==GL_FUNC_ADD_EXT && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
65659235bd5da794557613463bc942de0c634d2d961Brian Paul      SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop;
65759235bd5da794557613463bc942de0c634d2d961Brian Paul   }
65859235bd5da794557613463bc942de0c634d2d961Brian Paul   else if (eq==GL_FUNC_ADD_EXT && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
65959235bd5da794557613463bc942de0c634d2d961Brian Paul      SWRAST_CONTEXT(ctx)->BlendFunc = blend_replace;
66059235bd5da794557613463bc942de0c634d2d961Brian Paul   }
661e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
662cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
663e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
664e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
665e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
666e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
667e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
668e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
669e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the blending operator to a span of pixels.
670733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * We can handle horizontal runs of pixels (spans) or arrays of x/y
671733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * pixel coordinates.
672e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
673e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
674733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul_mesa_blend_span( GLcontext *ctx, const struct sw_span *span,
675733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                  GLchan rgba[][4] )
676e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
677733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
678733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   GLchan framebuffer[MAX_WIDTH][4];
679e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
680733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end < MAX_WIDTH);
681733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
682733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(!ctx->Color.ColorLogicOpEnabled);
683e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
684e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Read span of current frame buffer pixels */
685733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_XY) {
686733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* array of x/y pixel coords */
687733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      (*swrast->Driver.ReadRGBAPixels)( ctx, span->end,
688733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                        span->xArray, span->yArray,
689733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                        framebuffer, span->mask );
690733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (swrast->_RasterMask & ALPHABUF_BIT) {
691733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_read_alpha_pixels( ctx, span->end, span->xArray, span->yArray,
692733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                  framebuffer, span->mask );
693733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
694733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
695733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
696733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* horizontal run of pixels */
697733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      _mesa_read_rgba_span( ctx, ctx->DrawBuffer, span->end,
698733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                            span->x, span->y, framebuffer );
699733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
700e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
701733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->mask, rgba,
702733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul				   (const GLchan (*)[4]) framebuffer );
703e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
704