1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
4145f5f60f19574e06c536c102bec0cfd6320606dMark Anderson * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
6e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
13e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
16e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
193d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
203d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
213d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
223d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * 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#endif
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
53cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
54a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
55d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Integer divide by 255
56d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Declare "int divtemp" before using.
57d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * This satisfies Glean and should be reasonably fast.
58d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Contributed by Nathan Hand.
59d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */
60d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul#define DIV255(X)  (divtemp = (X), ((divtemp << 8) + divtemp + 256) >> 16)
61d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
62d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
63d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
64d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/**
65d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Special case for glBlendFunc(GL_ZERO, GL_ONE).
66d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * No-op means the framebuffer values remain unchanged.
67d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
6859235bd5da794557613463bc942de0c634d2d961Brian Paul */
6910035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
70f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_noop(struct gl_context *ctx, GLuint n, const GLubyte mask[],
71d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul           GLvoid *src, const GLvoid *dst, GLenum chanType)
7259235bd5da794557613463bc942de0c634d2d961Brian Paul{
73d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLint bytes;
74d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
75bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
76bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
77bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcRGB == GL_ZERO);
78bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstRGB == GL_ONE);
7959235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) ctx;
8059235bd5da794557613463bc942de0c634d2d961Brian Paul
81d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   /* just memcpy */
82d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE)
83d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      bytes = 4 * n * sizeof(GLubyte);
84d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT)
85d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      bytes = 4 * n * sizeof(GLushort);
86d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else
87d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      bytes = 4 * n * sizeof(GLfloat);
88d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
89c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke   memcpy(src, dst, bytes);
9059235bd5da794557613463bc942de0c634d2d961Brian Paul}
9159235bd5da794557613463bc942de0c634d2d961Brian Paul
9259235bd5da794557613463bc942de0c634d2d961Brian Paul
93a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
9459235bd5da794557613463bc942de0c634d2d961Brian Paul * Special case for glBlendFunc(GL_ONE, GL_ZERO)
95d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
9659235bd5da794557613463bc942de0c634d2d961Brian Paul */
9710035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
98f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_replace(struct gl_context *ctx, GLuint n, const GLubyte mask[],
99d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul              GLvoid *src, const GLvoid *dst, GLenum chanType)
10059235bd5da794557613463bc942de0c634d2d961Brian Paul{
101bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
102bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
103bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcRGB == GL_ONE);
104bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstRGB == GL_ZERO);
10559235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) ctx;
10659235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) n;
10759235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) mask;
108d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   (void) src;
109d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   (void) dst;
11059235bd5da794557613463bc942de0c634d2d961Brian Paul}
11159235bd5da794557613463bc942de0c634d2d961Brian Paul
11259235bd5da794557613463bc942de0c634d2d961Brian Paul
113a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
114d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Common transparency blending mode:
115d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
11710035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
118f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_transparency_ubyte(struct gl_context *ctx, GLuint n, const GLubyte mask[],
119d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                         GLvoid *src, const GLvoid *dst, GLenum chanType)
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
121d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
122d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
123e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
124d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
125bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
126bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
127bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
128bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
129bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
130bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
131bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(chanType == GL_UNSIGNED_BYTE);
132d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
133e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
134e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
135d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   for (i = 0; i < n; i++) {
136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
137d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         const GLint t = rgba[i][ACOMP];  /* t is in [0, 255] */
138e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (t == 0) {
139e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* 0% alpha */
140d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            COPY_4UBV(rgba[i], dest[i]);
141e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
142d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else if (t != 255) {
143d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul	    GLint divtemp;
14417b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP];
14517b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP];
14617b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP];
14717b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP];
148bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner            assert(r <= 255);
149bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner            assert(g <= 255);
150bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner            assert(b <= 255);
151bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner            assert(a <= 255);
152d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = (GLubyte) r;
153d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = (GLubyte) g;
154d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = (GLubyte) b;
155d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = (GLubyte) a;
156d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
157d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
158d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
159d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul}
1606b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul
161d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
16210035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
163f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_transparency_ushort(struct gl_context *ctx, GLuint n, const GLubyte mask[],
164d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                          GLvoid *src, const GLvoid *dst, GLenum chanType)
165d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{
166d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLushort (*rgba)[4] = (GLushort (*)[4]) src;
167d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
168d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLuint i;
169d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
170bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
171bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
172bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
173bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
174bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
175bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
176bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(chanType == GL_UNSIGNED_SHORT);
177d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
178d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   (void) ctx;
179d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
180d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   for (i = 0; i < n; i++) {
181d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (mask[i]) {
182d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         const GLint t = rgba[i][ACOMP];
183d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (t == 0) {
184d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            /* 0% alpha */
185d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            COPY_4V(rgba[i], dest[i]);
186d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
187d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else if (t != 65535) {
188d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            const GLfloat tt = (GLfloat) t / 65535.0F;
189d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLushort r = (GLushort) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]);
190d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLushort g = (GLushort) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]);
191d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLushort b = (GLushort) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]);
192d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLushort a = (GLushort) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]);
193d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            ASSIGN_4V(rgba[i], r, g, b, a);
194d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
195d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
196d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
197d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul}
198d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
199d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
20010035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
201f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_transparency_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
202d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                         GLvoid *src, const GLvoid *dst, GLenum chanType)
203d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{
204d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
205d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
206d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   GLuint i;
207d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
208bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
209bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
210bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
211bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
212bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
213bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
214bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(chanType == GL_FLOAT);
215d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
216d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   (void) ctx;
217d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
218d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   for (i = 0; i < n; i++) {
219d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (mask[i]) {
220d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         const GLfloat t = rgba[i][ACOMP];  /* t in [0, 1] */
221d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (t == 0.0F) {
222d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            /* 0% alpha */
223d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            COPY_4V(rgba[i], dest[i]);
224d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
225d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else if (t != 1.0F) {
226d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * t + dest[i][RCOMP];
227d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * t + dest[i][GCOMP];
228d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * t + dest[i][BCOMP];
229d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * t + dest[i][ACOMP];
230d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            ASSIGN_4V(rgba[i], r, g, b, a);
231e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
233e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
238a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
239d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Add src and dest: glBlendFunc(GL_ONE, GL_ONE).
240d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24210035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
243f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_add(struct gl_context *ctx, GLuint n, const GLubyte mask[],
244d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul          GLvoid *src, const GLvoid *dst, GLenum chanType)
245e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
246e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
247d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
248bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
249bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
250bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].SrcRGB == GL_ONE);
251bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].DstRGB == GL_ONE);
252e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
254d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE) {
255d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
256d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
257d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
258d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
259d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
260d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
261d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
262d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
263d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = (GLubyte) MIN2( r, 255 );
264d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = (GLubyte) MIN2( g, 255 );
265d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = (GLubyte) MIN2( b, 255 );
266d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = (GLubyte) MIN2( a, 255 );
267d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
268d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
269d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
270d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
271d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
272d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
273d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
274d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
275d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
276d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
277d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
278d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
279d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = (GLshort) MIN2( r, 255 );
280d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = (GLshort) MIN2( g, 255 );
281d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = (GLshort) MIN2( b, 255 );
282d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = (GLshort) MIN2( a, 255 );
283d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
284d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
285d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
286d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else {
287d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
288d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
289bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner      assert(chanType == GL_FLOAT);
290d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
291d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
292d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            /* don't RGB clamp to max */
293d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] += dest[i][RCOMP];
294d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] += dest[i][GCOMP];
295d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] += dest[i][BCOMP];
296d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] += dest[i][ACOMP];
297d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
304a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
305d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Blend min function.
306d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
30810035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
309f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_min(struct gl_context *ctx, GLuint n, const GLubyte mask[],
310d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul          GLvoid *src, const GLvoid *dst, GLenum chanType)
311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
313bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationRGB == GL_MIN);
314bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationA == GL_MIN);
315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
317d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE) {
318d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
319d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
320d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
321d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
322d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
323d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
324d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
325d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
326d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
327d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
328d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
329d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
330d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
331d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
332d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
333d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
334d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
335d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
336d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
337d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
338d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
339d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
340d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
341d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else {
342d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
343d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
344bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner      assert(chanType == GL_FLOAT);
345d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
346d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
347d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
348d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
349d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
350d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
351d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
352e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
353e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
354e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
356e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
357a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
358d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Blend max function.
359d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
360e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
36110035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
362f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_max(struct gl_context *ctx, GLuint n, const GLubyte mask[],
363d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul          GLvoid *src, const GLvoid *dst, GLenum chanType)
364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
366bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationRGB == GL_MAX);
367bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(ctx->Color.Blend[0].EquationA == GL_MAX);
368e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
370d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE) {
371d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
372d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
373d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
374d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
375d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
376d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
377d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
378d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
379d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
380d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
381d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
382d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
383d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
384d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
385d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
386d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
387d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
388d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
389d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
390d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
391d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
392d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
393d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
394d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else {
395d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
396d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
397bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner      assert(chanType == GL_FLOAT);
398d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
399d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
400d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
401d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
402d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
403d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
404d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
405e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
407e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
408e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
410e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
411a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
412e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Modulate:  result = src * dest
413d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Any chanType ok.
414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
41510035361b5c23483f236c59fe13c23153455e5c9Brian Paulstatic void
416f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_modulate(struct gl_context *ctx, GLuint n, const GLubyte mask[],
417d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               GLvoid *src, const GLvoid *dst, GLenum chanType)
418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
419e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
420e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
421e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
422d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   if (chanType == GL_UNSIGNED_BYTE) {
423d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
424d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
425d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
426d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
427d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul	    GLint divtemp;
428d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = DIV255(rgba[i][RCOMP] * dest[i][RCOMP]);
429d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = DIV255(rgba[i][GCOMP] * dest[i][GCOMP]);
430d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = DIV255(rgba[i][BCOMP] * dest[i][BCOMP]);
431d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = DIV255(rgba[i][ACOMP] * dest[i][ACOMP]);
432d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
433d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
434d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
435d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
436d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
437d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
438d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
439d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
440d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16;
441d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16;
442d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16;
443d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16;
444d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
445d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
446d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   }
447d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   else {
448d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
449d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
450bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner      assert(chanType == GL_FLOAT);
451d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      for (i=0;i<n;i++) {
452d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (mask[i]) {
453d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP];
454d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
455d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
456d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
457d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
458e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
459e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
460e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
463a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
464a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Do any blending operation, using floating point.
465a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param n  number of pixels
466a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param mask  fragment writemask array
467d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * \param rgba  array of incoming (and modified) pixels
468d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * \param dest  array of pixels from the dest color buffer
469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
470a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulstatic void
471f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
472d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                    GLfloat rgba[][4], GLfloat dest[][4],
473d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                    GLenum chanType)
474a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{
475a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   GLuint i;
476a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
477a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   for (i = 0; i < n; i++) {
478a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      if (mask[i]) {
479a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Incoming/source Color */
480a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Rs = rgba[i][RCOMP];
481a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Gs = rgba[i][GCOMP];
482a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Bs = rgba[i][BCOMP];
483a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat As = rgba[i][ACOMP];
484a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
485a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Frame buffer/dest color */
486a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Rd = dest[i][RCOMP];
487a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Gd = dest[i][GCOMP];
488a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Bd = dest[i][BCOMP];
489a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         const GLfloat Ad = dest[i][ACOMP];
490a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
491a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         GLfloat sR, sG, sB, sA;  /* Source factor */
492a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         GLfloat dR, dG, dB, dA;  /* Dest factor */
493a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         GLfloat r, g, b, a;      /* result color */
494a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
495a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* XXX for the case of constant blend terms we could init
496a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul          * the sX and dX variables just once before the loop.
497a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul          */
498a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
499a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Source RGB factor */
50074713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].SrcRGB) {
501a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ZERO:
502a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 0.0F;
503a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
504a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE:
505a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 1.0F;
506a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
507a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_COLOR:
508a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = Rd;
509a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = Gd;
510a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = Bd;
511a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
512a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_COLOR:
513a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = 1.0F - Rd;
514a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = 1.0F - Gd;
515a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = 1.0F - Bd;
516a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
517a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA:
518a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = As;
519a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
520a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_ALPHA:
521a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 1.0F - As;
522a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
523a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_ALPHA:
524a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = Ad;
525a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
526a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_ALPHA:
527a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 1.0F - Ad;
528a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
529a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA_SATURATE:
530a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               if (As < 1.0F - Ad) {
531a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul                  sR = sG = sB = As;
532a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               }
533a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               else {
534a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul                  sR = sG = sB = 1.0F - Ad;
535a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               }
536a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
537a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_COLOR:
538a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = ctx->Color.BlendColor[0];
539a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = ctx->Color.BlendColor[1];
540a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = ctx->Color.BlendColor[2];
541a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
542a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_COLOR:
543a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = 1.0F - ctx->Color.BlendColor[0];
544a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = 1.0F - ctx->Color.BlendColor[1];
545a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = 1.0F - ctx->Color.BlendColor[2];
546a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
547a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_ALPHA:
548a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = ctx->Color.BlendColor[3];
549a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
550a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_ALPHA:
551a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
552a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
553d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_SRC_COLOR:
554a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = Rs;
555a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = Gs;
556a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = Bs;
557a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
558d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_ONE_MINUS_SRC_COLOR:
559a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sR = 1.0F - Rs;
560a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sG = 1.0F - Gs;
561a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sB = 1.0F - Bs;
562a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
563a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            default:
564a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               /* this should never happen */
565a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float");
566a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               return;
567a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
568a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
569a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Source Alpha factor */
57074713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].SrcA) {
571a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ZERO:
572a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 0.0F;
573a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
574a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE:
575a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F;
576a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
577a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_COLOR:
578a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = Ad;
579a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
580a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_COLOR:
581a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - Ad;
582a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
583a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA:
584a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = As;
585a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
586a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_ALPHA:
587a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - As;
588a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
589a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_ALPHA:
590a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = Ad;
591a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
592a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_ALPHA:
593a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - Ad;
594a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
595a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA_SATURATE:
596a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0;
597a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
598a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_COLOR:
599a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = ctx->Color.BlendColor[3];
600a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
601a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_COLOR:
602a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - ctx->Color.BlendColor[3];
603a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
604a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_ALPHA:
605a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = ctx->Color.BlendColor[3];
606a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
607a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_ALPHA:
608a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - ctx->Color.BlendColor[3];
609a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
610d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_SRC_COLOR:
611a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = As;
612a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
613d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_ONE_MINUS_SRC_COLOR:
614a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 1.0F - As;
615a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
616a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            default:
617a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               /* this should never happen */
618a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               sA = 0.0F;
619a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               _mesa_problem(ctx, "Bad blend source A factor in blend_general_float");
620a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               return;
621a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
622a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
623a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Dest RGB factor */
62474713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].DstRGB) {
625a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ZERO:
626a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 0.0F;
627a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
628a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE:
629a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 1.0F;
630a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
631a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_COLOR:
632a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = Rs;
633a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = Gs;
634a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = Bs;
635a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
636a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_COLOR:
637a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = 1.0F - Rs;
638a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = 1.0F - Gs;
639a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = 1.0F - Bs;
640a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
641a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA:
642a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = As;
643a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
644a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_ALPHA:
645a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 1.0F - As;
646a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
647a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_ALPHA:
648a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = Ad;
649a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
650a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_ALPHA:
651a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 1.0F - Ad;
652a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
653a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_COLOR:
654a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = ctx->Color.BlendColor[0];
655a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = ctx->Color.BlendColor[1];
656a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = ctx->Color.BlendColor[2];
657a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
658a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_COLOR:
659a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = 1.0F - ctx->Color.BlendColor[0];
660a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = 1.0F - ctx->Color.BlendColor[1];
661a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = 1.0F - ctx->Color.BlendColor[2];
662a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
663a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_ALPHA:
664a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = ctx->Color.BlendColor[3];
665a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
666a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_ALPHA:
667a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
668a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
669d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_DST_COLOR:
670a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = Rd;
671a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = Gd;
672a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = Bd;
673a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
674d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_ONE_MINUS_DST_COLOR:
675a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = 1.0F - Rd;
676a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dG = 1.0F - Gd;
677a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dB = 1.0F - Bd;
678a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
679a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            default:
680a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               /* this should never happen */
681a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dR = dG = dB = 0.0F;
682a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float");
683a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               return;
684a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
685a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
686a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* Dest Alpha factor */
68774713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].DstA) {
688a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ZERO:
689a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 0.0F;
690a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
691a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE:
692a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F;
693a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
694a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_COLOR:
695a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = As;
696a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
697a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_COLOR:
698a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - As;
699a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
700a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_SRC_ALPHA:
701a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = As;
702a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
703a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_SRC_ALPHA:
704a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - As;
705a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
706a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_DST_ALPHA:
707a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = Ad;
708a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
709a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_DST_ALPHA:
710a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - Ad;
711a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
712a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_COLOR:
713a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = ctx->Color.BlendColor[3];
714a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
715a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_COLOR:
716a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - ctx->Color.BlendColor[3];
717a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
718a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_CONSTANT_ALPHA:
719a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = ctx->Color.BlendColor[3];
720a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
721a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            case GL_ONE_MINUS_CONSTANT_ALPHA:
722a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - ctx->Color.BlendColor[3];
723a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
724d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_DST_COLOR:
725a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = Ad;
726a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
727d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            case GL_ONE_MINUS_DST_COLOR:
728a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 1.0F - Ad;
729a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               break;
730a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            default:
731a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               /* this should never happen */
732a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               dA = 0.0F;
733a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float");
734a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul               return;
735a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
736a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
737a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* compute the blended RGB */
73874713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].EquationRGB) {
739a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_ADD:
740a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            r = Rs * sR + Rd * dR;
741a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            g = Gs * sG + Gd * dG;
742a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            b = Bs * sB + Bd * dB;
743a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = As * sA + Ad * dA;
744a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
745a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_SUBTRACT:
746a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            r = Rs * sR - Rd * dR;
747a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            g = Gs * sG - Gd * dG;
748a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            b = Bs * sB - Bd * dB;
749a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = As * sA - Ad * dA;
750a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
751a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_REVERSE_SUBTRACT:
752a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            r = Rd * dR - Rs * sR;
753a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            g = Gd * dG - Gs * sG;
754a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            b = Bd * dB - Bs * sB;
755a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = Ad * dA - As * sA;
756a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
757a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_MIN:
758a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    r = MIN2( Rd, Rs );
759a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    g = MIN2( Gd, Gs );
760a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    b = MIN2( Bd, Bs );
761a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
762a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_MAX:
763a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    r = MAX2( Rd, Rs );
764a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    g = MAX2( Gd, Gs );
765a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    b = MAX2( Bd, Bs );
766a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
767a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	 default:
768a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            /* should never get here */
769a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            r = g = b = 0.0F;  /* silence uninitialized var warning */
770a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
771a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            return;
772a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
773a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
774a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* compute the blended alpha */
77574713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul         switch (ctx->Color.Blend[0].EquationA) {
776a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_ADD:
777a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = As * sA + Ad * dA;
778a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
779a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_SUBTRACT:
780a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = As * sA - Ad * dA;
781a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
782a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_FUNC_REVERSE_SUBTRACT:
783a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = Ad * dA - As * sA;
784a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
785a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_MIN:
786a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    a = MIN2( Ad, As );
787a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
788a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         case GL_MAX:
789a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    a = MAX2( Ad, As );
790a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            break;
791a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         default:
792a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            /* should never get here */
793a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            a = 0.0F;  /* silence uninitialized var warning */
794a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
795a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            return;
796a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
797a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
798a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         /* final clamping */
799a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul#if 0
800a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         rgba[i][RCOMP] = MAX2( r, 0.0F );
801a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         rgba[i][GCOMP] = MAX2( g, 0.0F );
802a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         rgba[i][BCOMP] = MAX2( b, 0.0F );
803d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         rgba[i][ACOMP] = CLAMP( a, 0.0F, 1.0F );
804a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul#else
805a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         ASSIGN_4V(rgba[i], r, g, b, a);
806a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul#endif
807a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
808a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
809a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul}
810a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
811a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
812d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/**
813d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Do any blending operation, any chanType.
814d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */
815a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulstatic void
816f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblend_general(struct gl_context *ctx, GLuint n, const GLubyte mask[],
817d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul              void *src, const void *dst, GLenum chanType)
818a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{
81925662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   GLfloat (*rgbaF)[4], (*destF)[4];
82025662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul
82125662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   rgbaF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
82225662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   destF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
82325662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   if (!rgbaF || !destF) {
82425662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul      free(rgbaF);
82525662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul      free(destF);
82625662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "blending");
82725662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul      return;
82825662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   }
829a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
830a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   if (chanType == GL_UNSIGNED_BYTE) {
831a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
832a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
833a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      GLuint i;
834a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* convert ubytes to floats */
835a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      for (i = 0; i < n; i++) {
836a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         if (mask[i]) {
837a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]);
838a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]);
839a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]);
840a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]);
841a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]);
842a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]);
843a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]);
844a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]);
845a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
846a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
847a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* do blend */
848a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
849a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* convert back to ubytes */
850a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      for (i = 0; i < n; i++) {
85181a86aea4f0990a1b8795f9e00e7a6c4ba368281Dave Airlie         if (mask[i])
85281a86aea4f0990a1b8795f9e00e7a6c4ba368281Dave Airlie	   _mesa_unclamped_float_rgba_to_ubyte(rgba[i], rgbaF[i]);
853a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
854a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
855a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (chanType == GL_UNSIGNED_SHORT) {
856a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      GLushort (*rgba)[4] = (GLushort (*)[4]) src;
857a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
858a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      GLuint i;
859a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* convert ushorts to floats */
860a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      for (i = 0; i < n; i++) {
861a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         if (mask[i]) {
862a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]);
863a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]);
864a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]);
865a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]);
866a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]);
867a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]);
868a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]);
869a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]);
870a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
871a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
872a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* do blend */
873a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
874a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      /* convert back to ushorts */
875a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      for (i = 0; i < n; i++) {
876a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         if (mask[i]) {
877a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]);
878a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]);
879a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]);
880a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]);
881a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         }
882a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      }
883a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
884a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else {
885145f5f60f19574e06c536c102bec0cfd6320606dMark Anderson      blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src,
886145f5f60f19574e06c536c102bec0cfd6320606dMark Anderson                          (GLfloat (*)[4]) dst, chanType);
887a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
88825662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul
88925662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   free(rgbaF);
89025662f878ea5f3a8c55506d0becafe2c0a6370f2Brian Paul   free(destF);
891a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul}
892e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
893e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
894e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
895a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
896e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Analyze current blending parameters to pick fastest blending function.
897e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Result: the ctx->Color.BlendFunc pointer is updated.
898e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
899d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paulvoid
900f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_choose_blend_func(struct gl_context *ctx, GLenum chanType)
901e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
902a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
90374713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum eq = ctx->Color.Blend[0].EquationRGB;
90474713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
90574713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
90674713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum srcA = ctx->Color.Blend[0].SrcA;
90774713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   const GLenum dstA = ctx->Color.Blend[0].DstA;
908e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
90974713e2d293f9e796a4053a5a99ee5cb7df5c740Brian Paul   if (ctx->Color.Blend[0].EquationRGB != ctx->Color.Blend[0].EquationA) {
910a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      swrast->BlendFunc = blend_general;
911c93105eb9e2499efb237fd89dba0cebd48f18375Ian Romanick   }
912a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_MIN) {
91363f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      /* Note: GL_MIN ignores the blending weight factors */
91463f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul#if defined(USE_MMX_ASM)
915d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
916a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_min;
91763f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      }
91863f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      else
91963f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul#endif
920d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         swrast->BlendFunc = blend_min;
92163f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul   }
922a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_MAX) {
92363f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      /* Note: GL_MAX ignores the blending weight factors */
92463f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul#if defined(USE_MMX_ASM)
925d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
926a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_max;
92763f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      }
92863f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul      else
92963f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul#endif
930d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         swrast->BlendFunc = blend_max;
93163f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul   }
93263f4e198b41ad5a25200db3d126a6320d6cf8dccBrian Paul   else if (srcRGB != srcA || dstRGB != dstA) {
933a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      swrast->BlendFunc = blend_general;
934e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
935a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA
936a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul            && dstRGB == GL_ONE_MINUS_SRC_ALPHA) {
9379add9a21d8c51ee4238169265541fa9a40f0a8b0Brian Paul#if defined(USE_MMX_ASM)
938d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
939a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_transparency;
940cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      }
941cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      else
942cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#endif
943d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      {
944d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (chanType == GL_UNSIGNED_BYTE)
945d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            swrast->BlendFunc = blend_transparency_ubyte;
946d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else if (chanType == GL_UNSIGNED_SHORT)
947d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            swrast->BlendFunc = blend_transparency_ushort;
948d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         else
949d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            swrast->BlendFunc = blend_transparency_float;
950d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
951e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
952a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) {
9530c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca#if defined(USE_MMX_ASM)
954d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
955a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_add;
9560c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca      }
9570c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca      else
9580c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca#endif
959d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         swrast->BlendFunc = blend_add;
960e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
961a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT)
962a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	     && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR))
963cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	    ||
964a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	    ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT)
965a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul	     && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) {
966533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca#if defined(USE_MMX_ASM)
967d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
968a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul         swrast->BlendFunc = _mesa_mmx_blend_modulate;
969533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca      }
970533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca      else
971533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca#endif
972d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         swrast->BlendFunc = blend_modulate;
973e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
974a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
975d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      swrast->BlendFunc = blend_noop;
97659235bd5da794557613463bc942de0c634d2d961Brian Paul   }
977a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
978a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      swrast->BlendFunc = blend_replace;
97959235bd5da794557613463bc942de0c634d2d961Brian Paul   }
980e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
981a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      swrast->BlendFunc = blend_general;
982e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
983e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
984e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
985e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
986e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
987a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
988e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the blending operator to a span of pixels.
989733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * We can handle horizontal runs of pixels (spans) or arrays of x/y
990733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * pixel coordinates.
991e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
992e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
993f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_blend_span(struct gl_context *ctx, struct gl_renderbuffer *rb, SWspan *span)
994e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
995a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
996a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   void *rbPixels;
997e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
998bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(span->end <= SWRAST_MAX_WIDTH);
999bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(span->arrayMask & SPAN_RGBA);
1000bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(!ctx->Color.ColorLogicOpEnabled);
1001e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1002a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
1003e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1004a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   swrast->BlendFunc(ctx, span->end, span->array->mask,
1005d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                     span->array->rgba, rbPixels, span->array->ChanType);
1006e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1007