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