OSDN Git Service

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