In gl_texture_image replace IntFormat with InternalFormat and Format with
[mesa.git] / src / mesa / main / texstate.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file texstate.c
27 *
28 * Texture state handling.
29 */
30
31 #include "glheader.h"
32 #include "colormac.h"
33 #include "colortab.h"
34 #include "context.h"
35 #include "enums.h"
36 #include "extensions.h"
37 #include "macros.h"
38 #include "nvfragprog.h"
39 #include "texobj.h"
40 #include "teximage.h"
41 #include "texstate.h"
42 #include "texenvprogram.h"
43 #include "mtypes.h"
44 #include "math/m_xform.h"
45 #include "math/m_matrix.h"
46
47
48
49 #ifdef SPECIALCAST
50 /* Needed for an Amiga compiler */
51 #define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
52 #define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
53 #else
54 /* all other compilers */
55 #define ENUM_TO_FLOAT(X) ((GLfloat)(X))
56 #define ENUM_TO_DOUBLE(X) ((GLdouble)(X))
57 #endif
58
59 /**
60 * Default texture combine environment state. This is used to initialize
61 * a context's texture units and as the basis for converting "classic"
62 * texture environmnets to ARB_texture_env_combine style values.
63 */
64 static const struct gl_tex_env_combine_state default_combine_state = {
65 GL_MODULATE, GL_MODULATE,
66 { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
67 { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
68 { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA },
69 { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
70 0, 0,
71 2, 2
72 };
73
74
75 void
76 _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
77 {
78 GLuint i;
79
80 ASSERT(src);
81 ASSERT(dst);
82
83 dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
84 dst->Texture._GenFlags = src->Texture._GenFlags;
85 dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
86 dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
87 dst->Texture.SharedPalette = src->Texture.SharedPalette;
88
89 /* per-unit state */
90 for (i = 0; i < src->Const.MaxTextureUnits; i++) {
91 dst->Texture.Unit[i].Enabled = src->Texture.Unit[i].Enabled;
92 dst->Texture.Unit[i].EnvMode = src->Texture.Unit[i].EnvMode;
93 COPY_4V(dst->Texture.Unit[i].EnvColor, src->Texture.Unit[i].EnvColor);
94 dst->Texture.Unit[i].TexGenEnabled = src->Texture.Unit[i].TexGenEnabled;
95 dst->Texture.Unit[i].GenModeS = src->Texture.Unit[i].GenModeS;
96 dst->Texture.Unit[i].GenModeT = src->Texture.Unit[i].GenModeT;
97 dst->Texture.Unit[i].GenModeR = src->Texture.Unit[i].GenModeR;
98 dst->Texture.Unit[i].GenModeQ = src->Texture.Unit[i].GenModeQ;
99 dst->Texture.Unit[i]._GenBitS = src->Texture.Unit[i]._GenBitS;
100 dst->Texture.Unit[i]._GenBitT = src->Texture.Unit[i]._GenBitT;
101 dst->Texture.Unit[i]._GenBitR = src->Texture.Unit[i]._GenBitR;
102 dst->Texture.Unit[i]._GenBitQ = src->Texture.Unit[i]._GenBitQ;
103 dst->Texture.Unit[i]._GenFlags = src->Texture.Unit[i]._GenFlags;
104 COPY_4V(dst->Texture.Unit[i].ObjectPlaneS, src->Texture.Unit[i].ObjectPlaneS);
105 COPY_4V(dst->Texture.Unit[i].ObjectPlaneT, src->Texture.Unit[i].ObjectPlaneT);
106 COPY_4V(dst->Texture.Unit[i].ObjectPlaneR, src->Texture.Unit[i].ObjectPlaneR);
107 COPY_4V(dst->Texture.Unit[i].ObjectPlaneQ, src->Texture.Unit[i].ObjectPlaneQ);
108 COPY_4V(dst->Texture.Unit[i].EyePlaneS, src->Texture.Unit[i].EyePlaneS);
109 COPY_4V(dst->Texture.Unit[i].EyePlaneT, src->Texture.Unit[i].EyePlaneT);
110 COPY_4V(dst->Texture.Unit[i].EyePlaneR, src->Texture.Unit[i].EyePlaneR);
111 COPY_4V(dst->Texture.Unit[i].EyePlaneQ, src->Texture.Unit[i].EyePlaneQ);
112 dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias;
113
114 /* GL_EXT_texture_env_combine */
115 dst->Texture.Unit[i].Combine.ModeRGB = src->Texture.Unit[i].Combine.ModeRGB;
116 dst->Texture.Unit[i].Combine.ModeA = src->Texture.Unit[i].Combine.ModeA;
117 COPY_3V(dst->Texture.Unit[i].Combine.SourceRGB, src->Texture.Unit[i].Combine.SourceRGB);
118 COPY_3V(dst->Texture.Unit[i].Combine.SourceA, src->Texture.Unit[i].Combine.SourceA);
119 COPY_3V(dst->Texture.Unit[i].Combine.OperandRGB, src->Texture.Unit[i].Combine.OperandRGB);
120 COPY_3V(dst->Texture.Unit[i].Combine.OperandA, src->Texture.Unit[i].Combine.OperandA);
121 dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB;
122 dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA;
123
124 /* texture object state */
125 _mesa_copy_texture_object(dst->Texture.Unit[i].Current1D,
126 src->Texture.Unit[i].Current1D);
127 _mesa_copy_texture_object(dst->Texture.Unit[i].Current2D,
128 src->Texture.Unit[i].Current2D);
129 _mesa_copy_texture_object(dst->Texture.Unit[i].Current3D,
130 src->Texture.Unit[i].Current3D);
131 _mesa_copy_texture_object(dst->Texture.Unit[i].CurrentCubeMap,
132 src->Texture.Unit[i].CurrentCubeMap);
133 _mesa_copy_texture_object(dst->Texture.Unit[i].CurrentRect,
134 src->Texture.Unit[i].CurrentRect);
135 }
136 }
137
138
139 /*
140 * For debugging
141 */
142 void
143 _mesa_print_texunit_state( GLcontext *ctx, GLuint unit )
144 {
145 const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
146 _mesa_printf("Texture Unit %d\n", unit);
147 _mesa_printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
148 _mesa_printf(" GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
149 _mesa_printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
150 _mesa_printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
151 _mesa_printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
152 _mesa_printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
153 _mesa_printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
154 _mesa_printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
155 _mesa_printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
156 _mesa_printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
157 _mesa_printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
158 _mesa_printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
159 _mesa_printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
160 _mesa_printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
161 _mesa_printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
162 _mesa_printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
163 _mesa_printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
164 _mesa_printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
165 }
166
167
168
169 /**********************************************************************/
170 /* Texture Environment */
171 /**********************************************************************/
172
173 /**
174 * Convert "classic" texture environment to ARB_texture_env_combine style
175 * environments.
176 *
177 * \param state texture_env_combine state vector to be filled-in.
178 * \param mode Classic texture environment mode (i.e., \c GL_REPLACE,
179 * \c GL_BLEND, \c GL_DECAL, etc.).
180 * \param texBaseFormat Base format of the texture associated with the
181 * texture unit.
182 */
183 static void
184 calculate_derived_texenv( struct gl_tex_env_combine_state *state,
185 GLenum mode, GLenum texBaseFormat )
186 {
187 GLenum mode_rgb;
188 GLenum mode_a;
189
190 *state = default_combine_state;
191
192 switch (texBaseFormat) {
193 case GL_ALPHA:
194 state->SourceRGB[0] = GL_PREVIOUS;
195 break;
196
197 case GL_LUMINANCE_ALPHA:
198 case GL_INTENSITY:
199 case GL_RGBA:
200 break;
201
202 case GL_LUMINANCE:
203 case GL_RGB:
204 case GL_YCBCR_MESA:
205 state->SourceA[0] = GL_PREVIOUS;
206 break;
207
208 default:
209 _mesa_problem(NULL, "Invalid texBaseFormat in calculate_derived_texenv");
210 return;
211 }
212
213 switch (mode) {
214 case GL_REPLACE:
215 case GL_MODULATE:
216 mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
217 mode_a = mode;
218 break;
219
220 case GL_DECAL:
221 mode_rgb = GL_INTERPOLATE;
222 mode_a = GL_REPLACE;
223
224 state->SourceA[0] = GL_PREVIOUS;
225
226 /* Having alpha / luminance / intensity textures replace using the
227 * incoming fragment color matches the definition in NV_texture_shader.
228 * The 1.5 spec simply marks these as "undefined".
229 */
230 switch (texBaseFormat) {
231 case GL_ALPHA:
232 case GL_LUMINANCE:
233 case GL_LUMINANCE_ALPHA:
234 case GL_INTENSITY:
235 state->SourceRGB[0] = GL_PREVIOUS;
236 break;
237 case GL_RGB:
238 case GL_YCBCR_MESA:
239 mode_rgb = GL_REPLACE;
240 break;
241 case GL_RGBA:
242 state->SourceRGB[2] = GL_TEXTURE;
243 break;
244 }
245 break;
246
247 case GL_BLEND:
248 mode_rgb = GL_INTERPOLATE;
249 mode_a = GL_MODULATE;
250
251 switch (texBaseFormat) {
252 case GL_ALPHA:
253 mode_rgb = GL_REPLACE;
254 break;
255 case GL_INTENSITY:
256 mode_a = GL_INTERPOLATE;
257 state->SourceA[0] = GL_CONSTANT;
258 state->OperandA[2] = GL_SRC_ALPHA;
259 /* FALLTHROUGH */
260 case GL_LUMINANCE:
261 case GL_RGB:
262 case GL_LUMINANCE_ALPHA:
263 case GL_RGBA:
264 case GL_YCBCR_MESA:
265 state->SourceRGB[2] = GL_TEXTURE;
266 state->SourceA[2] = GL_TEXTURE;
267 state->SourceRGB[0] = GL_CONSTANT;
268 state->OperandRGB[2] = GL_SRC_COLOR;
269 break;
270 }
271 break;
272
273 case GL_ADD:
274 mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
275 mode_a = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
276 break;
277
278 default:
279 _mesa_problem(NULL,
280 "Invalid texture env mode in calculate_derived_texenv");
281 return;
282 }
283
284 state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
285 ? mode_rgb : GL_REPLACE;
286 state->ModeA = (state->SourceA[0] != GL_PREVIOUS)
287 ? mode_a : GL_REPLACE;
288 }
289
290
291 void GLAPIENTRY
292 _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
293 {
294 GET_CURRENT_CONTEXT(ctx);
295 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
296 ASSERT_OUTSIDE_BEGIN_END(ctx);
297
298 #define TE_ERROR(errCode, msg, value) \
299 _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
300
301 if (target == GL_TEXTURE_ENV) {
302 switch (pname) {
303 case GL_TEXTURE_ENV_MODE:
304 {
305 const GLenum mode = (GLenum) (GLint) *param;
306 if (texUnit->EnvMode == mode)
307 return;
308 if (mode == GL_MODULATE ||
309 mode == GL_BLEND ||
310 mode == GL_DECAL ||
311 mode == GL_REPLACE ||
312 (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
313 (mode == GL_COMBINE &&
314 (ctx->Extensions.EXT_texture_env_combine ||
315 ctx->Extensions.ARB_texture_env_combine))) {
316 /* legal */
317 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
318 texUnit->EnvMode = mode;
319 }
320 else {
321 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
322 return;
323 }
324 }
325 break;
326 case GL_TEXTURE_ENV_COLOR:
327 {
328 GLfloat tmp[4];
329 tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
330 tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
331 tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
332 tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
333 if (TEST_EQ_4V(tmp, texUnit->EnvColor))
334 return;
335 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
336 COPY_4FV(texUnit->EnvColor, tmp);
337 }
338 break;
339 case GL_COMBINE_RGB:
340 if (ctx->Extensions.EXT_texture_env_combine ||
341 ctx->Extensions.ARB_texture_env_combine) {
342 const GLenum mode = (GLenum) (GLint) *param;
343 if (texUnit->Combine.ModeRGB == mode)
344 return;
345 switch (mode) {
346 case GL_REPLACE:
347 case GL_MODULATE:
348 case GL_ADD:
349 case GL_ADD_SIGNED:
350 case GL_INTERPOLATE:
351 /* OK */
352 break;
353 case GL_SUBTRACT:
354 if (!ctx->Extensions.ARB_texture_env_combine) {
355 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
356 return;
357 }
358 break;
359 case GL_DOT3_RGB_EXT:
360 case GL_DOT3_RGBA_EXT:
361 if (!ctx->Extensions.EXT_texture_env_dot3) {
362 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
363 return;
364 }
365 break;
366 case GL_DOT3_RGB:
367 case GL_DOT3_RGBA:
368 if (!ctx->Extensions.ARB_texture_env_dot3) {
369 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
370 return;
371 }
372 break;
373 case GL_MODULATE_ADD_ATI:
374 case GL_MODULATE_SIGNED_ADD_ATI:
375 case GL_MODULATE_SUBTRACT_ATI:
376 if (!ctx->Extensions.ATI_texture_env_combine3) {
377 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
378 return;
379 }
380 break;
381 default:
382 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
383 return;
384 }
385 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
386 texUnit->Combine.ModeRGB = mode;
387 }
388 else {
389 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
390 return;
391 }
392 break;
393 case GL_COMBINE_ALPHA:
394 if (ctx->Extensions.EXT_texture_env_combine ||
395 ctx->Extensions.ARB_texture_env_combine) {
396 const GLenum mode = (GLenum) (GLint) *param;
397 if (texUnit->Combine.ModeA == mode)
398 return;
399 switch (mode) {
400 case GL_REPLACE:
401 case GL_MODULATE:
402 case GL_ADD:
403 case GL_ADD_SIGNED:
404 case GL_INTERPOLATE:
405 /* OK */
406 break;
407 case GL_SUBTRACT:
408 if (!ctx->Extensions.ARB_texture_env_combine) {
409 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
410 return;
411 }
412 break;
413 case GL_MODULATE_ADD_ATI:
414 case GL_MODULATE_SIGNED_ADD_ATI:
415 case GL_MODULATE_SUBTRACT_ATI:
416 if (!ctx->Extensions.ATI_texture_env_combine3) {
417 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
418 return;
419 }
420 break;
421 default:
422 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
423 return;
424 }
425 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
426 texUnit->Combine.ModeA = mode;
427 }
428 else {
429 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
430 return;
431 }
432 break;
433 case GL_SOURCE0_RGB:
434 case GL_SOURCE1_RGB:
435 case GL_SOURCE2_RGB:
436 if (ctx->Extensions.EXT_texture_env_combine ||
437 ctx->Extensions.ARB_texture_env_combine) {
438 const GLenum source = (GLenum) (GLint) *param;
439 const GLuint s = pname - GL_SOURCE0_RGB;
440 if (texUnit->Combine.SourceRGB[s] == source)
441 return;
442 if (source == GL_TEXTURE ||
443 source == GL_CONSTANT ||
444 source == GL_PRIMARY_COLOR ||
445 source == GL_PREVIOUS ||
446 (ctx->Extensions.ARB_texture_env_crossbar &&
447 source >= GL_TEXTURE0 &&
448 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
449 (ctx->Extensions.ATI_texture_env_combine3 &&
450 (source == GL_ZERO || source == GL_ONE))) {
451 /* legal */
452 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
453 texUnit->Combine.SourceRGB[s] = source;
454 }
455 else {
456 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
457 return;
458 }
459 }
460 else {
461 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
462 return;
463 }
464 break;
465 case GL_SOURCE0_ALPHA:
466 case GL_SOURCE1_ALPHA:
467 case GL_SOURCE2_ALPHA:
468 if (ctx->Extensions.EXT_texture_env_combine ||
469 ctx->Extensions.ARB_texture_env_combine) {
470 const GLenum source = (GLenum) (GLint) *param;
471 const GLuint s = pname - GL_SOURCE0_ALPHA;
472 if (texUnit->Combine.SourceA[s] == source)
473 return;
474 if (source == GL_TEXTURE ||
475 source == GL_CONSTANT ||
476 source == GL_PRIMARY_COLOR ||
477 source == GL_PREVIOUS ||
478 (ctx->Extensions.ARB_texture_env_crossbar &&
479 source >= GL_TEXTURE0 &&
480 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
481 (ctx->Extensions.ATI_texture_env_combine3 &&
482 (source == GL_ZERO || source == GL_ONE))) {
483 /* legal */
484 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
485 texUnit->Combine.SourceA[s] = source;
486 }
487 else {
488 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
489 return;
490 }
491 }
492 else {
493 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
494 return;
495 }
496 break;
497 case GL_OPERAND0_RGB:
498 case GL_OPERAND1_RGB:
499 if (ctx->Extensions.EXT_texture_env_combine ||
500 ctx->Extensions.ARB_texture_env_combine) {
501 const GLenum operand = (GLenum) (GLint) *param;
502 const GLuint s = pname - GL_OPERAND0_RGB;
503 if (texUnit->Combine.OperandRGB[s] == operand)
504 return;
505 switch (operand) {
506 case GL_SRC_COLOR:
507 case GL_ONE_MINUS_SRC_COLOR:
508 case GL_SRC_ALPHA:
509 case GL_ONE_MINUS_SRC_ALPHA:
510 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
511 texUnit->Combine.OperandRGB[s] = operand;
512 break;
513 default:
514 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
515 return;
516 }
517 }
518 else {
519 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
520 return;
521 }
522 break;
523 case GL_OPERAND0_ALPHA:
524 case GL_OPERAND1_ALPHA:
525 if (ctx->Extensions.EXT_texture_env_combine ||
526 ctx->Extensions.ARB_texture_env_combine) {
527 const GLenum operand = (GLenum) (GLint) *param;
528 if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand)
529 return;
530 switch (operand) {
531 case GL_SRC_ALPHA:
532 case GL_ONE_MINUS_SRC_ALPHA:
533 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
534 texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
535 break;
536 default:
537 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
538 return;
539 }
540 }
541 else {
542 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
543 return;
544 }
545 break;
546 case GL_OPERAND2_RGB:
547 if (ctx->Extensions.ARB_texture_env_combine) {
548 const GLenum operand = (GLenum) (GLint) *param;
549 if (texUnit->Combine.OperandRGB[2] == operand)
550 return;
551 switch (operand) {
552 case GL_SRC_COLOR: /* ARB combine only */
553 case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
554 case GL_SRC_ALPHA:
555 case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
556 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
557 texUnit->Combine.OperandRGB[2] = operand;
558 break;
559 default:
560 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
561 return;
562 }
563 }
564 else if (ctx->Extensions.EXT_texture_env_combine) {
565 const GLenum operand = (GLenum) (GLint) *param;
566 if (texUnit->Combine.OperandRGB[2] == operand)
567 return;
568 /* operand must be GL_SRC_ALPHA which is the initial value - thus
569 don't need to actually compare the operand to the possible value */
570 else {
571 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
572 return;
573 }
574 }
575 else {
576 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
577 return;
578 }
579 break;
580 case GL_OPERAND2_ALPHA:
581 if (ctx->Extensions.ARB_texture_env_combine) {
582 const GLenum operand = (GLenum) (GLint) *param;
583 if (texUnit->Combine.OperandA[2] == operand)
584 return;
585 switch (operand) {
586 case GL_SRC_ALPHA:
587 case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
588 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
589 texUnit->Combine.OperandA[2] = operand;
590 break;
591 default:
592 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
593 return;
594 }
595 }
596 else if (ctx->Extensions.EXT_texture_env_combine) {
597 const GLenum operand = (GLenum) (GLint) *param;
598 if (texUnit->Combine.OperandA[2] == operand)
599 return;
600 /* operand must be GL_SRC_ALPHA which is the initial value - thus
601 don't need to actually compare the operand to the possible value */
602 else {
603 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
604 return;
605 }
606 }
607 else {
608 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
609 return;
610 }
611 break;
612 case GL_RGB_SCALE:
613 if (ctx->Extensions.EXT_texture_env_combine ||
614 ctx->Extensions.ARB_texture_env_combine) {
615 GLuint newshift;
616 if (*param == 1.0) {
617 newshift = 0;
618 }
619 else if (*param == 2.0) {
620 newshift = 1;
621 }
622 else if (*param == 4.0) {
623 newshift = 2;
624 }
625 else {
626 _mesa_error( ctx, GL_INVALID_VALUE,
627 "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
628 return;
629 }
630 if (texUnit->Combine.ScaleShiftRGB == newshift)
631 return;
632 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
633 texUnit->Combine.ScaleShiftRGB = newshift;
634 }
635 else {
636 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
637 return;
638 }
639 break;
640 case GL_ALPHA_SCALE:
641 if (ctx->Extensions.EXT_texture_env_combine ||
642 ctx->Extensions.ARB_texture_env_combine) {
643 GLuint newshift;
644 if (*param == 1.0) {
645 newshift = 0;
646 }
647 else if (*param == 2.0) {
648 newshift = 1;
649 }
650 else if (*param == 4.0) {
651 newshift = 2;
652 }
653 else {
654 _mesa_error( ctx, GL_INVALID_VALUE,
655 "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
656 return;
657 }
658 if (texUnit->Combine.ScaleShiftA == newshift)
659 return;
660 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
661 texUnit->Combine.ScaleShiftA = newshift;
662 }
663 else {
664 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
665 return;
666 }
667 break;
668 default:
669 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
670 return;
671 }
672 }
673 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
674 /* GL_EXT_texture_lod_bias */
675 if (!ctx->Extensions.EXT_texture_lod_bias) {
676 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
677 return;
678 }
679 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
680 if (texUnit->LodBias == param[0])
681 return;
682 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
683 texUnit->LodBias = param[0];
684 }
685 else {
686 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
687 return;
688 }
689 }
690 else if (target == GL_POINT_SPRITE_NV) {
691 /* GL_ARB_point_sprite / GL_NV_point_sprite */
692 if (!ctx->Extensions.NV_point_sprite
693 && !ctx->Extensions.ARB_point_sprite) {
694 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
695 return;
696 }
697 if (pname == GL_COORD_REPLACE_NV) {
698 const GLenum value = (GLenum) param[0];
699 if (value == GL_TRUE || value == GL_FALSE) {
700 /* It's kind of weird to set point state via glTexEnv,
701 * but that's what the spec calls for.
702 */
703 const GLboolean state = (GLboolean) value;
704 if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
705 return;
706 FLUSH_VERTICES(ctx, _NEW_POINT);
707 ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
708 }
709 else {
710 _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
711 return;
712 }
713 }
714 else {
715 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
716 return;
717 }
718 }
719 else {
720 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
721 return;
722 }
723
724 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
725 _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
726 _mesa_lookup_enum_by_nr(target),
727 _mesa_lookup_enum_by_nr(pname),
728 *param,
729 _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));
730
731 /* Tell device driver about the new texture environment */
732 if (ctx->Driver.TexEnv) {
733 (*ctx->Driver.TexEnv)( ctx, target, pname, param );
734 }
735 }
736
737
738 void GLAPIENTRY
739 _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
740 {
741 _mesa_TexEnvfv( target, pname, &param );
742 }
743
744
745
746 void GLAPIENTRY
747 _mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
748 {
749 GLfloat p[4];
750 p[0] = (GLfloat) param;
751 p[1] = p[2] = p[3] = 0.0;
752 _mesa_TexEnvfv( target, pname, p );
753 }
754
755
756 void GLAPIENTRY
757 _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
758 {
759 GLfloat p[4];
760 if (pname == GL_TEXTURE_ENV_COLOR) {
761 p[0] = INT_TO_FLOAT( param[0] );
762 p[1] = INT_TO_FLOAT( param[1] );
763 p[2] = INT_TO_FLOAT( param[2] );
764 p[3] = INT_TO_FLOAT( param[3] );
765 }
766 else {
767 p[0] = (GLfloat) param[0];
768 p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */
769 }
770 _mesa_TexEnvfv( target, pname, p );
771 }
772
773
774 void GLAPIENTRY
775 _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
776 {
777 GET_CURRENT_CONTEXT(ctx);
778 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
779 ASSERT_OUTSIDE_BEGIN_END(ctx);
780
781 if (target == GL_TEXTURE_ENV) {
782 switch (pname) {
783 case GL_TEXTURE_ENV_MODE:
784 *params = ENUM_TO_FLOAT(texUnit->EnvMode);
785 break;
786 case GL_TEXTURE_ENV_COLOR:
787 COPY_4FV( params, texUnit->EnvColor );
788 break;
789 case GL_COMBINE_RGB:
790 if (ctx->Extensions.EXT_texture_env_combine ||
791 ctx->Extensions.ARB_texture_env_combine) {
792 *params = (GLfloat) texUnit->Combine.ModeRGB;
793 }
794 else {
795 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
796 }
797 break;
798 case GL_COMBINE_ALPHA:
799 if (ctx->Extensions.EXT_texture_env_combine ||
800 ctx->Extensions.ARB_texture_env_combine) {
801 *params = (GLfloat) texUnit->Combine.ModeA;
802 }
803 else {
804 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
805 }
806 break;
807 case GL_SOURCE0_RGB:
808 if (ctx->Extensions.EXT_texture_env_combine ||
809 ctx->Extensions.ARB_texture_env_combine) {
810 *params = (GLfloat) texUnit->Combine.SourceRGB[0];
811 }
812 else {
813 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
814 }
815 break;
816 case GL_SOURCE1_RGB:
817 if (ctx->Extensions.EXT_texture_env_combine ||
818 ctx->Extensions.ARB_texture_env_combine) {
819 *params = (GLfloat) texUnit->Combine.SourceRGB[1];
820 }
821 else {
822 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
823 }
824 break;
825 case GL_SOURCE2_RGB:
826 if (ctx->Extensions.EXT_texture_env_combine ||
827 ctx->Extensions.ARB_texture_env_combine) {
828 *params = (GLfloat) texUnit->Combine.SourceRGB[2];
829 }
830 else {
831 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
832 }
833 break;
834 case GL_SOURCE0_ALPHA:
835 if (ctx->Extensions.EXT_texture_env_combine ||
836 ctx->Extensions.ARB_texture_env_combine) {
837 *params = (GLfloat) texUnit->Combine.SourceA[0];
838 }
839 else {
840 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
841 }
842 break;
843 case GL_SOURCE1_ALPHA:
844 if (ctx->Extensions.EXT_texture_env_combine ||
845 ctx->Extensions.ARB_texture_env_combine) {
846 *params = (GLfloat) texUnit->Combine.SourceA[1];
847 }
848 else {
849 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
850 }
851 break;
852 case GL_SOURCE2_ALPHA:
853 if (ctx->Extensions.EXT_texture_env_combine ||
854 ctx->Extensions.ARB_texture_env_combine) {
855 *params = (GLfloat) texUnit->Combine.SourceA[2];
856 }
857 else {
858 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
859 }
860 break;
861 case GL_OPERAND0_RGB:
862 if (ctx->Extensions.EXT_texture_env_combine ||
863 ctx->Extensions.ARB_texture_env_combine) {
864 *params = (GLfloat) texUnit->Combine.OperandRGB[0];
865 }
866 else {
867 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
868 }
869 break;
870 case GL_OPERAND1_RGB:
871 if (ctx->Extensions.EXT_texture_env_combine ||
872 ctx->Extensions.ARB_texture_env_combine) {
873 *params = (GLfloat) texUnit->Combine.OperandRGB[1];
874 }
875 else {
876 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
877 }
878 break;
879 case GL_OPERAND2_RGB:
880 if (ctx->Extensions.EXT_texture_env_combine ||
881 ctx->Extensions.ARB_texture_env_combine) {
882 *params = (GLfloat) texUnit->Combine.OperandRGB[2];
883 }
884 else {
885 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
886 }
887 break;
888 case GL_OPERAND0_ALPHA:
889 if (ctx->Extensions.EXT_texture_env_combine ||
890 ctx->Extensions.ARB_texture_env_combine) {
891 *params = (GLfloat) texUnit->Combine.OperandA[0];
892 }
893 else {
894 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
895 }
896 break;
897 case GL_OPERAND1_ALPHA:
898 if (ctx->Extensions.EXT_texture_env_combine ||
899 ctx->Extensions.ARB_texture_env_combine) {
900 *params = (GLfloat) texUnit->Combine.OperandA[1];
901 }
902 else {
903 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
904 }
905 break;
906 case GL_OPERAND2_ALPHA:
907 if (ctx->Extensions.EXT_texture_env_combine ||
908 ctx->Extensions.ARB_texture_env_combine) {
909 *params = (GLfloat) texUnit->Combine.OperandA[2];
910 }
911 else {
912 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
913 }
914 break;
915 case GL_RGB_SCALE:
916 if (ctx->Extensions.EXT_texture_env_combine ||
917 ctx->Extensions.ARB_texture_env_combine) {
918 if (texUnit->Combine.ScaleShiftRGB == 0)
919 *params = 1.0;
920 else if (texUnit->Combine.ScaleShiftRGB == 1)
921 *params = 2.0;
922 else
923 *params = 4.0;
924 }
925 else {
926 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
927 return;
928 }
929 break;
930 case GL_ALPHA_SCALE:
931 if (ctx->Extensions.EXT_texture_env_combine ||
932 ctx->Extensions.ARB_texture_env_combine) {
933 if (texUnit->Combine.ScaleShiftA == 0)
934 *params = 1.0;
935 else if (texUnit->Combine.ScaleShiftA == 1)
936 *params = 2.0;
937 else
938 *params = 4.0;
939 }
940 else {
941 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
942 return;
943 }
944 break;
945 default:
946 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname=0x%x)", pname);
947 }
948 }
949 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
950 /* GL_EXT_texture_lod_bias */
951 if (!ctx->Extensions.EXT_texture_lod_bias) {
952 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
953 return;
954 }
955 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
956 *params = texUnit->LodBias;
957 }
958 else {
959 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
960 return;
961 }
962 }
963 else if (target == GL_POINT_SPRITE_NV) {
964 /* GL_ARB_point_sprite / GL_NV_point_sprite */
965 if (!ctx->Extensions.NV_point_sprite
966 && !ctx->Extensions.ARB_point_sprite) {
967 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
968 return;
969 }
970 if (pname == GL_COORD_REPLACE_NV) {
971 *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
972 }
973 else {
974 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
975 return;
976 }
977 }
978 else {
979 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
980 return;
981 }
982 }
983
984
985 void GLAPIENTRY
986 _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
987 {
988 GET_CURRENT_CONTEXT(ctx);
989 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
990 ASSERT_OUTSIDE_BEGIN_END(ctx);
991
992 if (target == GL_TEXTURE_ENV) {
993 switch (pname) {
994 case GL_TEXTURE_ENV_MODE:
995 *params = (GLint) texUnit->EnvMode;
996 break;
997 case GL_TEXTURE_ENV_COLOR:
998 params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
999 params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
1000 params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
1001 params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
1002 break;
1003 case GL_COMBINE_RGB:
1004 if (ctx->Extensions.EXT_texture_env_combine ||
1005 ctx->Extensions.ARB_texture_env_combine) {
1006 *params = (GLint) texUnit->Combine.ModeRGB;
1007 }
1008 else {
1009 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1010 }
1011 break;
1012 case GL_COMBINE_ALPHA:
1013 if (ctx->Extensions.EXT_texture_env_combine ||
1014 ctx->Extensions.ARB_texture_env_combine) {
1015 *params = (GLint) texUnit->Combine.ModeA;
1016 }
1017 else {
1018 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1019 }
1020 break;
1021 case GL_SOURCE0_RGB:
1022 if (ctx->Extensions.EXT_texture_env_combine ||
1023 ctx->Extensions.ARB_texture_env_combine) {
1024 *params = (GLint) texUnit->Combine.SourceRGB[0];
1025 }
1026 else {
1027 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1028 }
1029 break;
1030 case GL_SOURCE1_RGB:
1031 if (ctx->Extensions.EXT_texture_env_combine ||
1032 ctx->Extensions.ARB_texture_env_combine) {
1033 *params = (GLint) texUnit->Combine.SourceRGB[1];
1034 }
1035 else {
1036 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1037 }
1038 break;
1039 case GL_SOURCE2_RGB:
1040 if (ctx->Extensions.EXT_texture_env_combine ||
1041 ctx->Extensions.ARB_texture_env_combine) {
1042 *params = (GLint) texUnit->Combine.SourceRGB[2];
1043 }
1044 else {
1045 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1046 }
1047 break;
1048 case GL_SOURCE0_ALPHA:
1049 if (ctx->Extensions.EXT_texture_env_combine ||
1050 ctx->Extensions.ARB_texture_env_combine) {
1051 *params = (GLint) texUnit->Combine.SourceA[0];
1052 }
1053 else {
1054 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1055 }
1056 break;
1057 case GL_SOURCE1_ALPHA:
1058 if (ctx->Extensions.EXT_texture_env_combine ||
1059 ctx->Extensions.ARB_texture_env_combine) {
1060 *params = (GLint) texUnit->Combine.SourceA[1];
1061 }
1062 else {
1063 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1064 }
1065 break;
1066 case GL_SOURCE2_ALPHA:
1067 if (ctx->Extensions.EXT_texture_env_combine ||
1068 ctx->Extensions.ARB_texture_env_combine) {
1069 *params = (GLint) texUnit->Combine.SourceA[2];
1070 }
1071 else {
1072 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1073 }
1074 break;
1075 case GL_OPERAND0_RGB:
1076 if (ctx->Extensions.EXT_texture_env_combine ||
1077 ctx->Extensions.ARB_texture_env_combine) {
1078 *params = (GLint) texUnit->Combine.OperandRGB[0];
1079 }
1080 else {
1081 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1082 }
1083 break;
1084 case GL_OPERAND1_RGB:
1085 if (ctx->Extensions.EXT_texture_env_combine ||
1086 ctx->Extensions.ARB_texture_env_combine) {
1087 *params = (GLint) texUnit->Combine.OperandRGB[1];
1088 }
1089 else {
1090 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1091 }
1092 break;
1093 case GL_OPERAND2_RGB:
1094 if (ctx->Extensions.EXT_texture_env_combine ||
1095 ctx->Extensions.ARB_texture_env_combine) {
1096 *params = (GLint) texUnit->Combine.OperandRGB[2];
1097 }
1098 else {
1099 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1100 }
1101 break;
1102 case GL_OPERAND0_ALPHA:
1103 if (ctx->Extensions.EXT_texture_env_combine ||
1104 ctx->Extensions.ARB_texture_env_combine) {
1105 *params = (GLint) texUnit->Combine.OperandA[0];
1106 }
1107 else {
1108 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1109 }
1110 break;
1111 case GL_OPERAND1_ALPHA:
1112 if (ctx->Extensions.EXT_texture_env_combine ||
1113 ctx->Extensions.ARB_texture_env_combine) {
1114 *params = (GLint) texUnit->Combine.OperandA[1];
1115 }
1116 else {
1117 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1118 }
1119 break;
1120 case GL_OPERAND2_ALPHA:
1121 if (ctx->Extensions.EXT_texture_env_combine ||
1122 ctx->Extensions.ARB_texture_env_combine) {
1123 *params = (GLint) texUnit->Combine.OperandA[2];
1124 }
1125 else {
1126 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1127 }
1128 break;
1129 case GL_RGB_SCALE:
1130 if (ctx->Extensions.EXT_texture_env_combine ||
1131 ctx->Extensions.ARB_texture_env_combine) {
1132 if (texUnit->Combine.ScaleShiftRGB == 0)
1133 *params = 1;
1134 else if (texUnit->Combine.ScaleShiftRGB == 1)
1135 *params = 2;
1136 else
1137 *params = 4;
1138 }
1139 else {
1140 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1141 return;
1142 }
1143 break;
1144 case GL_ALPHA_SCALE:
1145 if (ctx->Extensions.EXT_texture_env_combine ||
1146 ctx->Extensions.ARB_texture_env_combine) {
1147 if (texUnit->Combine.ScaleShiftA == 0)
1148 *params = 1;
1149 else if (texUnit->Combine.ScaleShiftA == 1)
1150 *params = 2;
1151 else
1152 *params = 4;
1153 }
1154 else {
1155 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
1156 return;
1157 }
1158 break;
1159 default:
1160 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname=0x%x)",
1161 pname);
1162 }
1163 }
1164 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
1165 /* GL_EXT_texture_lod_bias */
1166 if (!ctx->Extensions.EXT_texture_lod_bias) {
1167 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
1168 return;
1169 }
1170 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
1171 *params = (GLint) texUnit->LodBias;
1172 }
1173 else {
1174 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
1175 return;
1176 }
1177 }
1178 else if (target == GL_POINT_SPRITE_NV) {
1179 /* GL_ARB_point_sprite / GL_NV_point_sprite */
1180 if (!ctx->Extensions.NV_point_sprite
1181 && !ctx->Extensions.ARB_point_sprite) {
1182 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
1183 return;
1184 }
1185 if (pname == GL_COORD_REPLACE_NV) {
1186 *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
1187 }
1188 else {
1189 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
1190 return;
1191 }
1192 }
1193 else {
1194 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
1195 return;
1196 }
1197 }
1198
1199
1200
1201
1202 /**********************************************************************/
1203 /* Texture Parameters */
1204 /**********************************************************************/
1205
1206 static GLboolean
1207 _mesa_validate_texture_wrap_mode(GLcontext * ctx,
1208 GLenum target, GLenum eparam)
1209 {
1210 const struct gl_extensions * const e = & ctx->Extensions;
1211
1212 if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
1213 (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
1214 /* any texture target */
1215 return GL_TRUE;
1216 }
1217 else if (target != GL_TEXTURE_RECTANGLE_NV &&
1218 (eparam == GL_REPEAT ||
1219 (eparam == GL_MIRRORED_REPEAT &&
1220 e->ARB_texture_mirrored_repeat) ||
1221 (eparam == GL_MIRROR_CLAMP_EXT &&
1222 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
1223 (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
1224 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
1225 (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
1226 (e->EXT_texture_mirror_clamp)))) {
1227 /* non-rectangle texture */
1228 return GL_TRUE;
1229 }
1230
1231 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1232 return GL_FALSE;
1233 }
1234
1235
1236 void GLAPIENTRY
1237 _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
1238 {
1239 _mesa_TexParameterfv(target, pname, &param);
1240 }
1241
1242
1243 void GLAPIENTRY
1244 _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
1245 {
1246 GET_CURRENT_CONTEXT(ctx);
1247 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1248 GLenum eparam = (GLenum) (GLint) params[0];
1249 struct gl_texture_object *texObj;
1250 ASSERT_OUTSIDE_BEGIN_END(ctx);
1251
1252 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
1253 _mesa_debug(ctx, "glTexParameter %s %s %.1f(%s)...\n",
1254 _mesa_lookup_enum_by_nr(target),
1255 _mesa_lookup_enum_by_nr(pname),
1256 *params,
1257 _mesa_lookup_enum_by_nr(eparam));
1258
1259
1260 switch (target) {
1261 case GL_TEXTURE_1D:
1262 texObj = texUnit->Current1D;
1263 break;
1264 case GL_TEXTURE_2D:
1265 texObj = texUnit->Current2D;
1266 break;
1267 case GL_TEXTURE_3D:
1268 texObj = texUnit->Current3D;
1269 break;
1270 case GL_TEXTURE_CUBE_MAP:
1271 if (!ctx->Extensions.ARB_texture_cube_map) {
1272 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
1273 return;
1274 }
1275 texObj = texUnit->CurrentCubeMap;
1276 break;
1277 case GL_TEXTURE_RECTANGLE_NV:
1278 if (!ctx->Extensions.NV_texture_rectangle) {
1279 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
1280 return;
1281 }
1282 texObj = texUnit->CurrentRect;
1283 break;
1284 default:
1285 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
1286 return;
1287 }
1288
1289 switch (pname) {
1290 case GL_TEXTURE_MIN_FILTER:
1291 /* A small optimization */
1292 if (texObj->MinFilter == eparam)
1293 return;
1294 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
1295 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1296 texObj->MinFilter = eparam;
1297 }
1298 else if ((eparam==GL_NEAREST_MIPMAP_NEAREST ||
1299 eparam==GL_LINEAR_MIPMAP_NEAREST ||
1300 eparam==GL_NEAREST_MIPMAP_LINEAR ||
1301 eparam==GL_LINEAR_MIPMAP_LINEAR) &&
1302 texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
1303 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1304 texObj->MinFilter = eparam;
1305 }
1306 else {
1307 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1308 return;
1309 }
1310 break;
1311 case GL_TEXTURE_MAG_FILTER:
1312 /* A small optimization */
1313 if (texObj->MagFilter == eparam)
1314 return;
1315
1316 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
1317 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1318 texObj->MagFilter = eparam;
1319 }
1320 else {
1321 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1322 return;
1323 }
1324 break;
1325 case GL_TEXTURE_WRAP_S:
1326 if (texObj->WrapS == eparam)
1327 return;
1328 if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
1329 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1330 texObj->WrapS = eparam;
1331 }
1332 else {
1333 return;
1334 }
1335 break;
1336 case GL_TEXTURE_WRAP_T:
1337 if (texObj->WrapT == eparam)
1338 return;
1339 if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
1340 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1341 texObj->WrapT = eparam;
1342 }
1343 else {
1344 return;
1345 }
1346 break;
1347 case GL_TEXTURE_WRAP_R:
1348 if (texObj->WrapR == eparam)
1349 return;
1350 if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
1351 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1352 texObj->WrapR = eparam;
1353 }
1354 else {
1355 return;
1356 }
1357 break;
1358 case GL_TEXTURE_BORDER_COLOR:
1359 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1360 texObj->BorderColor[RCOMP] = params[0];
1361 texObj->BorderColor[GCOMP] = params[1];
1362 texObj->BorderColor[BCOMP] = params[2];
1363 texObj->BorderColor[ACOMP] = params[3];
1364 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
1365 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
1366 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
1367 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
1368 break;
1369 case GL_TEXTURE_MIN_LOD:
1370 if (texObj->MinLod == params[0])
1371 return;
1372 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1373 texObj->MinLod = params[0];
1374 break;
1375 case GL_TEXTURE_MAX_LOD:
1376 if (texObj->MaxLod == params[0])
1377 return;
1378 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1379 texObj->MaxLod = params[0];
1380 break;
1381 case GL_TEXTURE_BASE_LEVEL:
1382 if (params[0] < 0.0) {
1383 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1384 return;
1385 }
1386 if (target == GL_TEXTURE_RECTANGLE_NV && params[0] != 0.0) {
1387 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1388 return;
1389 }
1390 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1391 texObj->BaseLevel = (GLint) params[0];
1392 break;
1393 case GL_TEXTURE_MAX_LEVEL:
1394 if (params[0] < 0.0) {
1395 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1396 return;
1397 }
1398 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1399 texObj->MaxLevel = (GLint) params[0];
1400 break;
1401 case GL_TEXTURE_PRIORITY:
1402 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1403 texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
1404 break;
1405 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1406 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1407 if (params[0] < 1.0) {
1408 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1409 return;
1410 }
1411 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1412 /* clamp to max, that's what NVIDIA does */
1413 texObj->MaxAnisotropy = MIN2(params[0],
1414 ctx->Const.MaxTextureMaxAnisotropy);
1415 }
1416 else {
1417 _mesa_error(ctx, GL_INVALID_ENUM,
1418 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
1419 return;
1420 }
1421 break;
1422 case GL_TEXTURE_COMPARE_SGIX:
1423 if (ctx->Extensions.SGIX_shadow) {
1424 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1425 texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
1426 }
1427 else {
1428 _mesa_error(ctx, GL_INVALID_ENUM,
1429 "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
1430 return;
1431 }
1432 break;
1433 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1434 if (ctx->Extensions.SGIX_shadow) {
1435 GLenum op = (GLenum) params[0];
1436 if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
1437 op == GL_TEXTURE_GEQUAL_R_SGIX) {
1438 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1439 texObj->CompareOperator = op;
1440 }
1441 else {
1442 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
1443 }
1444 }
1445 else {
1446 _mesa_error(ctx, GL_INVALID_ENUM,
1447 "glTexParameter(pname=GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
1448 return;
1449 }
1450 break;
1451 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1452 if (ctx->Extensions.SGIX_shadow_ambient) {
1453 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1454 texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F);
1455 }
1456 else {
1457 _mesa_error(ctx, GL_INVALID_ENUM,
1458 "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
1459 return;
1460 }
1461 break;
1462 case GL_GENERATE_MIPMAP_SGIS:
1463 if (ctx->Extensions.SGIS_generate_mipmap) {
1464 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
1465 }
1466 else {
1467 _mesa_error(ctx, GL_INVALID_ENUM,
1468 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
1469 return;
1470 }
1471 break;
1472 case GL_TEXTURE_COMPARE_MODE_ARB:
1473 if (ctx->Extensions.ARB_shadow) {
1474 const GLenum mode = (GLenum) params[0];
1475 if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
1476 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1477 texObj->CompareMode = mode;
1478 }
1479 else {
1480 _mesa_error(ctx, GL_INVALID_ENUM,
1481 "glTexParameter(bad GL_TEXTURE_COMPARE_MODE_ARB: 0x%x)", mode);
1482 return;
1483 }
1484 }
1485 else {
1486 _mesa_error(ctx, GL_INVALID_ENUM,
1487 "glTexParameter(pname=GL_TEXTURE_COMPARE_MODE_ARB)");
1488 return;
1489 }
1490 break;
1491 case GL_TEXTURE_COMPARE_FUNC_ARB:
1492 if (ctx->Extensions.ARB_shadow) {
1493 const GLenum func = (GLenum) params[0];
1494 if (func == GL_LEQUAL || func == GL_GEQUAL) {
1495 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1496 texObj->CompareFunc = func;
1497 }
1498 else if (ctx->Extensions.EXT_shadow_funcs &&
1499 (func == GL_EQUAL ||
1500 func == GL_NOTEQUAL ||
1501 func == GL_LESS ||
1502 func == GL_GREATER ||
1503 func == GL_ALWAYS ||
1504 func == GL_NEVER)) {
1505 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1506 texObj->CompareFunc = func;
1507 }
1508 else {
1509 _mesa_error(ctx, GL_INVALID_ENUM,
1510 "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)");
1511 return;
1512 }
1513 }
1514 else {
1515 _mesa_error(ctx, GL_INVALID_ENUM,
1516 "glTexParameter(pname=GL_TEXTURE_COMPARE_FUNC_ARB)");
1517 return;
1518 }
1519 break;
1520 case GL_DEPTH_TEXTURE_MODE_ARB:
1521 if (ctx->Extensions.ARB_depth_texture) {
1522 const GLenum result = (GLenum) params[0];
1523 if (result == GL_LUMINANCE || result == GL_INTENSITY
1524 || result == GL_ALPHA) {
1525 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1526 texObj->DepthMode = result;
1527 }
1528 else {
1529 _mesa_error(ctx, GL_INVALID_ENUM,
1530 "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
1531 return;
1532 }
1533 }
1534 else {
1535 _mesa_error(ctx, GL_INVALID_ENUM,
1536 "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)");
1537 return;
1538 }
1539 break;
1540 case GL_TEXTURE_LOD_BIAS:
1541 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias*/
1542 if (ctx->Extensions.EXT_texture_lod_bias) {
1543 if (texObj->LodBias != params[0]) {
1544 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1545 texObj->LodBias = params[0];
1546 }
1547 }
1548 break;
1549
1550 default:
1551 _mesa_error(ctx, GL_INVALID_ENUM,
1552 "glTexParameter(pname=0x%x)", pname);
1553 return;
1554 }
1555
1556 texObj->Complete = GL_FALSE;
1557
1558 if (ctx->Driver.TexParameter) {
1559 (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
1560 }
1561 }
1562
1563
1564 void GLAPIENTRY
1565 _mesa_TexParameteri( GLenum target, GLenum pname, GLint param )
1566 {
1567 GLfloat fparam[4];
1568 if (pname == GL_TEXTURE_PRIORITY)
1569 fparam[0] = INT_TO_FLOAT(param);
1570 else
1571 fparam[0] = (GLfloat) param;
1572 fparam[1] = fparam[2] = fparam[3] = 0.0;
1573 _mesa_TexParameterfv(target, pname, fparam);
1574 }
1575
1576
1577 void GLAPIENTRY
1578 _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
1579 {
1580 GLfloat fparam[4];
1581 if (pname == GL_TEXTURE_BORDER_COLOR) {
1582 fparam[0] = INT_TO_FLOAT(params[0]);
1583 fparam[1] = INT_TO_FLOAT(params[1]);
1584 fparam[2] = INT_TO_FLOAT(params[2]);
1585 fparam[3] = INT_TO_FLOAT(params[3]);
1586 }
1587 else {
1588 if (pname == GL_TEXTURE_PRIORITY)
1589 fparam[0] = INT_TO_FLOAT(params[0]);
1590 else
1591 fparam[0] = (GLfloat) params[0];
1592 fparam[1] = fparam[2] = fparam[3] = 0.0F;
1593 }
1594 _mesa_TexParameterfv(target, pname, fparam);
1595 }
1596
1597
1598 void GLAPIENTRY
1599 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
1600 GLenum pname, GLfloat *params )
1601 {
1602 GLint iparam;
1603 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
1604 *params = (GLfloat) iparam;
1605 }
1606
1607
1608 static GLuint
1609 tex_image_dimensions(GLcontext *ctx, GLenum target)
1610 {
1611 switch (target) {
1612 case GL_TEXTURE_1D:
1613 case GL_PROXY_TEXTURE_1D:
1614 return 1;
1615 case GL_TEXTURE_2D:
1616 case GL_PROXY_TEXTURE_2D:
1617 return 2;
1618 case GL_TEXTURE_3D:
1619 case GL_PROXY_TEXTURE_3D:
1620 return 3;
1621 case GL_TEXTURE_CUBE_MAP:
1622 case GL_PROXY_TEXTURE_CUBE_MAP:
1623 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1624 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1625 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1626 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1627 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1628 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1629 return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
1630 case GL_TEXTURE_RECTANGLE_NV:
1631 case GL_PROXY_TEXTURE_RECTANGLE_NV:
1632 return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
1633 default:
1634 _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
1635 return 0;
1636 }
1637 }
1638
1639
1640 void GLAPIENTRY
1641 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
1642 GLenum pname, GLint *params )
1643 {
1644 GET_CURRENT_CONTEXT(ctx);
1645 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1646 const struct gl_texture_image *img = NULL;
1647 GLuint dimensions;
1648 GLboolean isProxy;
1649 GLint maxLevels;
1650 ASSERT_OUTSIDE_BEGIN_END(ctx);
1651
1652 /* this will catch bad target values */
1653 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
1654 if (dimensions == 0) {
1655 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
1656 return;
1657 }
1658
1659 switch (target) {
1660 case GL_TEXTURE_1D:
1661 case GL_PROXY_TEXTURE_1D:
1662 case GL_TEXTURE_2D:
1663 case GL_PROXY_TEXTURE_2D:
1664 maxLevels = ctx->Const.MaxTextureLevels;
1665 break;
1666 case GL_TEXTURE_3D:
1667 case GL_PROXY_TEXTURE_3D:
1668 maxLevels = ctx->Const.Max3DTextureLevels;
1669 break;
1670 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1671 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1672 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1673 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1674 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1675 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1676 case GL_PROXY_TEXTURE_CUBE_MAP:
1677 maxLevels = ctx->Const.MaxCubeTextureLevels;
1678 break;
1679 case GL_TEXTURE_RECTANGLE_NV:
1680 case GL_PROXY_TEXTURE_RECTANGLE_NV:
1681 maxLevels = 1;
1682 break;
1683 default:
1684 _mesa_problem(ctx, "switch in _mesa_GetTexLevelParameter");
1685 return;
1686 }
1687
1688 if (level < 0 || level >= maxLevels) {
1689 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
1690 return;
1691 }
1692
1693 img = _mesa_select_tex_image(ctx, texUnit, target, level);
1694 if (!img || !img->TexFormat) {
1695 /* undefined texture image */
1696 if (pname == GL_TEXTURE_COMPONENTS)
1697 *params = 1;
1698 else
1699 *params = 0;
1700 return;
1701 }
1702
1703 isProxy = (target == GL_PROXY_TEXTURE_1D) ||
1704 (target == GL_PROXY_TEXTURE_2D) ||
1705 (target == GL_PROXY_TEXTURE_3D) ||
1706 (target == GL_PROXY_TEXTURE_CUBE_MAP) ||
1707 (target == GL_PROXY_TEXTURE_RECTANGLE_NV);
1708
1709 switch (pname) {
1710 case GL_TEXTURE_WIDTH:
1711 *params = img->Width;
1712 return;
1713 case GL_TEXTURE_HEIGHT:
1714 *params = img->Height;
1715 return;
1716 case GL_TEXTURE_DEPTH:
1717 *params = img->Depth;
1718 return;
1719 case GL_TEXTURE_INTERNAL_FORMAT:
1720 *params = img->InternalFormat;
1721 return;
1722 case GL_TEXTURE_BORDER:
1723 *params = img->Border;
1724 return;
1725 case GL_TEXTURE_RED_SIZE:
1726 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
1727 *params = img->TexFormat->RedBits;
1728 else
1729 *params = 0;
1730 return;
1731 case GL_TEXTURE_GREEN_SIZE:
1732 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
1733 *params = img->TexFormat->GreenBits;
1734 else
1735 *params = 0;
1736 return;
1737 case GL_TEXTURE_BLUE_SIZE:
1738 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
1739 *params = img->TexFormat->BlueBits;
1740 else
1741 *params = 0;
1742 return;
1743 case GL_TEXTURE_ALPHA_SIZE:
1744 if (img->_BaseFormat == GL_ALPHA ||
1745 img->_BaseFormat == GL_LUMINANCE_ALPHA ||
1746 img->_BaseFormat == GL_RGBA)
1747 *params = img->TexFormat->AlphaBits;
1748 else
1749 *params = 0;
1750 return;
1751 case GL_TEXTURE_INTENSITY_SIZE:
1752 if (img->_BaseFormat != GL_INTENSITY)
1753 *params = 0;
1754 else if (img->TexFormat->IntensityBits > 0)
1755 *params = img->TexFormat->IntensityBits;
1756 else /* intensity probably stored as rgb texture */
1757 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
1758 return;
1759 case GL_TEXTURE_LUMINANCE_SIZE:
1760 if (img->_BaseFormat != GL_LUMINANCE &&
1761 img->_BaseFormat != GL_LUMINANCE_ALPHA)
1762 *params = 0;
1763 else if (img->TexFormat->LuminanceBits > 0)
1764 *params = img->TexFormat->LuminanceBits;
1765 else /* luminance probably stored as rgb texture */
1766 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
1767 return;
1768 case GL_TEXTURE_INDEX_SIZE_EXT:
1769 if (img->_BaseFormat == GL_COLOR_INDEX)
1770 *params = img->TexFormat->IndexBits;
1771 else
1772 *params = 0;
1773 return;
1774 case GL_TEXTURE_DEPTH_SIZE_ARB:
1775 if (ctx->Extensions.SGIX_depth_texture ||
1776 ctx->Extensions.ARB_depth_texture)
1777 *params = img->TexFormat->DepthBits;
1778 else
1779 _mesa_error(ctx, GL_INVALID_ENUM,
1780 "glGetTexLevelParameter[if]v(pname)");
1781 return;
1782 case GL_TEXTURE_STENCIL_SIZE_EXT:
1783 if (ctx->Extensions.EXT_packed_depth_stencil) {
1784 *params = img->TexFormat->StencilBits;
1785 }
1786 else {
1787 _mesa_error(ctx, GL_INVALID_ENUM,
1788 "glGetTexLevelParameter[if]v(pname)");
1789 }
1790 return;
1791
1792 /* GL_ARB_texture_compression */
1793 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1794 if (ctx->Extensions.ARB_texture_compression) {
1795 if (img->IsCompressed && !isProxy)
1796 *params = img->CompressedSize;
1797 else
1798 _mesa_error(ctx, GL_INVALID_OPERATION,
1799 "glGetTexLevelParameter[if]v(pname)");
1800 }
1801 else {
1802 _mesa_error(ctx, GL_INVALID_ENUM,
1803 "glGetTexLevelParameter[if]v(pname)");
1804 }
1805 return;
1806 case GL_TEXTURE_COMPRESSED:
1807 if (ctx->Extensions.ARB_texture_compression) {
1808 *params = (GLint) img->IsCompressed;
1809 }
1810 else {
1811 _mesa_error(ctx, GL_INVALID_ENUM,
1812 "glGetTexLevelParameter[if]v(pname)");
1813 }
1814 return;
1815
1816 /* GL_ARB_texture_float */
1817 case GL_TEXTURE_RED_TYPE_ARB:
1818 if (ctx->Extensions.ARB_texture_float) {
1819 *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
1820 }
1821 else {
1822 _mesa_error(ctx, GL_INVALID_ENUM,
1823 "glGetTexLevelParameter[if]v(pname)");
1824 }
1825 return;
1826 case GL_TEXTURE_GREEN_TYPE_ARB:
1827 if (ctx->Extensions.ARB_texture_float) {
1828 *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
1829 }
1830 else {
1831 _mesa_error(ctx, GL_INVALID_ENUM,
1832 "glGetTexLevelParameter[if]v(pname)");
1833 }
1834 return;
1835 case GL_TEXTURE_BLUE_TYPE_ARB:
1836 if (ctx->Extensions.ARB_texture_float) {
1837 *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
1838 }
1839 else {
1840 _mesa_error(ctx, GL_INVALID_ENUM,
1841 "glGetTexLevelParameter[if]v(pname)");
1842 }
1843 return;
1844 case GL_TEXTURE_ALPHA_TYPE_ARB:
1845 if (ctx->Extensions.ARB_texture_float) {
1846 *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
1847 }
1848 else {
1849 _mesa_error(ctx, GL_INVALID_ENUM,
1850 "glGetTexLevelParameter[if]v(pname)");
1851 }
1852 return;
1853 case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1854 if (ctx->Extensions.ARB_texture_float) {
1855 *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
1856 }
1857 else {
1858 _mesa_error(ctx, GL_INVALID_ENUM,
1859 "glGetTexLevelParameter[if]v(pname)");
1860 }
1861 return;
1862 case GL_TEXTURE_INTENSITY_TYPE_ARB:
1863 if (ctx->Extensions.ARB_texture_float) {
1864 *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE;
1865 }
1866 else {
1867 _mesa_error(ctx, GL_INVALID_ENUM,
1868 "glGetTexLevelParameter[if]v(pname)");
1869 }
1870 return;
1871 case GL_TEXTURE_DEPTH_TYPE_ARB:
1872 if (ctx->Extensions.ARB_texture_float) {
1873 *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
1874 }
1875 else {
1876 _mesa_error(ctx, GL_INVALID_ENUM,
1877 "glGetTexLevelParameter[if]v(pname)");
1878 }
1879 return;
1880
1881 default:
1882 _mesa_error(ctx, GL_INVALID_ENUM,
1883 "glGetTexLevelParameter[if]v(pname)");
1884 }
1885 }
1886
1887
1888
1889 void GLAPIENTRY
1890 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
1891 {
1892 GET_CURRENT_CONTEXT(ctx);
1893 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1894 struct gl_texture_object *obj;
1895 ASSERT_OUTSIDE_BEGIN_END(ctx);
1896
1897 obj = _mesa_select_tex_object(ctx, texUnit, target);
1898 if (!obj) {
1899 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
1900 return;
1901 }
1902
1903 switch (pname) {
1904 case GL_TEXTURE_MAG_FILTER:
1905 *params = ENUM_TO_FLOAT(obj->MagFilter);
1906 return;
1907 case GL_TEXTURE_MIN_FILTER:
1908 *params = ENUM_TO_FLOAT(obj->MinFilter);
1909 return;
1910 case GL_TEXTURE_WRAP_S:
1911 *params = ENUM_TO_FLOAT(obj->WrapS);
1912 return;
1913 case GL_TEXTURE_WRAP_T:
1914 *params = ENUM_TO_FLOAT(obj->WrapT);
1915 return;
1916 case GL_TEXTURE_WRAP_R:
1917 *params = ENUM_TO_FLOAT(obj->WrapR);
1918 return;
1919 case GL_TEXTURE_BORDER_COLOR:
1920 params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
1921 params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
1922 params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
1923 params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
1924 return;
1925 case GL_TEXTURE_RESIDENT:
1926 {
1927 GLboolean resident;
1928 if (ctx->Driver.IsTextureResident)
1929 resident = ctx->Driver.IsTextureResident(ctx, obj);
1930 else
1931 resident = GL_TRUE;
1932 *params = ENUM_TO_FLOAT(resident);
1933 }
1934 return;
1935 case GL_TEXTURE_PRIORITY:
1936 *params = obj->Priority;
1937 return;
1938 case GL_TEXTURE_MIN_LOD:
1939 *params = obj->MinLod;
1940 return;
1941 case GL_TEXTURE_MAX_LOD:
1942 *params = obj->MaxLod;
1943 return;
1944 case GL_TEXTURE_BASE_LEVEL:
1945 *params = (GLfloat) obj->BaseLevel;
1946 return;
1947 case GL_TEXTURE_MAX_LEVEL:
1948 *params = (GLfloat) obj->MaxLevel;
1949 return;
1950 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1951 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1952 *params = obj->MaxAnisotropy;
1953 return;
1954 }
1955 break;
1956 case GL_TEXTURE_COMPARE_SGIX:
1957 if (ctx->Extensions.SGIX_shadow) {
1958 *params = (GLfloat) obj->CompareFlag;
1959 return;
1960 }
1961 break;
1962 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1963 if (ctx->Extensions.SGIX_shadow) {
1964 *params = (GLfloat) obj->CompareOperator;
1965 return;
1966 }
1967 break;
1968 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1969 if (ctx->Extensions.SGIX_shadow_ambient) {
1970 *params = obj->ShadowAmbient;
1971 return;
1972 }
1973 break;
1974 case GL_GENERATE_MIPMAP_SGIS:
1975 if (ctx->Extensions.SGIS_generate_mipmap) {
1976 *params = (GLfloat) obj->GenerateMipmap;
1977 return;
1978 }
1979 break;
1980 case GL_TEXTURE_COMPARE_MODE_ARB:
1981 if (ctx->Extensions.ARB_shadow) {
1982 *params = (GLfloat) obj->CompareMode;
1983 return;
1984 }
1985 break;
1986 case GL_TEXTURE_COMPARE_FUNC_ARB:
1987 if (ctx->Extensions.ARB_shadow) {
1988 *params = (GLfloat) obj->CompareFunc;
1989 return;
1990 }
1991 break;
1992 case GL_DEPTH_TEXTURE_MODE_ARB:
1993 if (ctx->Extensions.ARB_depth_texture) {
1994 *params = (GLfloat) obj->DepthMode;
1995 return;
1996 }
1997 break;
1998 case GL_TEXTURE_LOD_BIAS:
1999 if (ctx->Extensions.EXT_texture_lod_bias) {
2000 *params = obj->LodBias;
2001 return;
2002 }
2003 break;
2004 default:
2005 ; /* silence warnings */
2006 }
2007 /* If we get here, pname was an unrecognized enum */
2008 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
2009 pname);
2010 }
2011
2012
2013 void GLAPIENTRY
2014 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
2015 {
2016 GET_CURRENT_CONTEXT(ctx);
2017 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
2018 struct gl_texture_object *obj;
2019 ASSERT_OUTSIDE_BEGIN_END(ctx);
2020
2021 obj = _mesa_select_tex_object(ctx, texUnit, target);
2022 if (!obj) {
2023 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
2024 return;
2025 }
2026
2027 switch (pname) {
2028 case GL_TEXTURE_MAG_FILTER:
2029 *params = (GLint) obj->MagFilter;
2030 return;
2031 case GL_TEXTURE_MIN_FILTER:
2032 *params = (GLint) obj->MinFilter;
2033 return;
2034 case GL_TEXTURE_WRAP_S:
2035 *params = (GLint) obj->WrapS;
2036 return;
2037 case GL_TEXTURE_WRAP_T:
2038 *params = (GLint) obj->WrapT;
2039 return;
2040 case GL_TEXTURE_WRAP_R:
2041 *params = (GLint) obj->WrapR;
2042 return;
2043 case GL_TEXTURE_BORDER_COLOR:
2044 {
2045 GLfloat b[4];
2046 b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
2047 b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
2048 b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
2049 b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
2050 params[0] = FLOAT_TO_INT(b[0]);
2051 params[1] = FLOAT_TO_INT(b[1]);
2052 params[2] = FLOAT_TO_INT(b[2]);
2053 params[3] = FLOAT_TO_INT(b[3]);
2054 }
2055 return;
2056 case GL_TEXTURE_RESIDENT:
2057 {
2058 GLboolean resident;
2059 if (ctx->Driver.IsTextureResident)
2060 resident = ctx->Driver.IsTextureResident(ctx, obj);
2061 else
2062 resident = GL_TRUE;
2063 *params = (GLint) resident;
2064 }
2065 return;
2066 case GL_TEXTURE_PRIORITY:
2067 *params = FLOAT_TO_INT(obj->Priority);
2068 return;
2069 case GL_TEXTURE_MIN_LOD:
2070 *params = (GLint) obj->MinLod;
2071 return;
2072 case GL_TEXTURE_MAX_LOD:
2073 *params = (GLint) obj->MaxLod;
2074 return;
2075 case GL_TEXTURE_BASE_LEVEL:
2076 *params = obj->BaseLevel;
2077 return;
2078 case GL_TEXTURE_MAX_LEVEL:
2079 *params = obj->MaxLevel;
2080 return;
2081 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2082 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
2083 *params = (GLint) obj->MaxAnisotropy;
2084 return;
2085 }
2086 break;
2087 case GL_TEXTURE_COMPARE_SGIX:
2088 if (ctx->Extensions.SGIX_shadow) {
2089 *params = (GLint) obj->CompareFlag;
2090 return;
2091 }
2092 break;
2093 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
2094 if (ctx->Extensions.SGIX_shadow) {
2095 *params = (GLint) obj->CompareOperator;
2096 return;
2097 }
2098 break;
2099 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
2100 if (ctx->Extensions.SGIX_shadow_ambient) {
2101 *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
2102 return;
2103 }
2104 break;
2105 case GL_GENERATE_MIPMAP_SGIS:
2106 if (ctx->Extensions.SGIS_generate_mipmap) {
2107 *params = (GLint) obj->GenerateMipmap;
2108 return;
2109 }
2110 break;
2111 case GL_TEXTURE_COMPARE_MODE_ARB:
2112 if (ctx->Extensions.ARB_shadow) {
2113 *params = (GLint) obj->CompareMode;
2114 return;
2115 }
2116 break;
2117 case GL_TEXTURE_COMPARE_FUNC_ARB:
2118 if (ctx->Extensions.ARB_shadow) {
2119 *params = (GLint) obj->CompareFunc;
2120 return;
2121 }
2122 break;
2123 case GL_DEPTH_TEXTURE_MODE_ARB:
2124 if (ctx->Extensions.ARB_depth_texture) {
2125 *params = (GLint) obj->DepthMode;
2126 return;
2127 }
2128 break;
2129 case GL_TEXTURE_LOD_BIAS:
2130 if (ctx->Extensions.EXT_texture_lod_bias) {
2131 *params = (GLint) obj->LodBias;
2132 return;
2133 }
2134 break;
2135 default:
2136 ; /* silence warnings */
2137 }
2138 /* If we get here, pname was an unrecognized enum */
2139 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
2140 }
2141
2142
2143
2144
2145 /**********************************************************************/
2146 /* Texture Coord Generation */
2147 /**********************************************************************/
2148
2149 #if FEATURE_texgen
2150 void GLAPIENTRY
2151 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
2152 {
2153 GET_CURRENT_CONTEXT(ctx);
2154 GLuint tUnit = ctx->Texture.CurrentUnit;
2155 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
2156 ASSERT_OUTSIDE_BEGIN_END(ctx);
2157
2158 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
2159 _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
2160 _mesa_lookup_enum_by_nr(coord),
2161 _mesa_lookup_enum_by_nr(pname),
2162 *params,
2163 _mesa_lookup_enum_by_nr((GLenum) (GLint) *params));
2164
2165 switch (coord) {
2166 case GL_S:
2167 if (pname==GL_TEXTURE_GEN_MODE) {
2168 GLenum mode = (GLenum) (GLint) *params;
2169 GLbitfield bits;
2170 switch (mode) {
2171 case GL_OBJECT_LINEAR:
2172 bits = TEXGEN_OBJ_LINEAR;
2173 break;
2174 case GL_EYE_LINEAR:
2175 bits = TEXGEN_EYE_LINEAR;
2176 break;
2177 case GL_REFLECTION_MAP_NV:
2178 bits = TEXGEN_REFLECTION_MAP_NV;
2179 break;
2180 case GL_NORMAL_MAP_NV:
2181 bits = TEXGEN_NORMAL_MAP_NV;
2182 break;
2183 case GL_SPHERE_MAP:
2184 bits = TEXGEN_SPHERE_MAP;
2185 break;
2186 default:
2187 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
2188 return;
2189 }
2190 if (texUnit->GenModeS == mode)
2191 return;
2192 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2193 texUnit->GenModeS = mode;
2194 texUnit->_GenBitS = bits;
2195 }
2196 else if (pname==GL_OBJECT_PLANE) {
2197 if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
2198 return;
2199 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2200 texUnit->ObjectPlaneS[0] = params[0];
2201 texUnit->ObjectPlaneS[1] = params[1];
2202 texUnit->ObjectPlaneS[2] = params[2];
2203 texUnit->ObjectPlaneS[3] = params[3];
2204 }
2205 else if (pname==GL_EYE_PLANE) {
2206 GLfloat tmp[4];
2207
2208 /* Transform plane equation by the inverse modelview matrix */
2209 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
2210 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
2211 }
2212 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
2213 if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
2214 return;
2215 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2216 COPY_4FV(texUnit->EyePlaneS, tmp);
2217 }
2218 else {
2219 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
2220 return;
2221 }
2222 break;
2223 case GL_T:
2224 if (pname==GL_TEXTURE_GEN_MODE) {
2225 GLenum mode = (GLenum) (GLint) *params;
2226 GLbitfield bitt;
2227 switch (mode) {
2228 case GL_OBJECT_LINEAR:
2229 bitt = TEXGEN_OBJ_LINEAR;
2230 break;
2231 case GL_EYE_LINEAR:
2232 bitt = TEXGEN_EYE_LINEAR;
2233 break;
2234 case GL_REFLECTION_MAP_NV:
2235 bitt = TEXGEN_REFLECTION_MAP_NV;
2236 break;
2237 case GL_NORMAL_MAP_NV:
2238 bitt = TEXGEN_NORMAL_MAP_NV;
2239 break;
2240 case GL_SPHERE_MAP:
2241 bitt = TEXGEN_SPHERE_MAP;
2242 break;
2243 default:
2244 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
2245 return;
2246 }
2247 if (texUnit->GenModeT == mode)
2248 return;
2249 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2250 texUnit->GenModeT = mode;
2251 texUnit->_GenBitT = bitt;
2252 }
2253 else if (pname==GL_OBJECT_PLANE) {
2254 if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
2255 return;
2256 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2257 texUnit->ObjectPlaneT[0] = params[0];
2258 texUnit->ObjectPlaneT[1] = params[1];
2259 texUnit->ObjectPlaneT[2] = params[2];
2260 texUnit->ObjectPlaneT[3] = params[3];
2261 }
2262 else if (pname==GL_EYE_PLANE) {
2263 GLfloat tmp[4];
2264 /* Transform plane equation by the inverse modelview matrix */
2265 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
2266 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
2267 }
2268 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
2269 if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
2270 return;
2271 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2272 COPY_4FV(texUnit->EyePlaneT, tmp);
2273 }
2274 else {
2275 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
2276 return;
2277 }
2278 break;
2279 case GL_R:
2280 if (pname==GL_TEXTURE_GEN_MODE) {
2281 GLenum mode = (GLenum) (GLint) *params;
2282 GLbitfield bitr;
2283 switch (mode) {
2284 case GL_OBJECT_LINEAR:
2285 bitr = TEXGEN_OBJ_LINEAR;
2286 break;
2287 case GL_REFLECTION_MAP_NV:
2288 bitr = TEXGEN_REFLECTION_MAP_NV;
2289 break;
2290 case GL_NORMAL_MAP_NV:
2291 bitr = TEXGEN_NORMAL_MAP_NV;
2292 break;
2293 case GL_EYE_LINEAR:
2294 bitr = TEXGEN_EYE_LINEAR;
2295 break;
2296 default:
2297 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
2298 return;
2299 }
2300 if (texUnit->GenModeR == mode)
2301 return;
2302 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2303 texUnit->GenModeR = mode;
2304 texUnit->_GenBitR = bitr;
2305 }
2306 else if (pname==GL_OBJECT_PLANE) {
2307 if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
2308 return;
2309 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2310 texUnit->ObjectPlaneR[0] = params[0];
2311 texUnit->ObjectPlaneR[1] = params[1];
2312 texUnit->ObjectPlaneR[2] = params[2];
2313 texUnit->ObjectPlaneR[3] = params[3];
2314 }
2315 else if (pname==GL_EYE_PLANE) {
2316 GLfloat tmp[4];
2317 /* Transform plane equation by the inverse modelview matrix */
2318 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
2319 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
2320 }
2321 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
2322 if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
2323 return;
2324 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2325 COPY_4FV(texUnit->EyePlaneR, tmp);
2326 }
2327 else {
2328 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
2329 return;
2330 }
2331 break;
2332 case GL_Q:
2333 if (pname==GL_TEXTURE_GEN_MODE) {
2334 GLenum mode = (GLenum) (GLint) *params;
2335 GLbitfield bitq;
2336 switch (mode) {
2337 case GL_OBJECT_LINEAR:
2338 bitq = TEXGEN_OBJ_LINEAR;
2339 break;
2340 case GL_EYE_LINEAR:
2341 bitq = TEXGEN_EYE_LINEAR;
2342 break;
2343 default:
2344 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
2345 return;
2346 }
2347 if (texUnit->GenModeQ == mode)
2348 return;
2349 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2350 texUnit->GenModeQ = mode;
2351 texUnit->_GenBitQ = bitq;
2352 }
2353 else if (pname==GL_OBJECT_PLANE) {
2354 if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
2355 return;
2356 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2357 texUnit->ObjectPlaneQ[0] = params[0];
2358 texUnit->ObjectPlaneQ[1] = params[1];
2359 texUnit->ObjectPlaneQ[2] = params[2];
2360 texUnit->ObjectPlaneQ[3] = params[3];
2361 }
2362 else if (pname==GL_EYE_PLANE) {
2363 GLfloat tmp[4];
2364 /* Transform plane equation by the inverse modelview matrix */
2365 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
2366 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
2367 }
2368 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
2369 if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
2370 return;
2371 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2372 COPY_4FV(texUnit->EyePlaneQ, tmp);
2373 }
2374 else {
2375 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
2376 return;
2377 }
2378 break;
2379 default:
2380 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
2381 return;
2382 }
2383
2384 if (ctx->Driver.TexGen)
2385 ctx->Driver.TexGen( ctx, coord, pname, params );
2386 }
2387
2388
2389 void GLAPIENTRY
2390 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
2391 {
2392 GLfloat p[4];
2393 p[0] = (GLfloat) params[0];
2394 if (pname == GL_TEXTURE_GEN_MODE) {
2395 p[1] = p[2] = p[3] = 0.0F;
2396 }
2397 else {
2398 p[1] = (GLfloat) params[1];
2399 p[2] = (GLfloat) params[2];
2400 p[3] = (GLfloat) params[3];
2401 }
2402 _mesa_TexGenfv(coord, pname, p);
2403 }
2404
2405
2406 void GLAPIENTRY
2407 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
2408 {
2409 GLfloat p = (GLfloat) param;
2410 _mesa_TexGenfv( coord, pname, &p );
2411 }
2412
2413
2414 void GLAPIENTRY
2415 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
2416 {
2417 GLfloat p[4];
2418 p[0] = (GLfloat) params[0];
2419 if (pname == GL_TEXTURE_GEN_MODE) {
2420 p[1] = p[2] = p[3] = 0.0F;
2421 }
2422 else {
2423 p[1] = (GLfloat) params[1];
2424 p[2] = (GLfloat) params[2];
2425 p[3] = (GLfloat) params[3];
2426 }
2427 _mesa_TexGenfv( coord, pname, p );
2428 }
2429
2430
2431 void GLAPIENTRY
2432 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
2433 {
2434 _mesa_TexGenfv(coord, pname, &param);
2435 }
2436
2437
2438 void GLAPIENTRY
2439 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
2440 {
2441 _mesa_TexGeniv( coord, pname, &param );
2442 }
2443
2444
2445
2446 void GLAPIENTRY
2447 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
2448 {
2449 GET_CURRENT_CONTEXT(ctx);
2450 GLuint tUnit = ctx->Texture.CurrentUnit;
2451 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
2452 ASSERT_OUTSIDE_BEGIN_END(ctx);
2453
2454 switch (coord) {
2455 case GL_S:
2456 if (pname==GL_TEXTURE_GEN_MODE) {
2457 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
2458 }
2459 else if (pname==GL_OBJECT_PLANE) {
2460 COPY_4V( params, texUnit->ObjectPlaneS );
2461 }
2462 else if (pname==GL_EYE_PLANE) {
2463 COPY_4V( params, texUnit->EyePlaneS );
2464 }
2465 else {
2466 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
2467 return;
2468 }
2469 break;
2470 case GL_T:
2471 if (pname==GL_TEXTURE_GEN_MODE) {
2472 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
2473 }
2474 else if (pname==GL_OBJECT_PLANE) {
2475 COPY_4V( params, texUnit->ObjectPlaneT );
2476 }
2477 else if (pname==GL_EYE_PLANE) {
2478 COPY_4V( params, texUnit->EyePlaneT );
2479 }
2480 else {
2481 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
2482 return;
2483 }
2484 break;
2485 case GL_R:
2486 if (pname==GL_TEXTURE_GEN_MODE) {
2487 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
2488 }
2489 else if (pname==GL_OBJECT_PLANE) {
2490 COPY_4V( params, texUnit->ObjectPlaneR );
2491 }
2492 else if (pname==GL_EYE_PLANE) {
2493 COPY_4V( params, texUnit->EyePlaneR );
2494 }
2495 else {
2496 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
2497 return;
2498 }
2499 break;
2500 case GL_Q:
2501 if (pname==GL_TEXTURE_GEN_MODE) {
2502 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
2503 }
2504 else if (pname==GL_OBJECT_PLANE) {
2505 COPY_4V( params, texUnit->ObjectPlaneQ );
2506 }
2507 else if (pname==GL_EYE_PLANE) {
2508 COPY_4V( params, texUnit->EyePlaneQ );
2509 }
2510 else {
2511 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
2512 return;
2513 }
2514 break;
2515 default:
2516 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
2517 return;
2518 }
2519 }
2520
2521
2522
2523 void GLAPIENTRY
2524 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
2525 {
2526 GET_CURRENT_CONTEXT(ctx);
2527 GLuint tUnit = ctx->Texture.CurrentUnit;
2528 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
2529 ASSERT_OUTSIDE_BEGIN_END(ctx);
2530
2531 switch (coord) {
2532 case GL_S:
2533 if (pname==GL_TEXTURE_GEN_MODE) {
2534 params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
2535 }
2536 else if (pname==GL_OBJECT_PLANE) {
2537 COPY_4V( params, texUnit->ObjectPlaneS );
2538 }
2539 else if (pname==GL_EYE_PLANE) {
2540 COPY_4V( params, texUnit->EyePlaneS );
2541 }
2542 else {
2543 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
2544 return;
2545 }
2546 break;
2547 case GL_T:
2548 if (pname==GL_TEXTURE_GEN_MODE) {
2549 params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
2550 }
2551 else if (pname==GL_OBJECT_PLANE) {
2552 COPY_4V( params, texUnit->ObjectPlaneT );
2553 }
2554 else if (pname==GL_EYE_PLANE) {
2555 COPY_4V( params, texUnit->EyePlaneT );
2556 }
2557 else {
2558 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
2559 return;
2560 }
2561 break;
2562 case GL_R:
2563 if (pname==GL_TEXTURE_GEN_MODE) {
2564 params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
2565 }
2566 else if (pname==GL_OBJECT_PLANE) {
2567 COPY_4V( params, texUnit->ObjectPlaneR );
2568 }
2569 else if (pname==GL_EYE_PLANE) {
2570 COPY_4V( params, texUnit->EyePlaneR );
2571 }
2572 else {
2573 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
2574 return;
2575 }
2576 break;
2577 case GL_Q:
2578 if (pname==GL_TEXTURE_GEN_MODE) {
2579 params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
2580 }
2581 else if (pname==GL_OBJECT_PLANE) {
2582 COPY_4V( params, texUnit->ObjectPlaneQ );
2583 }
2584 else if (pname==GL_EYE_PLANE) {
2585 COPY_4V( params, texUnit->EyePlaneQ );
2586 }
2587 else {
2588 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
2589 return;
2590 }
2591 break;
2592 default:
2593 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
2594 return;
2595 }
2596 }
2597
2598
2599
2600 void GLAPIENTRY
2601 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
2602 {
2603 GET_CURRENT_CONTEXT(ctx);
2604 GLuint tUnit = ctx->Texture.CurrentUnit;
2605 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
2606 ASSERT_OUTSIDE_BEGIN_END(ctx);
2607
2608 switch (coord) {
2609 case GL_S:
2610 if (pname==GL_TEXTURE_GEN_MODE) {
2611 params[0] = texUnit->GenModeS;
2612 }
2613 else if (pname==GL_OBJECT_PLANE) {
2614 params[0] = (GLint) texUnit->ObjectPlaneS[0];
2615 params[1] = (GLint) texUnit->ObjectPlaneS[1];
2616 params[2] = (GLint) texUnit->ObjectPlaneS[2];
2617 params[3] = (GLint) texUnit->ObjectPlaneS[3];
2618 }
2619 else if (pname==GL_EYE_PLANE) {
2620 params[0] = (GLint) texUnit->EyePlaneS[0];
2621 params[1] = (GLint) texUnit->EyePlaneS[1];
2622 params[2] = (GLint) texUnit->EyePlaneS[2];
2623 params[3] = (GLint) texUnit->EyePlaneS[3];
2624 }
2625 else {
2626 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
2627 return;
2628 }
2629 break;
2630 case GL_T:
2631 if (pname==GL_TEXTURE_GEN_MODE) {
2632 params[0] = texUnit->GenModeT;
2633 }
2634 else if (pname==GL_OBJECT_PLANE) {
2635 params[0] = (GLint) texUnit->ObjectPlaneT[0];
2636 params[1] = (GLint) texUnit->ObjectPlaneT[1];
2637 params[2] = (GLint) texUnit->ObjectPlaneT[2];
2638 params[3] = (GLint) texUnit->ObjectPlaneT[3];
2639 }
2640 else if (pname==GL_EYE_PLANE) {
2641 params[0] = (GLint) texUnit->EyePlaneT[0];
2642 params[1] = (GLint) texUnit->EyePlaneT[1];
2643 params[2] = (GLint) texUnit->EyePlaneT[2];
2644 params[3] = (GLint) texUnit->EyePlaneT[3];
2645 }
2646 else {
2647 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
2648 return;
2649 }
2650 break;
2651 case GL_R:
2652 if (pname==GL_TEXTURE_GEN_MODE) {
2653 params[0] = texUnit->GenModeR;
2654 }
2655 else if (pname==GL_OBJECT_PLANE) {
2656 params[0] = (GLint) texUnit->ObjectPlaneR[0];
2657 params[1] = (GLint) texUnit->ObjectPlaneR[1];
2658 params[2] = (GLint) texUnit->ObjectPlaneR[2];
2659 params[3] = (GLint) texUnit->ObjectPlaneR[3];
2660 }
2661 else if (pname==GL_EYE_PLANE) {
2662 params[0] = (GLint) texUnit->EyePlaneR[0];
2663 params[1] = (GLint) texUnit->EyePlaneR[1];
2664 params[2] = (GLint) texUnit->EyePlaneR[2];
2665 params[3] = (GLint) texUnit->EyePlaneR[3];
2666 }
2667 else {
2668 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
2669 return;
2670 }
2671 break;
2672 case GL_Q:
2673 if (pname==GL_TEXTURE_GEN_MODE) {
2674 params[0] = texUnit->GenModeQ;
2675 }
2676 else if (pname==GL_OBJECT_PLANE) {
2677 params[0] = (GLint) texUnit->ObjectPlaneQ[0];
2678 params[1] = (GLint) texUnit->ObjectPlaneQ[1];
2679 params[2] = (GLint) texUnit->ObjectPlaneQ[2];
2680 params[3] = (GLint) texUnit->ObjectPlaneQ[3];
2681 }
2682 else if (pname==GL_EYE_PLANE) {
2683 params[0] = (GLint) texUnit->EyePlaneQ[0];
2684 params[1] = (GLint) texUnit->EyePlaneQ[1];
2685 params[2] = (GLint) texUnit->EyePlaneQ[2];
2686 params[3] = (GLint) texUnit->EyePlaneQ[3];
2687 }
2688 else {
2689 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
2690 return;
2691 }
2692 break;
2693 default:
2694 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
2695 return;
2696 }
2697 }
2698 #endif
2699
2700 /* GL_ARB_multitexture */
2701 void GLAPIENTRY
2702 _mesa_ActiveTextureARB( GLenum target )
2703 {
2704 GET_CURRENT_CONTEXT(ctx);
2705 const GLuint texUnit = target - GL_TEXTURE0;
2706 ASSERT_OUTSIDE_BEGIN_END(ctx);
2707
2708 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2709 _mesa_debug(ctx, "glActiveTexture %s\n",
2710 _mesa_lookup_enum_by_nr(target));
2711
2712 /* Cater for texture unit 0 is first, therefore use >= */
2713 if (texUnit >= ctx->Const.MaxTextureUnits) {
2714 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(target)");
2715 return;
2716 }
2717
2718 if (ctx->Texture.CurrentUnit == texUnit)
2719 return;
2720
2721 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2722
2723 ctx->Texture.CurrentUnit = texUnit;
2724 if (ctx->Transform.MatrixMode == GL_TEXTURE) {
2725 /* update current stack pointer */
2726 ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
2727 }
2728
2729 if (ctx->Driver.ActiveTexture) {
2730 (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
2731 }
2732 }
2733
2734
2735 /* GL_ARB_multitexture */
2736 void GLAPIENTRY
2737 _mesa_ClientActiveTextureARB( GLenum target )
2738 {
2739 GET_CURRENT_CONTEXT(ctx);
2740 GLuint texUnit = target - GL_TEXTURE0;
2741 ASSERT_OUTSIDE_BEGIN_END(ctx);
2742
2743 if (texUnit > ctx->Const.MaxTextureUnits) {
2744 _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(target)");
2745 return;
2746 }
2747
2748 FLUSH_VERTICES(ctx, _NEW_ARRAY);
2749 ctx->Array.ActiveTexture = texUnit;
2750 }
2751
2752
2753
2754 /**********************************************************************/
2755 /* Pixel Texgen Extensions */
2756 /**********************************************************************/
2757
2758 void GLAPIENTRY
2759 _mesa_PixelTexGenSGIX(GLenum mode)
2760 {
2761 GLenum newRgbSource, newAlphaSource;
2762 GET_CURRENT_CONTEXT(ctx);
2763 ASSERT_OUTSIDE_BEGIN_END(ctx);
2764
2765 switch (mode) {
2766 case GL_NONE:
2767 newRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
2768 newAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
2769 break;
2770 case GL_ALPHA:
2771 newRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
2772 newAlphaSource = GL_CURRENT_RASTER_COLOR;
2773 break;
2774 case GL_RGB:
2775 newRgbSource = GL_CURRENT_RASTER_COLOR;
2776 newAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
2777 break;
2778 case GL_RGBA:
2779 newRgbSource = GL_CURRENT_RASTER_COLOR;
2780 newAlphaSource = GL_CURRENT_RASTER_COLOR;
2781 break;
2782 default:
2783 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenSGIX(mode)");
2784 return;
2785 }
2786
2787 if (newRgbSource == ctx->Pixel.FragmentRgbSource &&
2788 newAlphaSource == ctx->Pixel.FragmentAlphaSource)
2789 return;
2790
2791 FLUSH_VERTICES(ctx, _NEW_PIXEL);
2792 ctx->Pixel.FragmentRgbSource = newRgbSource;
2793 ctx->Pixel.FragmentAlphaSource = newAlphaSource;
2794 }
2795
2796
2797 void GLAPIENTRY
2798 _mesa_PixelTexGenParameterfSGIS(GLenum target, GLfloat value)
2799 {
2800 _mesa_PixelTexGenParameteriSGIS(target, (GLint) value);
2801 }
2802
2803
2804 void GLAPIENTRY
2805 _mesa_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value)
2806 {
2807 _mesa_PixelTexGenParameteriSGIS(target, (GLint) *value);
2808 }
2809
2810
2811 void GLAPIENTRY
2812 _mesa_PixelTexGenParameteriSGIS(GLenum target, GLint value)
2813 {
2814 GET_CURRENT_CONTEXT(ctx);
2815 ASSERT_OUTSIDE_BEGIN_END(ctx);
2816
2817 if (value != GL_CURRENT_RASTER_COLOR && value != GL_PIXEL_GROUP_COLOR_SGIS) {
2818 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenParameterSGIS(value)");
2819 return;
2820 }
2821
2822 switch (target) {
2823 case GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS:
2824 if (ctx->Pixel.FragmentRgbSource == (GLenum) value)
2825 return;
2826 FLUSH_VERTICES(ctx, _NEW_PIXEL);
2827 ctx->Pixel.FragmentRgbSource = (GLenum) value;
2828 break;
2829 case GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS:
2830 if (ctx->Pixel.FragmentAlphaSource == (GLenum) value)
2831 return;
2832 FLUSH_VERTICES(ctx, _NEW_PIXEL);
2833 ctx->Pixel.FragmentAlphaSource = (GLenum) value;
2834 break;
2835 default:
2836 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenParameterSGIS(target)");
2837 return;
2838 }
2839 }
2840
2841
2842 void GLAPIENTRY
2843 _mesa_PixelTexGenParameterivSGIS(GLenum target, const GLint *value)
2844 {
2845 _mesa_PixelTexGenParameteriSGIS(target, *value);
2846 }
2847
2848
2849 void GLAPIENTRY
2850 _mesa_GetPixelTexGenParameterfvSGIS(GLenum target, GLfloat *value)
2851 {
2852 GET_CURRENT_CONTEXT(ctx);
2853 ASSERT_OUTSIDE_BEGIN_END(ctx);
2854
2855 if (target == GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) {
2856 *value = (GLfloat) ctx->Pixel.FragmentRgbSource;
2857 }
2858 else if (target == GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) {
2859 *value = (GLfloat) ctx->Pixel.FragmentAlphaSource;
2860 }
2861 else {
2862 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelTexGenParameterfvSGIS(target)");
2863 }
2864 }
2865
2866
2867 void GLAPIENTRY
2868 _mesa_GetPixelTexGenParameterivSGIS(GLenum target, GLint *value)
2869 {
2870 GET_CURRENT_CONTEXT(ctx);
2871 ASSERT_OUTSIDE_BEGIN_END(ctx);
2872
2873 if (target == GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) {
2874 *value = (GLint) ctx->Pixel.FragmentRgbSource;
2875 }
2876 else if (target == GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) {
2877 *value = (GLint) ctx->Pixel.FragmentAlphaSource;
2878 }
2879 else {
2880 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelTexGenParameterivSGIS(target)");
2881 }
2882 }
2883
2884
2885
2886 /**********************************************************************/
2887 /***** State management *****/
2888 /**********************************************************************/
2889
2890
2891 /**
2892 * \note This routine refers to derived texture attribute values to
2893 * compute the ENABLE_TEXMAT flags, but is only called on
2894 * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
2895 * flags are updated by _mesa_update_textures(), below.
2896 *
2897 * \param ctx GL context.
2898 */
2899 static void
2900 update_texture_matrices( GLcontext *ctx )
2901 {
2902 GLuint i;
2903
2904 ctx->Texture._TexMatEnabled = 0;
2905
2906 for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
2907 if (_math_matrix_is_dirty(ctx->TextureMatrixStack[i].Top)) {
2908 _math_matrix_analyse( ctx->TextureMatrixStack[i].Top );
2909
2910 if (ctx->Texture.Unit[i]._ReallyEnabled &&
2911 ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY)
2912 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i);
2913
2914 if (ctx->Driver.TextureMatrix)
2915 ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top);
2916 }
2917 }
2918 }
2919
2920
2921
2922
2923 /**
2924 * \note This routine refers to derived texture matrix values to
2925 * compute the ENABLE_TEXMAT flags, but is only called on
2926 * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
2927 * flags are updated by _mesa_update_texture_matrices, above.
2928 *
2929 * \param ctx GL context.
2930 */
2931 static void
2932 update_texture_state( GLcontext *ctx )
2933 {
2934 GLuint unit;
2935
2936 ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are
2937 * actual changes.
2938 */
2939
2940 ctx->Texture._EnabledUnits = 0;
2941 ctx->Texture._GenFlags = 0;
2942 ctx->Texture._TexMatEnabled = 0;
2943 ctx->Texture._TexGenEnabled = 0;
2944
2945 /* Update texture unit state.
2946 * XXX this loop should probably be broken into separate loops for
2947 * texture coord units and texture image units.
2948 */
2949 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
2950 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
2951 GLbitfield enableBits;
2952
2953 texUnit->_Current = NULL;
2954 texUnit->_ReallyEnabled = 0;
2955 texUnit->_GenFlags = 0;
2956
2957 /* Get the bitmask of texture enables */
2958 if (ctx->FragmentProgram._Enabled) {
2959 enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit];
2960 }
2961 else {
2962 if (!texUnit->Enabled)
2963 continue;
2964 enableBits = texUnit->Enabled;
2965 }
2966
2967 /* Look for the highest-priority texture target that's enabled and
2968 * complete. That's the one we'll use for texturing. If we're using
2969 * a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
2970 */
2971 if (enableBits & TEXTURE_CUBE_BIT) {
2972 struct gl_texture_object *texObj = texUnit->CurrentCubeMap;
2973 if (!texObj->Complete) {
2974 _mesa_test_texobj_completeness(ctx, texObj);
2975 }
2976 if (texObj->Complete) {
2977 texUnit->_ReallyEnabled = TEXTURE_CUBE_BIT;
2978 texUnit->_Current = texObj;
2979 }
2980 }
2981
2982 if (!texUnit->_ReallyEnabled && (enableBits & TEXTURE_3D_BIT)) {
2983 struct gl_texture_object *texObj = texUnit->Current3D;
2984 if (!texObj->Complete) {
2985 _mesa_test_texobj_completeness(ctx, texObj);
2986 }
2987 if (texObj->Complete) {
2988 texUnit->_ReallyEnabled = TEXTURE_3D_BIT;
2989 texUnit->_Current = texObj;
2990 }
2991 }
2992
2993 if (!texUnit->_ReallyEnabled && (enableBits & TEXTURE_RECT_BIT)) {
2994 struct gl_texture_object *texObj = texUnit->CurrentRect;
2995 if (!texObj->Complete) {
2996 _mesa_test_texobj_completeness(ctx, texObj);
2997 }
2998 if (texObj->Complete) {
2999 texUnit->_ReallyEnabled = TEXTURE_RECT_BIT;
3000 texUnit->_Current = texObj;
3001 }
3002 }
3003
3004 if (!texUnit->_ReallyEnabled && (enableBits & TEXTURE_2D_BIT)) {
3005 struct gl_texture_object *texObj = texUnit->Current2D;
3006 if (!texObj->Complete) {
3007 _mesa_test_texobj_completeness(ctx, texObj);
3008 }
3009 if (texObj->Complete) {
3010 texUnit->_ReallyEnabled = TEXTURE_2D_BIT;
3011 texUnit->_Current = texObj;
3012 }
3013 }
3014
3015 if (!texUnit->_ReallyEnabled && (enableBits & TEXTURE_1D_BIT)) {
3016 struct gl_texture_object *texObj = texUnit->Current1D;
3017 if (!texObj->Complete) {
3018 _mesa_test_texobj_completeness(ctx, texObj);
3019 }
3020 if (texObj->Complete) {
3021 texUnit->_ReallyEnabled = TEXTURE_1D_BIT;
3022 texUnit->_Current = texObj;
3023 }
3024 }
3025
3026 if (!texUnit->_ReallyEnabled) {
3027 continue;
3028 }
3029
3030 if (texUnit->_ReallyEnabled)
3031 ctx->Texture._EnabledUnits |= (1 << unit);
3032
3033 if (texUnit->EnvMode == GL_COMBINE) {
3034 texUnit->_CurrentCombine = & texUnit->Combine;
3035 }
3036 else {
3037 GLenum format = texUnit->_Current->Image[0][0]->_BaseFormat;
3038 if (format == GL_COLOR_INDEX) {
3039 format = GL_RGBA; /* a bit of a hack */
3040 }
3041 else if (format == GL_DEPTH_COMPONENT
3042 || format == GL_DEPTH_STENCIL_EXT) {
3043 format = texUnit->_Current->DepthMode;
3044 }
3045 calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
3046 texUnit->_CurrentCombine = & texUnit->_EnvMode;
3047 }
3048
3049 switch (texUnit->_CurrentCombine->ModeRGB) {
3050 case GL_REPLACE:
3051 texUnit->_CurrentCombine->_NumArgsRGB = 1;
3052 break;
3053 case GL_MODULATE:
3054 case GL_ADD:
3055 case GL_ADD_SIGNED:
3056 case GL_SUBTRACT:
3057 case GL_DOT3_RGB:
3058 case GL_DOT3_RGBA:
3059 case GL_DOT3_RGB_EXT:
3060 case GL_DOT3_RGBA_EXT:
3061 texUnit->_CurrentCombine->_NumArgsRGB = 2;
3062 break;
3063 case GL_INTERPOLATE:
3064 case GL_MODULATE_ADD_ATI:
3065 case GL_MODULATE_SIGNED_ADD_ATI:
3066 case GL_MODULATE_SUBTRACT_ATI:
3067 texUnit->_CurrentCombine->_NumArgsRGB = 3;
3068 break;
3069 default:
3070 texUnit->_CurrentCombine->_NumArgsRGB = 0;
3071 _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
3072 return;
3073 }
3074
3075 switch (texUnit->_CurrentCombine->ModeA) {
3076 case GL_REPLACE:
3077 texUnit->_CurrentCombine->_NumArgsA = 1;
3078 break;
3079 case GL_MODULATE:
3080 case GL_ADD:
3081 case GL_ADD_SIGNED:
3082 case GL_SUBTRACT:
3083 texUnit->_CurrentCombine->_NumArgsA = 2;
3084 break;
3085 case GL_INTERPOLATE:
3086 case GL_MODULATE_ADD_ATI:
3087 case GL_MODULATE_SIGNED_ADD_ATI:
3088 case GL_MODULATE_SUBTRACT_ATI:
3089 texUnit->_CurrentCombine->_NumArgsA = 3;
3090 break;
3091 default:
3092 texUnit->_CurrentCombine->_NumArgsA = 0;
3093 _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
3094 break;
3095 }
3096
3097 if (texUnit->TexGenEnabled) {
3098 if (texUnit->TexGenEnabled & S_BIT) {
3099 texUnit->_GenFlags |= texUnit->_GenBitS;
3100 }
3101 if (texUnit->TexGenEnabled & T_BIT) {
3102 texUnit->_GenFlags |= texUnit->_GenBitT;
3103 }
3104 if (texUnit->TexGenEnabled & Q_BIT) {
3105 texUnit->_GenFlags |= texUnit->_GenBitQ;
3106 }
3107 if (texUnit->TexGenEnabled & R_BIT) {
3108 texUnit->_GenFlags |= texUnit->_GenBitR;
3109 }
3110
3111 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
3112 ctx->Texture._GenFlags |= texUnit->_GenFlags;
3113 }
3114
3115 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
3116 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
3117 }
3118
3119 ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
3120 /* Fragment programs may need texture coordinates but not the
3121 * corresponding texture images.
3122 */
3123 if (ctx->FragmentProgram._Enabled) {
3124 ctx->Texture._EnabledCoordUnits |=
3125 (ctx->FragmentProgram.Current->InputsRead >> FRAG_ATTRIB_TEX0);
3126 }
3127 }
3128
3129
3130 void _mesa_update_texture( GLcontext *ctx, GLuint new_state )
3131 {
3132 if (new_state & _NEW_TEXTURE_MATRIX)
3133 update_texture_matrices( ctx );
3134
3135 if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
3136 update_texture_state( ctx );
3137 }
3138
3139 /**********************************************************************/
3140 /***** Initialization *****/
3141 /**********************************************************************/
3142
3143 /**
3144 * Allocate the proxy textures for the given context.
3145 *
3146 * \param ctx the context to allocate proxies for.
3147 *
3148 * \return GL_TRUE on success, or GL_FALSE on failure
3149 *
3150 * If run out of memory part way through the allocations, clean up and return
3151 * GL_FALSE.
3152 */
3153 static GLboolean
3154 alloc_proxy_textures( GLcontext *ctx )
3155 {
3156 ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
3157 if (!ctx->Texture.Proxy1D)
3158 goto cleanup;
3159
3160 ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
3161 if (!ctx->Texture.Proxy2D)
3162 goto cleanup;
3163
3164 ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
3165 if (!ctx->Texture.Proxy3D)
3166 goto cleanup;
3167
3168 ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
3169 if (!ctx->Texture.ProxyCubeMap)
3170 goto cleanup;
3171
3172 ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
3173 if (!ctx->Texture.ProxyRect)
3174 goto cleanup;
3175
3176 return GL_TRUE;
3177
3178 cleanup:
3179 if (ctx->Texture.Proxy1D)
3180 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D);
3181 if (ctx->Texture.Proxy2D)
3182 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D);
3183 if (ctx->Texture.Proxy3D)
3184 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D);
3185 if (ctx->Texture.ProxyCubeMap)
3186 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
3187 if (ctx->Texture.ProxyRect)
3188 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
3189 return GL_FALSE;
3190 }
3191
3192
3193 /**
3194 * Initialize a texture unit.
3195 *
3196 * \param ctx GL context.
3197 * \param unit texture unit number to be initialized.
3198 */
3199 static void
3200 init_texture_unit( GLcontext *ctx, GLuint unit )
3201 {
3202 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
3203
3204 texUnit->EnvMode = GL_MODULATE;
3205 ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
3206
3207 texUnit->Combine = default_combine_state;
3208 texUnit->_EnvMode = default_combine_state;
3209 texUnit->_CurrentCombine = & texUnit->_EnvMode;
3210
3211 texUnit->TexGenEnabled = 0;
3212 texUnit->GenModeS = GL_EYE_LINEAR;
3213 texUnit->GenModeT = GL_EYE_LINEAR;
3214 texUnit->GenModeR = GL_EYE_LINEAR;
3215 texUnit->GenModeQ = GL_EYE_LINEAR;
3216 texUnit->_GenBitS = TEXGEN_EYE_LINEAR;
3217 texUnit->_GenBitT = TEXGEN_EYE_LINEAR;
3218 texUnit->_GenBitR = TEXGEN_EYE_LINEAR;
3219 texUnit->_GenBitQ = TEXGEN_EYE_LINEAR;
3220
3221 /* Yes, these plane coefficients are correct! */
3222 ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
3223 ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
3224 ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
3225 ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
3226 ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
3227 ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
3228 ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
3229 ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
3230
3231 texUnit->Current1D = ctx->Shared->Default1D;
3232 texUnit->Current2D = ctx->Shared->Default2D;
3233 texUnit->Current3D = ctx->Shared->Default3D;
3234 texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
3235 texUnit->CurrentRect = ctx->Shared->DefaultRect;
3236 }
3237
3238
3239 GLboolean _mesa_init_texture( GLcontext * ctx )
3240 {
3241 int i;
3242
3243 assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
3244 assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
3245
3246 /* Effectively bind the default textures to all texture units */
3247 ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS;
3248 ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS;
3249 ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS;
3250 ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS;
3251 ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS;
3252
3253 /* Texture group */
3254 ctx->Texture.CurrentUnit = 0; /* multitexture */
3255 ctx->Texture._EnabledUnits = 0;
3256 for (i=0; i<MAX_TEXTURE_UNITS; i++)
3257 init_texture_unit( ctx, i );
3258 ctx->Texture.SharedPalette = GL_FALSE;
3259 _mesa_init_colortable(&ctx->Texture.Palette);
3260
3261 /* Allocate proxy textures */
3262 if (!alloc_proxy_textures( ctx ))
3263 return GL_FALSE;
3264
3265 return GL_TRUE;
3266 }
3267
3268 void _mesa_free_texture_data( GLcontext *ctx )
3269 {
3270 int i;
3271
3272 /* Free proxy texture objects */
3273 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D );
3274 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D );
3275 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D );
3276 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap );
3277 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect );
3278
3279 for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
3280 _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
3281
3282 _mesa_TexEnvProgramCacheDestroy( ctx );
3283 }