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