OSDN Git Service

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