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