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