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