texparam.c revision 72f0b4a55ba36bb8571b4c11d0098361f766814e
1/*
2 * Mesa 3-D graphics library
3 * Version:  7.5
4 *
5 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6 * Copyright (C) 1999-2009  VMware, Inc.  All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * \file texparam.c
28 *
29 * glTexParameter-related functions
30 */
31
32
33#include "main/glheader.h"
34#include "main/context.h"
35#include "main/enums.h"
36#include "main/colormac.h"
37#include "main/macros.h"
38#include "main/texcompress.h"
39#include "main/texparam.h"
40#include "main/teximage.h"
41#include "shader/prog_instruction.h"
42
43
44/**
45 * Check if a coordinate wrap mode is supported for the texture target.
46 * \return GL_TRUE if legal, GL_FALSE otherwise
47 */
48static GLboolean
49validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
50{
51   const struct gl_extensions * const e = & ctx->Extensions;
52
53   if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
54       (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
55      /* any texture target */
56      return GL_TRUE;
57   }
58   else if (target != GL_TEXTURE_RECTANGLE_NV &&
59	    (wrap == GL_REPEAT ||
60	     (wrap == GL_MIRRORED_REPEAT &&
61	      e->ARB_texture_mirrored_repeat) ||
62	     (wrap == GL_MIRROR_CLAMP_EXT &&
63	      (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
64	     (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
65	      (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
66	     (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
67	      (e->EXT_texture_mirror_clamp)))) {
68      /* non-rectangle texture */
69      return GL_TRUE;
70   }
71
72   _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
73   return GL_FALSE;
74}
75
76
77/**
78 * Get current texture object for given target.
79 * Return NULL if any error.
80 */
81static struct gl_texture_object *
82get_texobj(GLcontext *ctx, GLenum target)
83{
84   struct gl_texture_unit *texUnit;
85
86   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
87      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(current unit)");
88      return NULL;
89   }
90
91   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
92
93   switch (target) {
94   case GL_TEXTURE_1D:
95      return texUnit->Current1D;
96   case GL_TEXTURE_2D:
97      return texUnit->Current2D;
98   case GL_TEXTURE_3D:
99      return texUnit->Current3D;
100   case GL_TEXTURE_CUBE_MAP:
101      if (ctx->Extensions.ARB_texture_cube_map) {
102         return texUnit->CurrentCubeMap;
103      }
104      break;
105   case GL_TEXTURE_RECTANGLE_NV:
106      if (ctx->Extensions.NV_texture_rectangle) {
107         return texUnit->CurrentRect;
108      }
109      break;
110   case GL_TEXTURE_1D_ARRAY_EXT:
111      if (ctx->Extensions.MESA_texture_array) {
112         return texUnit->Current1DArray;
113      }
114      break;
115   case GL_TEXTURE_2D_ARRAY_EXT:
116      if (ctx->Extensions.MESA_texture_array) {
117         return texUnit->Current2DArray;
118      }
119      break;
120   default:
121      ;
122   }
123
124   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(target)");
125   return NULL;
126}
127
128
129/**
130 * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
131 * \return -1 if error.
132 */
133static GLint
134comp_to_swizzle(GLenum comp)
135{
136   switch (comp) {
137   case GL_RED:
138      return SWIZZLE_X;
139   case GL_GREEN:
140      return SWIZZLE_Y;
141   case GL_BLUE:
142      return SWIZZLE_Z;
143   case GL_ALPHA:
144      return SWIZZLE_W;
145   case GL_ZERO:
146      return SWIZZLE_ZERO;
147   case GL_ONE:
148      return SWIZZLE_ONE;
149   default:
150      return -1;
151   }
152}
153
154
155static void
156set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
157{
158   ASSERT(comp < 4);
159   ASSERT(swz <= SWIZZLE_NIL);
160   {
161      GLuint mask = 0x7 << (3 * comp);
162      GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
163      *swizzle = s;
164   }
165}
166
167
168/** Set an integer-valued texture parameter */
169static void
170set_tex_parameteri(GLcontext *ctx,
171                   struct gl_texture_object *texObj,
172                   GLenum pname, const GLint *params)
173{
174   switch (pname) {
175   case GL_TEXTURE_MIN_FILTER:
176      if (texObj->MinFilter == params[0])
177         return;
178      switch (params[0]) {
179      case GL_NEAREST:
180      case GL_LINEAR:
181         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
182         texObj->MinFilter = params[0];
183         return;
184      case GL_NEAREST_MIPMAP_NEAREST:
185      case GL_LINEAR_MIPMAP_NEAREST:
186      case GL_NEAREST_MIPMAP_LINEAR:
187      case GL_LINEAR_MIPMAP_LINEAR:
188         if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
189            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
190            texObj->MinFilter = params[0];
191            return;
192         }
193         /* fall-through */
194      default:
195         _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
196      }
197      return;
198
199   case GL_TEXTURE_MAG_FILTER:
200      if (texObj->MagFilter == params[0])
201         return;
202      switch (params[0]) {
203      case GL_NEAREST:
204      case GL_LINEAR:
205         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
206         texObj->MagFilter = params[0];
207         return;
208      default:
209         _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
210      }
211      return;
212
213   case GL_TEXTURE_WRAP_S:
214      if (texObj->WrapS == params[0])
215         return;
216      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
217         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
218         texObj->WrapS = params[0];
219      }
220      return;
221
222   case GL_TEXTURE_WRAP_T:
223      if (texObj->WrapT == params[0])
224         return;
225      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
226         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
227         texObj->WrapT = params[0];
228      }
229      return;
230
231   case GL_TEXTURE_WRAP_R:
232      if (texObj->WrapR == params[0])
233         return;
234      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
235         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
236         texObj->WrapR = params[0];
237      }
238      return;
239
240   case GL_TEXTURE_BASE_LEVEL:
241      if (texObj->BaseLevel == params[0])
242         return;
243      if (params[0] < 0 ||
244          (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
245         _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
246         return;
247      }
248      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
249      texObj->BaseLevel = params[0];
250      return;
251
252   case GL_TEXTURE_MAX_LEVEL:
253      if (texObj->MaxLevel == params[0])
254         return;
255      if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
256         _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)");
257         return;
258      }
259      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
260      texObj->MaxLevel = params[0];
261      return;
262
263   case GL_TEXTURE_COMPARE_SGIX:
264      if (ctx->Extensions.SGIX_shadow) {
265         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
266         texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
267      }
268      else {
269         _mesa_error(ctx, GL_INVALID_ENUM,
270                     "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
271      }
272      return;
273
274   case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
275      if (ctx->Extensions.SGIX_shadow &&
276          (params[0] == GL_TEXTURE_LEQUAL_R_SGIX ||
277           params[0] == GL_TEXTURE_GEQUAL_R_SGIX)) {
278         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
279         texObj->CompareOperator = params[0];
280      }
281      else {
282         _mesa_error(ctx, GL_INVALID_ENUM,
283                     "glTexParameter(GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
284      }
285      return;
286
287   case GL_GENERATE_MIPMAP_SGIS:
288      if (ctx->Extensions.SGIS_generate_mipmap) {
289         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
290         texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
291      }
292      else {
293         _mesa_error(ctx, GL_INVALID_ENUM,
294                     "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
295      }
296      return;
297
298   case GL_TEXTURE_COMPARE_MODE_ARB:
299      if (ctx->Extensions.ARB_shadow &&
300          (params[0] == GL_NONE ||
301           params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) {
302         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
303         texObj->CompareMode = params[0];
304      }
305      else {
306         _mesa_error(ctx, GL_INVALID_ENUM,
307                     "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)");
308      }
309      return;
310
311   case GL_TEXTURE_COMPARE_FUNC_ARB:
312      if (ctx->Extensions.ARB_shadow) {
313         switch (params[0]) {
314         case GL_LEQUAL:
315         case GL_GEQUAL:
316            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
317            texObj->CompareFunc = params[0];
318            return;
319         case GL_EQUAL:
320         case GL_NOTEQUAL:
321         case GL_LESS:
322         case GL_GREATER:
323         case GL_ALWAYS:
324         case GL_NEVER:
325            if (ctx->Extensions.EXT_shadow_funcs) {
326               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
327               texObj->CompareFunc = params[0];
328               return;
329            }
330            /* fall-through */
331         default:
332            _mesa_error(ctx, GL_INVALID_ENUM,
333                        "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)");
334         }
335      }
336      else {
337         _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
338      }
339      return;
340
341   case GL_DEPTH_TEXTURE_MODE_ARB:
342      if (ctx->Extensions.ARB_depth_texture &&
343          (params[0] == GL_LUMINANCE ||
344           params[0] == GL_INTENSITY ||
345           params[0] == GL_ALPHA)) {
346         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
347         texObj->DepthMode = params[0];
348      }
349      else {
350         _mesa_error(ctx, GL_INVALID_ENUM,
351                     "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)");
352      }
353      return;
354
355#ifdef FEATURE_OES_draw_texture
356   case GL_TEXTURE_CROP_RECT_OES:
357      texObj->CropRect[0] = params[0];
358      texObj->CropRect[1] = params[1];
359      texObj->CropRect[2] = params[2];
360      texObj->CropRect[3] = params[3];
361      return;
362#endif
363
364   case GL_TEXTURE_SWIZZLE_R_EXT:
365   case GL_TEXTURE_SWIZZLE_G_EXT:
366   case GL_TEXTURE_SWIZZLE_B_EXT:
367   case GL_TEXTURE_SWIZZLE_A_EXT:
368      if (ctx->Extensions.EXT_texture_swizzle) {
369         const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
370         const GLint swz = comp_to_swizzle(params[0]);
371         if (swz < 0) {
372            _mesa_error(ctx, GL_INVALID_OPERATION,
373                        "glTexParameter(swizzle 0x%x)", params[0]);
374            return;
375         }
376         ASSERT(comp < 4);
377         if (swz >= 0) {
378            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
379            texObj->Swizzle[comp] = params[0];
380            set_swizzle_component(&texObj->_Swizzle, comp, swz);
381            return;
382         }
383      }
384      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
385      return;
386
387   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
388      if (ctx->Extensions.EXT_texture_swizzle) {
389         GLuint comp;
390         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
391         for (comp = 0; comp < 4; comp++) {
392            const GLint swz = comp_to_swizzle(params[comp]);
393            if (swz >= 0) {
394               texObj->Swizzle[comp] = params[comp];
395               set_swizzle_component(&texObj->_Swizzle, comp, swz);
396            }
397            else {
398               _mesa_error(ctx, GL_INVALID_OPERATION,
399                           "glTexParameter(swizzle 0x%x)", params[comp]);
400               return;
401            }
402         }
403         return;
404      }
405      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
406      return;
407
408   default:
409      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
410   }
411}
412
413
414/** Set a float-valued texture parameter */
415static void
416set_tex_parameterf(GLcontext *ctx,
417                   struct gl_texture_object *texObj,
418                   GLenum pname, const GLfloat *params)
419{
420   switch (pname) {
421   case GL_TEXTURE_MIN_LOD:
422      if (texObj->MinLod == params[0])
423         return;
424      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
425      texObj->MinLod = params[0];
426      return;
427
428   case GL_TEXTURE_MAX_LOD:
429      if (texObj->MaxLod == params[0])
430         return;
431      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
432      texObj->MaxLod = params[0];
433      return;
434
435   case GL_TEXTURE_PRIORITY:
436      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
437      texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
438      return;
439
440   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
441      if (ctx->Extensions.EXT_texture_filter_anisotropic) {
442         if (params[0] < 1.0) {
443            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
444            return;
445         }
446         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
447         /* clamp to max, that's what NVIDIA does */
448         texObj->MaxAnisotropy = MIN2(params[0],
449                                      ctx->Const.MaxTextureMaxAnisotropy);
450      }
451      else {
452         _mesa_error(ctx, GL_INVALID_ENUM,
453                     "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
454      }
455      return;
456
457   case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
458      if (ctx->Extensions.SGIX_shadow_ambient) {
459         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
460         texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F);
461      }
462      else {
463         _mesa_error(ctx, GL_INVALID_ENUM,
464                     "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
465      }
466      return;
467
468   case GL_TEXTURE_LOD_BIAS:
469      /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
470      if (ctx->Extensions.EXT_texture_lod_bias) {
471         if (texObj->LodBias != params[0]) {
472            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
473            texObj->LodBias = params[0];
474         }
475      }
476      break;
477
478   case GL_TEXTURE_BORDER_COLOR:
479      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
480      texObj->BorderColor[RCOMP] = params[0];
481      texObj->BorderColor[GCOMP] = params[1];
482      texObj->BorderColor[BCOMP] = params[2];
483      texObj->BorderColor[ACOMP] = params[3];
484      UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
485      UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
486      UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
487      UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
488      return;
489
490   default:
491      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
492   }
493}
494
495
496void GLAPIENTRY
497_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
498{
499   struct gl_texture_object *texObj;
500   GET_CURRENT_CONTEXT(ctx);
501   ASSERT_OUTSIDE_BEGIN_END(ctx);
502
503   texObj = get_texobj(ctx, target);
504   if (!texObj)
505      return;
506
507   switch (pname) {
508   case GL_TEXTURE_MIN_FILTER:
509   case GL_TEXTURE_MAG_FILTER:
510   case GL_TEXTURE_WRAP_S:
511   case GL_TEXTURE_WRAP_T:
512   case GL_TEXTURE_WRAP_R:
513   case GL_TEXTURE_BASE_LEVEL:
514   case GL_TEXTURE_MAX_LEVEL:
515   case GL_TEXTURE_COMPARE_SGIX:
516   case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
517   case GL_GENERATE_MIPMAP_SGIS:
518   case GL_TEXTURE_COMPARE_MODE_ARB:
519   case GL_TEXTURE_COMPARE_FUNC_ARB:
520   case GL_DEPTH_TEXTURE_MODE_ARB:
521      {
522         /* convert float param to int */
523         GLint p = (GLint) param;
524         set_tex_parameteri(ctx, texObj, pname, &p);
525      }
526      return;
527   default:
528      /* this will generate an error if pname is illegal */
529      set_tex_parameterf(ctx, texObj, pname, &param);
530   }
531
532   texObj->_Complete = GL_FALSE;
533
534   if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
535      ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
536   }
537}
538
539
540void GLAPIENTRY
541_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
542{
543   struct gl_texture_object *texObj;
544   GET_CURRENT_CONTEXT(ctx);
545   ASSERT_OUTSIDE_BEGIN_END(ctx);
546
547   texObj = get_texobj(ctx, target);
548   if (!texObj)
549      return;
550
551   switch (pname) {
552   case GL_TEXTURE_MIN_FILTER:
553   case GL_TEXTURE_MAG_FILTER:
554   case GL_TEXTURE_WRAP_S:
555   case GL_TEXTURE_WRAP_T:
556   case GL_TEXTURE_WRAP_R:
557   case GL_TEXTURE_BASE_LEVEL:
558   case GL_TEXTURE_MAX_LEVEL:
559   case GL_TEXTURE_COMPARE_SGIX:
560   case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
561   case GL_GENERATE_MIPMAP_SGIS:
562   case GL_TEXTURE_COMPARE_MODE_ARB:
563   case GL_TEXTURE_COMPARE_FUNC_ARB:
564   case GL_DEPTH_TEXTURE_MODE_ARB:
565      {
566         /* convert float param to int */
567         GLint p = (GLint) params[0];
568         set_tex_parameteri(ctx, texObj, pname, &p);
569      }
570      break;
571
572#ifdef FEATURE_OES_draw_texture
573   case GL_TEXTURE_CROP_RECT_OES:
574      {
575         /* convert float params to int */
576         GLint iparams[4];
577         iparams[0] = (GLint) params[0];
578         iparams[1] = (GLint) params[1];
579         iparams[2] = (GLint) params[2];
580         iparams[3] = (GLint) params[3];
581         set_tex_parameteri(ctx, target, iparams);
582      }
583      break;
584#endif
585
586   default:
587      /* this will generate an error if pname is illegal */
588      set_tex_parameterf(ctx, texObj, pname, params);
589   }
590
591   texObj->_Complete = GL_FALSE;
592
593   if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
594      ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
595   }
596}
597
598
599void GLAPIENTRY
600_mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
601{
602   struct gl_texture_object *texObj;
603   GET_CURRENT_CONTEXT(ctx);
604   ASSERT_OUTSIDE_BEGIN_END(ctx);
605
606   texObj = get_texobj(ctx, target);
607   if (!texObj)
608      return;
609
610   switch (pname) {
611   case GL_TEXTURE_MIN_LOD:
612   case GL_TEXTURE_MAX_LOD:
613   case GL_TEXTURE_PRIORITY:
614   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
615   case GL_TEXTURE_LOD_BIAS:
616   case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
617      {
618         GLfloat fparam = (GLfloat) param;
619         /* convert int param to float */
620         set_tex_parameterf(ctx, texObj, pname, &fparam);
621      }
622      break;
623   default:
624      /* this will generate an error if pname is illegal */
625      set_tex_parameteri(ctx, texObj, pname, &param);
626   }
627
628   texObj->_Complete = GL_FALSE;
629
630   if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
631      GLfloat fparam = (GLfloat) param;
632      ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
633   }
634}
635
636
637void GLAPIENTRY
638_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
639{
640   struct gl_texture_object *texObj;
641   GET_CURRENT_CONTEXT(ctx);
642   ASSERT_OUTSIDE_BEGIN_END(ctx);
643
644   texObj = get_texobj(ctx, target);
645   if (!texObj)
646      return;
647
648   switch (pname) {
649   case GL_TEXTURE_BORDER_COLOR:
650      {
651         /* convert int params to float */
652         GLfloat fparams[4];
653         fparams[0] = INT_TO_FLOAT(params[0]);
654         fparams[1] = INT_TO_FLOAT(params[1]);
655         fparams[2] = INT_TO_FLOAT(params[2]);
656         fparams[3] = INT_TO_FLOAT(params[3]);
657         set_tex_parameterf(ctx, texObj, pname, fparams);
658      }
659      break;
660   case GL_TEXTURE_MIN_LOD:
661   case GL_TEXTURE_MAX_LOD:
662   case GL_TEXTURE_PRIORITY:
663   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
664   case GL_TEXTURE_LOD_BIAS:
665   case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
666      {
667         /* convert int param to float */
668         GLfloat fparam = (GLfloat) params[0];
669         set_tex_parameterf(ctx, texObj, pname, &fparam);
670      }
671      break;
672   default:
673      /* this will generate an error if pname is illegal */
674      set_tex_parameteri(ctx, texObj, pname, params);
675   }
676
677   texObj->_Complete = GL_FALSE;
678
679   if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
680      GLfloat fparams[4];
681      fparams[0] = INT_TO_FLOAT(params[0]);
682      if (pname == GL_TEXTURE_BORDER_COLOR ||
683          pname == GL_TEXTURE_CROP_RECT_OES) {
684         fparams[1] = INT_TO_FLOAT(params[1]);
685         fparams[2] = INT_TO_FLOAT(params[2]);
686         fparams[3] = INT_TO_FLOAT(params[3]);
687      }
688      ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
689   }
690}
691
692
693void GLAPIENTRY
694_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
695                              GLenum pname, GLfloat *params )
696{
697   GLint iparam;
698   _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
699   *params = (GLfloat) iparam;
700}
701
702
703static GLuint
704tex_image_dimensions(GLcontext *ctx, GLenum target)
705{
706   switch (target) {
707      case GL_TEXTURE_1D:
708      case GL_PROXY_TEXTURE_1D:
709         return 1;
710      case GL_TEXTURE_2D:
711      case GL_PROXY_TEXTURE_2D:
712         return 2;
713      case GL_TEXTURE_3D:
714      case GL_PROXY_TEXTURE_3D:
715         return 3;
716      case GL_TEXTURE_CUBE_MAP:
717      case GL_PROXY_TEXTURE_CUBE_MAP:
718      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
719      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
720      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
721      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
722      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
723      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
724         return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
725      case GL_TEXTURE_RECTANGLE_NV:
726      case GL_PROXY_TEXTURE_RECTANGLE_NV:
727         return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
728      case GL_TEXTURE_1D_ARRAY_EXT:
729      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
730         return ctx->Extensions.MESA_texture_array ? 2 : 0;
731      case GL_TEXTURE_2D_ARRAY_EXT:
732      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
733         return ctx->Extensions.MESA_texture_array ? 3 : 0;
734      default:
735         _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
736         return 0;
737   }
738}
739
740
741void GLAPIENTRY
742_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
743                              GLenum pname, GLint *params )
744{
745   const struct gl_texture_unit *texUnit;
746   struct gl_texture_object *texObj;
747   const struct gl_texture_image *img = NULL;
748   GLuint dimensions;
749   GLboolean isProxy;
750   GLint maxLevels;
751   GET_CURRENT_CONTEXT(ctx);
752   ASSERT_OUTSIDE_BEGIN_END(ctx);
753
754   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
755      _mesa_error(ctx, GL_INVALID_OPERATION,
756                  "glGetTexLevelParameteriv(current unit)");
757      return;
758   }
759
760   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
761
762   /* this will catch bad target values */
763   dimensions = tex_image_dimensions(ctx, target);  /* 1, 2 or 3 */
764   if (dimensions == 0) {
765      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
766      return;
767   }
768
769   maxLevels = _mesa_max_texture_levels(ctx, target);
770   if (maxLevels == 0) {
771      /* should not happen since <target> was just checked above */
772      _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
773      return;
774   }
775
776   if (level < 0 || level >= maxLevels) {
777      _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
778      return;
779   }
780
781   texObj = _mesa_select_tex_object(ctx, texUnit, target);
782   _mesa_lock_texture(ctx, texObj);
783
784   img = _mesa_select_tex_image(ctx, texObj, target, level);
785   if (!img || !img->TexFormat) {
786      /* undefined texture image */
787      if (pname == GL_TEXTURE_COMPONENTS)
788         *params = 1;
789      else
790         *params = 0;
791      goto out;
792   }
793
794   isProxy = _mesa_is_proxy_texture(target);
795
796   switch (pname) {
797      case GL_TEXTURE_WIDTH:
798         *params = img->Width;
799         break;
800      case GL_TEXTURE_HEIGHT:
801         *params = img->Height;
802         break;
803      case GL_TEXTURE_DEPTH:
804         *params = img->Depth;
805         break;
806      case GL_TEXTURE_INTERNAL_FORMAT:
807         *params = img->InternalFormat;
808         break;
809      case GL_TEXTURE_BORDER:
810         *params = img->Border;
811         break;
812      case GL_TEXTURE_RED_SIZE:
813         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
814            *params = img->TexFormat->RedBits;
815         else
816            *params = 0;
817         break;
818      case GL_TEXTURE_GREEN_SIZE:
819         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
820            *params = img->TexFormat->GreenBits;
821         else
822            *params = 0;
823         break;
824      case GL_TEXTURE_BLUE_SIZE:
825         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
826            *params = img->TexFormat->BlueBits;
827         else
828            *params = 0;
829         break;
830      case GL_TEXTURE_ALPHA_SIZE:
831         if (img->_BaseFormat == GL_ALPHA ||
832             img->_BaseFormat == GL_LUMINANCE_ALPHA ||
833             img->_BaseFormat == GL_RGBA)
834            *params = img->TexFormat->AlphaBits;
835         else
836            *params = 0;
837         break;
838      case GL_TEXTURE_INTENSITY_SIZE:
839         if (img->_BaseFormat != GL_INTENSITY)
840            *params = 0;
841         else if (img->TexFormat->IntensityBits > 0)
842            *params = img->TexFormat->IntensityBits;
843         else /* intensity probably stored as rgb texture */
844            *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
845         break;
846      case GL_TEXTURE_LUMINANCE_SIZE:
847         if (img->_BaseFormat != GL_LUMINANCE &&
848             img->_BaseFormat != GL_LUMINANCE_ALPHA)
849            *params = 0;
850         else if (img->TexFormat->LuminanceBits > 0)
851            *params = img->TexFormat->LuminanceBits;
852         else /* luminance probably stored as rgb texture */
853            *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
854         break;
855      case GL_TEXTURE_INDEX_SIZE_EXT:
856         if (img->_BaseFormat == GL_COLOR_INDEX)
857            *params = img->TexFormat->IndexBits;
858         else
859            *params = 0;
860         break;
861      case GL_TEXTURE_DEPTH_SIZE_ARB:
862         if (ctx->Extensions.ARB_depth_texture)
863            *params = img->TexFormat->DepthBits;
864         else
865            _mesa_error(ctx, GL_INVALID_ENUM,
866                        "glGetTexLevelParameter[if]v(pname)");
867         break;
868      case GL_TEXTURE_STENCIL_SIZE_EXT:
869         if (ctx->Extensions.EXT_packed_depth_stencil) {
870            *params = img->TexFormat->StencilBits;
871         }
872         else {
873            _mesa_error(ctx, GL_INVALID_ENUM,
874                        "glGetTexLevelParameter[if]v(pname)");
875         }
876         break;
877
878      /* GL_ARB_texture_compression */
879      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
880         if (ctx->Extensions.ARB_texture_compression) {
881            if (img->IsCompressed && !isProxy) {
882               /* Don't use ctx->Driver.CompressedTextureSize() since that
883                * may returned a padded hardware size.
884                */
885               *params = _mesa_compressed_texture_size(ctx, img->Width,
886                                                   img->Height, img->Depth,
887                                                   img->TexFormat->MesaFormat);
888            }
889            else {
890               _mesa_error(ctx, GL_INVALID_OPERATION,
891                           "glGetTexLevelParameter[if]v(pname)");
892            }
893         }
894         else {
895            _mesa_error(ctx, GL_INVALID_ENUM,
896                        "glGetTexLevelParameter[if]v(pname)");
897         }
898         break;
899      case GL_TEXTURE_COMPRESSED:
900         if (ctx->Extensions.ARB_texture_compression) {
901            *params = (GLint) img->IsCompressed;
902         }
903         else {
904            _mesa_error(ctx, GL_INVALID_ENUM,
905                        "glGetTexLevelParameter[if]v(pname)");
906         }
907         break;
908
909      /* GL_ARB_texture_float */
910      case GL_TEXTURE_RED_TYPE_ARB:
911         if (ctx->Extensions.ARB_texture_float) {
912            *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
913         }
914         else {
915            _mesa_error(ctx, GL_INVALID_ENUM,
916                        "glGetTexLevelParameter[if]v(pname)");
917         }
918         break;
919      case GL_TEXTURE_GREEN_TYPE_ARB:
920         if (ctx->Extensions.ARB_texture_float) {
921            *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
922         }
923         else {
924            _mesa_error(ctx, GL_INVALID_ENUM,
925                        "glGetTexLevelParameter[if]v(pname)");
926         }
927         break;
928      case GL_TEXTURE_BLUE_TYPE_ARB:
929         if (ctx->Extensions.ARB_texture_float) {
930            *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
931         }
932         else {
933            _mesa_error(ctx, GL_INVALID_ENUM,
934                        "glGetTexLevelParameter[if]v(pname)");
935         }
936         break;
937      case GL_TEXTURE_ALPHA_TYPE_ARB:
938         if (ctx->Extensions.ARB_texture_float) {
939            *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
940         }
941         else {
942            _mesa_error(ctx, GL_INVALID_ENUM,
943                        "glGetTexLevelParameter[if]v(pname)");
944         }
945         break;
946      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
947         if (ctx->Extensions.ARB_texture_float) {
948            *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
949         }
950         else {
951            _mesa_error(ctx, GL_INVALID_ENUM,
952                        "glGetTexLevelParameter[if]v(pname)");
953         }
954         break;
955      case GL_TEXTURE_INTENSITY_TYPE_ARB:
956         if (ctx->Extensions.ARB_texture_float) {
957            *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE;
958         }
959         else {
960            _mesa_error(ctx, GL_INVALID_ENUM,
961                        "glGetTexLevelParameter[if]v(pname)");
962         }
963         break;
964      case GL_TEXTURE_DEPTH_TYPE_ARB:
965         if (ctx->Extensions.ARB_texture_float) {
966            *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
967         }
968         else {
969            _mesa_error(ctx, GL_INVALID_ENUM,
970                        "glGetTexLevelParameter[if]v(pname)");
971         }
972         break;
973
974      default:
975         _mesa_error(ctx, GL_INVALID_ENUM,
976                     "glGetTexLevelParameter[if]v(pname)");
977   }
978
979 out:
980   _mesa_unlock_texture(ctx, texObj);
981}
982
983
984
985void GLAPIENTRY
986_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
987{
988   struct gl_texture_unit *texUnit;
989   struct gl_texture_object *obj;
990   GLboolean error = GL_FALSE;
991   GET_CURRENT_CONTEXT(ctx);
992   ASSERT_OUTSIDE_BEGIN_END(ctx);
993
994   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
995      _mesa_error(ctx, GL_INVALID_OPERATION,
996                  "glGetTexParameterfv(current unit)");
997      return;
998   }
999
1000   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1001
1002   obj = _mesa_select_tex_object(ctx, texUnit, target);
1003   if (!obj) {
1004      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
1005      return;
1006   }
1007
1008   _mesa_lock_texture(ctx, obj);
1009   switch (pname) {
1010      case GL_TEXTURE_MAG_FILTER:
1011	 *params = ENUM_TO_FLOAT(obj->MagFilter);
1012	 break;
1013      case GL_TEXTURE_MIN_FILTER:
1014         *params = ENUM_TO_FLOAT(obj->MinFilter);
1015         break;
1016      case GL_TEXTURE_WRAP_S:
1017         *params = ENUM_TO_FLOAT(obj->WrapS);
1018         break;
1019      case GL_TEXTURE_WRAP_T:
1020         *params = ENUM_TO_FLOAT(obj->WrapT);
1021         break;
1022      case GL_TEXTURE_WRAP_R:
1023         *params = ENUM_TO_FLOAT(obj->WrapR);
1024         break;
1025      case GL_TEXTURE_BORDER_COLOR:
1026         params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
1027         params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
1028         params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
1029         params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
1030         break;
1031      case GL_TEXTURE_RESIDENT:
1032         {
1033            GLboolean resident;
1034            if (ctx->Driver.IsTextureResident)
1035               resident = ctx->Driver.IsTextureResident(ctx, obj);
1036            else
1037               resident = GL_TRUE;
1038            *params = ENUM_TO_FLOAT(resident);
1039         }
1040         break;
1041      case GL_TEXTURE_PRIORITY:
1042         *params = obj->Priority;
1043         break;
1044      case GL_TEXTURE_MIN_LOD:
1045         *params = obj->MinLod;
1046         break;
1047      case GL_TEXTURE_MAX_LOD:
1048         *params = obj->MaxLod;
1049         break;
1050      case GL_TEXTURE_BASE_LEVEL:
1051         *params = (GLfloat) obj->BaseLevel;
1052         break;
1053      case GL_TEXTURE_MAX_LEVEL:
1054         *params = (GLfloat) obj->MaxLevel;
1055         break;
1056      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1057         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1058            *params = obj->MaxAnisotropy;
1059         }
1060	 else
1061	    error = GL_TRUE;
1062         break;
1063      case GL_TEXTURE_COMPARE_SGIX:
1064         if (ctx->Extensions.SGIX_shadow) {
1065            *params = (GLfloat) obj->CompareFlag;
1066         }
1067	 else
1068	    error = GL_TRUE;
1069         break;
1070      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1071         if (ctx->Extensions.SGIX_shadow) {
1072            *params = (GLfloat) obj->CompareOperator;
1073         }
1074	 else
1075	    error = GL_TRUE;
1076         break;
1077      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1078         if (ctx->Extensions.SGIX_shadow_ambient) {
1079            *params = obj->ShadowAmbient;
1080         }
1081	 else
1082	    error = GL_TRUE;
1083         break;
1084      case GL_GENERATE_MIPMAP_SGIS:
1085         if (ctx->Extensions.SGIS_generate_mipmap) {
1086            *params = (GLfloat) obj->GenerateMipmap;
1087         }
1088	 else
1089	    error = GL_TRUE;
1090         break;
1091      case GL_TEXTURE_COMPARE_MODE_ARB:
1092         if (ctx->Extensions.ARB_shadow) {
1093            *params = (GLfloat) obj->CompareMode;
1094         }
1095	 else
1096	    error = GL_TRUE;
1097         break;
1098      case GL_TEXTURE_COMPARE_FUNC_ARB:
1099         if (ctx->Extensions.ARB_shadow) {
1100            *params = (GLfloat) obj->CompareFunc;
1101         }
1102	 else
1103	    error = GL_TRUE;
1104         break;
1105      case GL_DEPTH_TEXTURE_MODE_ARB:
1106         if (ctx->Extensions.ARB_depth_texture) {
1107            *params = (GLfloat) obj->DepthMode;
1108         }
1109	 else
1110	    error = GL_TRUE;
1111         break;
1112      case GL_TEXTURE_LOD_BIAS:
1113         if (ctx->Extensions.EXT_texture_lod_bias) {
1114            *params = obj->LodBias;
1115         }
1116	 else
1117	    error = GL_TRUE;
1118         break;
1119#ifdef FEATURE_OES_draw_texture
1120      case GL_TEXTURE_CROP_RECT_OES:
1121         params[0] = obj->CropRect[0];
1122         params[1] = obj->CropRect[1];
1123         params[2] = obj->CropRect[2];
1124         params[3] = obj->CropRect[3];
1125         break;
1126#endif
1127
1128      case GL_TEXTURE_SWIZZLE_R_EXT:
1129      case GL_TEXTURE_SWIZZLE_G_EXT:
1130      case GL_TEXTURE_SWIZZLE_B_EXT:
1131      case GL_TEXTURE_SWIZZLE_A_EXT:
1132         if (ctx->Extensions.EXT_texture_swizzle) {
1133            GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
1134            *params = (GLfloat) obj->Swizzle[comp];
1135         }
1136         else {
1137            error = GL_TRUE;
1138         }
1139         break;
1140
1141      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1142         if (ctx->Extensions.EXT_texture_swizzle) {
1143            GLuint comp;
1144            for (comp = 0; comp < 4; comp++) {
1145               params[comp] = (GLfloat) obj->Swizzle[comp];
1146            }
1147         }
1148         else {
1149            error = GL_TRUE;
1150         }
1151         break;
1152
1153      default:
1154	 error = GL_TRUE;
1155	 break;
1156   }
1157
1158   if (error)
1159      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
1160		  pname);
1161
1162   _mesa_unlock_texture(ctx, obj);
1163}
1164
1165
1166void GLAPIENTRY
1167_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1168{
1169   struct gl_texture_unit *texUnit;
1170   struct gl_texture_object *obj;
1171   GLboolean error = GL_FALSE;
1172   GET_CURRENT_CONTEXT(ctx);
1173   ASSERT_OUTSIDE_BEGIN_END(ctx);
1174
1175   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
1176      _mesa_error(ctx, GL_INVALID_OPERATION,
1177                  "glGetTexParameteriv(current unit)");
1178      return;
1179   }
1180
1181   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1182
1183   obj = _mesa_select_tex_object(ctx, texUnit, target);
1184   if (!obj) {
1185      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
1186      return;
1187   }
1188
1189   switch (pname) {
1190      case GL_TEXTURE_MAG_FILTER:
1191         *params = (GLint) obj->MagFilter;
1192         break;;
1193      case GL_TEXTURE_MIN_FILTER:
1194         *params = (GLint) obj->MinFilter;
1195         break;;
1196      case GL_TEXTURE_WRAP_S:
1197         *params = (GLint) obj->WrapS;
1198         break;;
1199      case GL_TEXTURE_WRAP_T:
1200         *params = (GLint) obj->WrapT;
1201         break;;
1202      case GL_TEXTURE_WRAP_R:
1203         *params = (GLint) obj->WrapR;
1204         break;;
1205      case GL_TEXTURE_BORDER_COLOR:
1206         {
1207            GLfloat b[4];
1208            b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
1209            b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
1210            b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
1211            b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
1212            params[0] = FLOAT_TO_INT(b[0]);
1213            params[1] = FLOAT_TO_INT(b[1]);
1214            params[2] = FLOAT_TO_INT(b[2]);
1215            params[3] = FLOAT_TO_INT(b[3]);
1216         }
1217         break;;
1218      case GL_TEXTURE_RESIDENT:
1219         {
1220            GLboolean resident;
1221            if (ctx->Driver.IsTextureResident)
1222               resident = ctx->Driver.IsTextureResident(ctx, obj);
1223            else
1224               resident = GL_TRUE;
1225            *params = (GLint) resident;
1226         }
1227         break;;
1228      case GL_TEXTURE_PRIORITY:
1229         *params = FLOAT_TO_INT(obj->Priority);
1230         break;;
1231      case GL_TEXTURE_MIN_LOD:
1232         *params = (GLint) obj->MinLod;
1233         break;;
1234      case GL_TEXTURE_MAX_LOD:
1235         *params = (GLint) obj->MaxLod;
1236         break;;
1237      case GL_TEXTURE_BASE_LEVEL:
1238         *params = obj->BaseLevel;
1239         break;;
1240      case GL_TEXTURE_MAX_LEVEL:
1241         *params = obj->MaxLevel;
1242         break;;
1243      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1244         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1245            *params = (GLint) obj->MaxAnisotropy;
1246         }
1247         else {
1248            error = GL_TRUE;
1249         }
1250         break;
1251      case GL_TEXTURE_COMPARE_SGIX:
1252         if (ctx->Extensions.SGIX_shadow) {
1253            *params = (GLint) obj->CompareFlag;
1254         }
1255         else {
1256            error = GL_TRUE;
1257         }
1258         break;
1259      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1260         if (ctx->Extensions.SGIX_shadow) {
1261            *params = (GLint) obj->CompareOperator;
1262         }
1263         else {
1264            error = GL_TRUE;
1265         }
1266         break;
1267      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1268         if (ctx->Extensions.SGIX_shadow_ambient) {
1269            *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
1270         }
1271         else {
1272            error = GL_TRUE;
1273         }
1274         break;
1275      case GL_GENERATE_MIPMAP_SGIS:
1276         if (ctx->Extensions.SGIS_generate_mipmap) {
1277            *params = (GLint) obj->GenerateMipmap;
1278         }
1279         else {
1280            error = GL_TRUE;
1281         }
1282         break;
1283      case GL_TEXTURE_COMPARE_MODE_ARB:
1284         if (ctx->Extensions.ARB_shadow) {
1285            *params = (GLint) obj->CompareMode;
1286         }
1287         else {
1288            error = GL_TRUE;
1289         }
1290         break;
1291      case GL_TEXTURE_COMPARE_FUNC_ARB:
1292         if (ctx->Extensions.ARB_shadow) {
1293            *params = (GLint) obj->CompareFunc;
1294         }
1295         else {
1296            error = GL_TRUE;
1297         }
1298         break;
1299      case GL_DEPTH_TEXTURE_MODE_ARB:
1300         if (ctx->Extensions.ARB_depth_texture) {
1301            *params = (GLint) obj->DepthMode;
1302         }
1303         else {
1304            error = GL_TRUE;
1305         }
1306         break;
1307      case GL_TEXTURE_LOD_BIAS:
1308         if (ctx->Extensions.EXT_texture_lod_bias) {
1309            *params = (GLint) obj->LodBias;
1310         }
1311         else {
1312            error = GL_TRUE;
1313         }
1314         break;
1315#ifdef FEATURE_OES_draw_texture
1316      case GL_TEXTURE_CROP_RECT_OES:
1317         params[0] = obj->CropRect[0];
1318         params[1] = obj->CropRect[1];
1319         params[2] = obj->CropRect[2];
1320         params[3] = obj->CropRect[3];
1321         break;
1322#endif
1323      case GL_TEXTURE_SWIZZLE_R_EXT:
1324      case GL_TEXTURE_SWIZZLE_G_EXT:
1325      case GL_TEXTURE_SWIZZLE_B_EXT:
1326      case GL_TEXTURE_SWIZZLE_A_EXT:
1327         if (ctx->Extensions.EXT_texture_swizzle) {
1328            GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
1329            *params = obj->Swizzle[comp];
1330         }
1331         else {
1332            error = GL_TRUE;
1333         }
1334         break;
1335
1336      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1337         if (ctx->Extensions.EXT_texture_swizzle) {
1338            COPY_4V(params, obj->Swizzle);
1339         }
1340         else {
1341            error = GL_TRUE;
1342         }
1343         break;
1344
1345      default:
1346         ; /* silence warnings */
1347   }
1348
1349   if (error)
1350      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)",
1351		  pname);
1352
1353   _mesa_unlock_texture(ctx, obj);
1354}
1355