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