swrast: general clean-up of texture combine code
[mesa.git] / src / mesa / swrast / s_texcombine.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.5
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 #include "main/glheader.h"
28 #include "main/context.h"
29 #include "main/colormac.h"
30 #include "main/image.h"
31 #include "main/imports.h"
32 #include "main/macros.h"
33 #include "main/pixel.h"
34 #include "shader/prog_instruction.h"
35
36 #include "s_context.h"
37 #include "s_texcombine.h"
38
39
40 #define MAX_COMBINER_TERMS 4
41
42
43 /**
44 * Do texture application for GL_ARB/EXT_texture_env_combine.
45 * This function also supports GL_{EXT,ARB}_texture_env_dot3 and
46 * GL_ATI_texture_env_combine3. Since "classic" texture environments are
47 * implemented using GL_ARB_texture_env_combine-like state, this same function
48 * is used for classic texture environment application as well.
49 *
50 * \param ctx rendering context
51 * \param textureUnit the texture unit to apply
52 * \param n number of fragments to process (span width)
53 * \param primary_rgba incoming fragment color array
54 * \param texelBuffer pointer to texel colors for all texture units
55 *
56 * \param rgba incoming colors, which get modified here
57 */
58 static void
59 texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
60 CONST GLfloat (*primary_rgba)[4],
61 CONST GLfloat *texelBuffer,
62 GLchan (*rgbaChan)[4] )
63 {
64 const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
65 const struct gl_tex_env_combine_state *combine = textureUnit->_CurrentCombine;
66 const GLfloat (*argRGB [MAX_COMBINER_TERMS])[4];
67 const GLfloat (*argA [MAX_COMBINER_TERMS])[4];
68 const GLfloat RGBmult = (GLfloat) (1 << combine->ScaleShiftRGB);
69 const GLfloat Amult = (GLfloat) (1 << combine->ScaleShiftA);
70 const GLuint numColorArgs = combine->_NumArgsRGB;
71 const GLuint numAlphaArgs = combine->_NumArgsA;
72 GLfloat ccolor[MAX_COMBINER_TERMS][MAX_WIDTH][4]; /* temp color buffers */
73 GLfloat rgba[MAX_WIDTH][4];
74 GLuint i, term;
75
76 ASSERT(ctx->Extensions.EXT_texture_env_combine ||
77 ctx->Extensions.ARB_texture_env_combine);
78 ASSERT(CONST_SWRAST_CONTEXT(ctx)->_AnyTextureCombine);
79
80 for (i = 0; i < n; i++) {
81 rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]);
82 rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]);
83 rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]);
84 rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]);
85 }
86
87 /*
88 printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n",
89 combine->ModeRGB,
90 combine->ModeA,
91 combine->SourceRGB[0],
92 combine->SourceA[0],
93 combine->SourceRGB[1],
94 combine->SourceA[1]);
95 */
96
97 /*
98 * Do operand setup for up to 4 operands. Loop over the terms.
99 */
100 for (term = 0; term < numColorArgs; term++) {
101 const GLenum srcRGB = combine->SourceRGB[term];
102 const GLenum operandRGB = combine->OperandRGB[term];
103
104 switch (srcRGB) {
105 case GL_TEXTURE:
106 argRGB[term] = (const GLfloat (*)[4])
107 (texelBuffer + unit * (n * 4 * sizeof(GLfloat)));
108 break;
109 case GL_PRIMARY_COLOR:
110 argRGB[term] = primary_rgba;
111 break;
112 case GL_PREVIOUS:
113 argRGB[term] = (const GLfloat (*)[4]) rgba;
114 break;
115 case GL_CONSTANT:
116 {
117 GLfloat (*c)[4] = ccolor[term];
118 GLfloat red = textureUnit->EnvColor[0];
119 GLfloat green = textureUnit->EnvColor[1];
120 GLfloat blue = textureUnit->EnvColor[2];
121 GLfloat alpha = textureUnit->EnvColor[3];
122 for (i = 0; i < n; i++) {
123 ASSIGN_4V(c[i], red, green, blue, alpha);
124 }
125 argRGB[term] = (const GLfloat (*)[4]) ccolor[term];
126 }
127 break;
128 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
129 */
130 case GL_ZERO:
131 {
132 GLfloat (*c)[4] = ccolor[term];
133 for (i = 0; i < n; i++) {
134 ASSIGN_4V(c[i], 0.0F, 0.0F, 0.0F, 0.0F);
135 }
136 argRGB[term] = (const GLfloat (*)[4]) ccolor[term];
137 }
138 break;
139 case GL_ONE:
140 {
141 GLfloat (*c)[4] = ccolor[term];
142 for (i = 0; i < n; i++) {
143 ASSIGN_4V(c[i], 1.0F, 1.0F, 1.0F, 1.0F);
144 }
145 argRGB[term] = (const GLfloat (*)[4]) ccolor[term];
146 }
147 break;
148 default:
149 /* ARB_texture_env_crossbar source */
150 {
151 const GLuint srcUnit = srcRGB - GL_TEXTURE0;
152 ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
153 if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
154 return;
155 argRGB[term] = (const GLfloat (*)[4])
156 (texelBuffer + srcUnit * (n * 4 * sizeof(GLfloat)));
157 }
158 }
159
160 if (operandRGB != GL_SRC_COLOR) {
161 const GLfloat (*src)[4] = argRGB[term];
162 GLfloat (*dst)[4] = ccolor[term];
163
164 /* point to new arg[term] storage */
165 argRGB[term] = (const GLfloat (*)[4]) ccolor[term];
166
167 switch (operandRGB) {
168 case GL_ONE_MINUS_SRC_COLOR:
169 for (i = 0; i < n; i++) {
170 dst[i][RCOMP] = 1.0F - src[i][RCOMP];
171 dst[i][GCOMP] = 1.0F - src[i][GCOMP];
172 dst[i][BCOMP] = 1.0F - src[i][BCOMP];
173 }
174 break;
175 case GL_SRC_ALPHA:
176 for (i = 0; i < n; i++) {
177 dst[i][RCOMP] = src[i][ACOMP];
178 dst[i][GCOMP] = src[i][ACOMP];
179 dst[i][BCOMP] = src[i][ACOMP];
180 }
181 break;
182 case GL_ONE_MINUS_SRC_ALPHA:
183 for (i = 0; i < n; i++) {
184 dst[i][RCOMP] = 1.0F - src[i][ACOMP];
185 dst[i][GCOMP] = 1.0F - src[i][ACOMP];
186 dst[i][BCOMP] = 1.0F - src[i][ACOMP];
187 }
188 break;
189 default:
190 _mesa_problem(ctx, "Bad operandRGB");
191 }
192 }
193 }
194
195 /*
196 * Set up the argA[i] pointers
197 */
198 for (term = 0; term < numAlphaArgs; term++) {
199 const GLenum srcA = combine->SourceA[term];
200 const GLenum operandA = combine->OperandA[term];
201
202 switch (srcA) {
203 case GL_TEXTURE:
204 argA[term] = (const GLfloat (*)[4])
205 (texelBuffer + unit * (n * 4 * sizeof(GLfloat)));
206 break;
207 case GL_PRIMARY_COLOR:
208 argA[term] = primary_rgba;
209 break;
210 case GL_PREVIOUS:
211 argA[term] = (const GLfloat (*)[4]) rgba;
212 break;
213 case GL_CONSTANT:
214 {
215 GLfloat (*c)[4] = ccolor[term];
216 GLfloat alpha = textureUnit->EnvColor[3];
217 for (i = 0; i < n; i++)
218 c[i][ACOMP] = alpha;
219 argA[term] = (const GLfloat (*)[4]) ccolor[term];
220 }
221 break;
222 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
223 */
224 case GL_ZERO:
225 {
226 GLfloat (*c)[4] = ccolor[term];
227 for (i = 0; i < n; i++)
228 c[i][ACOMP] = 0.0F;
229 argA[term] = (const GLfloat (*)[4]) ccolor[term];
230 }
231 break;
232 case GL_ONE:
233 {
234 GLfloat (*c)[4] = ccolor[term];
235 for (i = 0; i < n; i++)
236 c[i][ACOMP] = 1.0F;
237 argA[term] = (const GLfloat (*)[4]) ccolor[term];
238 }
239 break;
240 default:
241 /* ARB_texture_env_crossbar source */
242 {
243 const GLuint srcUnit = srcA - GL_TEXTURE0;
244 ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
245 if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
246 return;
247 argA[term] = (const GLfloat (*)[4])
248 (texelBuffer + srcUnit * (n * 4 * sizeof(GLfloat)));
249 }
250 }
251
252 if (operandA == GL_ONE_MINUS_SRC_ALPHA) {
253 const GLfloat (*src)[4] = argA[term];
254 GLfloat (*dst)[4] = ccolor[term];
255 argA[term] = (const GLfloat (*)[4]) ccolor[term];
256 for (i = 0; i < n; i++) {
257 dst[i][ACOMP] = 1.0F - src[i][ACOMP];
258 }
259 }
260 }
261
262 /* RGB channel combine */
263 {
264 const GLfloat (*arg0)[4] = (const GLfloat (*)[4]) argRGB[0];
265 const GLfloat (*arg1)[4] = (const GLfloat (*)[4]) argRGB[1];
266 const GLfloat (*arg2)[4] = (const GLfloat (*)[4]) argRGB[2];
267 const GLfloat (*arg3)[4] = (const GLfloat (*)[4]) argRGB[3];
268
269 switch (combine->ModeRGB) {
270 case GL_REPLACE:
271 for (i = 0; i < n; i++) {
272 rgba[i][RCOMP] = arg0[i][RCOMP] * RGBmult;
273 rgba[i][GCOMP] = arg0[i][GCOMP] * RGBmult;
274 rgba[i][BCOMP] = arg0[i][BCOMP] * RGBmult;
275 }
276 break;
277 case GL_MODULATE:
278 for (i = 0; i < n; i++) {
279 rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * RGBmult;
280 rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * RGBmult;
281 rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * RGBmult;
282 }
283 break;
284 case GL_ADD:
285 if (textureUnit->EnvMode == GL_COMBINE4_NV) {
286 /* (a * b) + (c * d) */
287 for (i = 0; i < n; i++) {
288 rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] +
289 arg2[i][RCOMP] * arg3[i][RCOMP]) * RGBmult;
290 rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] +
291 arg2[i][GCOMP] * arg3[i][GCOMP]) * RGBmult;
292 rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] +
293 arg2[i][BCOMP] * arg3[i][BCOMP]) * RGBmult;
294 }
295 }
296 else {
297 /* 2-term addition */
298 for (i = 0; i < n; i++) {
299 rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * RGBmult;
300 rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * RGBmult;
301 rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * RGBmult;
302 }
303 }
304 break;
305 case GL_ADD_SIGNED:
306 if (textureUnit->EnvMode == GL_COMBINE4_NV) {
307 /* (a * b) + (c * d) - 0.5 */
308 for (i = 0; i < n; i++) {
309 rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] *
310 arg2[i][RCOMP] + arg3[i][RCOMP] - 0.5) * RGBmult;
311 rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] *
312 arg2[i][GCOMP] + arg3[i][GCOMP] - 0.5) * RGBmult;
313 rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] *
314 arg2[i][BCOMP] + arg3[i][BCOMP] - 0.5) * RGBmult;
315 }
316 }
317 else {
318 for (i = 0; i < n; i++) {
319 rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5) * RGBmult;
320 rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * RGBmult;
321 rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * RGBmult;
322 }
323 }
324 break;
325 case GL_INTERPOLATE:
326 for (i = 0; i < n; i++) {
327 rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] +
328 arg1[i][RCOMP] * (1.0F - arg2[i][RCOMP])) * RGBmult;
329 rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] +
330 arg1[i][GCOMP] * (1.0F - arg2[i][GCOMP])) * RGBmult;
331 rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] +
332 arg1[i][BCOMP] * (1.0F - arg2[i][BCOMP])) * RGBmult;
333 }
334 break;
335 case GL_SUBTRACT:
336 for (i = 0; i < n; i++) {
337 rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * RGBmult;
338 rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * RGBmult;
339 rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * RGBmult;
340 }
341 break;
342 case GL_DOT3_RGB_EXT:
343 case GL_DOT3_RGBA_EXT:
344 /* Do not scale the result by 1 2 or 4 */
345 for (i = 0; i < n; i++) {
346 GLfloat dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) +
347 (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) +
348 (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F))
349 * 4.0F;
350 dot = CLAMP(dot, 0.0F, 1.0F);
351 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLfloat) dot;
352 }
353 break;
354 case GL_DOT3_RGB:
355 case GL_DOT3_RGBA:
356 /* DO scale the result by 1 2 or 4 */
357 for (i = 0; i < n; i++) {
358 GLfloat dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) +
359 (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) +
360 (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F))
361 * 4.0F * RGBmult;
362 dot = CLAMP(dot, 0.0, 1.0F);
363 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLfloat) dot;
364 }
365 break;
366 case GL_MODULATE_ADD_ATI:
367 for (i = 0; i < n; i++) {
368 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) +
369 arg1[i][RCOMP]) * RGBmult;
370 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) +
371 arg1[i][GCOMP]) * RGBmult;
372 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) +
373 arg1[i][BCOMP]) * RGBmult;
374 }
375 break;
376 case GL_MODULATE_SIGNED_ADD_ATI:
377 for (i = 0; i < n; i++) {
378 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) +
379 arg1[i][RCOMP] - 0.5) * RGBmult;
380 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) +
381 arg1[i][GCOMP] - 0.5) * RGBmult;
382 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) +
383 arg1[i][BCOMP] - 0.5) * RGBmult;
384 }
385 break;
386 case GL_MODULATE_SUBTRACT_ATI:
387 for (i = 0; i < n; i++) {
388 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) -
389 arg1[i][RCOMP]) * RGBmult;
390 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) -
391 arg1[i][GCOMP]) * RGBmult;
392 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) -
393 arg1[i][BCOMP]) * RGBmult;
394 }
395 break;
396 case GL_BUMP_ENVMAP_ATI:
397 {
398 /* this produces a fixed rgba color, and the coord calc is done elsewhere */
399 for (i = 0; i < n; i++) {
400 /* rgba result is 0,0,0,1 */
401 #if CHAN_TYPE == GL_FLOAT
402 rgba[i][RCOMP] = 0.0;
403 rgba[i][GCOMP] = 0.0;
404 rgba[i][BCOMP] = 0.0;
405 rgba[i][ACOMP] = 1.0;
406 #else
407 rgba[i][RCOMP] = 0;
408 rgba[i][GCOMP] = 0;
409 rgba[i][BCOMP] = 0;
410 rgba[i][ACOMP] = CHAN_MAX;
411 #endif
412 }
413 }
414 return; /* no alpha processing */
415 default:
416 _mesa_problem(ctx, "invalid combine mode");
417 }
418 }
419
420 /* Alpha channel combine */
421 {
422 const GLfloat (*arg0)[4] = (const GLfloat (*)[4]) argA[0];
423 const GLfloat (*arg1)[4] = (const GLfloat (*)[4]) argA[1];
424 const GLfloat (*arg2)[4] = (const GLfloat (*)[4]) argA[2];
425 const GLfloat (*arg3)[4] = (const GLfloat (*)[4]) argA[3];
426
427 switch (combine->ModeA) {
428 case GL_REPLACE:
429 for (i = 0; i < n; i++) {
430 GLfloat a = arg0[i][ACOMP] * Amult;
431 rgba[i][ACOMP] = (GLfloat) MIN2(a, 1.0F);
432 }
433 break;
434 case GL_MODULATE:
435 for (i = 0; i < n; i++) {
436 rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * Amult;
437 }
438 break;
439 case GL_ADD:
440 if (textureUnit->EnvMode == GL_COMBINE4_NV) {
441 /* (a * b) + (c * d) */
442 for (i = 0; i < n; i++) {
443 rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] +
444 arg2[i][ACOMP] * arg3[i][ACOMP]) * Amult;
445 }
446 }
447 else {
448 /* two-term add */
449 for (i = 0; i < n; i++) {
450 rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * Amult;
451 }
452 }
453 break;
454 case GL_ADD_SIGNED:
455 if (textureUnit->EnvMode == GL_COMBINE4_NV) {
456 /* (a * b) + (c * d) - 0.5 */
457 for (i = 0; i < n; i++) {
458 rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] +
459 arg2[i][ACOMP] * arg3[i][ACOMP] -
460 0.5) * Amult;
461 }
462 }
463 else {
464 /* a + b - 0.5 */
465 for (i = 0; i < n; i++) {
466 rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * Amult;
467 }
468 }
469 break;
470 case GL_INTERPOLATE:
471 for (i=0; i<n; i++) {
472 rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] +
473 arg1[i][ACOMP] * (1.0F - arg2[i][ACOMP]))
474 * Amult;
475 }
476 break;
477 case GL_SUBTRACT:
478 for (i = 0; i < n; i++) {
479 rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * Amult;
480 }
481 break;
482 case GL_MODULATE_ADD_ATI:
483 for (i = 0; i < n; i++) {
484 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP])
485 + arg1[i][ACOMP]) * Amult;
486 }
487 break;
488 case GL_MODULATE_SIGNED_ADD_ATI:
489 for (i = 0; i < n; i++) {
490 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) +
491 arg1[i][ACOMP] - 0.5F) * Amult;
492 }
493 break;
494 case GL_MODULATE_SUBTRACT_ATI:
495 for (i = 0; i < n; i++) {
496 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP])
497 - arg1[i][ACOMP]) * Amult;
498 }
499 break;
500 default:
501 _mesa_problem(ctx, "invalid combine mode");
502 }
503 }
504
505 /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining.
506 * This is kind of a kludge. It would have been better if the spec
507 * were written such that the GL_COMBINE_ALPHA value could be set to
508 * GL_DOT3.
509 */
510 if (combine->ModeRGB == GL_DOT3_RGBA_EXT ||
511 combine->ModeRGB == GL_DOT3_RGBA) {
512 for (i = 0; i < n; i++) {
513 rgba[i][ACOMP] = rgba[i][RCOMP];
514 }
515 }
516
517 for (i = 0; i < n; i++) {
518 UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]);
519 UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]);
520 UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]);
521 UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]);
522 }
523 }
524
525
526
527 /**
528 * Apply X/Y/Z/W/0/1 swizzle to an array of colors/texels.
529 * See GL_EXT_texture_swizzle.
530 */
531 static void
532 swizzle_texels(GLuint swizzle, GLuint count, GLfloat (*texels)[4])
533 {
534 const GLuint swzR = GET_SWZ(swizzle, 0);
535 const GLuint swzG = GET_SWZ(swizzle, 1);
536 const GLuint swzB = GET_SWZ(swizzle, 2);
537 const GLuint swzA = GET_SWZ(swizzle, 3);
538 GLfloat vector[6];
539 GLuint i;
540
541 vector[SWIZZLE_ZERO] = 0;
542 vector[SWIZZLE_ONE] = 1.0F;
543
544 for (i = 0; i < count; i++) {
545 vector[SWIZZLE_X] = texels[i][0];
546 vector[SWIZZLE_Y] = texels[i][1];
547 vector[SWIZZLE_Z] = texels[i][2];
548 vector[SWIZZLE_W] = texels[i][3];
549 texels[i][RCOMP] = vector[swzR];
550 texels[i][GCOMP] = vector[swzG];
551 texels[i][BCOMP] = vector[swzB];
552 texels[i][ACOMP] = vector[swzA];
553 }
554 }
555
556
557 /**
558 * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
559 * MODULATE, or DECAL) to an array of fragments.
560 * Input: textureUnit - pointer to texture unit to apply
561 * format - base internal texture format
562 * n - number of fragments
563 * primary_rgba - primary colors (may alias rgba for single texture)
564 * texels - array of texel colors
565 * InOut: rgba - incoming fragment colors modified by texel colors
566 * according to the texture environment mode.
567 */
568 static void
569 texture_apply( const GLcontext *ctx,
570 const struct gl_texture_unit *texUnit,
571 GLuint n,
572 CONST GLfloat primary_rgba[][4], CONST GLfloat texel[][4],
573 GLchan rgbaChan[][4] )
574 {
575 GLint baseLevel;
576 GLuint i;
577 GLfloat Rc, Gc, Bc, Ac;
578 GLenum format;
579 GLfloat rgba[MAX_WIDTH][4];
580
581 (void) primary_rgba;
582
583 ASSERT(texUnit);
584 ASSERT(texUnit->_Current);
585
586 baseLevel = texUnit->_Current->BaseLevel;
587 ASSERT(texUnit->_Current->Image[0][baseLevel]);
588
589 format = texUnit->_Current->Image[0][baseLevel]->_BaseFormat;
590
591 if (format == GL_COLOR_INDEX || format == GL_YCBCR_MESA) {
592 format = GL_RGBA; /* a bit of a hack */
593 }
594 else if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
595 format = texUnit->_Current->DepthMode;
596 }
597
598 if (texUnit->EnvMode != GL_REPLACE) {
599 /* convert GLchan colors to GLfloat */
600 for (i = 0; i < n; i++) {
601 rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]);
602 rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]);
603 rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]);
604 rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]);
605 }
606 }
607
608 switch (texUnit->EnvMode) {
609 case GL_REPLACE:
610 switch (format) {
611 case GL_ALPHA:
612 for (i=0;i<n;i++) {
613 /* Cv = Cf */
614 /* Av = At */
615 rgba[i][ACOMP] = texel[i][ACOMP];
616 }
617 break;
618 case GL_LUMINANCE:
619 for (i=0;i<n;i++) {
620 /* Cv = Lt */
621 GLfloat Lt = texel[i][RCOMP];
622 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
623 /* Av = Af */
624 }
625 break;
626 case GL_LUMINANCE_ALPHA:
627 for (i=0;i<n;i++) {
628 GLfloat Lt = texel[i][RCOMP];
629 /* Cv = Lt */
630 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
631 /* Av = At */
632 rgba[i][ACOMP] = texel[i][ACOMP];
633 }
634 break;
635 case GL_INTENSITY:
636 for (i=0;i<n;i++) {
637 /* Cv = It */
638 GLfloat It = texel[i][RCOMP];
639 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It;
640 /* Av = It */
641 rgba[i][ACOMP] = It;
642 }
643 break;
644 case GL_RGB:
645 for (i=0;i<n;i++) {
646 /* Cv = Ct */
647 rgba[i][RCOMP] = texel[i][RCOMP];
648 rgba[i][GCOMP] = texel[i][GCOMP];
649 rgba[i][BCOMP] = texel[i][BCOMP];
650 /* Av = Af */
651 }
652 break;
653 case GL_RGBA:
654 for (i=0;i<n;i++) {
655 /* Cv = Ct */
656 rgba[i][RCOMP] = texel[i][RCOMP];
657 rgba[i][GCOMP] = texel[i][GCOMP];
658 rgba[i][BCOMP] = texel[i][BCOMP];
659 /* Av = At */
660 rgba[i][ACOMP] = texel[i][ACOMP];
661 }
662 break;
663 default:
664 _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply");
665 return;
666 }
667 break;
668
669 case GL_MODULATE:
670 switch (format) {
671 case GL_ALPHA:
672 for (i=0;i<n;i++) {
673 /* Cv = Cf */
674 /* Av = AfAt */
675 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
676 }
677 break;
678 case GL_LUMINANCE:
679 for (i=0;i<n;i++) {
680 /* Cv = LtCf */
681 GLfloat Lt = texel[i][RCOMP];
682 rgba[i][RCOMP] = rgba[i][RCOMP] * Lt;
683 rgba[i][GCOMP] = rgba[i][GCOMP] * Lt;
684 rgba[i][BCOMP] = rgba[i][BCOMP] * Lt;
685 /* Av = Af */
686 }
687 break;
688 case GL_LUMINANCE_ALPHA:
689 for (i=0;i<n;i++) {
690 /* Cv = CfLt */
691 GLfloat Lt = texel[i][RCOMP];
692 rgba[i][RCOMP] = rgba[i][RCOMP] * Lt;
693 rgba[i][GCOMP] = rgba[i][GCOMP] * Lt;
694 rgba[i][BCOMP] = rgba[i][BCOMP] * Lt;
695 /* Av = AfAt */
696 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
697 }
698 break;
699 case GL_INTENSITY:
700 for (i=0;i<n;i++) {
701 /* Cv = CfIt */
702 GLfloat It = texel[i][RCOMP];
703 rgba[i][RCOMP] = rgba[i][RCOMP] * It;
704 rgba[i][GCOMP] = rgba[i][GCOMP] * It;
705 rgba[i][BCOMP] = rgba[i][BCOMP] * It;
706 /* Av = AfIt */
707 rgba[i][ACOMP] = rgba[i][ACOMP] * It;
708 }
709 break;
710 case GL_RGB:
711 for (i=0;i<n;i++) {
712 /* Cv = CfCt */
713 rgba[i][RCOMP] = rgba[i][RCOMP] * texel[i][RCOMP];
714 rgba[i][GCOMP] = rgba[i][GCOMP] * texel[i][GCOMP];
715 rgba[i][BCOMP] = rgba[i][BCOMP] * texel[i][BCOMP];
716 /* Av = Af */
717 }
718 break;
719 case GL_RGBA:
720 for (i=0;i<n;i++) {
721 /* Cv = CfCt */
722 rgba[i][RCOMP] = rgba[i][RCOMP] * texel[i][RCOMP];
723 rgba[i][GCOMP] = rgba[i][GCOMP] * texel[i][GCOMP];
724 rgba[i][BCOMP] = rgba[i][BCOMP] * texel[i][BCOMP];
725 /* Av = AfAt */
726 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
727 }
728 break;
729 default:
730 _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply");
731 return;
732 }
733 break;
734
735 case GL_DECAL:
736 switch (format) {
737 case GL_ALPHA:
738 case GL_LUMINANCE:
739 case GL_LUMINANCE_ALPHA:
740 case GL_INTENSITY:
741 /* undefined */
742 break;
743 case GL_RGB:
744 for (i=0;i<n;i++) {
745 /* Cv = Ct */
746 rgba[i][RCOMP] = texel[i][RCOMP];
747 rgba[i][GCOMP] = texel[i][GCOMP];
748 rgba[i][BCOMP] = texel[i][BCOMP];
749 /* Av = Af */
750 }
751 break;
752 case GL_RGBA:
753 for (i=0;i<n;i++) {
754 /* Cv = Cf(1-At) + CtAt */
755 GLfloat t = texel[i][ACOMP], s = 1.0F - t;
756 rgba[i][RCOMP] = rgba[i][RCOMP] * s + texel[i][RCOMP] * t;
757 rgba[i][GCOMP] = rgba[i][GCOMP] * s + texel[i][GCOMP] * t;
758 rgba[i][BCOMP] = rgba[i][BCOMP] * s + texel[i][BCOMP] * t;
759 /* Av = Af */
760 }
761 break;
762 default:
763 _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply");
764 return;
765 }
766 break;
767
768 case GL_BLEND:
769 Rc = texUnit->EnvColor[0];
770 Gc = texUnit->EnvColor[1];
771 Bc = texUnit->EnvColor[2];
772 Ac = texUnit->EnvColor[3];
773 switch (format) {
774 case GL_ALPHA:
775 for (i=0;i<n;i++) {
776 /* Cv = Cf */
777 /* Av = AfAt */
778 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
779 }
780 break;
781 case GL_LUMINANCE:
782 for (i=0;i<n;i++) {
783 /* Cv = Cf(1-Lt) + CcLt */
784 GLfloat Lt = texel[i][RCOMP], s = 1.0F - Lt;
785 rgba[i][RCOMP] = rgba[i][RCOMP] * s + Rc * Lt;
786 rgba[i][GCOMP] = rgba[i][GCOMP] * s + Gc * Lt;
787 rgba[i][BCOMP] = rgba[i][BCOMP] * s + Bc * Lt;
788 /* Av = Af */
789 }
790 break;
791 case GL_LUMINANCE_ALPHA:
792 for (i=0;i<n;i++) {
793 /* Cv = Cf(1-Lt) + CcLt */
794 GLfloat Lt = texel[i][RCOMP], s = 1.0F - Lt;
795 rgba[i][RCOMP] = rgba[i][RCOMP] * s + Rc * Lt;
796 rgba[i][GCOMP] = rgba[i][GCOMP] * s + Gc * Lt;
797 rgba[i][BCOMP] = rgba[i][BCOMP] * s + Bc * Lt;
798 /* Av = AfAt */
799 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
800 }
801 break;
802 case GL_INTENSITY:
803 for (i=0;i<n;i++) {
804 /* Cv = Cf(1-It) + CcIt */
805 GLfloat It = texel[i][RCOMP], s = 1.0F - It;
806 rgba[i][RCOMP] = rgba[i][RCOMP] * s + Rc * It;
807 rgba[i][GCOMP] = rgba[i][GCOMP] * s + Gc * It;
808 rgba[i][BCOMP] = rgba[i][BCOMP] * s + Bc * It;
809 /* Av = Af(1-It) + Ac*It */
810 rgba[i][ACOMP] = rgba[i][ACOMP] * s + Ac * It;
811 }
812 break;
813 case GL_RGB:
814 for (i=0;i<n;i++) {
815 /* Cv = Cf(1-Ct) + CcCt */
816 rgba[i][RCOMP] = rgba[i][RCOMP] * (1.0F - texel[i][RCOMP])
817 + Rc * texel[i][RCOMP];
818 rgba[i][GCOMP] = rgba[i][GCOMP] * (1.0F - texel[i][GCOMP])
819 + Gc * texel[i][GCOMP];
820 rgba[i][BCOMP] = rgba[i][BCOMP] * (1.0F - texel[i][BCOMP])
821 + Bc * texel[i][BCOMP];
822 /* Av = Af */
823 }
824 break;
825 case GL_RGBA:
826 for (i=0;i<n;i++) {
827 /* Cv = Cf(1-Ct) + CcCt */
828 rgba[i][RCOMP] = rgba[i][RCOMP] * (1.0F - texel[i][RCOMP])
829 + Rc * texel[i][RCOMP];
830 rgba[i][GCOMP] = rgba[i][GCOMP] * (1.0F - texel[i][GCOMP])
831 + Gc * texel[i][GCOMP];
832 rgba[i][BCOMP] = rgba[i][BCOMP] * (1.0F - texel[i][BCOMP])
833 + Bc * texel[i][BCOMP];
834 /* Av = AfAt */
835 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
836 }
837 break;
838 default:
839 _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply");
840 return;
841 }
842 break;
843
844 /* XXX don't clamp results if GLfloat is float??? */
845
846 case GL_ADD: /* GL_EXT_texture_add_env */
847 switch (format) {
848 case GL_ALPHA:
849 for (i=0;i<n;i++) {
850 /* Rv = Rf */
851 /* Gv = Gf */
852 /* Bv = Bf */
853 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
854 }
855 break;
856 case GL_LUMINANCE:
857 for (i=0;i<n;i++) {
858 GLfloat Lt = texel[i][RCOMP];
859 GLfloat r = rgba[i][RCOMP] + Lt;
860 GLfloat g = rgba[i][GCOMP] + Lt;
861 GLfloat b = rgba[i][BCOMP] + Lt;
862 rgba[i][RCOMP] = MIN2(r, 1.0F);
863 rgba[i][GCOMP] = MIN2(g, 1.0F);
864 rgba[i][BCOMP] = MIN2(b, 1.0F);
865 /* Av = Af */
866 }
867 break;
868 case GL_LUMINANCE_ALPHA:
869 for (i=0;i<n;i++) {
870 GLfloat Lt = texel[i][RCOMP];
871 GLfloat r = rgba[i][RCOMP] + Lt;
872 GLfloat g = rgba[i][GCOMP] + Lt;
873 GLfloat b = rgba[i][BCOMP] + Lt;
874 rgba[i][RCOMP] = MIN2(r, 1.0F);
875 rgba[i][GCOMP] = MIN2(g, 1.0F);
876 rgba[i][BCOMP] = MIN2(b, 1.0F);
877 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
878 }
879 break;
880 case GL_INTENSITY:
881 for (i=0;i<n;i++) {
882 GLfloat It = texel[i][RCOMP];
883 GLfloat r = rgba[i][RCOMP] + It;
884 GLfloat g = rgba[i][GCOMP] + It;
885 GLfloat b = rgba[i][BCOMP] + It;
886 GLfloat a = rgba[i][ACOMP] + It;
887 rgba[i][RCOMP] = MIN2(r, 1.0F);
888 rgba[i][GCOMP] = MIN2(g, 1.0F);
889 rgba[i][BCOMP] = MIN2(b, 1.0F);
890 rgba[i][ACOMP] = MIN2(a, 1.0F);
891 }
892 break;
893 case GL_RGB:
894 for (i=0;i<n;i++) {
895 GLfloat r = rgba[i][RCOMP] + texel[i][RCOMP];
896 GLfloat g = rgba[i][GCOMP] + texel[i][GCOMP];
897 GLfloat b = rgba[i][BCOMP] + texel[i][BCOMP];
898 rgba[i][RCOMP] = MIN2(r, 1.0F);
899 rgba[i][GCOMP] = MIN2(g, 1.0F);
900 rgba[i][BCOMP] = MIN2(b, 1.0F);
901 /* Av = Af */
902 }
903 break;
904 case GL_RGBA:
905 for (i=0;i<n;i++) {
906 GLfloat r = rgba[i][RCOMP] + texel[i][RCOMP];
907 GLfloat g = rgba[i][GCOMP] + texel[i][GCOMP];
908 GLfloat b = rgba[i][BCOMP] + texel[i][BCOMP];
909 rgba[i][RCOMP] = MIN2(r, 1.0F);
910 rgba[i][GCOMP] = MIN2(g, 1.0F);
911 rgba[i][BCOMP] = MIN2(b, 1.0F);
912 rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
913 }
914 break;
915 default:
916 _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply");
917 return;
918 }
919 break;
920
921 default:
922 _mesa_problem(ctx, "Bad env mode in texture_apply");
923 return;
924 }
925
926 /* convert GLfloat colors to GLchan */
927 for (i = 0; i < n; i++) {
928 CLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]);
929 CLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]);
930 CLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]);
931 CLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]);
932 }
933 }
934
935
936
937 /**
938 * Apply texture mapping to a span of fragments.
939 */
940 void
941 _swrast_texture_span( GLcontext *ctx, SWspan *span )
942 {
943 SWcontext *swrast = SWRAST_CONTEXT(ctx);
944 GLfloat primary_rgba[MAX_WIDTH][4];
945 GLuint unit;
946
947 ASSERT(span->end < MAX_WIDTH);
948
949 /*
950 * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
951 */
952 if (swrast->_AnyTextureCombine) {
953 GLuint i;
954 for (i = 0; i < span->end; i++) {
955 primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]);
956 primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]);
957 primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]);
958 primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]);
959 }
960 }
961
962 /* First must sample all bump maps */
963 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
964 if (ctx->Texture.Unit[unit]._ReallyEnabled &&
965 ctx->Texture.Unit[unit]._CurrentCombine->ModeRGB == GL_BUMP_ENVMAP_ATI) {
966 const GLfloat (*texcoords)[4]
967 = (const GLfloat (*)[4])
968 span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
969 GLfloat (*targetcoords)[4]
970 = (GLfloat (*)[4])
971 span->array->attribs[FRAG_ATTRIB_TEX0 +
972 ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0];
973
974 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
975 const struct gl_texture_object *curObj = texUnit->_Current;
976 GLfloat *lambda = span->array->lambda[unit];
977 GLchan (*texels)[4] = (GLchan (*)[4])
978 (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan)));
979 GLuint i;
980 GLfloat rotMatrix00 = ctx->Texture.Unit[unit].RotMatrix[0];
981 GLfloat rotMatrix01 = ctx->Texture.Unit[unit].RotMatrix[1];
982 GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2];
983 GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3];
984
985 /* adjust texture lod (lambda) */
986 if (span->arrayMask & SPAN_LAMBDA) {
987 if (texUnit->LodBias + curObj->LodBias != 0.0F) {
988 /* apply LOD bias, but don't clamp yet */
989 const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias,
990 -ctx->Const.MaxTextureLodBias,
991 ctx->Const.MaxTextureLodBias);
992 GLuint i;
993 for (i = 0; i < span->end; i++) {
994 lambda[i] += bias;
995 }
996 }
997
998 if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) {
999 /* apply LOD clamping to lambda */
1000 const GLfloat min = curObj->MinLod;
1001 const GLfloat max = curObj->MaxLod;
1002 GLuint i;
1003 for (i = 0; i < span->end; i++) {
1004 GLfloat l = lambda[i];
1005 lambda[i] = CLAMP(l, min, max);
1006 }
1007 }
1008 }
1009
1010 /* Sample the texture (span->end = number of fragments) */
1011 swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
1012 texcoords, lambda, texels );
1013
1014 /* manipulate the span values of the bump target
1015 not sure this can work correctly even ignoring
1016 the problem that channel is unsigned */
1017 for (i = 0; i < span->end; i++) {
1018 #if CHAN_TYPE == GL_FLOAT
1019 targetcoords[i][0] += (texels[i][0] * rotMatrix00 + texels[i][1] *
1020 rotMatrix01) / targetcoords[i][3];
1021 targetcoords[i][1] += (texels[i][0] * rotMatrix10 + texels[i][1] *
1022 rotMatrix11) / targetcoords[i][3];
1023 #else
1024 targetcoords[i][0] += (CHAN_TO_FLOAT(texels[i][1]) * rotMatrix00 +
1025 CHAN_TO_FLOAT(texels[i][1]) * rotMatrix01) /
1026 targetcoords[i][3];
1027 targetcoords[i][1] += (CHAN_TO_FLOAT(texels[i][0]) * rotMatrix10 +
1028 CHAN_TO_FLOAT(texels[i][1]) * rotMatrix11) /
1029 targetcoords[i][3];
1030 #endif
1031 }
1032 }
1033 }
1034
1035 /*
1036 * Must do all texture sampling before combining in order to
1037 * accomodate GL_ARB_texture_env_crossbar.
1038 */
1039 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
1040 if (ctx->Texture.Unit[unit]._ReallyEnabled &&
1041 ctx->Texture.Unit[unit]._CurrentCombine->ModeRGB != GL_BUMP_ENVMAP_ATI) {
1042 const GLfloat (*texcoords)[4]
1043 = (const GLfloat (*)[4])
1044 span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
1045 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1046 const struct gl_texture_object *curObj = texUnit->_Current;
1047 GLfloat *lambda = span->array->lambda[unit];
1048 GLfloat (*texels)[4] = (GLfloat (*)[4])
1049 (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLfloat)));
1050
1051 /* adjust texture lod (lambda) */
1052 if (span->arrayMask & SPAN_LAMBDA) {
1053 if (texUnit->LodBias + curObj->LodBias != 0.0F) {
1054 /* apply LOD bias, but don't clamp yet */
1055 const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias,
1056 -ctx->Const.MaxTextureLodBias,
1057 ctx->Const.MaxTextureLodBias);
1058 GLuint i;
1059 for (i = 0; i < span->end; i++) {
1060 lambda[i] += bias;
1061 }
1062 }
1063
1064 if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) {
1065 /* apply LOD clamping to lambda */
1066 const GLfloat min = curObj->MinLod;
1067 const GLfloat max = curObj->MaxLod;
1068 GLuint i;
1069 for (i = 0; i < span->end; i++) {
1070 GLfloat l = lambda[i];
1071 lambda[i] = CLAMP(l, min, max);
1072 }
1073 }
1074 }
1075
1076 /* Sample the texture (span->end = number of fragments) */
1077 swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
1078 texcoords, lambda, texels );
1079
1080 /* GL_SGI_texture_color_table */
1081 if (texUnit->ColorTableEnabled) {
1082 _mesa_lookup_rgba_float(&texUnit->ColorTable, span->end, texels);
1083 }
1084
1085 /* GL_EXT_texture_swizzle */
1086 if (curObj->_Swizzle != SWIZZLE_NOOP) {
1087 swizzle_texels(curObj->_Swizzle, span->end, texels);
1088 }
1089 }
1090 }
1091
1092
1093 /*
1094 * OK, now apply the texture (aka texture combine/blend).
1095 * We modify the span->color.rgba values.
1096 */
1097 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
1098 if (ctx->Texture.Unit[unit]._ReallyEnabled) {
1099 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1100 if (texUnit->_CurrentCombine != &texUnit->_EnvMode ) {
1101 texture_combine( ctx, unit, span->end,
1102 (CONST GLfloat (*)[4]) primary_rgba,
1103 swrast->TexelBuffer,
1104 span->array->rgba );
1105 }
1106 else {
1107 /* conventional texture blend */
1108 const GLfloat (*texels)[4] = (const GLfloat (*)[4])
1109 (swrast->TexelBuffer + unit *
1110 (span->end * 4 * sizeof(GLfloat)));
1111
1112
1113 texture_apply( ctx, texUnit, span->end,
1114 (CONST GLfloat (*)[4]) primary_rgba, texels,
1115 span->array->rgba );
1116 }
1117 }
1118 }
1119 }