12cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/*
22cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Mesa 3-D graphics library
32d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul * Version:  7.5
42cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
52d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
62d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul * Copyright (C) 2009  VMware, Inc.   All Rights Reserved.
72cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
82cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a
92cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * copy of this software and associated documentation files (the "Software"),
102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * to deal in the Software without restriction, including without limitation
112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * and/or sell copies of the Software, and to permit persons to whom the
132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Software is furnished to do so, subject to the following conditions:
142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * The above copyright notice and this permission notice shall be included
162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * in all copies or substantial portions of the Software.
172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h"
30bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
311c131752c3e07ef91f49d4970dafca6d26585334Brian Paul#include "main/pixeltransfer.h"
32cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen#include "main/samplerobj.h"
33ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_instruction.h"
342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_context.h"
362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_texcombine.h"
372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
400695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul * Pointer to array of float[4]
410695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul * This type makes the code below more concise and avoids a lot of casting.
420695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul */
430695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paultypedef float (*float4_array)[4];
440695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul
450695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul
460695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul/**
470695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul * Return array of texels for given unit.
480695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul */
499520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline float4_array
501b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paulget_texel_array(SWcontext *swrast, GLuint unit)
510695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul{
52e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#ifdef _OPENMP
5347d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul   return (float4_array) (swrast->TexelBuffer + unit * SWRAST_MAX_WIDTH * 4 * omp_get_num_threads() + (SWRAST_MAX_WIDTH * 4 * omp_get_thread_num()));
54e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#else
5547d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul   return (float4_array) (swrast->TexelBuffer + unit * SWRAST_MAX_WIDTH * 4);
56e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#endif
570695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul}
580695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul
590695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul
600695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul
610695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul/**
62bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * Do texture application for:
63bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul *  GL_EXT_texture_env_combine
64bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul *  GL_ARB_texture_env_combine
65bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul *  GL_EXT_texture_env_dot3
66bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul *  GL_ARB_texture_env_dot3
67bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul *  GL_ATI_texture_env_combine3
68bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul *  GL_NV_texture_env_combine4
69bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul *  conventional GL texture env modes
702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \param ctx          rendering context
72bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * \param unit         the texture combiner unit
732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \param primary_rgba incoming fragment color array
742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \param texelBuffer  pointer to texel colors for all texture units
752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
766ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu * \param span         two fields are used in this function:
776ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu *                       span->end: number of fragments to process
786ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu *                       span->array->rgba: incoming/result fragment colors
792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
816ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liutexture_combine( struct gl_context *ctx, GLuint unit,
820695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul                 const float4_array primary_rgba,
830695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul                 const GLfloat *texelBuffer,
846ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu                 SWspan *span )
852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
861b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
88933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul   const struct gl_tex_env_combine_state *combine = textureUnit->_CurrentCombine;
890695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul   float4_array argRGB[MAX_COMBINER_TERMS];
900695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul   float4_array argA[MAX_COMBINER_TERMS];
91bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul   const GLfloat scaleRGB = (GLfloat) (1 << combine->ScaleShiftRGB);
92bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul   const GLfloat scaleA = (GLfloat) (1 << combine->ScaleShiftA);
93bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul   const GLuint numArgsRGB = combine->_NumArgsRGB;
94bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul   const GLuint numArgsA = combine->_NumArgsA;
95aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   float4_array ccolor[4], rgba;
96933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul   GLuint i, term;
976ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu   GLuint n = span->end;
986ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu   GLchan (*rgbaChan)[4] = span->array->rgba;
992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
100aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   /* alloc temp pixel buffers */
101aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   rgba = (float4_array) malloc(4 * n * sizeof(GLfloat));
102aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   if (!rgba) {
103aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
104aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul      return;
105aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   }
106aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul
107aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   for (i = 0; i < numArgsRGB || i < numArgsA; i++) {
108aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul      ccolor[i] = (float4_array) malloc(4 * n * sizeof(GLfloat));
109aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul      if (!ccolor[i]) {
110aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul         while (i) {
111aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul            free(ccolor[i]);
112aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul            i--;
113aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul         }
114aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
115c81b441ba2b8ab61d5e1f24ec7a34914c8a3b215Vinson Lee         free(rgba);
116aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul         return;
117aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul      }
118aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   }
119aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul
120de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   for (i = 0; i < n; i++) {
121de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]);
122de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]);
123de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]);
124de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]);
125de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   }
126de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul
1272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /*
1282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   printf("modeRGB 0x%x  modeA 0x%x  srcRGB1 0x%x  srcA1 0x%x  srcRGB2 0x%x  srcA2 0x%x\n",
129933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul          combine->ModeRGB,
130933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul          combine->ModeA,
131933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul          combine->SourceRGB[0],
132933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul          combine->SourceA[0],
133933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul          combine->SourceRGB[1],
134933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul          combine->SourceA[1]);
1352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   */
1362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /*
1382d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul    * Do operand setup for up to 4 operands.  Loop over the terms.
1392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
140bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul   for (term = 0; term < numArgsRGB; term++) {
141933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      const GLenum srcRGB = combine->SourceRGB[term];
142933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      const GLenum operandRGB = combine->OperandRGB[term];
1432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      switch (srcRGB) {
1452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         case GL_TEXTURE:
1461b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul            argRGB[term] = get_texel_array(swrast, unit);
1472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
1482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         case GL_PRIMARY_COLOR:
149933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            argRGB[term] = primary_rgba;
1502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
1512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         case GL_PREVIOUS:
1520695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul            argRGB[term] = rgba;
1532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
1542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         case GL_CONSTANT:
1552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            {
1560695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               float4_array c = ccolor[term];
157de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               GLfloat red   = textureUnit->EnvColor[0];
158de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               GLfloat green = textureUnit->EnvColor[1];
159de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               GLfloat blue  = textureUnit->EnvColor[2];
160de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               GLfloat alpha = textureUnit->EnvColor[3];
1612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               for (i = 0; i < n; i++) {
162de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  ASSIGN_4V(c[i], red, green, blue, alpha);
1632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               }
1640695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               argRGB[term] = ccolor[term];
1652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
1662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
1672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
1682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	  */
1692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 case GL_ZERO:
170de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul            {
1710695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               float4_array c = ccolor[term];
172de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               for (i = 0; i < n; i++) {
173de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  ASSIGN_4V(c[i], 0.0F, 0.0F, 0.0F, 0.0F);
174de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               }
1750695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               argRGB[term] = ccolor[term];
176de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul            }
1772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
1782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 case GL_ONE:
179de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul            {
1800695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               float4_array c = ccolor[term];
181de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               for (i = 0; i < n; i++) {
182de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  ASSIGN_4V(c[i], 1.0F, 1.0F, 1.0F, 1.0F);
183de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               }
1840695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               argRGB[term] = ccolor[term];
185de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul            }
1862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
1872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         default:
1882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            /* ARB_texture_env_crossbar source */
1892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            {
1902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               const GLuint srcUnit = srcRGB - GL_TEXTURE0;
1912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
1922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
193aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul                  goto end;
1941b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul               argRGB[term] = get_texel_array(swrast, srcUnit);
1952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
1962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
1972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
198933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      if (operandRGB != GL_SRC_COLOR) {
1990695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul         float4_array src = argRGB[term];
2000695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul         float4_array dst = ccolor[term];
2012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
202933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         /* point to new arg[term] storage */
2030695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul         argRGB[term] = ccolor[term];
2042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
205933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         switch (operandRGB) {
206933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         case GL_ONE_MINUS_SRC_COLOR:
2072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            for (i = 0; i < n; i++) {
208de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               dst[i][RCOMP] = 1.0F - src[i][RCOMP];
209de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               dst[i][GCOMP] = 1.0F - src[i][GCOMP];
210de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               dst[i][BCOMP] = 1.0F - src[i][BCOMP];
2112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
212933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            break;
213933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         case GL_SRC_ALPHA:
2142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            for (i = 0; i < n; i++) {
215aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul               dst[i][RCOMP] =
216aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul               dst[i][GCOMP] =
2172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               dst[i][BCOMP] = src[i][ACOMP];
2182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
219933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            break;
220933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         case GL_ONE_MINUS_SRC_ALPHA:
2212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            for (i = 0; i < n; i++) {
222aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul               dst[i][RCOMP] =
223aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul               dst[i][GCOMP] =
224de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul               dst[i][BCOMP] = 1.0F - src[i][ACOMP];
2252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
226933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            break;
227933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         default:
228933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            _mesa_problem(ctx, "Bad operandRGB");
2292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
2302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
2312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
2322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /*
234bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul    * Set up the argA[term] pointers
2352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
236bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul   for (term = 0; term < numArgsA; term++) {
237933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      const GLenum srcA = combine->SourceA[term];
238933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      const GLenum operandA = combine->OperandA[term];
2392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      switch (srcA) {
2412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         case GL_TEXTURE:
2421b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul            argA[term] = get_texel_array(swrast, unit);
2432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
2442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         case GL_PRIMARY_COLOR:
245933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            argA[term] = primary_rgba;
2462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
2472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         case GL_PREVIOUS:
2480695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul            argA[term] = rgba;
2492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
2502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         case GL_CONSTANT:
2512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            {
2520695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               float4_array c = ccolor[term];
253933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul               GLfloat alpha = textureUnit->EnvColor[3];
2542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               for (i = 0; i < n; i++)
2552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  c[i][ACOMP] = alpha;
2560695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               argA[term] = ccolor[term];
2572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
2582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
2592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
2602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	  */
2612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 case GL_ZERO:
262933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            {
2630695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               float4_array c = ccolor[term];
264933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul               for (i = 0; i < n; i++)
265933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul                  c[i][ACOMP] = 0.0F;
2660695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               argA[term] = ccolor[term];
267933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            }
2682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
2692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 case GL_ONE:
270933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            {
2710695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               float4_array c = ccolor[term];
272933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul               for (i = 0; i < n; i++)
273933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul                  c[i][ACOMP] = 1.0F;
2740695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul               argA[term] = ccolor[term];
275933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            }
2762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            break;
2772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         default:
2782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            /* ARB_texture_env_crossbar source */
2792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            {
2802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               const GLuint srcUnit = srcA - GL_TEXTURE0;
2812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
2822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
283aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul                  goto end;
2841b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul               argA[term] = get_texel_array(swrast, srcUnit);
2852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
2862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
2872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
288933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      if (operandA == GL_ONE_MINUS_SRC_ALPHA) {
2890695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul         float4_array src = argA[term];
2900695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul         float4_array dst = ccolor[term];
2910695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul         argA[term] = ccolor[term];
2922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = 0; i < n; i++) {
293de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul            dst[i][ACOMP] = 1.0F - src[i][ACOMP];
2942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
2952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
2962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
2972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
298933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul   /* RGB channel combine */
299933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul   {
3000695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul      float4_array arg0 = argRGB[0];
3010695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul      float4_array arg1 = argRGB[1];
3020695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul      float4_array arg2 = argRGB[2];
3030695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul      float4_array arg3 = argRGB[3];
304933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul
305933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      switch (combine->ModeRGB) {
3062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_REPLACE:
307933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
308bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][RCOMP] = arg0[i][RCOMP] * scaleRGB;
309bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][GCOMP] = arg0[i][GCOMP] * scaleRGB;
310bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][BCOMP] = arg0[i][BCOMP] * scaleRGB;
3112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
3132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_MODULATE:
314933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
315bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * scaleRGB;
316bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * scaleRGB;
317bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * scaleRGB;
3182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
3202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_ADD:
3212d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         if (textureUnit->EnvMode == GL_COMBINE4_NV) {
3222d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            /* (a * b) + (c * d) */
3232d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            for (i = 0; i < n; i++) {
3242d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul               rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] +
325bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                                 arg2[i][RCOMP] * arg3[i][RCOMP]) * scaleRGB;
3262d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul               rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] +
327bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                                 arg2[i][GCOMP] * arg3[i][GCOMP]) * scaleRGB;
3282d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul               rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] +
329bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                                 arg2[i][BCOMP] * arg3[i][BCOMP]) * scaleRGB;
3302d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            }
3312d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         }
3322d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         else {
3332d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            /* 2-term addition */
3342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            for (i = 0; i < n; i++) {
335bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul               rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * scaleRGB;
336bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul               rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * scaleRGB;
337bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul               rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * scaleRGB;
3382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
3392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
3412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_ADD_SIGNED:
3422d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         if (textureUnit->EnvMode == GL_COMBINE4_NV) {
3432d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            /* (a * b) + (c * d) - 0.5 */
3442d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            for (i = 0; i < n; i++) {
34587c356a222bb97ecf9b04e8d509b103199159b11Brian Paul               rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] +
346880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul                                 arg2[i][RCOMP] * arg3[i][RCOMP] - 0.5F) * scaleRGB;
34787c356a222bb97ecf9b04e8d509b103199159b11Brian Paul               rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] +
348880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul                                 arg2[i][GCOMP] * arg3[i][GCOMP] - 0.5F) * scaleRGB;
34987c356a222bb97ecf9b04e8d509b103199159b11Brian Paul               rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] +
350880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul                                 arg2[i][BCOMP] * arg3[i][BCOMP] - 0.5F) * scaleRGB;
3512d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            }
3522d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         }
3532d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         else {
3542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            for (i = 0; i < n; i++) {
355880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul               rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5F) * scaleRGB;
356880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul               rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5F) * scaleRGB;
357880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul               rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5F) * scaleRGB;
3582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
3592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
3612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_INTERPOLATE:
362933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
363933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] +
364bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                          arg1[i][RCOMP] * (1.0F - arg2[i][RCOMP])) * scaleRGB;
365933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] +
366bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                          arg1[i][GCOMP] * (1.0F - arg2[i][GCOMP])) * scaleRGB;
367933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] +
368bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                          arg1[i][BCOMP] * (1.0F - arg2[i][BCOMP])) * scaleRGB;
3692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
3712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_SUBTRACT:
372933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
373bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * scaleRGB;
374bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * scaleRGB;
375bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * scaleRGB;
3762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
3782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_DOT3_RGB_EXT:
3792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_DOT3_RGBA_EXT:
380933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         /* Do not scale the result by 1 2 or 4 */
381933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
382bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) +
383bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                           (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) +
384bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                           (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F))
385933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul               * 4.0F;
386933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            dot = CLAMP(dot, 0.0F, 1.0F);
387aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul            rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot;
3882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
3902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_DOT3_RGB:
3912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_DOT3_RGBA:
392933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         /* DO scale the result by 1 2 or 4 */
393933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
394bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) +
395bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                           (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) +
396bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                           (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F))
397bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul               * 4.0F * scaleRGB;
398b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz            dot = CLAMP(dot, 0.0F, 1.0F);
399aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul            rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot;
4002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
4012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
4022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_MODULATE_ADD_ATI:
403933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
404933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) +
405bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              arg1[i][RCOMP]) * scaleRGB;
406933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) +
407bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              arg1[i][GCOMP]) * scaleRGB;
408933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) +
409bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              arg1[i][BCOMP]) * scaleRGB;
4102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 }
4112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
4122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_MODULATE_SIGNED_ADD_ATI:
413933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
414933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) +
415880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul                              arg1[i][RCOMP] - 0.5F) * scaleRGB;
416933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) +
417880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul                              arg1[i][GCOMP] - 0.5F) * scaleRGB;
418933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) +
419880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul                              arg1[i][BCOMP] - 0.5F) * scaleRGB;
4202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 }
4212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
4222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_MODULATE_SUBTRACT_ATI:
423933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
424933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) -
425bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              arg1[i][RCOMP]) * scaleRGB;
426933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) -
427bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              arg1[i][GCOMP]) * scaleRGB;
428933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) -
429bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              arg1[i][BCOMP]) * scaleRGB;
4302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 }
4312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
432114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger      case GL_BUMP_ENVMAP_ATI:
4333630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul         /* this produces a fixed rgba color, and the coord calc is done elsewhere */
4343630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul         for (i = 0; i < n; i++) {
435114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            /* rgba result is 0,0,0,1 */
4363630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul            rgba[i][RCOMP] = 0.0;
4373630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul            rgba[i][GCOMP] = 0.0;
4383630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul            rgba[i][BCOMP] = 0.0;
4393630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul            rgba[i][ACOMP] = 1.0;
440114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger	 }
441aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul         goto end; /* no alpha processing */
4422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
4432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "invalid combine mode");
444933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      }
4452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
4462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
447933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul   /* Alpha channel combine */
448933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul   {
4490695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul      float4_array arg0 = argA[0];
4500695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul      float4_array arg1 = argA[1];
4510695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul      float4_array arg2 = argA[2];
4520695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul      float4_array arg3 = argA[3];
453933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul
454933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      switch (combine->ModeA) {
4552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_REPLACE:
456933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
457aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul            rgba[i][ACOMP] = arg0[i][ACOMP] * scaleA;
4582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
4592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
4602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_MODULATE:
461933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
462bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * scaleA;
4632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
4642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
4652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_ADD:
4662d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         if (textureUnit->EnvMode == GL_COMBINE4_NV) {
4672d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            /* (a * b) + (c * d) */
4682d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            for (i = 0; i < n; i++) {
4692d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul               rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] +
470bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                                 arg2[i][ACOMP] * arg3[i][ACOMP]) * scaleA;
4712d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            }
4722d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         }
4732d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         else {
4742d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            /* two-term add */
4752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            for (i = 0; i < n; i++) {
476bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul               rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * scaleA;
4772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
4782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
4792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
4802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_ADD_SIGNED:
4812d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         if (textureUnit->EnvMode == GL_COMBINE4_NV) {
4822d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            /* (a * b) + (c * d) - 0.5 */
4832d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            for (i = 0; i < n; i++) {
4842d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul               rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] +
4852d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul                                 arg2[i][ACOMP] * arg3[i][ACOMP] -
486880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul                                 0.5F) * scaleA;
4872d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            }
4882d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         }
4892d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul         else {
4902d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul            /* a + b - 0.5 */
4912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            for (i = 0; i < n; i++) {
492bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul               rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * scaleA;
4932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
4942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
4952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
4962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_INTERPOLATE:
497aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul         for (i = 0; i < n; i++) {
498933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] +
499933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul                              arg1[i][ACOMP] * (1.0F - arg2[i][ACOMP]))
500bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul               * scaleA;
5012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
5022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
5032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_SUBTRACT:
504933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
505bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul            rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * scaleA;
5062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
5072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
5082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_MODULATE_ADD_ATI:
509933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
510933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP])
511bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              + arg1[i][ACOMP]) * scaleA;
5122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
5132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
5142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_MODULATE_SIGNED_ADD_ATI:
515933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
516933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) +
517bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              arg1[i][ACOMP] - 0.5F) * scaleA;
5182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
5192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
5202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_MODULATE_SUBTRACT_ATI:
521933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul         for (i = 0; i < n; i++) {
522933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul            rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP])
523bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul                              - arg1[i][ACOMP]) * scaleA;
5242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
5252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
5262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
5272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "invalid combine mode");
528933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul      }
5292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
5302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
5312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining.
5322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * This is kind of a kludge.  It would have been better if the spec
5332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * were written such that the GL_COMBINE_ALPHA value could be set to
5342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * GL_DOT3.
5352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
536933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul   if (combine->ModeRGB == GL_DOT3_RGBA_EXT ||
537933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul       combine->ModeRGB == GL_DOT3_RGBA) {
5382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      for (i = 0; i < n; i++) {
5392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul	 rgba[i][ACOMP] = rgba[i][RCOMP];
5402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
5412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
542de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul
543de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   for (i = 0; i < n; i++) {
544de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]);
545de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]);
546de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]);
547de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]);
548de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   }
5492e6402feb754dd6384ee27fe623a7f9fce66dcafYuanhan Liu   /* The span->array->rgba values are of CHAN type so set
5502e6402feb754dd6384ee27fe623a7f9fce66dcafYuanhan Liu    * span->array->ChanType field accordingly.
5512e6402feb754dd6384ee27fe623a7f9fce66dcafYuanhan Liu    */
5522e6402feb754dd6384ee27fe623a7f9fce66dcafYuanhan Liu   span->array->ChanType = CHAN_TYPE;
553aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul
554aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paulend:
555aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   for (i = 0; i < numArgsRGB || i < numArgsA; i++) {
556aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul      free(ccolor[i]);
557aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   }
558aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   free(rgba);
5592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
560de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul
5612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
5622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
56354c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul * Apply X/Y/Z/W/0/1 swizzle to an array of colors/texels.
56454c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul * See GL_EXT_texture_swizzle.
56554c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul */
56654c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paulstatic void
5670695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paulswizzle_texels(GLuint swizzle, GLuint count, float4_array texels)
56854c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul{
56954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul   const GLuint swzR = GET_SWZ(swizzle, 0);
57054c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul   const GLuint swzG = GET_SWZ(swizzle, 1);
57154c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul   const GLuint swzB = GET_SWZ(swizzle, 2);
57254c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul   const GLuint swzA = GET_SWZ(swizzle, 3);
573de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat vector[6];
57454c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul   GLuint i;
57554c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul
57654c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul   vector[SWIZZLE_ZERO] = 0;
577de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   vector[SWIZZLE_ONE] = 1.0F;
57854c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul
57954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul   for (i = 0; i < count; i++) {
58054c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul      vector[SWIZZLE_X] = texels[i][0];
58154c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul      vector[SWIZZLE_Y] = texels[i][1];
58254c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul      vector[SWIZZLE_Z] = texels[i][2];
58354c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul      vector[SWIZZLE_W] = texels[i][3];
58454c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul      texels[i][RCOMP] = vector[swzR];
58554c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul      texels[i][GCOMP] = vector[swzG];
58654c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul      texels[i][BCOMP] = vector[swzB];
58754c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul      texels[i][ACOMP] = vector[swzA];
58854c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul   }
58954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul}
59054c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul
59154c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul
59254c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul/**
5932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Apply texture mapping to a span of fragments.
5942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
5952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulvoid
596f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_texture_span( struct gl_context *ctx, SWspan *span )
5972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
5982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
599aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   float4_array primary_rgba;
6002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint unit;
6012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6029119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul   if (!swrast->TexelBuffer) {
6039119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul#ifdef _OPENMP
6049119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul      const GLint maxThreads = omp_get_max_threads();
6059119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul#else
6069119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul      const GLint maxThreads = 1;
6079119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul#endif
6089119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul
6099119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul      /* TexelBuffer is also global and normally shared by all SWspan
6109119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul       * instances; when running with multiple threads, create one per
6119119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul       * thread.
6129119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul       */
6139119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul      swrast->TexelBuffer =
6149119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul	 (GLfloat *) MALLOC(ctx->Const.MaxTextureImageUnits * maxThreads *
61547d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul			    SWRAST_MAX_WIDTH * 4 * sizeof(GLfloat));
6169119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul      if (!swrast->TexelBuffer) {
6179119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul	 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
6189119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul	 return;
6199119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul      }
6209119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul   }
6219119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul
622aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   primary_rgba = (float4_array) malloc(span->end * 4 * sizeof(GLfloat));
623aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul
624aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   if (!primary_rgba) {
625aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_span");
626aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul      return;
627aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   }
628aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul
62947d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul   ASSERT(span->end <= SWRAST_MAX_WIDTH);
6302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /*
6322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
6332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
6347aed2b0c30c6d29d70efd2402a68a8e3de98418cBrian Paul   if (swrast->_TextureCombinePrimary) {
635de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      GLuint i;
636de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      for (i = 0; i < span->end; i++) {
637de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]);
638de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]);
639de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]);
640de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]);
641de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      }
642de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   }
6432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
644114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger   /* First must sample all bump maps */
645114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
6461b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul      const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
6471b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul
6481b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul      if (texUnit->_ReallyEnabled &&
6491b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul         texUnit->_CurrentCombine->ModeRGB == GL_BUMP_ENVMAP_ATI) {
6501b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul         const GLfloat (*texcoords)[4] = (const GLfloat (*)[4])
651114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
6521b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul         float4_array targetcoords =
653114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            span->array->attribs[FRAG_ATTRIB_TEX0 +
654114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0];
655114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
656cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
657114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         GLfloat *lambda = span->array->lambda[unit];
6581b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul         float4_array texels = get_texel_array(swrast, unit);
659114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         GLuint i;
660114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         GLfloat rotMatrix00 = ctx->Texture.Unit[unit].RotMatrix[0];
661114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         GLfloat rotMatrix01 = ctx->Texture.Unit[unit].RotMatrix[1];
662114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2];
663114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3];
664114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
665114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         /* adjust texture lod (lambda) */
666114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         if (span->arrayMask & SPAN_LAMBDA) {
667cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            if (texUnit->LodBias + samp->LodBias != 0.0F) {
668114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               /* apply LOD bias, but don't clamp yet */
669cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               const GLfloat bias = CLAMP(texUnit->LodBias + samp->LodBias,
670114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger                                          -ctx->Const.MaxTextureLodBias,
671114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger                                          ctx->Const.MaxTextureLodBias);
672114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               GLuint i;
673114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               for (i = 0; i < span->end; i++) {
674114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger                  lambda[i] += bias;
675114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               }
676114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            }
677114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
678cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            if (samp->MinLod != -1000.0 ||
679cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                samp->MaxLod != 1000.0) {
680114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               /* apply LOD clamping to lambda */
681cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               const GLfloat min = samp->MinLod;
682cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               const GLfloat max = samp->MaxLod;
683114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               GLuint i;
684114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               for (i = 0; i < span->end; i++) {
685114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger                  GLfloat l = lambda[i];
686114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger                  lambda[i] = CLAMP(l, min, max);
687114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger               }
688114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            }
689114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         }
690114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
691114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         /* Sample the texture (span->end = number of fragments) */
692cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         swrast->TextureSample[unit]( ctx, samp,
693cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      ctx->Texture.Unit[unit]._Current,
694cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      span->end, texcoords, lambda, texels );
695114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
696114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         /* manipulate the span values of the bump target
697114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            not sure this can work correctly even ignoring
698114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            the problem that channel is unsigned */
699114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         for (i = 0; i < span->end; i++) {
700114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            targetcoords[i][0] += (texels[i][0] * rotMatrix00 + texels[i][1] *
701114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger                                  rotMatrix01) / targetcoords[i][3];
702114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger            targetcoords[i][1] += (texels[i][0] * rotMatrix10 + texels[i][1] *
703114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger                                  rotMatrix11) / targetcoords[i][3];
704114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger         }
705114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger      }
706114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger   }
707114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
7082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /*
7092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * Must do all texture sampling before combining in order to
7102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * accomodate GL_ARB_texture_env_crossbar.
7112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
7122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
7131b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul      const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
7141b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul      if (texUnit->_ReallyEnabled &&
7151b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul          texUnit->_CurrentCombine->ModeRGB != GL_BUMP_ENVMAP_ATI) {
7160695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul         const GLfloat (*texcoords)[4] = (const GLfloat (*)[4])
717f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian            span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
7182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const struct gl_texture_object *curObj = texUnit->_Current;
719cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
7202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         GLfloat *lambda = span->array->lambda[unit];
7211b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul         float4_array texels = get_texel_array(swrast, unit);
7222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
7232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         /* adjust texture lod (lambda) */
7242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         if (span->arrayMask & SPAN_LAMBDA) {
725cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            if (texUnit->LodBias + samp->LodBias != 0.0F) {
7262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               /* apply LOD bias, but don't clamp yet */
727cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               const GLfloat bias = CLAMP(texUnit->LodBias + samp->LodBias,
7282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                          -ctx->Const.MaxTextureLodBias,
7292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                          ctx->Const.MaxTextureLodBias);
7302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               GLuint i;
7312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               for (i = 0; i < span->end; i++) {
7322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  lambda[i] += bias;
7332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               }
7342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
7352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
736cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            if (samp->MinLod != -1000.0 ||
737cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                samp->MaxLod != 1000.0) {
7382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               /* apply LOD clamping to lambda */
739cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               const GLfloat min = samp->MinLod;
740cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               const GLfloat max = samp->MaxLod;
7412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               GLuint i;
7422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               for (i = 0; i < span->end; i++) {
7432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  GLfloat l = lambda[i];
7442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  lambda[i] = CLAMP(l, min, max);
7452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               }
7462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
7472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
748cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         else if (samp->MaxAnisotropy > 1.0 &&
749cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  samp->MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
7508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            /* sample_lambda_2d_aniso is beeing used as texture_sample_func,
7518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger             * it requires the current SWspan *span as an additional parameter.
7528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger             * In order to keep the same function signature, the unused lambda
7538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger             * parameter will be modified to actually contain the SWspan pointer.
7548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger             * This is a Hack. To make it right, the texture_sample_func
7558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger             * signature and all implementing functions need to be modified.
7568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger             */
7578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            /* "hide" SWspan struct; cast to (GLfloat *) to suppress warning */
7588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            lambda = (GLfloat *)span;
7598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         }
7602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
761aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul         /* Sample the texture (span->end = number of fragments) */
762cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         swrast->TextureSample[unit]( ctx, samp,
763cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      ctx->Texture.Unit[unit]._Current,
764cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      span->end, texcoords, lambda, texels );
7652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
76654c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul         /* GL_EXT_texture_swizzle */
76754c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul         if (curObj->_Swizzle != SWIZZLE_NOOP) {
76854c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul            swizzle_texels(curObj->_Swizzle, span->end, texels);
76954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul         }
7702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
7712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
7722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
7732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /*
7742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * OK, now apply the texture (aka texture combine/blend).
7752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * We modify the span->color.rgba values.
7762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
7772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
7786ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu      if (ctx->Texture.Unit[unit]._ReallyEnabled)
7796ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu         texture_combine(ctx, unit, primary_rgba, swrast->TexelBuffer, span);
7802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
781aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul
782aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul   free(primary_rgba);
7832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
784