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