1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
3145f5f60f19574e06c536c102bec0cfd6320606dMark Anderson * Version:  7.1
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
5145f5f60f19574e06c536c102bec0cfd6320606dMark Anderson * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
25d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
26d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/**
27d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * \file swrast/s_blend.c
28d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * \brief software blending.
29d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * \author Brian Paul
30ae7666385d6bb2885fce2590d4f07c6caa8b3260Brian Paul *
31d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Only a few blend modes have been optimized (min, max, transparency, add)
32d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * more optimized cases can easily be added if needed.
33d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Celestia uses glBlendFunc(GL_SRC_ALPHA, GL_ONE), for example.
34ae7666385d6bb2885fce2590d4f07c6caa8b3260Brian Paul */
35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
36e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
37d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
38bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
39bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
40bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h"
41bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h"
44cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
48cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#if defined(USE_MMX_ASM)
495f3439916b74ed792ad12d1e614a2a5bc0a94b3aBrian Paul#include "x86/mmx.h"
505f3439916b74ed792ad12d1e614a2a5bc0a94b3aBrian Paul#include "x86/common_x86_asm.h"
51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define _BLENDAPI _ASMAPI
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#else
53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define _BLENDAPI
54e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
55e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
56cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
57a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
58d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Integer divide by 255
59d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Declare "int divtemp" before using.
60d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * This satisfies Glean and should be reasonably fast.
61d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Contributed by Nathan Hand.
62d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */
63d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul#define DIV255(X)  (divtemp = (X), ((divtemp << 8) + divtemp + 256) >> 16)
64d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
65d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
66d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
67d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/**
68d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Special case for glBlendFunc(GL_ZERO, GL_ONE).
69d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * No-op means the framebuffer values remain unchanged.
70d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
7159235bd5da794557613463bc942de0c634d2d961Brian Paul */
7259235bd5da794557613463bc942de0c634d2d961Brian Paulstatic void _BLENDAPI
73f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_noop(struct gl_context *ctx, GLuint n, const GLubyte mask[],
74d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul           GLvoid *src, const GLvoid *dst, GLenum chanType)
7559235bd5da794557613463bc942de0c634d2d961Brian Paul{
76d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLint bytes;
77d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
7874713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
7974713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
8074713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ZERO);
8174713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE);
8259235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) ctx;
8359235bd5da794557613463bc942de0c634d2d961Brian Paul
84d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   /* just memcpy */
85d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE)
86d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      bytes = 4 * n * sizeof(GLubyte);
87d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT)
88d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      bytes = 4 * n * sizeof(GLushort);
89d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else
90d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      bytes = 4 * n * sizeof(GLfloat);
91d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
92c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke   memcpy(src, dst, bytes);
9359235bd5da794557613463bc942de0c634d2d961Brian Paul}
9459235bd5da794557613463bc942de0c634d2d961Brian Paul
9559235bd5da794557613463bc942de0c634d2d961Brian Paul
96a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
9759235bd5da794557613463bc942de0c634d2d961Brian Paul * Special case for glBlendFunc(GL_ONE, GL_ZERO)
98d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
9959235bd5da794557613463bc942de0c634d2d961Brian Paul */
10059235bd5da794557613463bc942de0c634d2d961Brian Paulstatic void _BLENDAPI
101f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_replace(struct gl_context *ctx, GLuint n, const GLubyte mask[],
102d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul              GLvoid *src, const GLvoid *dst, GLenum chanType)
10359235bd5da794557613463bc942de0c634d2d961Brian Paul{
10474713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
10574713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
10674713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE);
10774713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstRGB == GL_ZERO);
10859235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) ctx;
10959235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) n;
11059235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) mask;
111d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   (void) src;
112d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   (void) dst;
11359235bd5da794557613463bc942de0c634d2d961Brian Paul}
11459235bd5da794557613463bc942de0c634d2d961Brian Paul
11559235bd5da794557613463bc942de0c634d2d961Brian Paul
116a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
117d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Common transparency blending mode:
118d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
121f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_transparency_ubyte(struct gl_context *ctx, GLuint n, const GLubyte mask[],
122d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                         GLvoid *src, const GLvoid *dst, GLenum chanType)
123e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
124d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
125d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
127d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
12874713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
12974713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
13074713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
13174713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
13274713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
13374713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
134d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   ASSERT(chanType == GL_UNSIGNED_BYTE);
135d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
137e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
138d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   for (i = 0; i < n; i++) {
139e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
140d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         const GLint t = rgba[i][ACOMP];  /* t is in [0, 255] */
141e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (t == 0) {
142e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* 0% alpha */
143d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            COPY_4UBV(rgba[i], dest[i]);
144e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
145d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else if (t != 255) {
146d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul	    GLint divtemp;
14717b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP];
14817b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP];
14917b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP];
15017b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP];
151d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            ASSERT(r <= 255);
152d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            ASSERT(g <= 255);
153d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            ASSERT(b <= 255);
154d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            ASSERT(a <= 255);
155d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = (GLubyte) r;
156d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = (GLubyte) g;
157d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = (GLubyte) b;
158d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = (GLubyte) a;
159d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
160d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
161d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
162d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul}
1636b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul
164d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
165d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paulstatic void _BLENDAPI
166f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_transparency_ushort(struct gl_context *ctx, GLuint n, const GLubyte mask[],
167d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                          GLvoid *src, const GLvoid *dst, GLenum chanType)
168d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{
169d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLushort (*rgba)[4] = (GLushort (*)[4]) src;
170d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
171d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLuint i;
172d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
17374713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
17474713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
17574713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
17674713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
17774713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
17874713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
179d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   ASSERT(chanType == GL_UNSIGNED_SHORT);
180d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
181d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   (void) ctx;
182d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
183d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   for (i = 0; i < n; i++) {
184d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (mask[i]) {
185d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         const GLint t = rgba[i][ACOMP];
186d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (t == 0) {
187d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            /* 0% alpha */
188d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            COPY_4V(rgba[i], dest[i]);
189d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
190d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else if (t != 65535) {
191d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            const GLfloat tt = (GLfloat) t / 65535.0F;
192d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLushort r = (GLushort) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]);
193d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLushort g = (GLushort) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]);
194d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLushort b = (GLushort) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]);
195d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLushort a = (GLushort) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]);
196d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            ASSIGN_4V(rgba[i], r, g, b, a);
197d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
198d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
199d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
200d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul}
201d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
202d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
203d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paulstatic void _BLENDAPI
204f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_transparency_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
205d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                         GLvoid *src, const GLvoid *dst, GLenum chanType)
206d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{
207d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
208d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
209d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLuint i;
210d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
21174713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
21274713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
21374713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
21474713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
21574713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
21674713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
217d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   ASSERT(chanType == GL_FLOAT);
218d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
219d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   (void) ctx;
220d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
221d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   for (i = 0; i < n; i++) {
222d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (mask[i]) {
223d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         const GLfloat t = rgba[i][ACOMP];  /* t in [0, 1] */
224d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (t == 0.0F) {
225d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            /* 0% alpha */
226d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            COPY_4V(rgba[i], dest[i]);
227d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
228d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else if (t != 1.0F) {
229d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * t + dest[i][RCOMP];
230d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * t + dest[i][GCOMP];
231d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * t + dest[i][BCOMP];
232d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * t + dest[i][ACOMP];
233d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            ASSIGN_4V(rgba[i], r, g, b, a);
234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
238e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
240e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
241a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
242d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Add src and dest: glBlendFunc(GL_ONE, GL_ONE).
243d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
244e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
245e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
246f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_add(struct gl_context *ctx, GLuint n, const GLubyte mask[],
247d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul          GLvoid *src, const GLvoid *dst, GLenum chanType)
248e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
249e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
250d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
25174713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
25274713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
25374713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE);
25474713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE);
255e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
256e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
257d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE) {
258d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
259d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
260d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
261d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
262d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
263d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
264d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
265d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
266d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = (GLubyte) MIN2( r, 255 );
267d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = (GLubyte) MIN2( g, 255 );
268d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = (GLubyte) MIN2( b, 255 );
269d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = (GLubyte) MIN2( a, 255 );
270d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
271d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
272d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
273d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
274d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
275d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
276d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
277d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
278d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
279d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
280d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
281d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
282d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = (GLshort) MIN2( r, 255 );
283d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = (GLshort) MIN2( g, 255 );
284d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = (GLshort) MIN2( b, 255 );
285d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = (GLshort) MIN2( a, 255 );
286d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
287d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
288d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
289d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else {
290d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
291d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
292d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      ASSERT(chanType == GL_FLOAT);
293d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
294d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
295d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            /* don't RGB clamp to max */
296d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] += dest[i][RCOMP];
297d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] += dest[i][GCOMP];
298d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] += dest[i][BCOMP];
299d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] += dest[i][ACOMP];
300d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
307a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
308d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Blend min function.
309d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
312f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_min(struct gl_context *ctx, GLuint n, const GLubyte mask[],
313d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul          GLvoid *src, const GLvoid *dst, GLenum chanType)
314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
31674713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MIN);
31774713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationA == GL_MIN);
318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
320d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE) {
321d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
322d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
323d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
324d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
325d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
326d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
327d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
328d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
329d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
330d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
331d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
332d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
333d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
334d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
335d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
336d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
337d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
338d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
339d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
340d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
341d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
342d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
343d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
344d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else {
345d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
346d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
347d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      ASSERT(chanType == GL_FLOAT);
348d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
349d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
350d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
351d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
352d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
353d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
354d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
356e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
357e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
358e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
359e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
360a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
361d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Blend max function.
362d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
365f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_max(struct gl_context *ctx, GLuint n, const GLubyte mask[],
366d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul          GLvoid *src, const GLvoid *dst, GLenum chanType)
367e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
368e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
36974713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MAX);
37074713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   ASSERT(ctx->Color.Blend[0].EquationA == GL_MAX);
371e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
373d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE) {
374d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
375d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
376d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
377d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
378d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
379d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
380d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
381d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
382d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
383d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
384d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
385d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
386d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
387d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
388d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
389d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
390d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
391d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
392d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
393d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
394d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
395d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
396d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
397d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else {
398d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
399d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
400d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      ASSERT(chanType == GL_FLOAT);
401d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
402d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
403d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
404d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
405d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
406d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
407d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
408e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
410e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
411e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
412e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
413e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
414a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
415e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Modulate:  result = src * dest
416d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
417e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
419f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_modulate(struct gl_context *ctx, GLuint n, const GLubyte mask[],
420d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               GLvoid *src, const GLvoid *dst, GLenum chanType)
421e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
422e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
423e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
424e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
425d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE) {
426d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
427d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
428d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
429d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
430d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul	    GLint divtemp;
431d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = DIV255(rgba[i][RCOMP] * dest[i][RCOMP]);
432d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = DIV255(rgba[i][GCOMP] * dest[i][GCOMP]);
433d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = DIV255(rgba[i][BCOMP] * dest[i][BCOMP]);
434d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = DIV255(rgba[i][ACOMP] * dest[i][ACOMP]);
435d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
436d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
437d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
438d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
439d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
440d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
441d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
442d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
443d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16;
444d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16;
445d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16;
446d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16;
447d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
448d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
449d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
450d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else {
451d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
452d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
453d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      ASSERT(chanType == GL_FLOAT);
454d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
455d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
456d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP];
457d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
458d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
459d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
460d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
463e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
464e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
465e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
466a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
467a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Do any blending operation, using floating point.
468a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param n  number of pixels
469a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param mask  fragment writemask array
470d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * \param rgba  array of incoming (and modified) pixels
471d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * \param dest  array of pixels from the dest color buffer
472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
473a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulstatic void
474f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
475d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                    GLfloat rgba[][4], GLfloat dest[][4],
476d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                    GLenum chanType)
477a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{
478a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   GLuint i;
479a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
480a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   for (i = 0; i < n; i++) {
481a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      if (mask[i]) {
482a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Incoming/source Color */
483a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Rs = rgba[i][RCOMP];
484a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Gs = rgba[i][GCOMP];
485a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Bs = rgba[i][BCOMP];
486a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat As = rgba[i][ACOMP];
487a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
488a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Frame buffer/dest color */
489a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Rd = dest[i][RCOMP];
490a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Gd = dest[i][GCOMP];
491a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Bd = dest[i][BCOMP];
492a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Ad = dest[i][ACOMP];
493a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
494a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         GLfloat sR, sG, sB, sA;  /* Source factor */
495a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         GLfloat dR, dG, dB, dA;  /* Dest factor */
496a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         GLfloat r, g, b, a;      /* result color */
497a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
498a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* XXX for the case of constant blend terms we could init
499a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul          * the sX and dX variables just once before the loop.
500a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul          */
501a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
502a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Source RGB factor */
50374713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].SrcRGB) {
504a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ZERO:
505a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 0.0F;
506a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
507a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE:
508a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 1.0F;
509a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
510a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_COLOR:
511a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = Rd;
512a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = Gd;
513a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = Bd;
514a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
515a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_COLOR:
516a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = 1.0F - Rd;
517a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = 1.0F - Gd;
518a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = 1.0F - Bd;
519a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
520a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA:
521a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = As;
522a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
523a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_ALPHA:
524a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 1.0F - As;
525a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
526a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_ALPHA:
527a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = Ad;
528a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
529a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_ALPHA:
530a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 1.0F - Ad;
531a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
532a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA_SATURATE:
533a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               if (As < 1.0F - Ad) {
534a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul                  sR = sG = sB = As;
535a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               }
536a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               else {
537a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul                  sR = sG = sB = 1.0F - Ad;
538a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               }
539a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
540a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_COLOR:
541a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = ctx->Color.BlendColor[0];
542a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = ctx->Color.BlendColor[1];
543a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = ctx->Color.BlendColor[2];
544a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
545a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_COLOR:
546a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = 1.0F - ctx->Color.BlendColor[0];
547a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = 1.0F - ctx->Color.BlendColor[1];
548a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = 1.0F - ctx->Color.BlendColor[2];
549a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
550a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_ALPHA:
551a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = ctx->Color.BlendColor[3];
552a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
553a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_ALPHA:
554a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
555a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
556d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_SRC_COLOR:
557a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = Rs;
558a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = Gs;
559a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = Bs;
560a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
561d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_ONE_MINUS_SRC_COLOR:
562a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = 1.0F - Rs;
563a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = 1.0F - Gs;
564a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = 1.0F - Bs;
565a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
566a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            default:
567a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               /* this should never happen */
568a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float");
569a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               return;
570a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
571a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
572a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Source Alpha factor */
57374713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].SrcA) {
574a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ZERO:
575a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 0.0F;
576a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
577a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE:
578a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F;
579a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
580a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_COLOR:
581a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = Ad;
582a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
583a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_COLOR:
584a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - Ad;
585a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
586a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA:
587a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = As;
588a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
589a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_ALPHA:
590a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - As;
591a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
592a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_ALPHA:
593a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = Ad;
594a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
595a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_ALPHA:
596a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - Ad;
597a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
598a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA_SATURATE:
599a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0;
600a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
601a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_COLOR:
602a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = ctx->Color.BlendColor[3];
603a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
604a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_COLOR:
605a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - ctx->Color.BlendColor[3];
606a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
607a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_ALPHA:
608a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = ctx->Color.BlendColor[3];
609a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
610a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_ALPHA:
611a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - ctx->Color.BlendColor[3];
612a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
613d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_SRC_COLOR:
614a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = As;
615a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
616d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_ONE_MINUS_SRC_COLOR:
617a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - As;
618a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
619a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            default:
620a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               /* this should never happen */
621a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 0.0F;
622a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               _mesa_problem(ctx, "Bad blend source A factor in blend_general_float");
623a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               return;
624a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
625a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
626a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Dest RGB factor */
62774713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].DstRGB) {
628a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ZERO:
629a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 0.0F;
630a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
631a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE:
632a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 1.0F;
633a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
634a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_COLOR:
635a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = Rs;
636a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = Gs;
637a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = Bs;
638a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
639a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_COLOR:
640a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = 1.0F - Rs;
641a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = 1.0F - Gs;
642a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = 1.0F - Bs;
643a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
644a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA:
645a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = As;
646a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
647a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_ALPHA:
648a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 1.0F - As;
649a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
650a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_ALPHA:
651a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = Ad;
652a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
653a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_ALPHA:
654a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 1.0F - Ad;
655a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
656a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_COLOR:
657a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = ctx->Color.BlendColor[0];
658a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = ctx->Color.BlendColor[1];
659a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = ctx->Color.BlendColor[2];
660a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
661a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_COLOR:
662a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = 1.0F - ctx->Color.BlendColor[0];
663a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = 1.0F - ctx->Color.BlendColor[1];
664a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = 1.0F - ctx->Color.BlendColor[2];
665a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
666a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_ALPHA:
667a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = ctx->Color.BlendColor[3];
668a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
669a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_ALPHA:
670a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
671a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
672d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_DST_COLOR:
673a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = Rd;
674a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = Gd;
675a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = Bd;
676a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
677d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_ONE_MINUS_DST_COLOR:
678a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = 1.0F - Rd;
679a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = 1.0F - Gd;
680a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = 1.0F - Bd;
681a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
682a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            default:
683a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               /* this should never happen */
684a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 0.0F;
685a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float");
686a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               return;
687a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
688a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
689a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Dest Alpha factor */
69074713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].DstA) {
691a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ZERO:
692a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 0.0F;
693a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
694a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE:
695a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F;
696a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
697a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_COLOR:
698a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = As;
699a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
700a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_COLOR:
701a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - As;
702a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
703a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA:
704a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = As;
705a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
706a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_ALPHA:
707a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - As;
708a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
709a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_ALPHA:
710a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = Ad;
711a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
712a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_ALPHA:
713a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - Ad;
714a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
715a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_COLOR:
716a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = ctx->Color.BlendColor[3];
717a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
718a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_COLOR:
719a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - ctx->Color.BlendColor[3];
720a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
721a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_ALPHA:
722a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = ctx->Color.BlendColor[3];
723a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
724a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_ALPHA:
725a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - ctx->Color.BlendColor[3];
726a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
727d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_DST_COLOR:
728a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = Ad;
729a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
730d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_ONE_MINUS_DST_COLOR:
731a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - Ad;
732a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
733a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            default:
734a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               /* this should never happen */
735a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 0.0F;
736a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float");
737a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               return;
738a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
739a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
740a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* compute the blended RGB */
74174713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].EquationRGB) {
742a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_ADD:
743a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            r = Rs * sR + Rd * dR;
744a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            g = Gs * sG + Gd * dG;
745a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            b = Bs * sB + Bd * dB;
746a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = As * sA + Ad * dA;
747a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
748a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_SUBTRACT:
749a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            r = Rs * sR - Rd * dR;
750a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            g = Gs * sG - Gd * dG;
751a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            b = Bs * sB - Bd * dB;
752a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = As * sA - Ad * dA;
753a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
754a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_REVERSE_SUBTRACT:
755a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            r = Rd * dR - Rs * sR;
756a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            g = Gd * dG - Gs * sG;
757a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            b = Bd * dB - Bs * sB;
758a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = Ad * dA - As * sA;
759a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
760a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_MIN:
761a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    r = MIN2( Rd, Rs );
762a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    g = MIN2( Gd, Gs );
763a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    b = MIN2( Bd, Bs );
764a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
765a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_MAX:
766a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    r = MAX2( Rd, Rs );
767a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    g = MAX2( Gd, Gs );
768a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    b = MAX2( Bd, Bs );
769a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
770a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	 default:
771a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            /* should never get here */
772a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            r = g = b = 0.0F;  /* silence uninitialized var warning */
773a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
774a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            return;
775a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
776a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
777a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* compute the blended alpha */
77874713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].EquationA) {
779a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_ADD:
780a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = As * sA + Ad * dA;
781a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
782a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_SUBTRACT:
783a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = As * sA - Ad * dA;
784a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
785a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_REVERSE_SUBTRACT:
786a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = Ad * dA - As * sA;
787a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
788a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_MIN:
789a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    a = MIN2( Ad, As );
790a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
791a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_MAX:
792a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    a = MAX2( Ad, As );
793a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
794a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         default:
795a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            /* should never get here */
796a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = 0.0F;  /* silence uninitialized var warning */
797a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
798a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            return;
799a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
800a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
801a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* final clamping */
802a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul#if 0
803a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         rgba[i][RCOMP] = MAX2( r, 0.0F );
804a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         rgba[i][GCOMP] = MAX2( g, 0.0F );
805a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         rgba[i][BCOMP] = MAX2( b, 0.0F );
806d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         rgba[i][ACOMP] = CLAMP( a, 0.0F, 1.0F );
807a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul#else
808a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         ASSIGN_4V(rgba[i], r, g, b, a);
809a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul#endif
810a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
811a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
812a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul}
813a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
814a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
815d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/**
816d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Do any blending operation, any chanType.
817d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */
818a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulstatic void
819f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_general(struct gl_context *ctx, GLuint n, const GLubyte mask[],
820d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul              void *src, const void *dst, GLenum chanType)
821a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{
82225662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   GLfloat (*rgbaF)[4], (*destF)[4];
82325662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul
82425662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   rgbaF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
82525662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   destF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
82625662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   if (!rgbaF || !destF) {
82725662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul      free(rgbaF);
82825662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul      free(destF);
82925662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "blending");
83025662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul      return;
83125662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   }
832a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
833a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   if (chanType == GL_UNSIGNED_BYTE) {
834a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
835a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
836a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      GLuint i;
837a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* convert ubytes to floats */
838a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      for (i = 0; i < n; i++) {
839a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         if (mask[i]) {
840a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]);
841a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]);
842a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]);
843a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]);
844a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]);
845a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]);
846a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]);
847a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]);
848a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
849a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
850a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* do blend */
851a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
852a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* convert back to ubytes */
853a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      for (i = 0; i < n; i++) {
85481a86aea4f0990a1b8795f9e00e7a6c4ba368281Dave Airlie         if (mask[i])
85581a86aea4f0990a1b8795f9e00e7a6c4ba368281Dave Airlie	   _mesa_unclamped_float_rgba_to_ubyte(rgba[i], rgbaF[i]);
856a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
857a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
858a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
859a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
860a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
861a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      GLuint i;
862a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* convert ushorts to floats */
863a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      for (i = 0; i < n; i++) {
864a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         if (mask[i]) {
865a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]);
866a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]);
867a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]);
868a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]);
869a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]);
870a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]);
871a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]);
872a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]);
873a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
874a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
875a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* do blend */
876a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
877a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* convert back to ushorts */
878a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      for (i = 0; i < n; i++) {
879a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         if (mask[i]) {
880a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]);
881a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]);
882a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]);
883a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]);
884a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
885a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
886a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
887a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else {
888145f5f60f19574e06c536c102bec0cfd6320606dMark Anderson      blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src,
889145f5f60f19574e06c536c102bec0cfd6320606dMark Anderson                          (GLfloat (*)[4]) dst, chanType);
890a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
89125662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul
89225662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   free(rgbaF);
89325662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   free(destF);
894a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul}
895e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
896e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
897e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
898a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
899e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Analyze current blending parameters to pick fastest blending function.
900e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Result: the ctx->Color.BlendFunc pointer is updated.
901e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
902d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paulvoid
903f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_choose_blend_func(struct gl_context *ctx, GLenum chanType)
904e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
905a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
90674713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum eq = ctx->Color.Blend[0].EquationRGB;
90774713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
90874713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
90974713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum srcA = ctx->Color.Blend[0].SrcA;
91074713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum dstA = ctx->Color.Blend[0].DstA;
911e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
91274713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   if (ctx->Color.Blend[0].EquationRGB != ctx->Color.Blend[0].EquationA) {
913a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      swrast->BlendFunc = blend_general;
914c93105eb9e2499efb237fd89dba0cebd48f18375Ian Romanick   }
915a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_MIN) {
91663f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      /* Note: GL_MIN ignores the blending weight factors */
91763f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul#if defined(USE_MMX_ASM)
918d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
919a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_min;
92063f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      }
92163f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      else
92263f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul#endif
923d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         swrast->BlendFunc = blend_min;
92463f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul   }
925a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_MAX) {
92663f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      /* Note: GL_MAX ignores the blending weight factors */
92763f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul#if defined(USE_MMX_ASM)
928d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
929a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_max;
93063f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      }
93163f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      else
93263f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul#endif
933d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         swrast->BlendFunc = blend_max;
93463f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul   }
93563f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul   else if (srcRGB != srcA || dstRGB != dstA) {
936a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      swrast->BlendFunc = blend_general;
937e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
938a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA
939a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            && dstRGB == GL_ONE_MINUS_SRC_ALPHA) {
9409add9a21d8c51ee4238169265541fa9a40f0a8b0Brian Paul#if defined(USE_MMX_ASM)
941d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
942a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_transparency;
943cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      }
944cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      else
945cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#endif
946d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      {
947d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (chanType == GL_UNSIGNED_BYTE)
948d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            swrast->BlendFunc = blend_transparency_ubyte;
949d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else if (chanType == GL_UNSIGNED_SHORT)
950d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            swrast->BlendFunc = blend_transparency_ushort;
951d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else
952d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            swrast->BlendFunc = blend_transparency_float;
953d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
954e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
955a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) {
9560c527ab0546eb1de9ee10cc31bc386a40e6b3f98Jose Fonseca#if defined(USE_MMX_ASM)
957d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
958a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_add;
9590c527ab0546eb1de9ee10cc31bc386a40e6b3f98Jose Fonseca      }
9600c527ab0546eb1de9ee10cc31bc386a40e6b3f98Jose Fonseca      else
9610c527ab0546eb1de9ee10cc31bc386a40e6b3f98Jose Fonseca#endif
962d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         swrast->BlendFunc = blend_add;
963e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
964a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT)
965a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	     && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR))
966cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	    ||
967a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT)
968a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	     && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) {
969533e88824af9f60a926e7b70ddd40ad1386be686Jose Fonseca#if defined(USE_MMX_ASM)
970d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
971a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_modulate;
972533e88824af9f60a926e7b70ddd40ad1386be686Jose Fonseca      }
973533e88824af9f60a926e7b70ddd40ad1386be686Jose Fonseca      else
974533e88824af9f60a926e7b70ddd40ad1386be686Jose Fonseca#endif
975d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         swrast->BlendFunc = blend_modulate;
976e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
977a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
978d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      swrast->BlendFunc = blend_noop;
97959235bd5da794557613463bc942de0c634d2d961Brian Paul   }
980a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
981a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      swrast->BlendFunc = blend_replace;
98259235bd5da794557613463bc942de0c634d2d961Brian Paul   }
983e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
984a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      swrast->BlendFunc = blend_general;
985e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
986e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
987e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
988e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
989e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
990a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
991e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the blending operator to a span of pixels.
992733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * We can handle horizontal runs of pixels (spans) or arrays of x/y
993733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * pixel coordinates.
994e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
995e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
996f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_blend_span(struct gl_context *ctx, struct gl_renderbuffer *rb, SWspan *span)
997e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
998a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
999a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   void *rbPixels;
1000e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
100147d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul   ASSERT(span->end <= SWRAST_MAX_WIDTH);
1002733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
10032836aab2031d5b6926923fbc70f867ec638301bdIan Romanick   ASSERT(!ctx->Color.ColorLogicOpEnabled);
1004e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1005a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
1006e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1007a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   swrast->BlendFunc(ctx, span->end, span->array->mask,
1008d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                     span->array->rgba, rbPixels, span->array->ChanType);
1009e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1010