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