OSDN Git Service

mesa: Change "BRIAN PAUL" to "THE AUTHORS" in license text.
[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  * THE AUTHORS 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 #include <stdbool.h>
33 #include "main/glheader.h"
34 #include "main/blend.h"
35 #include "main/colormac.h"
36 #include "main/context.h"
37 #include "main/enums.h"
38 #include "main/formats.h"
39 #include "main/glformats.h"
40 #include "main/macros.h"
41 #include "main/mtypes.h"
42 #include "main/state.h"
43 #include "main/texcompress.h"
44 #include "main/texobj.h"
45 #include "main/texparam.h"
46 #include "main/teximage.h"
47 #include "main/texstate.h"
48 #include "program/prog_instruction.h"
49
50
51 /**
52  * Check if a coordinate wrap mode is supported for the texture target.
53  * \return GL_TRUE if legal, GL_FALSE otherwise
54  */
55 static GLboolean 
56 validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
57 {
58    const struct gl_extensions * const e = & ctx->Extensions;
59    const bool is_desktop_gl = _mesa_is_desktop_gl(ctx);
60    bool supported;
61
62    switch (wrap) {
63    case GL_CLAMP:
64       /* GL_CLAMP was removed in the core profile, and it has never existed in
65        * OpenGL ES.
66        */
67       supported = (ctx->API == API_OPENGL_COMPAT)
68          && (target != GL_TEXTURE_EXTERNAL_OES);
69       break;
70
71    case GL_CLAMP_TO_EDGE:
72       supported = true;
73       break;
74
75    case GL_CLAMP_TO_BORDER:
76       supported = is_desktop_gl && e->ARB_texture_border_clamp
77          && (target != GL_TEXTURE_EXTERNAL_OES);
78       break;
79
80    case GL_REPEAT:
81    case GL_MIRRORED_REPEAT:
82       supported = (target != GL_TEXTURE_RECTANGLE_NV)
83          && (target != GL_TEXTURE_EXTERNAL_OES);
84       break;
85
86    case GL_MIRROR_CLAMP_EXT:
87    case GL_MIRROR_CLAMP_TO_EDGE_EXT:
88       supported = is_desktop_gl 
89          && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
90          && (target != GL_TEXTURE_RECTANGLE_NV)
91          && (target != GL_TEXTURE_EXTERNAL_OES);
92       break;
93
94    case GL_MIRROR_CLAMP_TO_BORDER_EXT:
95       supported = is_desktop_gl && e->EXT_texture_mirror_clamp
96          && (target != GL_TEXTURE_RECTANGLE_NV)
97          && (target != GL_TEXTURE_EXTERNAL_OES);
98       break;
99
100    default:
101       supported = false;
102       break;
103    }
104
105    if (!supported)
106       _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
107
108    return supported;
109 }
110
111
112 /**
113  * Get current texture object for given target.
114  * Return NULL if any error (and record the error).
115  * Note that this is different from _mesa_select_tex_object() in that proxy
116  * targets are not accepted.
117  * Only the glGetTexLevelParameter() functions accept proxy targets.
118  */
119 static struct gl_texture_object *
120 get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
121 {
122    struct gl_texture_unit *texUnit;
123
124    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
125       _mesa_error(ctx, GL_INVALID_OPERATION,
126                   "gl%sTexParameter(current unit)", get ? "Get" : "");
127       return NULL;
128    }
129
130    texUnit = _mesa_get_current_tex_unit(ctx);
131
132    switch (target) {
133    case GL_TEXTURE_1D:
134       if (_mesa_is_desktop_gl(ctx))
135          return texUnit->CurrentTex[TEXTURE_1D_INDEX];
136       break;
137    case GL_TEXTURE_2D:
138       return texUnit->CurrentTex[TEXTURE_2D_INDEX];
139    case GL_TEXTURE_3D:
140       if (ctx->API != API_OPENGLES)
141          return texUnit->CurrentTex[TEXTURE_3D_INDEX];
142       break;
143    case GL_TEXTURE_CUBE_MAP:
144       if (ctx->Extensions.ARB_texture_cube_map) {
145          return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
146       }
147       break;
148    case GL_TEXTURE_RECTANGLE_NV:
149       if (_mesa_is_desktop_gl(ctx)
150           && ctx->Extensions.NV_texture_rectangle) {
151          return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
152       }
153       break;
154    case GL_TEXTURE_1D_ARRAY_EXT:
155       if (_mesa_is_desktop_gl(ctx)
156           && (ctx->Extensions.MESA_texture_array ||
157               ctx->Extensions.EXT_texture_array)) {
158          return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
159       }
160       break;
161    case GL_TEXTURE_2D_ARRAY_EXT:
162       if ((_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx))
163           && (ctx->Extensions.MESA_texture_array ||
164               ctx->Extensions.EXT_texture_array)) {
165          return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
166       }
167       break;
168    case GL_TEXTURE_EXTERNAL_OES:
169       if (_mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external) {
170          return texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX];
171       }
172       break;
173    case GL_TEXTURE_CUBE_MAP_ARRAY:
174       if (ctx->Extensions.ARB_texture_cube_map_array) {
175          return texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX];
176       }
177       break;
178    case GL_TEXTURE_2D_MULTISAMPLE:
179       if (ctx->Extensions.ARB_texture_storage_multisample) {
180          return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX];
181       }
182       break;
183    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
184       if (ctx->Extensions.ARB_texture_storage_multisample) {
185          return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX];
186       }
187       break;
188    default:
189       ;
190    }
191
192    _mesa_error(ctx, GL_INVALID_ENUM,
193                   "gl%sTexParameter(target)", get ? "Get" : "");
194    return NULL;
195 }
196
197
198 /**
199  * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
200  * \return -1 if error.
201  */
202 static GLint
203 comp_to_swizzle(GLenum comp)
204 {
205    switch (comp) {
206    case GL_RED:
207       return SWIZZLE_X;
208    case GL_GREEN:
209       return SWIZZLE_Y;
210    case GL_BLUE:
211       return SWIZZLE_Z;
212    case GL_ALPHA:
213       return SWIZZLE_W;
214    case GL_ZERO:
215       return SWIZZLE_ZERO;
216    case GL_ONE:
217       return SWIZZLE_ONE;
218    default:
219       return -1;
220    }
221 }
222
223
224 static void
225 set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
226 {
227    ASSERT(comp < 4);
228    ASSERT(swz <= SWIZZLE_NIL);
229    {
230       GLuint mask = 0x7 << (3 * comp);
231       GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
232       *swizzle = s;
233    }
234 }
235
236
237 /**
238  * This is called just prior to changing any texture object state which
239  * will not effect texture completeness.
240  */
241 static inline void
242 flush(struct gl_context *ctx)
243 {
244    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
245 }
246
247
248 /**
249  * This is called just prior to changing any texture object state which
250  * can effect texture completeness (texture base level, max level).
251  * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
252  * state flag and then mark the texture object as 'incomplete' so that any
253  * per-texture derived state gets recomputed.
254  */
255 static inline void
256 incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
257 {
258    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
259    _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
260 }
261
262
263 static GLboolean
264 target_allows_setting_sampler_parameters(GLenum target)
265 {
266    switch (target) {
267    case GL_TEXTURE_2D_MULTISAMPLE:
268    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
269       return GL_FALSE;
270
271    default:
272       return GL_TRUE;
273    }
274 }
275
276
277 /**
278  * Set an integer-valued texture parameter
279  * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
280  */
281 static GLboolean
282 set_tex_parameteri(struct gl_context *ctx,
283                    struct gl_texture_object *texObj,
284                    GLenum pname, const GLint *params)
285 {
286    switch (pname) {
287    case GL_TEXTURE_MIN_FILTER:
288       if (!target_allows_setting_sampler_parameters(texObj->Target))
289          goto invalid_operation;
290
291       if (texObj->Sampler.MinFilter == params[0])
292          return GL_FALSE;
293       switch (params[0]) {
294       case GL_NEAREST:
295       case GL_LINEAR:
296          flush(ctx);
297          texObj->Sampler.MinFilter = params[0];
298          return GL_TRUE;
299       case GL_NEAREST_MIPMAP_NEAREST:
300       case GL_LINEAR_MIPMAP_NEAREST:
301       case GL_NEAREST_MIPMAP_LINEAR:
302       case GL_LINEAR_MIPMAP_LINEAR:
303          if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
304              texObj->Target != GL_TEXTURE_EXTERNAL_OES) {
305             flush(ctx);
306             texObj->Sampler.MinFilter = params[0];
307             return GL_TRUE;
308          }
309          /* fall-through */
310       default:
311          goto invalid_param;
312       }
313       return GL_FALSE;
314
315    case GL_TEXTURE_MAG_FILTER:
316       if (!target_allows_setting_sampler_parameters(texObj->Target))
317          goto invalid_operation;
318
319       if (texObj->Sampler.MagFilter == params[0])
320          return GL_FALSE;
321       switch (params[0]) {
322       case GL_NEAREST:
323       case GL_LINEAR:
324          flush(ctx); /* does not effect completeness */
325          texObj->Sampler.MagFilter = params[0];
326          return GL_TRUE;
327       default:
328          goto invalid_param;
329       }
330       return GL_FALSE;
331
332    case GL_TEXTURE_WRAP_S:
333       if (!target_allows_setting_sampler_parameters(texObj->Target))
334          goto invalid_operation;
335
336       if (texObj->Sampler.WrapS == params[0])
337          return GL_FALSE;
338       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
339          flush(ctx);
340          texObj->Sampler.WrapS = params[0];
341          return GL_TRUE;
342       }
343       return GL_FALSE;
344
345    case GL_TEXTURE_WRAP_T:
346       if (!target_allows_setting_sampler_parameters(texObj->Target))
347          goto invalid_operation;
348
349       if (texObj->Sampler.WrapT == params[0])
350          return GL_FALSE;
351       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
352          flush(ctx);
353          texObj->Sampler.WrapT = params[0];
354          return GL_TRUE;
355       }
356       return GL_FALSE;
357
358    case GL_TEXTURE_WRAP_R:
359       if (!target_allows_setting_sampler_parameters(texObj->Target))
360          goto invalid_operation;
361
362       if (texObj->Sampler.WrapR == params[0])
363          return GL_FALSE;
364       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
365          flush(ctx);
366          texObj->Sampler.WrapR = params[0];
367          return GL_TRUE;
368       }
369       return GL_FALSE;
370
371    case GL_TEXTURE_BASE_LEVEL:
372       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
373          goto invalid_pname;
374
375       if (texObj->BaseLevel == params[0])
376          return GL_FALSE;
377
378       if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
379            texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0)
380          goto invalid_operation;
381
382       if (params[0] < 0 ||
383           (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
384          _mesa_error(ctx, GL_INVALID_VALUE,
385                      "glTexParameter(param=%d)", params[0]);
386          return GL_FALSE;
387       }
388       incomplete(ctx, texObj);
389       texObj->BaseLevel = params[0];
390       return GL_TRUE;
391
392    case GL_TEXTURE_MAX_LEVEL:
393       if (texObj->MaxLevel == params[0])
394          return GL_FALSE;
395
396       if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
397          _mesa_error(ctx, GL_INVALID_VALUE,
398                      "glTexParameter(param=%d)", params[0]);
399          return GL_FALSE;
400       }
401       incomplete(ctx, texObj);
402       texObj->MaxLevel = params[0];
403       return GL_TRUE;
404
405    case GL_GENERATE_MIPMAP_SGIS:
406       if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
407          goto invalid_pname;
408
409       if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES)
410          goto invalid_param;
411       if (texObj->GenerateMipmap != params[0]) {
412          /* no flush() */
413          texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
414          return GL_TRUE;
415       }
416       return GL_FALSE;
417
418    case GL_TEXTURE_COMPARE_MODE_ARB:
419       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
420           || _mesa_is_gles3(ctx)) {
421
422          if (!target_allows_setting_sampler_parameters(texObj->Target))
423             goto invalid_operation;
424
425          if (texObj->Sampler.CompareMode == params[0])
426             return GL_FALSE;
427          if (params[0] == GL_NONE ||
428              params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) {
429             flush(ctx);
430             texObj->Sampler.CompareMode = params[0];
431             return GL_TRUE;
432          }
433          goto invalid_param;
434       }
435       goto invalid_pname;
436
437    case GL_TEXTURE_COMPARE_FUNC_ARB:
438       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
439           || _mesa_is_gles3(ctx)) {
440
441          if (!target_allows_setting_sampler_parameters(texObj->Target))
442             goto invalid_operation;
443
444          if (texObj->Sampler.CompareFunc == params[0])
445             return GL_FALSE;
446          switch (params[0]) {
447          case GL_LEQUAL:
448          case GL_GEQUAL:
449             flush(ctx);
450             texObj->Sampler.CompareFunc = params[0];
451             return GL_TRUE;
452          case GL_EQUAL:
453          case GL_NOTEQUAL:
454          case GL_LESS:
455          case GL_GREATER:
456          case GL_ALWAYS:
457          case GL_NEVER:
458             if (ctx->Extensions.EXT_shadow_funcs) {
459                flush(ctx);
460                texObj->Sampler.CompareFunc = params[0];
461                return GL_TRUE;
462             }
463             /* fall-through */
464          default:
465             goto invalid_param;
466          }
467       }
468       goto invalid_pname;
469
470    case GL_DEPTH_TEXTURE_MODE_ARB:
471       /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never
472        * existed in OpenGL ES.
473        */
474       if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) {
475          if (texObj->DepthMode == params[0])
476             return GL_FALSE;
477          if (params[0] == GL_LUMINANCE ||
478              params[0] == GL_INTENSITY ||
479              params[0] == GL_ALPHA ||
480              (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) {
481             flush(ctx);
482             texObj->DepthMode = params[0];
483             return GL_TRUE;
484          }
485          goto invalid_param;
486       }
487       goto invalid_pname;
488
489    case GL_TEXTURE_CROP_RECT_OES:
490       if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
491          goto invalid_pname;
492
493       texObj->CropRect[0] = params[0];
494       texObj->CropRect[1] = params[1];
495       texObj->CropRect[2] = params[2];
496       texObj->CropRect[3] = params[3];
497       return GL_TRUE;
498
499    case GL_TEXTURE_SWIZZLE_R_EXT:
500    case GL_TEXTURE_SWIZZLE_G_EXT:
501    case GL_TEXTURE_SWIZZLE_B_EXT:
502    case GL_TEXTURE_SWIZZLE_A_EXT:
503       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
504           || _mesa_is_gles3(ctx)) {
505          const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
506          const GLint swz = comp_to_swizzle(params[0]);
507          if (swz < 0) {
508             _mesa_error(ctx, GL_INVALID_OPERATION,
509                         "glTexParameter(swizzle 0x%x)", params[0]);
510             return GL_FALSE;
511          }
512          ASSERT(comp < 4);
513
514          flush(ctx);
515          texObj->Swizzle[comp] = params[0];
516          set_swizzle_component(&texObj->_Swizzle, comp, swz);
517          return GL_TRUE;
518       }
519       goto invalid_pname;
520
521    case GL_TEXTURE_SWIZZLE_RGBA_EXT:
522       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
523           || _mesa_is_gles3(ctx)) {
524          GLuint comp;
525          flush(ctx);
526          for (comp = 0; comp < 4; comp++) {
527             const GLint swz = comp_to_swizzle(params[comp]);
528             if (swz >= 0) {
529                texObj->Swizzle[comp] = params[comp];
530                set_swizzle_component(&texObj->_Swizzle, comp, swz);
531             }
532             else {
533                _mesa_error(ctx, GL_INVALID_OPERATION,
534                            "glTexParameter(swizzle 0x%x)", params[comp]);
535                return GL_FALSE;
536             }
537          }
538          return GL_TRUE;
539       }
540       goto invalid_pname;
541
542    case GL_TEXTURE_SRGB_DECODE_EXT:
543       if (_mesa_is_desktop_gl(ctx)
544           && ctx->Extensions.EXT_texture_sRGB_decode) {
545          GLenum decode = params[0];
546
547          if (!target_allows_setting_sampler_parameters(texObj->Target))
548             goto invalid_operation;
549
550          if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
551             if (texObj->Sampler.sRGBDecode != decode) {
552                flush(ctx);
553                texObj->Sampler.sRGBDecode = decode;
554             }
555             return GL_TRUE;
556          }
557       }
558       goto invalid_pname;
559
560    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
561       if (_mesa_is_desktop_gl(ctx)
562           && ctx->Extensions.AMD_seamless_cubemap_per_texture) {
563          GLenum param = params[0];
564
565          if (!target_allows_setting_sampler_parameters(texObj->Target))
566             goto invalid_operation;
567
568          if (param != GL_TRUE && param != GL_FALSE) {
569             goto invalid_param;
570          }
571          if (param != texObj->Sampler.CubeMapSeamless) {
572             flush(ctx);
573             texObj->Sampler.CubeMapSeamless = param;
574          }
575          return GL_TRUE;
576       }
577       goto invalid_pname;
578
579    default:
580       goto invalid_pname;
581    }
582
583 invalid_pname:
584    _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
585                _mesa_lookup_enum_by_nr(pname));
586    return GL_FALSE;
587
588 invalid_param:
589    _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)",
590                _mesa_lookup_enum_by_nr(params[0]));
591    return GL_FALSE;
592
593 invalid_operation:
594    _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
595                _mesa_lookup_enum_by_nr(pname));
596    return GL_FALSE;
597 }
598
599
600 /**
601  * Set a float-valued texture parameter
602  * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
603  */
604 static GLboolean
605 set_tex_parameterf(struct gl_context *ctx,
606                    struct gl_texture_object *texObj,
607                    GLenum pname, const GLfloat *params)
608 {
609    switch (pname) {
610    case GL_TEXTURE_MIN_LOD:
611       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
612          goto invalid_pname;
613
614       if (!target_allows_setting_sampler_parameters(texObj->Target))
615          goto invalid_operation;
616
617       if (texObj->Sampler.MinLod == params[0])
618          return GL_FALSE;
619       flush(ctx);
620       texObj->Sampler.MinLod = params[0];
621       return GL_TRUE;
622
623    case GL_TEXTURE_MAX_LOD:
624       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
625          goto invalid_pname;
626
627       if (!target_allows_setting_sampler_parameters(texObj->Target))
628          goto invalid_operation;
629
630       if (texObj->Sampler.MaxLod == params[0])
631          return GL_FALSE;
632       flush(ctx);
633       texObj->Sampler.MaxLod = params[0];
634       return GL_TRUE;
635
636    case GL_TEXTURE_PRIORITY:
637       if (ctx->API != API_OPENGL_COMPAT)
638          goto invalid_pname;
639
640       flush(ctx);
641       texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
642       return GL_TRUE;
643
644    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
645       if (ctx->Extensions.EXT_texture_filter_anisotropic) {
646          if (!target_allows_setting_sampler_parameters(texObj->Target))
647             goto invalid_operation;
648
649          if (texObj->Sampler.MaxAnisotropy == params[0])
650             return GL_FALSE;
651          if (params[0] < 1.0) {
652             _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
653             return GL_FALSE;
654          }
655          flush(ctx);
656          /* clamp to max, that's what NVIDIA does */
657          texObj->Sampler.MaxAnisotropy = MIN2(params[0],
658                                       ctx->Const.MaxTextureMaxAnisotropy);
659          return GL_TRUE;
660       }
661       else {
662          static GLuint count = 0;
663          if (count++ < 10)
664             goto invalid_pname;
665       }
666       return GL_FALSE;
667
668    case GL_TEXTURE_LOD_BIAS:
669       /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias.
670        * It was removed in core-profile, and it has never existed in OpenGL
671        * ES.
672        */
673       if (ctx->API != API_OPENGL_COMPAT)
674          goto invalid_pname;
675
676       if (!target_allows_setting_sampler_parameters(texObj->Target))
677          goto invalid_operation;
678
679       if (texObj->Sampler.LodBias != params[0]) {
680          flush(ctx);
681          texObj->Sampler.LodBias = params[0];
682          return GL_TRUE;
683       }
684       break;
685
686    case GL_TEXTURE_BORDER_COLOR:
687       if (!_mesa_is_desktop_gl(ctx))
688          goto invalid_pname;
689
690       if (!target_allows_setting_sampler_parameters(texObj->Target))
691          goto invalid_operation;
692
693       flush(ctx);
694       /* ARB_texture_float disables clamping */
695       if (ctx->Extensions.ARB_texture_float) {
696          texObj->Sampler.BorderColor.f[RCOMP] = params[0];
697          texObj->Sampler.BorderColor.f[GCOMP] = params[1];
698          texObj->Sampler.BorderColor.f[BCOMP] = params[2];
699          texObj->Sampler.BorderColor.f[ACOMP] = params[3];
700       } else {
701          texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
702          texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
703          texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
704          texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
705       }
706       return GL_TRUE;
707
708    default:
709       goto invalid_pname;
710    }
711    return GL_FALSE;
712
713 invalid_pname:
714    _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
715                _mesa_lookup_enum_by_nr(pname));
716    return GL_FALSE;
717
718 invalid_operation:
719    _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
720                _mesa_lookup_enum_by_nr(pname));
721    return GL_FALSE;
722 }
723
724
725 void GLAPIENTRY
726 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
727 {
728    GLboolean need_update;
729    struct gl_texture_object *texObj;
730    GET_CURRENT_CONTEXT(ctx);
731
732    texObj = get_texobj(ctx, target, GL_FALSE);
733    if (!texObj)
734       return;
735
736    switch (pname) {
737    case GL_TEXTURE_MIN_FILTER:
738    case GL_TEXTURE_MAG_FILTER:
739    case GL_TEXTURE_WRAP_S:
740    case GL_TEXTURE_WRAP_T:
741    case GL_TEXTURE_WRAP_R:
742    case GL_TEXTURE_BASE_LEVEL:
743    case GL_TEXTURE_MAX_LEVEL:
744    case GL_GENERATE_MIPMAP_SGIS:
745    case GL_TEXTURE_COMPARE_MODE_ARB:
746    case GL_TEXTURE_COMPARE_FUNC_ARB:
747    case GL_DEPTH_TEXTURE_MODE_ARB:
748    case GL_TEXTURE_SRGB_DECODE_EXT:
749    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
750    case GL_TEXTURE_SWIZZLE_R_EXT:
751    case GL_TEXTURE_SWIZZLE_G_EXT:
752    case GL_TEXTURE_SWIZZLE_B_EXT:
753    case GL_TEXTURE_SWIZZLE_A_EXT:
754       {
755          GLint p[4];
756          p[0] = (param > 0) ?
757                 ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
758                 ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
759
760          p[1] = p[2] = p[3] = 0;
761          need_update = set_tex_parameteri(ctx, texObj, pname, p);
762       }
763       break;
764    default:
765       {
766          /* this will generate an error if pname is illegal */
767          GLfloat p[4];
768          p[0] = param;
769          p[1] = p[2] = p[3] = 0.0F;
770          need_update = set_tex_parameterf(ctx, texObj, pname, p);
771       }
772    }
773
774    if (ctx->Driver.TexParameter && need_update) {
775       ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
776    }
777 }
778
779
780 void GLAPIENTRY
781 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
782 {
783    GLboolean need_update;
784    struct gl_texture_object *texObj;
785    GET_CURRENT_CONTEXT(ctx);
786
787    texObj = get_texobj(ctx, target, GL_FALSE);
788    if (!texObj)
789       return;
790
791    switch (pname) {
792    case GL_TEXTURE_MIN_FILTER:
793    case GL_TEXTURE_MAG_FILTER:
794    case GL_TEXTURE_WRAP_S:
795    case GL_TEXTURE_WRAP_T:
796    case GL_TEXTURE_WRAP_R:
797    case GL_TEXTURE_BASE_LEVEL:
798    case GL_TEXTURE_MAX_LEVEL:
799    case GL_GENERATE_MIPMAP_SGIS:
800    case GL_TEXTURE_COMPARE_MODE_ARB:
801    case GL_TEXTURE_COMPARE_FUNC_ARB:
802    case GL_DEPTH_TEXTURE_MODE_ARB:
803    case GL_TEXTURE_SRGB_DECODE_EXT:
804    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
805       {
806          /* convert float param to int */
807          GLint p[4];
808          p[0] = (GLint) params[0];
809          p[1] = p[2] = p[3] = 0;
810          need_update = set_tex_parameteri(ctx, texObj, pname, p);
811       }
812       break;
813    case GL_TEXTURE_CROP_RECT_OES:
814       {
815          /* convert float params to int */
816          GLint iparams[4];
817          iparams[0] = (GLint) params[0];
818          iparams[1] = (GLint) params[1];
819          iparams[2] = (GLint) params[2];
820          iparams[3] = (GLint) params[3];
821          need_update = set_tex_parameteri(ctx, texObj, pname, iparams);
822       }
823       break;
824    case GL_TEXTURE_SWIZZLE_R_EXT:
825    case GL_TEXTURE_SWIZZLE_G_EXT:
826    case GL_TEXTURE_SWIZZLE_B_EXT:
827    case GL_TEXTURE_SWIZZLE_A_EXT:
828    case GL_TEXTURE_SWIZZLE_RGBA_EXT:
829       {
830          GLint p[4] = {0, 0, 0, 0};
831          p[0] = (GLint) params[0];
832          if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
833             p[1] = (GLint) params[1];
834             p[2] = (GLint) params[2];
835             p[3] = (GLint) params[3];
836          }
837          need_update = set_tex_parameteri(ctx, texObj, pname, p);
838       }
839       break;
840    default:
841       /* this will generate an error if pname is illegal */
842       need_update = set_tex_parameterf(ctx, texObj, pname, params);
843    }
844
845    if (ctx->Driver.TexParameter && need_update) {
846       ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
847    }
848 }
849
850
851 void GLAPIENTRY
852 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
853 {
854    GLboolean need_update;
855    struct gl_texture_object *texObj;
856    GET_CURRENT_CONTEXT(ctx);
857
858    texObj = get_texobj(ctx, target, GL_FALSE);
859    if (!texObj)
860       return;
861
862    switch (pname) {
863    case GL_TEXTURE_MIN_LOD:
864    case GL_TEXTURE_MAX_LOD:
865    case GL_TEXTURE_PRIORITY:
866    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
867    case GL_TEXTURE_LOD_BIAS:
868    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
869       {
870          GLfloat fparam[4];
871          fparam[0] = (GLfloat) param;
872          fparam[1] = fparam[2] = fparam[3] = 0.0F;
873          /* convert int param to float */
874          need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
875       }
876       break;
877    default:
878       /* this will generate an error if pname is illegal */
879       {
880          GLint iparam[4];
881          iparam[0] = param;
882          iparam[1] = iparam[2] = iparam[3] = 0;
883          need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
884       }
885    }
886
887    if (ctx->Driver.TexParameter && need_update) {
888       GLfloat fparam = (GLfloat) param;
889       ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
890    }
891 }
892
893
894 void GLAPIENTRY
895 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
896 {
897    GLboolean need_update;
898    struct gl_texture_object *texObj;
899    GET_CURRENT_CONTEXT(ctx);
900
901    texObj = get_texobj(ctx, target, GL_FALSE);
902    if (!texObj)
903       return;
904
905    switch (pname) {
906    case GL_TEXTURE_BORDER_COLOR:
907       {
908          /* convert int params to float */
909          GLfloat fparams[4];
910          fparams[0] = INT_TO_FLOAT(params[0]);
911          fparams[1] = INT_TO_FLOAT(params[1]);
912          fparams[2] = INT_TO_FLOAT(params[2]);
913          fparams[3] = INT_TO_FLOAT(params[3]);
914          need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
915       }
916       break;
917    case GL_TEXTURE_MIN_LOD:
918    case GL_TEXTURE_MAX_LOD:
919    case GL_TEXTURE_PRIORITY:
920    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
921    case GL_TEXTURE_LOD_BIAS:
922    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
923       {
924          /* convert int param to float */
925          GLfloat fparams[4];
926          fparams[0] = (GLfloat) params[0];
927          fparams[1] = fparams[2] = fparams[3] = 0.0F;
928          need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
929       }
930       break;
931    default:
932       /* this will generate an error if pname is illegal */
933       need_update = set_tex_parameteri(ctx, texObj, pname, params);
934    }
935
936    if (ctx->Driver.TexParameter && need_update) {
937       GLfloat fparams[4];
938       fparams[0] = INT_TO_FLOAT(params[0]);
939       if (pname == GL_TEXTURE_BORDER_COLOR ||
940           pname == GL_TEXTURE_CROP_RECT_OES) {
941          fparams[1] = INT_TO_FLOAT(params[1]);
942          fparams[2] = INT_TO_FLOAT(params[2]);
943          fparams[3] = INT_TO_FLOAT(params[3]);
944       }
945       ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
946    }
947 }
948
949
950 /**
951  * Set tex parameter to integer value(s).  Primarily intended to set
952  * integer-valued texture border color (for integer-valued textures).
953  * New in GL 3.0.
954  */
955 void GLAPIENTRY
956 _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
957 {
958    struct gl_texture_object *texObj;
959    GET_CURRENT_CONTEXT(ctx);
960
961    texObj = get_texobj(ctx, target, GL_FALSE);
962    if (!texObj)
963       return;
964
965    switch (pname) {
966    case GL_TEXTURE_BORDER_COLOR:
967       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
968       /* set the integer-valued border color */
969       COPY_4V(texObj->Sampler.BorderColor.i, params);
970       break;
971    default:
972       _mesa_TexParameteriv(target, pname, params);
973       break;
974    }
975    /* XXX no driver hook for TexParameterIiv() yet */
976 }
977
978
979 /**
980  * Set tex parameter to unsigned integer value(s).  Primarily intended to set
981  * uint-valued texture border color (for integer-valued textures).
982  * New in GL 3.0
983  */
984 void GLAPIENTRY
985 _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
986 {
987    struct gl_texture_object *texObj;
988    GET_CURRENT_CONTEXT(ctx);
989
990    texObj = get_texobj(ctx, target, GL_FALSE);
991    if (!texObj)
992       return;
993
994    switch (pname) {
995    case GL_TEXTURE_BORDER_COLOR:
996       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
997       /* set the unsigned integer-valued border color */
998       COPY_4V(texObj->Sampler.BorderColor.ui, params);
999       break;
1000    default:
1001       _mesa_TexParameteriv(target, pname, (const GLint *) params);
1002       break;
1003    }
1004    /* XXX no driver hook for TexParameterIuiv() yet */
1005 }
1006
1007
1008 static GLboolean
1009 legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
1010 {
1011    switch (target) {
1012    case GL_TEXTURE_1D:
1013    case GL_PROXY_TEXTURE_1D:
1014    case GL_TEXTURE_2D:
1015    case GL_PROXY_TEXTURE_2D:
1016    case GL_TEXTURE_3D:
1017    case GL_PROXY_TEXTURE_3D:
1018       return GL_TRUE;
1019    case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1020    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1021    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1022    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1023    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1024    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1025    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
1026       return ctx->Extensions.ARB_texture_cube_map;
1027    case GL_TEXTURE_RECTANGLE_NV:
1028    case GL_PROXY_TEXTURE_RECTANGLE_NV:
1029       return ctx->Extensions.NV_texture_rectangle;
1030    case GL_TEXTURE_1D_ARRAY_EXT:
1031    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1032    case GL_TEXTURE_2D_ARRAY_EXT:
1033    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1034       return (ctx->Extensions.MESA_texture_array ||
1035               ctx->Extensions.EXT_texture_array);
1036    case GL_TEXTURE_BUFFER:
1037       /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
1038        * but not in earlier versions that expose ARB_texture_buffer_object.
1039        *
1040        * From the ARB_texture_buffer_object spec:
1041        * "(7) Do buffer textures support texture parameters (TexParameter) or
1042        *      queries (GetTexParameter, GetTexLevelParameter, GetTexImage)?
1043        *
1044        *    RESOLVED:  No. [...] Note that the spec edits above don't add
1045        *    explicit error language for any of these cases.  That is because
1046        *    each of the functions enumerate the set of valid <target>
1047        *    parameters.  Not editing the spec to allow TEXTURE_BUFFER_ARB in
1048        *    these cases means that target is not legal, and an INVALID_ENUM
1049        *    error should be generated."
1050        *
1051        * From the OpenGL 3.1 spec:
1052        * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
1053        */
1054       return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
1055    case GL_TEXTURE_2D_MULTISAMPLE:
1056    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1057       return ctx->Extensions.ARB_texture_multisample;
1058    default:
1059       return GL_FALSE;
1060    }
1061 }
1062
1063
1064 static void
1065 get_tex_level_parameter_image(struct gl_context *ctx,
1066                               const struct gl_texture_object *texObj,
1067                               GLenum target, GLint level,
1068                               GLenum pname, GLint *params)
1069 {
1070    const struct gl_texture_image *img = NULL;
1071    gl_format texFormat;
1072
1073    img = _mesa_select_tex_image(ctx, texObj, target, level);
1074    if (!img || img->TexFormat == MESA_FORMAT_NONE) {
1075       /* undefined texture image */
1076       if (pname == GL_TEXTURE_COMPONENTS)
1077          *params = 1;
1078       else
1079          *params = 0;
1080       return;
1081    }
1082
1083    texFormat = img->TexFormat;
1084
1085    switch (pname) {
1086       case GL_TEXTURE_WIDTH:
1087          *params = img->Width;
1088          break;
1089       case GL_TEXTURE_HEIGHT:
1090          *params = img->Height;
1091          break;
1092       case GL_TEXTURE_DEPTH:
1093          *params = img->Depth;
1094          break;
1095       case GL_TEXTURE_INTERNAL_FORMAT:
1096          if (_mesa_is_format_compressed(texFormat)) {
1097             /* need to return the actual compressed format */
1098             *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
1099          }
1100          else {
1101             /* If the true internal format is not compressed but the user
1102              * requested a generic compressed format, we have to return the
1103              * generic base format that matches.
1104              *
1105              * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
1106              *
1107              *     "If no specific compressed format is available,
1108              *     internalformat is instead replaced by the corresponding base
1109              *     internal format."
1110              *
1111              * Otherwise just return the user's requested internal format
1112              */
1113             const GLenum f =
1114                _mesa_gl_compressed_format_base_format(img->InternalFormat);
1115
1116             *params = (f != 0) ? f : img->InternalFormat;
1117          }
1118          break;
1119       case GL_TEXTURE_BORDER:
1120          *params = img->Border;
1121          break;
1122       case GL_TEXTURE_RED_SIZE:
1123       case GL_TEXTURE_GREEN_SIZE:
1124       case GL_TEXTURE_BLUE_SIZE:
1125       case GL_TEXTURE_ALPHA_SIZE:
1126          if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1127             *params = _mesa_get_format_bits(texFormat, pname);
1128          else
1129             *params = 0;
1130          break;
1131       case GL_TEXTURE_INTENSITY_SIZE:
1132       case GL_TEXTURE_LUMINANCE_SIZE:
1133          if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
1134             *params = _mesa_get_format_bits(texFormat, pname);
1135             if (*params == 0) {
1136                /* intensity or luminance is probably stored as RGB[A] */
1137                *params = MIN2(_mesa_get_format_bits(texFormat,
1138                                                     GL_TEXTURE_RED_SIZE),
1139                               _mesa_get_format_bits(texFormat,
1140                                                     GL_TEXTURE_GREEN_SIZE));
1141             }
1142          }
1143          else {
1144             *params = 0;
1145          }
1146          break;
1147       case GL_TEXTURE_DEPTH_SIZE_ARB:
1148          if (!ctx->Extensions.ARB_depth_texture)
1149             goto invalid_pname;
1150          *params = _mesa_get_format_bits(texFormat, pname);
1151          break;
1152       case GL_TEXTURE_STENCIL_SIZE_EXT:
1153          if (!ctx->Extensions.EXT_packed_depth_stencil &&
1154              !ctx->Extensions.ARB_framebuffer_object)
1155             goto invalid_pname;
1156          *params = _mesa_get_format_bits(texFormat, pname);
1157          break;
1158       case GL_TEXTURE_SHARED_SIZE:
1159          if (ctx->Version < 30 &&
1160              !ctx->Extensions.EXT_texture_shared_exponent)
1161             goto invalid_pname;
1162          *params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0;
1163          break;
1164
1165       /* GL_ARB_texture_compression */
1166       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1167          if (_mesa_is_format_compressed(texFormat) &&
1168              !_mesa_is_proxy_texture(target)) {
1169             *params = _mesa_format_image_size(texFormat, img->Width,
1170                                               img->Height, img->Depth);
1171          }
1172          else {
1173             _mesa_error(ctx, GL_INVALID_OPERATION,
1174                         "glGetTexLevelParameter[if]v(pname)");
1175          }
1176          break;
1177       case GL_TEXTURE_COMPRESSED:
1178          *params = (GLint) _mesa_is_format_compressed(texFormat);
1179          break;
1180
1181       /* GL_ARB_texture_float */
1182       case GL_TEXTURE_RED_TYPE_ARB:
1183       case GL_TEXTURE_GREEN_TYPE_ARB:
1184       case GL_TEXTURE_BLUE_TYPE_ARB:
1185       case GL_TEXTURE_ALPHA_TYPE_ARB:
1186       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1187       case GL_TEXTURE_INTENSITY_TYPE_ARB:
1188       case GL_TEXTURE_DEPTH_TYPE_ARB:
1189          if (!ctx->Extensions.ARB_texture_float)
1190             goto invalid_pname;
1191          if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1192             *params = _mesa_get_format_datatype(texFormat);
1193          else
1194             *params = GL_NONE;
1195          break;
1196
1197       /* GL_ARB_texture_multisample */
1198       case GL_TEXTURE_SAMPLES:
1199          if (!ctx->Extensions.ARB_texture_multisample)
1200             goto invalid_pname;
1201          *params = img->NumSamples;
1202          break;
1203
1204       case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1205          if (!ctx->Extensions.ARB_texture_multisample)
1206             goto invalid_pname;
1207          *params = img->FixedSampleLocations;
1208          break;
1209
1210       default:
1211          goto invalid_pname;
1212    }
1213
1214    /* no error if we get here */
1215    return;
1216
1217 invalid_pname:
1218    _mesa_error(ctx, GL_INVALID_ENUM,
1219                "glGetTexLevelParameter[if]v(pname=%s)",
1220                _mesa_lookup_enum_by_nr(pname));
1221 }
1222
1223
1224 static void
1225 get_tex_level_parameter_buffer(struct gl_context *ctx,
1226                                const struct gl_texture_object *texObj,
1227                                GLenum pname, GLint *params)
1228 {
1229    const struct gl_buffer_object *bo = texObj->BufferObject;
1230    gl_format texFormat = texObj->_BufferObjectFormat;
1231    GLenum internalFormat = texObj->BufferObjectFormat;
1232    GLenum baseFormat = _mesa_get_format_base_format(texFormat);
1233
1234    if (!bo) {
1235       /* undefined texture buffer object */
1236       *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0;
1237       return;
1238    }
1239
1240    switch (pname) {
1241       case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
1242          *params = bo->Name;
1243          break;
1244       case GL_TEXTURE_WIDTH:
1245          *params = bo->Size;
1246          break;
1247       case GL_TEXTURE_HEIGHT:
1248       case GL_TEXTURE_DEPTH:
1249       case GL_TEXTURE_BORDER:
1250       case GL_TEXTURE_SHARED_SIZE:
1251       case GL_TEXTURE_COMPRESSED:
1252          *params = 0;
1253          break;
1254       case GL_TEXTURE_INTERNAL_FORMAT:
1255          *params = internalFormat;
1256          break;
1257       case GL_TEXTURE_RED_SIZE:
1258       case GL_TEXTURE_GREEN_SIZE:
1259       case GL_TEXTURE_BLUE_SIZE:
1260       case GL_TEXTURE_ALPHA_SIZE:
1261          if (_mesa_base_format_has_channel(baseFormat, pname))
1262             *params = _mesa_get_format_bits(texFormat, pname);
1263          else
1264             *params = 0;
1265          break;
1266       case GL_TEXTURE_INTENSITY_SIZE:
1267       case GL_TEXTURE_LUMINANCE_SIZE:
1268          if (_mesa_base_format_has_channel(baseFormat, pname)) {
1269             *params = _mesa_get_format_bits(texFormat, pname);
1270             if (*params == 0) {
1271                /* intensity or luminance is probably stored as RGB[A] */
1272                *params = MIN2(_mesa_get_format_bits(texFormat,
1273                                                     GL_TEXTURE_RED_SIZE),
1274                               _mesa_get_format_bits(texFormat,
1275                                                     GL_TEXTURE_GREEN_SIZE));
1276             }
1277          } else {
1278             *params = 0;
1279          }
1280          break;
1281       case GL_TEXTURE_DEPTH_SIZE_ARB:
1282       case GL_TEXTURE_STENCIL_SIZE_EXT:
1283          *params = _mesa_get_format_bits(texFormat, pname);
1284          break;
1285
1286       /* GL_ARB_texture_buffer_range */
1287       case GL_TEXTURE_BUFFER_OFFSET:
1288          if (!ctx->Extensions.ARB_texture_buffer_range)
1289             goto invalid_pname;
1290          *params = texObj->BufferOffset;
1291          break;
1292       case GL_TEXTURE_BUFFER_SIZE:
1293          if (!ctx->Extensions.ARB_texture_buffer_range)
1294             goto invalid_pname;
1295          *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
1296          break;
1297
1298       /* GL_ARB_texture_compression */
1299       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1300          /* Always illegal for GL_TEXTURE_BUFFER */
1301          _mesa_error(ctx, GL_INVALID_OPERATION,
1302                      "glGetTexLevelParameter[if]v(pname)");
1303          break;
1304
1305       /* GL_ARB_texture_float */
1306       case GL_TEXTURE_RED_TYPE_ARB:
1307       case GL_TEXTURE_GREEN_TYPE_ARB:
1308       case GL_TEXTURE_BLUE_TYPE_ARB:
1309       case GL_TEXTURE_ALPHA_TYPE_ARB:
1310       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1311       case GL_TEXTURE_INTENSITY_TYPE_ARB:
1312       case GL_TEXTURE_DEPTH_TYPE_ARB:
1313          if (!ctx->Extensions.ARB_texture_float)
1314             goto invalid_pname;
1315          if (_mesa_base_format_has_channel(baseFormat, pname))
1316             *params = _mesa_get_format_datatype(texFormat);
1317          else
1318             *params = GL_NONE;
1319          break;
1320
1321       default:
1322          goto invalid_pname;
1323    }
1324
1325    /* no error if we get here */
1326    return;
1327
1328 invalid_pname:
1329    _mesa_error(ctx, GL_INVALID_ENUM,
1330                "glGetTexLevelParameter[if]v(pname=%s)",
1331                _mesa_lookup_enum_by_nr(pname));
1332 }
1333
1334
1335 void GLAPIENTRY
1336 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
1337                               GLenum pname, GLfloat *params )
1338 {
1339    GLint iparam;
1340    _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
1341    *params = (GLfloat) iparam;
1342 }
1343
1344
1345 void GLAPIENTRY
1346 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
1347                               GLenum pname, GLint *params )
1348 {
1349    const struct gl_texture_unit *texUnit;
1350    struct gl_texture_object *texObj;
1351    GLint maxLevels;
1352    GET_CURRENT_CONTEXT(ctx);
1353
1354    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
1355       _mesa_error(ctx, GL_INVALID_OPERATION,
1356                   "glGetTexLevelParameteriv(current unit)");
1357       return;
1358    }
1359
1360    texUnit = _mesa_get_current_tex_unit(ctx);
1361
1362    if (!legal_get_tex_level_parameter_target(ctx, target)) {
1363       _mesa_error(ctx, GL_INVALID_ENUM,
1364                   "glGetTexLevelParameter[if]v(target=0x%x)", target);
1365       return;
1366    }
1367
1368    maxLevels = _mesa_max_texture_levels(ctx, target);
1369    assert(maxLevels != 0);
1370
1371    if (level < 0 || level >= maxLevels) {
1372       _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
1373       return;
1374    }
1375
1376    texObj = _mesa_select_tex_object(ctx, texUnit, target);
1377
1378    if (target == GL_TEXTURE_BUFFER)
1379       get_tex_level_parameter_buffer(ctx, texObj, pname, params);
1380    else
1381       get_tex_level_parameter_image(ctx, texObj, target, level, pname, params);
1382 }
1383
1384
1385 void GLAPIENTRY
1386 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
1387 {
1388    struct gl_texture_object *obj;
1389    GET_CURRENT_CONTEXT(ctx);
1390
1391    obj = get_texobj(ctx, target, GL_TRUE);
1392    if (!obj)
1393       return;
1394
1395    _mesa_lock_texture(ctx, obj);
1396    switch (pname) {
1397       case GL_TEXTURE_MAG_FILTER:
1398          *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
1399          break;
1400       case GL_TEXTURE_MIN_FILTER:
1401          *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
1402          break;
1403       case GL_TEXTURE_WRAP_S:
1404          *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
1405          break;
1406       case GL_TEXTURE_WRAP_T:
1407          *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
1408          break;
1409       case GL_TEXTURE_WRAP_R:
1410          *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
1411          break;
1412       case GL_TEXTURE_BORDER_COLOR:
1413          if (!_mesa_is_desktop_gl(ctx))
1414             goto invalid_pname;
1415
1416          if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
1417             _mesa_update_state_locked(ctx);
1418          if (_mesa_get_clamp_fragment_color(ctx)) {
1419             params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1420             params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1421             params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1422             params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1423          }
1424          else {
1425             params[0] = obj->Sampler.BorderColor.f[0];
1426             params[1] = obj->Sampler.BorderColor.f[1];
1427             params[2] = obj->Sampler.BorderColor.f[2];
1428             params[3] = obj->Sampler.BorderColor.f[3];
1429          }
1430          break;
1431       case GL_TEXTURE_RESIDENT:
1432          if (ctx->API != API_OPENGL_COMPAT)
1433             goto invalid_pname;
1434
1435          *params = 1.0F;
1436          break;
1437       case GL_TEXTURE_PRIORITY:
1438          if (ctx->API != API_OPENGL_COMPAT)
1439             goto invalid_pname;
1440
1441          *params = obj->Priority;
1442          break;
1443       case GL_TEXTURE_MIN_LOD:
1444          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1445             goto invalid_pname;
1446
1447          *params = obj->Sampler.MinLod;
1448          break;
1449       case GL_TEXTURE_MAX_LOD:
1450          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1451             goto invalid_pname;
1452
1453          *params = obj->Sampler.MaxLod;
1454          break;
1455       case GL_TEXTURE_BASE_LEVEL:
1456          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1457             goto invalid_pname;
1458
1459          *params = (GLfloat) obj->BaseLevel;
1460          break;
1461       case GL_TEXTURE_MAX_LEVEL:
1462          *params = (GLfloat) obj->MaxLevel;
1463          break;
1464       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1465          if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1466             goto invalid_pname;
1467          *params = obj->Sampler.MaxAnisotropy;
1468          break;
1469       case GL_GENERATE_MIPMAP_SGIS:
1470          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1471             goto invalid_pname;
1472
1473          *params = (GLfloat) obj->GenerateMipmap;
1474          break;
1475       case GL_TEXTURE_COMPARE_MODE_ARB:
1476          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1477              && !_mesa_is_gles3(ctx))
1478             goto invalid_pname;
1479          *params = (GLfloat) obj->Sampler.CompareMode;
1480          break;
1481       case GL_TEXTURE_COMPARE_FUNC_ARB:
1482          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1483              && !_mesa_is_gles3(ctx))
1484             goto invalid_pname;
1485          *params = (GLfloat) obj->Sampler.CompareFunc;
1486          break;
1487       case GL_DEPTH_TEXTURE_MODE_ARB:
1488          /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
1489           * never existed in OpenGL ES.
1490           */
1491          if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
1492             goto invalid_pname;
1493          *params = (GLfloat) obj->DepthMode;
1494          break;
1495       case GL_TEXTURE_LOD_BIAS:
1496          if (ctx->API != API_OPENGL_COMPAT)
1497             goto invalid_pname;
1498
1499          *params = obj->Sampler.LodBias;
1500          break;
1501       case GL_TEXTURE_CROP_RECT_OES:
1502          if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
1503             goto invalid_pname;
1504
1505          params[0] = (GLfloat) obj->CropRect[0];
1506          params[1] = (GLfloat) obj->CropRect[1];
1507          params[2] = (GLfloat) obj->CropRect[2];
1508          params[3] = (GLfloat) obj->CropRect[3];
1509          break;
1510
1511       case GL_TEXTURE_SWIZZLE_R_EXT:
1512       case GL_TEXTURE_SWIZZLE_G_EXT:
1513       case GL_TEXTURE_SWIZZLE_B_EXT:
1514       case GL_TEXTURE_SWIZZLE_A_EXT:
1515          if ((!_mesa_is_desktop_gl(ctx)
1516               || !ctx->Extensions.EXT_texture_swizzle)
1517              && !_mesa_is_gles3(ctx))
1518             goto invalid_pname;
1519          *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
1520          break;
1521
1522       case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1523          if ((!_mesa_is_desktop_gl(ctx)
1524               || !ctx->Extensions.EXT_texture_swizzle)
1525              && !_mesa_is_gles3(ctx)) {
1526             goto invalid_pname;
1527          }
1528          else {
1529             GLuint comp;
1530             for (comp = 0; comp < 4; comp++) {
1531                params[comp] = (GLfloat) obj->Swizzle[comp];
1532             }
1533          }
1534          break;
1535
1536       case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1537          if (!_mesa_is_desktop_gl(ctx)
1538              || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
1539             goto invalid_pname;
1540          *params = (GLfloat) obj->Sampler.CubeMapSeamless;
1541          break;
1542
1543       case GL_TEXTURE_IMMUTABLE_FORMAT:
1544          if (!ctx->Extensions.ARB_texture_storage)
1545             goto invalid_pname;
1546          *params = (GLfloat) obj->Immutable;
1547          break;
1548
1549       case GL_TEXTURE_IMMUTABLE_LEVELS:
1550          if (!_mesa_is_gles3(ctx))
1551             goto invalid_pname;
1552          *params = (GLfloat) obj->ImmutableLevels;
1553          break;
1554
1555       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1556          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
1557             goto invalid_pname;
1558          *params = obj->RequiredTextureImageUnits;
1559          break;
1560
1561       case GL_TEXTURE_SRGB_DECODE_EXT:
1562          if (!ctx->Extensions.EXT_texture_sRGB_decode)
1563             goto invalid_pname;
1564          *params = (GLfloat) obj->Sampler.sRGBDecode;
1565          break;
1566
1567       default:
1568          goto invalid_pname;
1569    }
1570
1571    /* no error if we get here */
1572    _mesa_unlock_texture(ctx, obj);
1573    return;
1574
1575 invalid_pname:
1576    _mesa_unlock_texture(ctx, obj);
1577    _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname);
1578 }
1579
1580
1581 void GLAPIENTRY
1582 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1583 {
1584    struct gl_texture_object *obj;
1585    GET_CURRENT_CONTEXT(ctx);
1586
1587    obj = get_texobj(ctx, target, GL_TRUE);
1588    if (!obj)
1589       return;
1590
1591    _mesa_lock_texture(ctx, obj);
1592    switch (pname) {
1593       case GL_TEXTURE_MAG_FILTER:
1594          *params = (GLint) obj->Sampler.MagFilter;
1595          break;
1596       case GL_TEXTURE_MIN_FILTER:
1597          *params = (GLint) obj->Sampler.MinFilter;
1598          break;
1599       case GL_TEXTURE_WRAP_S:
1600          *params = (GLint) obj->Sampler.WrapS;
1601          break;
1602       case GL_TEXTURE_WRAP_T:
1603          *params = (GLint) obj->Sampler.WrapT;
1604          break;
1605       case GL_TEXTURE_WRAP_R:
1606          *params = (GLint) obj->Sampler.WrapR;
1607          break;
1608       case GL_TEXTURE_BORDER_COLOR:
1609          if (!_mesa_is_desktop_gl(ctx))
1610             goto invalid_pname;
1611
1612          {
1613             GLfloat b[4];
1614             b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1615             b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1616             b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1617             b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1618             params[0] = FLOAT_TO_INT(b[0]);
1619             params[1] = FLOAT_TO_INT(b[1]);
1620             params[2] = FLOAT_TO_INT(b[2]);
1621             params[3] = FLOAT_TO_INT(b[3]);
1622          }
1623          break;
1624       case GL_TEXTURE_RESIDENT:
1625          if (ctx->API != API_OPENGL_COMPAT)
1626             goto invalid_pname;
1627
1628          *params = 1;
1629          break;
1630       case GL_TEXTURE_PRIORITY:
1631          if (ctx->API != API_OPENGL_COMPAT)
1632             goto invalid_pname;
1633
1634          *params = FLOAT_TO_INT(obj->Priority);
1635          break;
1636       case GL_TEXTURE_MIN_LOD:
1637          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1638             goto invalid_pname;
1639
1640          *params = (GLint) obj->Sampler.MinLod;
1641          break;
1642       case GL_TEXTURE_MAX_LOD:
1643          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1644             goto invalid_pname;
1645
1646          *params = (GLint) obj->Sampler.MaxLod;
1647          break;
1648       case GL_TEXTURE_BASE_LEVEL:
1649          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1650             goto invalid_pname;
1651
1652          *params = obj->BaseLevel;
1653          break;
1654       case GL_TEXTURE_MAX_LEVEL:
1655          *params = obj->MaxLevel;
1656          break;
1657       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1658          if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1659             goto invalid_pname;
1660          *params = (GLint) obj->Sampler.MaxAnisotropy;
1661          break;
1662       case GL_GENERATE_MIPMAP_SGIS:
1663          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1664             goto invalid_pname;
1665
1666          *params = (GLint) obj->GenerateMipmap;
1667          break;
1668       case GL_TEXTURE_COMPARE_MODE_ARB:
1669          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1670              && !_mesa_is_gles3(ctx))
1671             goto invalid_pname;
1672          *params = (GLint) obj->Sampler.CompareMode;
1673          break;
1674       case GL_TEXTURE_COMPARE_FUNC_ARB:
1675          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1676              && !_mesa_is_gles3(ctx))
1677             goto invalid_pname;
1678          *params = (GLint) obj->Sampler.CompareFunc;
1679          break;
1680       case GL_DEPTH_TEXTURE_MODE_ARB:
1681          if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
1682             goto invalid_pname;
1683          *params = (GLint) obj->DepthMode;
1684          break;
1685       case GL_TEXTURE_LOD_BIAS:
1686          if (ctx->API != API_OPENGL_COMPAT)
1687             goto invalid_pname;
1688
1689          *params = (GLint) obj->Sampler.LodBias;
1690          break;
1691       case GL_TEXTURE_CROP_RECT_OES:
1692          if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
1693             goto invalid_pname;
1694
1695          params[0] = obj->CropRect[0];
1696          params[1] = obj->CropRect[1];
1697          params[2] = obj->CropRect[2];
1698          params[3] = obj->CropRect[3];
1699          break;
1700       case GL_TEXTURE_SWIZZLE_R_EXT:
1701       case GL_TEXTURE_SWIZZLE_G_EXT:
1702       case GL_TEXTURE_SWIZZLE_B_EXT:
1703       case GL_TEXTURE_SWIZZLE_A_EXT:
1704          if ((!_mesa_is_desktop_gl(ctx)
1705               || !ctx->Extensions.EXT_texture_swizzle)
1706              && !_mesa_is_gles3(ctx))
1707             goto invalid_pname;
1708          *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
1709          break;
1710
1711       case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1712          if ((!_mesa_is_desktop_gl(ctx)
1713               || !ctx->Extensions.EXT_texture_swizzle)
1714              && !_mesa_is_gles3(ctx))
1715             goto invalid_pname;
1716          COPY_4V(params, obj->Swizzle);
1717          break;
1718
1719       case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1720          if (!_mesa_is_desktop_gl(ctx)
1721              || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
1722             goto invalid_pname;
1723          *params = (GLint) obj->Sampler.CubeMapSeamless;
1724          break;
1725
1726       case GL_TEXTURE_IMMUTABLE_FORMAT:
1727          if (!ctx->Extensions.ARB_texture_storage)
1728             goto invalid_pname;
1729          *params = (GLint) obj->Immutable;
1730          break;
1731
1732       case GL_TEXTURE_IMMUTABLE_LEVELS:
1733          if (!_mesa_is_gles3(ctx))
1734             goto invalid_pname;
1735          *params = obj->ImmutableLevels;
1736          break;
1737
1738       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1739          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
1740             goto invalid_pname;
1741          *params = obj->RequiredTextureImageUnits;
1742          break;
1743
1744       case GL_TEXTURE_SRGB_DECODE_EXT:
1745          if (!ctx->Extensions.EXT_texture_sRGB_decode)
1746             goto invalid_pname;
1747          *params = obj->Sampler.sRGBDecode;
1748          break;
1749
1750       default:
1751          goto invalid_pname;
1752    }
1753
1754    /* no error if we get here */
1755    _mesa_unlock_texture(ctx, obj);
1756    return;
1757
1758 invalid_pname:
1759    _mesa_unlock_texture(ctx, obj);
1760    _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
1761 }
1762
1763
1764 /** New in GL 3.0 */
1765 void GLAPIENTRY
1766 _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
1767 {
1768    struct gl_texture_object *texObj;
1769    GET_CURRENT_CONTEXT(ctx);
1770
1771    texObj = get_texobj(ctx, target, GL_TRUE);
1772    if (!texObj)
1773       return;
1774    
1775    switch (pname) {
1776    case GL_TEXTURE_BORDER_COLOR:
1777       COPY_4V(params, texObj->Sampler.BorderColor.i);
1778       break;
1779    default:
1780       _mesa_GetTexParameteriv(target, pname, params);
1781    }
1782 }
1783
1784
1785 /** New in GL 3.0 */
1786 void GLAPIENTRY
1787 _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
1788 {
1789    struct gl_texture_object *texObj;
1790    GET_CURRENT_CONTEXT(ctx);
1791
1792    texObj = get_texobj(ctx, target, GL_TRUE);
1793    if (!texObj)
1794       return;
1795    
1796    switch (pname) {
1797    case GL_TEXTURE_BORDER_COLOR:
1798       COPY_4V(params, texObj->Sampler.BorderColor.i);
1799       break;
1800    default:
1801       {
1802          GLint ip[4];
1803          _mesa_GetTexParameteriv(target, pname, ip);
1804          params[0] = ip[0];
1805          if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || 
1806              pname == GL_TEXTURE_CROP_RECT_OES) {
1807             params[1] = ip[1];
1808             params[2] = ip[2];
1809             params[3] = ip[3];
1810          }
1811       }
1812    }
1813 }