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