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