Home | History | Annotate | Download | only in main
      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/context.h"
     36 #include "main/enums.h"
     37 #include "main/formats.h"
     38 #include "main/glformats.h"
     39 #include "main/macros.h"
     40 #include "main/mtypes.h"
     41 #include "main/state.h"
     42 #include "main/texcompress.h"
     43 #include "main/texobj.h"
     44 #include "main/texparam.h"
     45 #include "main/teximage.h"
     46 #include "main/texstate.h"
     47 #include "program/prog_instruction.h"
     48 
     49 
     50 /**
     51  * Check if a coordinate wrap mode is supported for the texture target.
     52  * \return GL_TRUE if legal, GL_FALSE otherwise
     53  */
     54 static GLboolean
     55 validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
     56 {
     57    const struct gl_extensions * const e = & ctx->Extensions;
     58    const bool is_desktop_gl = _mesa_is_desktop_gl(ctx);
     59    bool supported;
     60 
     61    switch (wrap) {
     62    case GL_CLAMP:
     63       /* GL_CLAMP was removed in the core profile, and it has never existed in
     64        * OpenGL ES.
     65        */
     66       supported = (ctx->API == API_OPENGL_COMPAT)
     67          && (target != GL_TEXTURE_EXTERNAL_OES);
     68       break;
     69 
     70    case GL_CLAMP_TO_EDGE:
     71       supported = true;
     72       break;
     73 
     74    case GL_CLAMP_TO_BORDER:
     75       supported = ctx->API != API_OPENGLES && e->ARB_texture_border_clamp
     76          && (target != GL_TEXTURE_EXTERNAL_OES);
     77       break;
     78 
     79    case GL_REPEAT:
     80    case GL_MIRRORED_REPEAT:
     81       supported = (target != GL_TEXTURE_RECTANGLE_NV)
     82          && (target != GL_TEXTURE_EXTERNAL_OES);
     83       break;
     84 
     85    case GL_MIRROR_CLAMP_EXT:
     86       supported = is_desktop_gl
     87          && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
     88          && (target != GL_TEXTURE_RECTANGLE_NV)
     89          && (target != GL_TEXTURE_EXTERNAL_OES);
     90       break;
     91 
     92    case GL_MIRROR_CLAMP_TO_EDGE_EXT:
     93       supported = is_desktop_gl
     94          && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge)
     95          && (target != GL_TEXTURE_RECTANGLE_NV)
     96          && (target != GL_TEXTURE_EXTERNAL_OES);
     97       break;
     98 
     99    case GL_MIRROR_CLAMP_TO_BORDER_EXT:
    100       supported = is_desktop_gl && e->EXT_texture_mirror_clamp
    101          && (target != GL_TEXTURE_RECTANGLE_NV)
    102          && (target != GL_TEXTURE_EXTERNAL_OES);
    103       break;
    104 
    105    default:
    106       supported = false;
    107       break;
    108    }
    109 
    110    if (!supported)
    111       _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
    112 
    113    return supported;
    114 }
    115 
    116 
    117 /**
    118  * Get current texture object for given target.
    119  * Return NULL if any error (and record the error).
    120  * Note that this is different from _mesa_get_current_tex_object() in that
    121  * proxy targets are not accepted.
    122  * Only the glGetTexLevelParameter() functions accept proxy targets.
    123  */
    124 static struct gl_texture_object *
    125 get_texobj_by_target(struct gl_context *ctx, GLenum target, GLboolean get)
    126 {
    127    struct gl_texture_unit *texUnit;
    128    int targetIndex;
    129 
    130    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
    131       _mesa_error(ctx, GL_INVALID_OPERATION,
    132                   "gl%sTexParameter(current unit)", get ? "Get" : "");
    133       return NULL;
    134    }
    135 
    136    texUnit = _mesa_get_current_tex_unit(ctx);
    137 
    138    targetIndex = _mesa_tex_target_to_index(ctx, target);
    139    if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) {
    140       _mesa_error(ctx, GL_INVALID_ENUM,
    141                   "gl%sTexParameter(target)", get ? "Get" : "");
    142       return NULL;
    143    }
    144    assert(targetIndex < NUM_TEXTURE_TARGETS);
    145 
    146    return texUnit->CurrentTex[targetIndex];
    147 }
    148 
    149 /**
    150  * Get current texture object for given name.
    151  * Return NULL if any error (and record the error).
    152  * Note that proxy targets are not accepted.
    153  * Only the glGetTexLevelParameter() functions accept proxy targets.
    154  */
    155 static struct gl_texture_object *
    156 get_texobj_by_name(struct gl_context *ctx, GLuint texture, GLboolean get)
    157 {
    158    struct gl_texture_object *texObj;
    159 
    160    texObj = _mesa_lookup_texture(ctx, texture);
    161    if (!texObj) {
    162       /*
    163        * User passed a non-generated name.
    164        * Throw the error in the caller.
    165        */
    166       return NULL;
    167    }
    168 
    169    switch (texObj->Target) {
    170    case GL_TEXTURE_1D:
    171    case GL_TEXTURE_1D_ARRAY:
    172    case GL_TEXTURE_2D:
    173    case GL_TEXTURE_2D_ARRAY:
    174    case GL_TEXTURE_2D_MULTISAMPLE:
    175    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
    176    case GL_TEXTURE_3D:
    177    case GL_TEXTURE_CUBE_MAP:
    178    case GL_TEXTURE_CUBE_MAP_ARRAY:
    179    case GL_TEXTURE_RECTANGLE:
    180       return texObj;
    181    default:
    182       _mesa_error(ctx, GL_INVALID_ENUM,
    183                   "gl%sTextureParameter(target)", get ? "Get" : "");
    184       return NULL;
    185    }
    186 
    187 }
    188 
    189 
    190 /**
    191  * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
    192  * \return -1 if error.
    193  */
    194 static GLint
    195 comp_to_swizzle(GLenum comp)
    196 {
    197    switch (comp) {
    198    case GL_RED:
    199       return SWIZZLE_X;
    200    case GL_GREEN:
    201       return SWIZZLE_Y;
    202    case GL_BLUE:
    203       return SWIZZLE_Z;
    204    case GL_ALPHA:
    205       return SWIZZLE_W;
    206    case GL_ZERO:
    207       return SWIZZLE_ZERO;
    208    case GL_ONE:
    209       return SWIZZLE_ONE;
    210    default:
    211       return -1;
    212    }
    213 }
    214 
    215 
    216 static void
    217 set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
    218 {
    219    assert(comp < 4);
    220    assert(swz <= SWIZZLE_NIL);
    221    {
    222       GLuint mask = 0x7 << (3 * comp);
    223       GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
    224       *swizzle = s;
    225    }
    226 }
    227 
    228 
    229 /**
    230  * This is called just prior to changing any texture object state which
    231  * will not affect texture completeness.
    232  */
    233 static inline void
    234 flush(struct gl_context *ctx)
    235 {
    236    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
    237 }
    238 
    239 
    240 /**
    241  * This is called just prior to changing any texture object state which
    242  * could affect texture completeness (texture base level, max level).
    243  * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
    244  * state flag and then mark the texture object as 'incomplete' so that any
    245  * per-texture derived state gets recomputed.
    246  */
    247 static inline void
    248 incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
    249 {
    250    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
    251    _mesa_dirty_texobj(ctx, texObj);
    252 }
    253 
    254 
    255 GLboolean
    256 _mesa_target_allows_setting_sampler_parameters(GLenum target)
    257 {
    258    switch (target) {
    259    case GL_TEXTURE_2D_MULTISAMPLE:
    260    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
    261       return GL_FALSE;
    262 
    263    default:
    264       return GL_TRUE;
    265    }
    266 }
    267 
    268 
    269 /**
    270  * Set an integer-valued texture parameter
    271  * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
    272  */
    273 static GLboolean
    274 set_tex_parameteri(struct gl_context *ctx,
    275                    struct gl_texture_object *texObj,
    276                    GLenum pname, const GLint *params, bool dsa)
    277 {
    278    const char *suffix = dsa ? "ture" : "";
    279 
    280    switch (pname) {
    281    case GL_TEXTURE_MIN_FILTER:
    282       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    283          goto invalid_enum;
    284 
    285       if (texObj->Sampler.MinFilter == params[0])
    286          return GL_FALSE;
    287       switch (params[0]) {
    288       case GL_NEAREST:
    289       case GL_LINEAR:
    290          flush(ctx);
    291          texObj->Sampler.MinFilter = params[0];
    292          return GL_TRUE;
    293       case GL_NEAREST_MIPMAP_NEAREST:
    294       case GL_LINEAR_MIPMAP_NEAREST:
    295       case GL_NEAREST_MIPMAP_LINEAR:
    296       case GL_LINEAR_MIPMAP_LINEAR:
    297          if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
    298              texObj->Target != GL_TEXTURE_EXTERNAL_OES) {
    299             flush(ctx);
    300             texObj->Sampler.MinFilter = params[0];
    301             return GL_TRUE;
    302          }
    303          /* fall-through */
    304       default:
    305          goto invalid_param;
    306       }
    307       return GL_FALSE;
    308 
    309    case GL_TEXTURE_MAG_FILTER:
    310       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    311          goto invalid_enum;
    312 
    313       if (texObj->Sampler.MagFilter == params[0])
    314          return GL_FALSE;
    315       switch (params[0]) {
    316       case GL_NEAREST:
    317       case GL_LINEAR:
    318          flush(ctx); /* does not effect completeness */
    319          texObj->Sampler.MagFilter = params[0];
    320          return GL_TRUE;
    321       default:
    322          goto invalid_param;
    323       }
    324       return GL_FALSE;
    325 
    326    case GL_TEXTURE_WRAP_S:
    327       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    328          goto invalid_enum;
    329 
    330       if (texObj->Sampler.WrapS == params[0])
    331          return GL_FALSE;
    332       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
    333          flush(ctx);
    334          texObj->Sampler.WrapS = params[0];
    335          return GL_TRUE;
    336       }
    337       return GL_FALSE;
    338 
    339    case GL_TEXTURE_WRAP_T:
    340       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    341          goto invalid_enum;
    342 
    343       if (texObj->Sampler.WrapT == params[0])
    344          return GL_FALSE;
    345       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
    346          flush(ctx);
    347          texObj->Sampler.WrapT = params[0];
    348          return GL_TRUE;
    349       }
    350       return GL_FALSE;
    351 
    352    case GL_TEXTURE_WRAP_R:
    353       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    354          goto invalid_enum;
    355 
    356       if (texObj->Sampler.WrapR == params[0])
    357          return GL_FALSE;
    358       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
    359          flush(ctx);
    360          texObj->Sampler.WrapR = params[0];
    361          return GL_TRUE;
    362       }
    363       return GL_FALSE;
    364 
    365    case GL_TEXTURE_BASE_LEVEL:
    366       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
    367          goto invalid_pname;
    368 
    369       if (texObj->BaseLevel == params[0])
    370          return GL_FALSE;
    371 
    372       if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
    373            texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0)
    374          goto invalid_operation;
    375 
    376       if (params[0] < 0) {
    377          _mesa_error(ctx, GL_INVALID_VALUE,
    378                      "glTex%sParameter(param=%d)", suffix, params[0]);
    379          return GL_FALSE;
    380       }
    381       if (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0) {
    382          _mesa_error(ctx, GL_INVALID_OPERATION,
    383                      "glTex%sParameter(target=%s, param=%d)", suffix,
    384                      _mesa_enum_to_string(texObj->Target), params[0]);
    385          return GL_FALSE;
    386       }
    387       incomplete(ctx, texObj);
    388 
    389       /** See note about ARB_texture_storage below */
    390       if (texObj->Immutable)
    391          texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]);
    392       else
    393          texObj->BaseLevel = params[0];
    394 
    395       return GL_TRUE;
    396 
    397    case GL_TEXTURE_MAX_LEVEL:
    398       if (texObj->MaxLevel == params[0])
    399          return GL_FALSE;
    400 
    401       if (params[0] < 0 ||
    402           (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) {
    403          _mesa_error(ctx, GL_INVALID_VALUE,
    404                      "glTex%sParameter(param=%d)", suffix,
    405                      params[0]);
    406          return GL_FALSE;
    407       }
    408       incomplete(ctx, texObj);
    409 
    410       /** From ARB_texture_storage:
    411        * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is
    412        * clamped to the range [0, <levels> - 1] and level_max is then clamped to
    413        * the range [level_base, <levels> - 1], where <levels> is the parameter
    414        * passed the call to TexStorage* for the texture object.
    415        */
    416       if (texObj->Immutable)
    417           texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel,
    418                                    texObj->ImmutableLevels - 1);
    419       else
    420          texObj->MaxLevel = params[0];
    421 
    422       return GL_TRUE;
    423 
    424    case GL_GENERATE_MIPMAP_SGIS:
    425       if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
    426          goto invalid_pname;
    427 
    428       if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES)
    429          goto invalid_param;
    430       if (texObj->GenerateMipmap != params[0]) {
    431          /* no flush() */
    432 	 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
    433 	 return GL_TRUE;
    434       }
    435       return GL_FALSE;
    436 
    437    case GL_TEXTURE_COMPARE_MODE_ARB:
    438       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
    439           || _mesa_is_gles3(ctx)) {
    440 
    441          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    442             goto invalid_enum;
    443 
    444          if (texObj->Sampler.CompareMode == params[0])
    445             return GL_FALSE;
    446          if (params[0] == GL_NONE ||
    447              params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) {
    448             flush(ctx);
    449             texObj->Sampler.CompareMode = params[0];
    450             return GL_TRUE;
    451          }
    452          goto invalid_param;
    453       }
    454       goto invalid_pname;
    455 
    456    case GL_TEXTURE_COMPARE_FUNC_ARB:
    457       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
    458           || _mesa_is_gles3(ctx)) {
    459 
    460          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    461             goto invalid_enum;
    462 
    463          if (texObj->Sampler.CompareFunc == params[0])
    464             return GL_FALSE;
    465          switch (params[0]) {
    466          case GL_LEQUAL:
    467          case GL_GEQUAL:
    468          case GL_EQUAL:
    469          case GL_NOTEQUAL:
    470          case GL_LESS:
    471          case GL_GREATER:
    472          case GL_ALWAYS:
    473          case GL_NEVER:
    474             flush(ctx);
    475             texObj->Sampler.CompareFunc = params[0];
    476             return GL_TRUE;
    477          default:
    478             goto invalid_param;
    479          }
    480       }
    481       goto invalid_pname;
    482 
    483    case GL_DEPTH_TEXTURE_MODE_ARB:
    484       /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never
    485        * existed in OpenGL ES.
    486        */
    487       if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) {
    488          if (texObj->DepthMode == params[0])
    489             return GL_FALSE;
    490          if (params[0] == GL_LUMINANCE ||
    491              params[0] == GL_INTENSITY ||
    492              params[0] == GL_ALPHA ||
    493              (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) {
    494             flush(ctx);
    495             texObj->DepthMode = params[0];
    496             return GL_TRUE;
    497          }
    498          goto invalid_param;
    499       }
    500       goto invalid_pname;
    501 
    502    case GL_DEPTH_STENCIL_TEXTURE_MODE:
    503       if (_mesa_has_ARB_stencil_texturing(ctx) || _mesa_is_gles31(ctx)) {
    504          bool stencil = params[0] == GL_STENCIL_INDEX;
    505          if (!stencil && params[0] != GL_DEPTH_COMPONENT)
    506             goto invalid_param;
    507 
    508          if (texObj->StencilSampling == stencil)
    509             return GL_FALSE;
    510 
    511          texObj->StencilSampling = stencil;
    512          return GL_TRUE;
    513       }
    514       goto invalid_pname;
    515 
    516    case GL_TEXTURE_CROP_RECT_OES:
    517       if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
    518          goto invalid_pname;
    519 
    520       texObj->CropRect[0] = params[0];
    521       texObj->CropRect[1] = params[1];
    522       texObj->CropRect[2] = params[2];
    523       texObj->CropRect[3] = params[3];
    524       return GL_TRUE;
    525 
    526    case GL_TEXTURE_SWIZZLE_R_EXT:
    527    case GL_TEXTURE_SWIZZLE_G_EXT:
    528    case GL_TEXTURE_SWIZZLE_B_EXT:
    529    case GL_TEXTURE_SWIZZLE_A_EXT:
    530       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
    531           || _mesa_is_gles3(ctx)) {
    532          const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
    533          const GLint swz = comp_to_swizzle(params[0]);
    534          if (swz < 0) {
    535             _mesa_error(ctx, GL_INVALID_ENUM,
    536                         "glTex%sParameter(swizzle 0x%x)", suffix, params[0]);
    537             return GL_FALSE;
    538          }
    539          assert(comp < 4);
    540 
    541          flush(ctx);
    542          texObj->Swizzle[comp] = params[0];
    543          set_swizzle_component(&texObj->_Swizzle, comp, swz);
    544          return GL_TRUE;
    545       }
    546       goto invalid_pname;
    547 
    548    case GL_TEXTURE_SWIZZLE_RGBA_EXT:
    549       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
    550           || _mesa_is_gles3(ctx)) {
    551          GLuint comp;
    552          flush(ctx);
    553          for (comp = 0; comp < 4; comp++) {
    554             const GLint swz = comp_to_swizzle(params[comp]);
    555             if (swz >= 0) {
    556                texObj->Swizzle[comp] = params[comp];
    557                set_swizzle_component(&texObj->_Swizzle, comp, swz);
    558             }
    559             else {
    560                _mesa_error(ctx, GL_INVALID_ENUM,
    561                            "glTex%sParameter(swizzle 0x%x)",
    562                            suffix, params[comp]);
    563                return GL_FALSE;
    564             }
    565          }
    566          return GL_TRUE;
    567       }
    568       goto invalid_pname;
    569 
    570    case GL_TEXTURE_SRGB_DECODE_EXT:
    571       if (ctx->Extensions.EXT_texture_sRGB_decode) {
    572          GLenum decode = params[0];
    573 
    574          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    575             goto invalid_enum;
    576 
    577 	 if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
    578 	    if (texObj->Sampler.sRGBDecode != decode) {
    579 	       flush(ctx);
    580 	       texObj->Sampler.sRGBDecode = decode;
    581 	    }
    582 	    return GL_TRUE;
    583 	 }
    584       }
    585       goto invalid_pname;
    586 
    587    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
    588       if (_mesa_is_desktop_gl(ctx)
    589           && ctx->Extensions.AMD_seamless_cubemap_per_texture) {
    590          GLenum param = params[0];
    591 
    592          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    593             goto invalid_enum;
    594 
    595          if (param != GL_TRUE && param != GL_FALSE) {
    596             goto invalid_param;
    597          }
    598          if (param != texObj->Sampler.CubeMapSeamless) {
    599             flush(ctx);
    600             texObj->Sampler.CubeMapSeamless = param;
    601          }
    602          return GL_TRUE;
    603       }
    604       goto invalid_pname;
    605 
    606    default:
    607       goto invalid_pname;
    608    }
    609 
    610 invalid_pname:
    611    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
    612                suffix, _mesa_enum_to_string(pname));
    613    return GL_FALSE;
    614 
    615 invalid_param:
    616    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(param=%s)",
    617                suffix, _mesa_enum_to_string(params[0]));
    618    return GL_FALSE;
    619 
    620 invalid_operation:
    621    _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)",
    622                suffix, _mesa_enum_to_string(pname));
    623    return GL_FALSE;
    624 
    625 invalid_enum:
    626    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
    627                suffix, _mesa_enum_to_string(pname));
    628    return GL_FALSE;
    629 }
    630 
    631 
    632 /**
    633  * Set a float-valued texture parameter
    634  * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
    635  */
    636 static GLboolean
    637 set_tex_parameterf(struct gl_context *ctx,
    638                    struct gl_texture_object *texObj,
    639                    GLenum pname, const GLfloat *params, bool dsa)
    640 {
    641    const char *suffix = dsa ? "ture" : "";
    642 
    643    switch (pname) {
    644    case GL_TEXTURE_MIN_LOD:
    645       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
    646          goto invalid_pname;
    647 
    648       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    649          goto invalid_enum;
    650 
    651       if (texObj->Sampler.MinLod == params[0])
    652          return GL_FALSE;
    653       flush(ctx);
    654       texObj->Sampler.MinLod = params[0];
    655       return GL_TRUE;
    656 
    657    case GL_TEXTURE_MAX_LOD:
    658       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
    659          goto invalid_pname;
    660 
    661       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    662          goto invalid_enum;
    663 
    664       if (texObj->Sampler.MaxLod == params[0])
    665          return GL_FALSE;
    666       flush(ctx);
    667       texObj->Sampler.MaxLod = params[0];
    668       return GL_TRUE;
    669 
    670    case GL_TEXTURE_PRIORITY:
    671       if (ctx->API != API_OPENGL_COMPAT)
    672          goto invalid_pname;
    673 
    674       flush(ctx);
    675       texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
    676       return GL_TRUE;
    677 
    678    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
    679       if (ctx->Extensions.EXT_texture_filter_anisotropic) {
    680          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    681             goto invalid_enum;
    682 
    683          if (texObj->Sampler.MaxAnisotropy == params[0])
    684             return GL_FALSE;
    685          if (params[0] < 1.0F) {
    686             _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sParameter(param)",
    687                         suffix);
    688             return GL_FALSE;
    689          }
    690          flush(ctx);
    691          /* clamp to max, that's what NVIDIA does */
    692          texObj->Sampler.MaxAnisotropy = MIN2(params[0],
    693                                       ctx->Const.MaxTextureMaxAnisotropy);
    694          return GL_TRUE;
    695       }
    696       else {
    697          static GLuint count = 0;
    698          if (count++ < 10)
    699             goto invalid_pname;
    700       }
    701       return GL_FALSE;
    702 
    703    case GL_TEXTURE_LOD_BIAS:
    704       /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */
    705       if (_mesa_is_gles(ctx))
    706          goto invalid_pname;
    707 
    708       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    709          goto invalid_enum;
    710 
    711       if (texObj->Sampler.LodBias != params[0]) {
    712 	 flush(ctx);
    713 	 texObj->Sampler.LodBias = params[0];
    714 	 return GL_TRUE;
    715       }
    716       break;
    717 
    718    case GL_TEXTURE_BORDER_COLOR:
    719       if (ctx->API == API_OPENGLES ||
    720           !ctx->Extensions.ARB_texture_border_clamp)
    721          goto invalid_pname;
    722 
    723       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
    724          goto invalid_enum;
    725 
    726       flush(ctx);
    727       /* ARB_texture_float disables clamping */
    728       if (ctx->Extensions.ARB_texture_float) {
    729          texObj->Sampler.BorderColor.f[RCOMP] = params[0];
    730          texObj->Sampler.BorderColor.f[GCOMP] = params[1];
    731          texObj->Sampler.BorderColor.f[BCOMP] = params[2];
    732          texObj->Sampler.BorderColor.f[ACOMP] = params[3];
    733       } else {
    734          texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
    735          texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
    736          texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
    737          texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
    738       }
    739       return GL_TRUE;
    740 
    741    default:
    742       goto invalid_pname;
    743    }
    744    return GL_FALSE;
    745 
    746 invalid_pname:
    747    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
    748                suffix, _mesa_enum_to_string(pname));
    749    return GL_FALSE;
    750 
    751 invalid_enum:
    752    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
    753                suffix, _mesa_enum_to_string(pname));
    754    return GL_FALSE;
    755 }
    756 
    757 
    758 void
    759 _mesa_texture_parameterf(struct gl_context *ctx,
    760                          struct gl_texture_object *texObj,
    761                          GLenum pname, GLfloat param, bool dsa)
    762 {
    763    GLboolean need_update;
    764 
    765    switch (pname) {
    766    case GL_TEXTURE_MIN_FILTER:
    767    case GL_TEXTURE_MAG_FILTER:
    768    case GL_TEXTURE_WRAP_S:
    769    case GL_TEXTURE_WRAP_T:
    770    case GL_TEXTURE_WRAP_R:
    771    case GL_TEXTURE_BASE_LEVEL:
    772    case GL_TEXTURE_MAX_LEVEL:
    773    case GL_GENERATE_MIPMAP_SGIS:
    774    case GL_TEXTURE_COMPARE_MODE_ARB:
    775    case GL_TEXTURE_COMPARE_FUNC_ARB:
    776    case GL_DEPTH_TEXTURE_MODE_ARB:
    777    case GL_DEPTH_STENCIL_TEXTURE_MODE:
    778    case GL_TEXTURE_SRGB_DECODE_EXT:
    779    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
    780    case GL_TEXTURE_SWIZZLE_R_EXT:
    781    case GL_TEXTURE_SWIZZLE_G_EXT:
    782    case GL_TEXTURE_SWIZZLE_B_EXT:
    783    case GL_TEXTURE_SWIZZLE_A_EXT:
    784       {
    785          GLint p[4];
    786          p[0] = (param > 0) ?
    787                 ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
    788                 ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
    789 
    790          p[1] = p[2] = p[3] = 0;
    791          need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
    792       }
    793       break;
    794    case GL_TEXTURE_BORDER_COLOR:
    795    case GL_TEXTURE_SWIZZLE_RGBA:
    796       _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameterf(non-scalar pname)",
    797                   dsa ? "ture" : "");
    798       return;
    799    default:
    800       {
    801          /* this will generate an error if pname is illegal */
    802          GLfloat p[4];
    803          p[0] = param;
    804          p[1] = p[2] = p[3] = 0.0F;
    805          need_update = set_tex_parameterf(ctx, texObj, pname, p, dsa);
    806       }
    807    }
    808 
    809    if (ctx->Driver.TexParameter && need_update) {
    810       ctx->Driver.TexParameter(ctx, texObj, pname);
    811    }
    812 }
    813 
    814 
    815 void
    816 _mesa_texture_parameterfv(struct gl_context *ctx,
    817                           struct gl_texture_object *texObj,
    818                           GLenum pname, const GLfloat *params, bool dsa)
    819 {
    820    GLboolean need_update;
    821    switch (pname) {
    822    case GL_TEXTURE_MIN_FILTER:
    823    case GL_TEXTURE_MAG_FILTER:
    824    case GL_TEXTURE_WRAP_S:
    825    case GL_TEXTURE_WRAP_T:
    826    case GL_TEXTURE_WRAP_R:
    827    case GL_TEXTURE_BASE_LEVEL:
    828    case GL_TEXTURE_MAX_LEVEL:
    829    case GL_GENERATE_MIPMAP_SGIS:
    830    case GL_TEXTURE_COMPARE_MODE_ARB:
    831    case GL_TEXTURE_COMPARE_FUNC_ARB:
    832    case GL_DEPTH_TEXTURE_MODE_ARB:
    833    case GL_DEPTH_STENCIL_TEXTURE_MODE:
    834    case GL_TEXTURE_SRGB_DECODE_EXT:
    835    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
    836       {
    837          /* convert float param to int */
    838          GLint p[4];
    839          p[0] = (GLint) params[0];
    840          p[1] = p[2] = p[3] = 0;
    841          need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
    842       }
    843       break;
    844    case GL_TEXTURE_CROP_RECT_OES:
    845       {
    846          /* convert float params to int */
    847          GLint iparams[4];
    848          iparams[0] = (GLint) params[0];
    849          iparams[1] = (GLint) params[1];
    850          iparams[2] = (GLint) params[2];
    851          iparams[3] = (GLint) params[3];
    852          need_update = set_tex_parameteri(ctx, texObj, pname, iparams, dsa);
    853       }
    854       break;
    855    case GL_TEXTURE_SWIZZLE_R_EXT:
    856    case GL_TEXTURE_SWIZZLE_G_EXT:
    857    case GL_TEXTURE_SWIZZLE_B_EXT:
    858    case GL_TEXTURE_SWIZZLE_A_EXT:
    859    case GL_TEXTURE_SWIZZLE_RGBA_EXT:
    860       {
    861          GLint p[4] = {0, 0, 0, 0};
    862          p[0] = (GLint) params[0];
    863          if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
    864             p[1] = (GLint) params[1];
    865             p[2] = (GLint) params[2];
    866             p[3] = (GLint) params[3];
    867          }
    868          need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
    869       }
    870       break;
    871    default:
    872       /* this will generate an error if pname is illegal */
    873       need_update = set_tex_parameterf(ctx, texObj, pname, params, dsa);
    874    }
    875 
    876    if (ctx->Driver.TexParameter && need_update) {
    877       ctx->Driver.TexParameter(ctx, texObj, pname);
    878    }
    879 }
    880 
    881 
    882 void
    883 _mesa_texture_parameteri(struct gl_context *ctx,
    884                          struct gl_texture_object *texObj,
    885                          GLenum pname, GLint param, bool dsa)
    886 {
    887    GLboolean need_update;
    888    switch (pname) {
    889    case GL_TEXTURE_MIN_LOD:
    890    case GL_TEXTURE_MAX_LOD:
    891    case GL_TEXTURE_PRIORITY:
    892    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
    893    case GL_TEXTURE_LOD_BIAS:
    894    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
    895       {
    896          GLfloat fparam[4];
    897          fparam[0] = (GLfloat) param;
    898          fparam[1] = fparam[2] = fparam[3] = 0.0F;
    899          /* convert int param to float */
    900          need_update = set_tex_parameterf(ctx, texObj, pname, fparam, dsa);
    901       }
    902       break;
    903    case GL_TEXTURE_BORDER_COLOR:
    904    case GL_TEXTURE_SWIZZLE_RGBA:
    905       {
    906          _mesa_error(ctx, GL_INVALID_ENUM,
    907                      "glTex%sParameteri(non-scalar pname)",
    908                      dsa ? "ture" : "");
    909          return;
    910       }
    911    default:
    912       /* this will generate an error if pname is illegal */
    913       {
    914          GLint iparam[4];
    915          iparam[0] = param;
    916          iparam[1] = iparam[2] = iparam[3] = 0;
    917          need_update = set_tex_parameteri(ctx, texObj, pname, iparam, dsa);
    918       }
    919    }
    920 
    921    if (ctx->Driver.TexParameter && need_update) {
    922       ctx->Driver.TexParameter(ctx, texObj, pname);
    923    }
    924 }
    925 
    926 
    927 void
    928 _mesa_texture_parameteriv(struct gl_context *ctx,
    929                           struct gl_texture_object *texObj,
    930                           GLenum pname, const GLint *params, bool dsa)
    931 {
    932    GLboolean need_update;
    933 
    934    switch (pname) {
    935    case GL_TEXTURE_BORDER_COLOR:
    936       {
    937          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) {
    938             _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameteriv(texture)");
    939             return;
    940          }
    941          /* convert int params to float */
    942          GLfloat fparams[4];
    943          fparams[0] = INT_TO_FLOAT(params[0]);
    944          fparams[1] = INT_TO_FLOAT(params[1]);
    945          fparams[2] = INT_TO_FLOAT(params[2]);
    946          fparams[3] = INT_TO_FLOAT(params[3]);
    947          need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa);
    948       }
    949       break;
    950    case GL_TEXTURE_MIN_LOD:
    951    case GL_TEXTURE_MAX_LOD:
    952    case GL_TEXTURE_PRIORITY:
    953    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
    954    case GL_TEXTURE_LOD_BIAS:
    955    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
    956       {
    957          /* convert int param to float */
    958          GLfloat fparams[4];
    959          fparams[0] = (GLfloat) params[0];
    960          fparams[1] = fparams[2] = fparams[3] = 0.0F;
    961          need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa);
    962       }
    963       break;
    964    default:
    965       /* this will generate an error if pname is illegal */
    966       need_update = set_tex_parameteri(ctx, texObj, pname, params, dsa);
    967    }
    968 
    969    if (ctx->Driver.TexParameter && need_update) {
    970       ctx->Driver.TexParameter(ctx, texObj, pname);
    971    }
    972 }
    973 
    974 void
    975 _mesa_texture_parameterIiv(struct gl_context *ctx,
    976                            struct gl_texture_object *texObj,
    977                            GLenum pname, const GLint *params, bool dsa)
    978 {
    979    switch (pname) {
    980    case GL_TEXTURE_BORDER_COLOR:
    981       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) {
    982          _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIiv(texture)");
    983          return;
    984       }
    985       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
    986       /* set the integer-valued border color */
    987       COPY_4V(texObj->Sampler.BorderColor.i, params);
    988       break;
    989    default:
    990       _mesa_texture_parameteriv(ctx, texObj, pname, params, dsa);
    991       break;
    992    }
    993    /* XXX no driver hook for TexParameterIiv() yet */
    994 }
    995 
    996 void
    997 _mesa_texture_parameterIuiv(struct gl_context *ctx,
    998                             struct gl_texture_object *texObj,
    999                             GLenum pname, const GLuint *params, bool dsa)
   1000 {
   1001    switch (pname) {
   1002    case GL_TEXTURE_BORDER_COLOR:
   1003       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) {
   1004          _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIuiv(texture)");
   1005          return;
   1006       }
   1007       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
   1008       /* set the unsigned integer-valued border color */
   1009       COPY_4V(texObj->Sampler.BorderColor.ui, params);
   1010       break;
   1011    default:
   1012       _mesa_texture_parameteriv(ctx, texObj, pname, (const GLint *) params,
   1013                                 dsa);
   1014       break;
   1015    }
   1016    /* XXX no driver hook for TexParameterIuiv() yet */
   1017 }
   1018 
   1019 void GLAPIENTRY
   1020 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
   1021 {
   1022    struct gl_texture_object *texObj;
   1023    GET_CURRENT_CONTEXT(ctx);
   1024 
   1025    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
   1026    if (!texObj)
   1027       return;
   1028 
   1029    _mesa_texture_parameterf(ctx, texObj, pname, param, false);
   1030 }
   1031 
   1032 void GLAPIENTRY
   1033 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
   1034 {
   1035    struct gl_texture_object *texObj;
   1036    GET_CURRENT_CONTEXT(ctx);
   1037 
   1038    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
   1039    if (!texObj)
   1040       return;
   1041 
   1042    _mesa_texture_parameterfv(ctx, texObj, pname, params, false);
   1043 }
   1044 
   1045 void GLAPIENTRY
   1046 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
   1047 {
   1048    struct gl_texture_object *texObj;
   1049    GET_CURRENT_CONTEXT(ctx);
   1050 
   1051    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
   1052    if (!texObj)
   1053       return;
   1054 
   1055    _mesa_texture_parameteri(ctx, texObj, pname, param, false);
   1056 }
   1057 
   1058 void GLAPIENTRY
   1059 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
   1060 {
   1061    struct gl_texture_object *texObj;
   1062    GET_CURRENT_CONTEXT(ctx);
   1063 
   1064    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
   1065    if (!texObj)
   1066       return;
   1067 
   1068    _mesa_texture_parameteriv(ctx, texObj, pname, params, false);
   1069 }
   1070 
   1071 /**
   1072  * Set tex parameter to integer value(s).  Primarily intended to set
   1073  * integer-valued texture border color (for integer-valued textures).
   1074  * New in GL 3.0.
   1075  */
   1076 void GLAPIENTRY
   1077 _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
   1078 {
   1079    struct gl_texture_object *texObj;
   1080    GET_CURRENT_CONTEXT(ctx);
   1081 
   1082    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
   1083    if (!texObj)
   1084       return;
   1085 
   1086    _mesa_texture_parameterIiv(ctx, texObj, pname, params, false);
   1087 }
   1088 
   1089 /**
   1090  * Set tex parameter to unsigned integer value(s).  Primarily intended to set
   1091  * uint-valued texture border color (for integer-valued textures).
   1092  * New in GL 3.0
   1093  */
   1094 void GLAPIENTRY
   1095 _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
   1096 {
   1097    struct gl_texture_object *texObj;
   1098    GET_CURRENT_CONTEXT(ctx);
   1099 
   1100    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
   1101    if (!texObj)
   1102       return;
   1103 
   1104    _mesa_texture_parameterIuiv(ctx, texObj, pname, params, false);
   1105 }
   1106 
   1107 
   1108 void GLAPIENTRY
   1109 _mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params)
   1110 {
   1111    struct gl_texture_object *texObj;
   1112    GET_CURRENT_CONTEXT(ctx);
   1113 
   1114    texObj = get_texobj_by_name(ctx, texture, GL_FALSE);
   1115    if (!texObj) {
   1116       /* User passed a non-generated name. */
   1117       _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfv(texture)");
   1118       return;
   1119    }
   1120 
   1121    _mesa_texture_parameterfv(ctx, texObj, pname, params, true);
   1122 }
   1123 
   1124 void GLAPIENTRY
   1125 _mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param)
   1126 {
   1127    struct gl_texture_object *texObj;
   1128    GET_CURRENT_CONTEXT(ctx);
   1129 
   1130    texObj = get_texobj_by_name(ctx, texture, GL_FALSE);
   1131    if (!texObj) {
   1132       /* User passed a non-generated name. */
   1133       _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterf(texture)");
   1134       return;
   1135    }
   1136 
   1137    _mesa_texture_parameterf(ctx, texObj, pname, param, true);
   1138 }
   1139 
   1140 void GLAPIENTRY
   1141 _mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param)
   1142 {
   1143    struct gl_texture_object *texObj;
   1144    GET_CURRENT_CONTEXT(ctx);
   1145 
   1146    texObj = get_texobj_by_name(ctx, texture, GL_FALSE);
   1147    if (!texObj) {
   1148       /* User passed a non-generated name. */
   1149       _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteri(texture)");
   1150       return;
   1151    }
   1152 
   1153    _mesa_texture_parameteri(ctx, texObj, pname, param, true);
   1154 }
   1155 
   1156 void GLAPIENTRY
   1157 _mesa_TextureParameteriv(GLuint texture, GLenum pname,
   1158                          const GLint *params)
   1159 {
   1160    struct gl_texture_object *texObj;
   1161    GET_CURRENT_CONTEXT(ctx);
   1162 
   1163    texObj = get_texobj_by_name(ctx, texture, GL_FALSE);
   1164    if (!texObj) {
   1165       /* User passed a non-generated name. */
   1166       _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteriv(texture)");
   1167       return;
   1168    }
   1169 
   1170    _mesa_texture_parameteriv(ctx, texObj, pname, params, true);
   1171 }
   1172 
   1173 
   1174 void GLAPIENTRY
   1175 _mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params)
   1176 {
   1177    struct gl_texture_object *texObj;
   1178    GET_CURRENT_CONTEXT(ctx);
   1179 
   1180    texObj = get_texobj_by_name(ctx, texture, GL_FALSE);
   1181    if (!texObj) {
   1182       /* User passed a non-generated name. */
   1183       _mesa_error(ctx, GL_INVALID_OPERATION,
   1184                   "glTextureParameterIiv(texture)");
   1185       return;
   1186    }
   1187 
   1188    _mesa_texture_parameterIiv(ctx, texObj, pname, params, true);
   1189 }
   1190 
   1191 void GLAPIENTRY
   1192 _mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params)
   1193 {
   1194    struct gl_texture_object *texObj;
   1195    GET_CURRENT_CONTEXT(ctx);
   1196 
   1197    texObj = get_texobj_by_name(ctx, texture, GL_FALSE);
   1198    if (!texObj) {
   1199       /* User passed a non-generated name. */
   1200       _mesa_error(ctx, GL_INVALID_OPERATION,
   1201                   "glTextureParameterIuiv(texture)");
   1202       return;
   1203    }
   1204 
   1205    _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true);
   1206 }
   1207 
   1208 GLboolean
   1209 _mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target,
   1210                                            bool dsa)
   1211 {
   1212    /* Common targets for desktop GL and GLES 3.1. */
   1213    switch (target) {
   1214    case GL_TEXTURE_2D:
   1215    case GL_TEXTURE_3D:
   1216       return GL_TRUE;
   1217    case GL_TEXTURE_2D_ARRAY_EXT:
   1218       return ctx->Extensions.EXT_texture_array;
   1219    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   1220    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   1221    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   1222    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   1223    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   1224    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   1225       return ctx->Extensions.ARB_texture_cube_map;
   1226    case GL_TEXTURE_2D_MULTISAMPLE:
   1227    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1228       return ctx->Extensions.ARB_texture_multisample;
   1229    case GL_TEXTURE_BUFFER:
   1230       /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
   1231        * but not in earlier versions that expose ARB_texture_buffer_object.
   1232        *
   1233        * From the ARB_texture_buffer_object spec:
   1234        * "(7) Do buffer textures support texture parameters (TexParameter) or
   1235        *      queries (GetTexParameter, GetTexLevelParameter, GetTexImage)?
   1236        *
   1237        *    RESOLVED:  No. [...] Note that the spec edits above don't add
   1238        *    explicit error language for any of these cases.  That is because
   1239        *    each of the functions enumerate the set of valid <target>
   1240        *    parameters.  Not editing the spec to allow TEXTURE_BUFFER_ARB in
   1241        *    these cases means that target is not legal, and an INVALID_ENUM
   1242        *    error should be generated."
   1243        *
   1244        * From the OpenGL 3.1 spec:
   1245        * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
   1246        */
   1247       return (ctx->API == API_OPENGL_CORE && ctx->Version >= 31) ||
   1248          _mesa_has_OES_texture_buffer(ctx);
   1249    case GL_TEXTURE_CUBE_MAP_ARRAY:
   1250       return _mesa_has_texture_cube_map_array(ctx);
   1251    }
   1252 
   1253    if (!_mesa_is_desktop_gl(ctx))
   1254       return GL_FALSE;
   1255 
   1256    /* Rest of the desktop GL targets. */
   1257    switch (target) {
   1258    case GL_TEXTURE_1D:
   1259    case GL_PROXY_TEXTURE_1D:
   1260    case GL_PROXY_TEXTURE_2D:
   1261    case GL_PROXY_TEXTURE_3D:
   1262       return GL_TRUE;
   1263    case GL_PROXY_TEXTURE_CUBE_MAP:
   1264       return ctx->Extensions.ARB_texture_cube_map;
   1265    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
   1266       return ctx->Extensions.ARB_texture_cube_map_array;
   1267    case GL_TEXTURE_RECTANGLE_NV:
   1268    case GL_PROXY_TEXTURE_RECTANGLE_NV:
   1269       return ctx->Extensions.NV_texture_rectangle;
   1270    case GL_TEXTURE_1D_ARRAY_EXT:
   1271    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
   1272    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
   1273       return ctx->Extensions.EXT_texture_array;
   1274    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
   1275    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
   1276       return ctx->Extensions.ARB_texture_multisample;
   1277 
   1278    /*  This is a valid target for dsa, but the OpenGL 4.5 core spec
   1279     *  (30.10.2014) Section 8.11 Texture Queries says:
   1280     *       "For GetTextureLevelParameter* only, texture may also be a cube
   1281     *       map texture object.  In this case the query is always performed
   1282     *       for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there
   1283     *       is no way to specify another face."
   1284     */
   1285    case GL_TEXTURE_CUBE_MAP:
   1286       return dsa;
   1287    default:
   1288       return GL_FALSE;
   1289    }
   1290 }
   1291 
   1292 
   1293 static void
   1294 get_tex_level_parameter_image(struct gl_context *ctx,
   1295                               const struct gl_texture_object *texObj,
   1296                               GLenum target, GLint level,
   1297                               GLenum pname, GLint *params,
   1298                               bool dsa)
   1299 {
   1300    const struct gl_texture_image *img = NULL;
   1301    struct gl_texture_image dummy_image;
   1302    mesa_format texFormat;
   1303    const char *suffix = dsa ? "ture" : "";
   1304 
   1305    img = _mesa_select_tex_image(texObj, target, level);
   1306    if (!img || img->TexFormat == MESA_FORMAT_NONE) {
   1307       /* In case of undefined texture image return the default values.
   1308        *
   1309        * From OpenGL 4.0 spec, page 398:
   1310        *    "The initial internal format of a texel array is RGBA
   1311        *     instead of 1. TEXTURE_COMPONENTS is deprecated; always
   1312        *     use TEXTURE_INTERNAL_FORMAT."
   1313        */
   1314       memset(&dummy_image, 0, sizeof(dummy_image));
   1315       dummy_image.TexFormat = MESA_FORMAT_NONE;
   1316       dummy_image.InternalFormat = GL_RGBA;
   1317       dummy_image._BaseFormat = GL_NONE;
   1318       dummy_image.FixedSampleLocations = GL_TRUE;
   1319 
   1320       img = &dummy_image;
   1321    }
   1322 
   1323    texFormat = img->TexFormat;
   1324 
   1325    switch (pname) {
   1326       case GL_TEXTURE_WIDTH:
   1327          *params = img->Width;
   1328          break;
   1329       case GL_TEXTURE_HEIGHT:
   1330          *params = img->Height;
   1331          break;
   1332       case GL_TEXTURE_DEPTH:
   1333          *params = img->Depth;
   1334          break;
   1335       case GL_TEXTURE_INTERNAL_FORMAT:
   1336          if (_mesa_is_format_compressed(texFormat)) {
   1337             /* need to return the actual compressed format */
   1338             *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
   1339          }
   1340          else {
   1341 	    /* If the true internal format is not compressed but the user
   1342 	     * requested a generic compressed format, we have to return the
   1343 	     * generic base format that matches.
   1344 	     *
   1345 	     * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
   1346 	     *
   1347 	     *     "If no specific compressed format is available,
   1348 	     *     internalformat is instead replaced by the corresponding base
   1349 	     *     internal format."
   1350 	     *
   1351 	     * Otherwise just return the user's requested internal format
   1352 	     */
   1353 	    const GLenum f =
   1354 	       _mesa_gl_compressed_format_base_format(img->InternalFormat);
   1355 
   1356 	    *params = (f != 0) ? f : img->InternalFormat;
   1357 	 }
   1358          break;
   1359       case GL_TEXTURE_BORDER:
   1360          if (ctx->API != API_OPENGL_COMPAT)
   1361             goto invalid_pname;
   1362          *params = img->Border;
   1363          break;
   1364       case GL_TEXTURE_RED_SIZE:
   1365       case GL_TEXTURE_GREEN_SIZE:
   1366       case GL_TEXTURE_BLUE_SIZE:
   1367       case GL_TEXTURE_ALPHA_SIZE:
   1368          if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
   1369             *params = _mesa_get_format_bits(texFormat, pname);
   1370          else
   1371             *params = 0;
   1372          break;
   1373       case GL_TEXTURE_INTENSITY_SIZE:
   1374       case GL_TEXTURE_LUMINANCE_SIZE:
   1375          if (ctx->API != API_OPENGL_COMPAT)
   1376             goto invalid_pname;
   1377          if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
   1378             *params = _mesa_get_format_bits(texFormat, pname);
   1379             if (*params == 0) {
   1380                /* intensity or luminance is probably stored as RGB[A] */
   1381                *params = MIN2(_mesa_get_format_bits(texFormat,
   1382                                                     GL_TEXTURE_RED_SIZE),
   1383                               _mesa_get_format_bits(texFormat,
   1384                                                     GL_TEXTURE_GREEN_SIZE));
   1385             }
   1386          }
   1387          else {
   1388             *params = 0;
   1389          }
   1390          break;
   1391       case GL_TEXTURE_DEPTH_SIZE_ARB:
   1392          if (!ctx->Extensions.ARB_depth_texture)
   1393             goto invalid_pname;
   1394          *params = _mesa_get_format_bits(texFormat, pname);
   1395          break;
   1396       case GL_TEXTURE_STENCIL_SIZE:
   1397          *params = _mesa_get_format_bits(texFormat, pname);
   1398          break;
   1399       case GL_TEXTURE_SHARED_SIZE:
   1400          if (ctx->Version < 30 &&
   1401              !ctx->Extensions.EXT_texture_shared_exponent)
   1402             goto invalid_pname;
   1403          *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0;
   1404          break;
   1405 
   1406       /* GL_ARB_texture_compression */
   1407       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
   1408 	 if (_mesa_is_format_compressed(texFormat) &&
   1409              !_mesa_is_proxy_texture(target)) {
   1410             *params = _mesa_format_image_size(texFormat, img->Width,
   1411                                               img->Height, img->Depth);
   1412     }
   1413     else {
   1414        _mesa_error(ctx, GL_INVALID_OPERATION,
   1415                    "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
   1416                    _mesa_enum_to_string(pname));
   1417     }
   1418          break;
   1419       case GL_TEXTURE_COMPRESSED:
   1420          *params = (GLint) _mesa_is_format_compressed(texFormat);
   1421          break;
   1422 
   1423       /* GL_ARB_texture_float */
   1424       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
   1425       case GL_TEXTURE_INTENSITY_TYPE_ARB:
   1426          if (ctx->API != API_OPENGL_COMPAT)
   1427             goto invalid_pname;
   1428          /* FALLTHROUGH */
   1429       case GL_TEXTURE_RED_TYPE_ARB:
   1430       case GL_TEXTURE_GREEN_TYPE_ARB:
   1431       case GL_TEXTURE_BLUE_TYPE_ARB:
   1432       case GL_TEXTURE_ALPHA_TYPE_ARB:
   1433       case GL_TEXTURE_DEPTH_TYPE_ARB:
   1434          if (!ctx->Extensions.ARB_texture_float)
   1435             goto invalid_pname;
   1436 	 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
   1437 	    *params = _mesa_get_format_datatype(texFormat);
   1438 	 else
   1439 	    *params = GL_NONE;
   1440          break;
   1441 
   1442       /* GL_ARB_texture_multisample */
   1443       case GL_TEXTURE_SAMPLES:
   1444          if (!ctx->Extensions.ARB_texture_multisample)
   1445             goto invalid_pname;
   1446          *params = img->NumSamples;
   1447          break;
   1448 
   1449       case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
   1450          if (!ctx->Extensions.ARB_texture_multisample)
   1451             goto invalid_pname;
   1452          *params = img->FixedSampleLocations;
   1453          break;
   1454 
   1455       /* There is never a buffer data store here, but these pnames still have
   1456        * to work.
   1457        */
   1458 
   1459       /* GL_ARB_texture_buffer_object */
   1460       case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
   1461          if (!ctx->Extensions.ARB_texture_buffer_object)
   1462             goto invalid_pname;
   1463          *params = 0;
   1464          break;
   1465 
   1466       /* GL_ARB_texture_buffer_range */
   1467       case GL_TEXTURE_BUFFER_OFFSET:
   1468          if (!ctx->Extensions.ARB_texture_buffer_range)
   1469             goto invalid_pname;
   1470          *params = 0;
   1471          break;
   1472       case GL_TEXTURE_BUFFER_SIZE:
   1473          if (!ctx->Extensions.ARB_texture_buffer_range)
   1474             goto invalid_pname;
   1475          *params = 0;
   1476          break;
   1477 
   1478       default:
   1479          goto invalid_pname;
   1480    }
   1481 
   1482    /* no error if we get here */
   1483    return;
   1484 
   1485 invalid_pname:
   1486    _mesa_error(ctx, GL_INVALID_ENUM,
   1487                "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
   1488                _mesa_enum_to_string(pname));
   1489 }
   1490 
   1491 
   1492 /**
   1493  * Handle a glGetTexLevelParamteriv() call for a texture buffer.
   1494  */
   1495 static void
   1496 get_tex_level_parameter_buffer(struct gl_context *ctx,
   1497                                const struct gl_texture_object *texObj,
   1498                                GLenum pname, GLint *params, bool dsa)
   1499 {
   1500    const struct gl_buffer_object *bo = texObj->BufferObject;
   1501    mesa_format texFormat = texObj->_BufferObjectFormat;
   1502    int bytes = MAX2(1, _mesa_get_format_bytes(texFormat));
   1503    GLenum internalFormat = texObj->BufferObjectFormat;
   1504    GLenum baseFormat = _mesa_get_format_base_format(texFormat);
   1505    const char *suffix = dsa ? "ture" : "";
   1506 
   1507    assert(texObj->Target == GL_TEXTURE_BUFFER);
   1508 
   1509    if (!bo) {
   1510       /* undefined texture buffer object */
   1511       switch (pname) {
   1512       case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
   1513          *params = GL_TRUE;
   1514          break;
   1515       case GL_TEXTURE_INTERNAL_FORMAT:
   1516          *params = internalFormat;
   1517          break;
   1518       default:
   1519          *params = 0;
   1520          break;
   1521       }
   1522       return;
   1523    }
   1524 
   1525    switch (pname) {
   1526       case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
   1527          *params = bo->Name;
   1528          break;
   1529       case GL_TEXTURE_WIDTH:
   1530          *params = ((texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize)
   1531             / bytes;
   1532          break;
   1533       case GL_TEXTURE_HEIGHT:
   1534       case GL_TEXTURE_DEPTH:
   1535          *params = 1;
   1536          break;
   1537       case GL_TEXTURE_BORDER:
   1538       case GL_TEXTURE_SHARED_SIZE:
   1539       case GL_TEXTURE_COMPRESSED:
   1540          *params = 0;
   1541          break;
   1542       case GL_TEXTURE_INTERNAL_FORMAT:
   1543          *params = internalFormat;
   1544          break;
   1545       case GL_TEXTURE_RED_SIZE:
   1546       case GL_TEXTURE_GREEN_SIZE:
   1547       case GL_TEXTURE_BLUE_SIZE:
   1548       case GL_TEXTURE_ALPHA_SIZE:
   1549          if (_mesa_base_format_has_channel(baseFormat, pname))
   1550             *params = _mesa_get_format_bits(texFormat, pname);
   1551          else
   1552             *params = 0;
   1553          break;
   1554       case GL_TEXTURE_INTENSITY_SIZE:
   1555       case GL_TEXTURE_LUMINANCE_SIZE:
   1556          if (_mesa_base_format_has_channel(baseFormat, pname)) {
   1557             *params = _mesa_get_format_bits(texFormat, pname);
   1558             if (*params == 0) {
   1559                /* intensity or luminance is probably stored as RGB[A] */
   1560                *params = MIN2(_mesa_get_format_bits(texFormat,
   1561                                                     GL_TEXTURE_RED_SIZE),
   1562                               _mesa_get_format_bits(texFormat,
   1563                                                     GL_TEXTURE_GREEN_SIZE));
   1564             }
   1565          } else {
   1566             *params = 0;
   1567          }
   1568          break;
   1569       case GL_TEXTURE_DEPTH_SIZE_ARB:
   1570       case GL_TEXTURE_STENCIL_SIZE_EXT:
   1571          *params = _mesa_get_format_bits(texFormat, pname);
   1572          break;
   1573 
   1574       /* GL_ARB_texture_buffer_range */
   1575       case GL_TEXTURE_BUFFER_OFFSET:
   1576          if (!ctx->Extensions.ARB_texture_buffer_range)
   1577             goto invalid_pname;
   1578          *params = texObj->BufferOffset;
   1579          break;
   1580       case GL_TEXTURE_BUFFER_SIZE:
   1581          if (!ctx->Extensions.ARB_texture_buffer_range)
   1582             goto invalid_pname;
   1583          *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
   1584          break;
   1585 
   1586       /* GL_ARB_texture_multisample */
   1587       case GL_TEXTURE_SAMPLES:
   1588          if (!ctx->Extensions.ARB_texture_multisample)
   1589             goto invalid_pname;
   1590          *params = 0;
   1591          break;
   1592 
   1593       case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
   1594          if (!ctx->Extensions.ARB_texture_multisample)
   1595             goto invalid_pname;
   1596          *params = GL_TRUE;
   1597          break;
   1598 
   1599       /* GL_ARB_texture_compression */
   1600       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
   1601          /* Always illegal for GL_TEXTURE_BUFFER */
   1602          _mesa_error(ctx, GL_INVALID_OPERATION,
   1603                      "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
   1604                      _mesa_enum_to_string(pname));
   1605          break;
   1606 
   1607       /* GL_ARB_texture_float */
   1608       case GL_TEXTURE_RED_TYPE_ARB:
   1609       case GL_TEXTURE_GREEN_TYPE_ARB:
   1610       case GL_TEXTURE_BLUE_TYPE_ARB:
   1611       case GL_TEXTURE_ALPHA_TYPE_ARB:
   1612       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
   1613       case GL_TEXTURE_INTENSITY_TYPE_ARB:
   1614       case GL_TEXTURE_DEPTH_TYPE_ARB:
   1615          if (!ctx->Extensions.ARB_texture_float)
   1616             goto invalid_pname;
   1617          if (_mesa_base_format_has_channel(baseFormat, pname))
   1618             *params = _mesa_get_format_datatype(texFormat);
   1619          else
   1620             *params = GL_NONE;
   1621          break;
   1622 
   1623       default:
   1624          goto invalid_pname;
   1625    }
   1626 
   1627    /* no error if we get here */
   1628    return;
   1629 
   1630 invalid_pname:
   1631    _mesa_error(ctx, GL_INVALID_ENUM,
   1632                "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
   1633                _mesa_enum_to_string(pname));
   1634 }
   1635 
   1636 static bool
   1637 valid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target,
   1638                                    bool dsa)
   1639 {
   1640    const char *suffix = dsa ? "ture" : "";
   1641    if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, dsa)) {
   1642       _mesa_error(ctx, GL_INVALID_ENUM,
   1643                   "glGetTex%sLevelParameter[if]v(target=%s)", suffix,
   1644                   _mesa_enum_to_string(target));
   1645       return false;
   1646    }
   1647    return true;
   1648 }
   1649 
   1650 /**
   1651  * This isn't exposed to the rest of the driver because it is a part of the
   1652  * OpenGL API that is rarely used.
   1653  */
   1654 static void
   1655 get_tex_level_parameteriv(struct gl_context *ctx,
   1656                           struct gl_texture_object *texObj,
   1657                           GLenum target, GLint level,
   1658                           GLenum pname, GLint *params,
   1659                           bool dsa)
   1660 {
   1661    GLint maxLevels;
   1662    const char *suffix = dsa ? "ture" : "";
   1663 
   1664    /* Check for errors */
   1665    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
   1666       _mesa_error(ctx, GL_INVALID_OPERATION,
   1667                   "glGetTex%sLevelParameter[if]v("
   1668                   "current unit >= max combined texture units)", suffix);
   1669       return;
   1670    }
   1671 
   1672    maxLevels = _mesa_max_texture_levels(ctx, target);
   1673    assert(maxLevels != 0);
   1674 
   1675    if (level < 0 || level >= maxLevels) {
   1676       _mesa_error(ctx, GL_INVALID_VALUE,
   1677                   "glGetTex%sLevelParameter[if]v(level out of range)", suffix);
   1678       return;
   1679    }
   1680 
   1681    /* Get the level parameter */
   1682    if (target == GL_TEXTURE_BUFFER) {
   1683       get_tex_level_parameter_buffer(ctx, texObj, pname, params, dsa);
   1684    }
   1685    else {
   1686       get_tex_level_parameter_image(ctx, texObj, target,
   1687                                     level, pname, params, dsa);
   1688    }
   1689 }
   1690 
   1691 void GLAPIENTRY
   1692 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
   1693                               GLenum pname, GLfloat *params )
   1694 {
   1695    struct gl_texture_object *texObj;
   1696    GLint iparam;
   1697    GET_CURRENT_CONTEXT(ctx);
   1698 
   1699    if (!valid_tex_level_parameteriv_target(ctx, target, false))
   1700       return;
   1701 
   1702    texObj = _mesa_get_current_tex_object(ctx, target);
   1703    if (!texObj)
   1704       return;
   1705 
   1706    get_tex_level_parameteriv(ctx, texObj, target, level,
   1707                              pname, &iparam, false);
   1708 
   1709    *params = (GLfloat) iparam;
   1710 }
   1711 
   1712 void GLAPIENTRY
   1713 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
   1714                               GLenum pname, GLint *params )
   1715 {
   1716    struct gl_texture_object *texObj;
   1717    GET_CURRENT_CONTEXT(ctx);
   1718 
   1719    if (!valid_tex_level_parameteriv_target(ctx, target, false))
   1720       return;
   1721 
   1722    texObj = _mesa_get_current_tex_object(ctx, target);
   1723    if (!texObj)
   1724       return;
   1725 
   1726    get_tex_level_parameteriv(ctx, texObj, target, level,
   1727                              pname, params, false);
   1728 }
   1729 
   1730 void GLAPIENTRY
   1731 _mesa_GetTextureLevelParameterfv(GLuint texture, GLint level,
   1732                                  GLenum pname, GLfloat *params)
   1733 {
   1734    struct gl_texture_object *texObj;
   1735    GLint iparam;
   1736    GET_CURRENT_CONTEXT(ctx);
   1737 
   1738    texObj = _mesa_lookup_texture_err(ctx, texture,
   1739                                      "glGetTextureLevelParameterfv");
   1740    if (!texObj)
   1741       return;
   1742 
   1743    if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
   1744       return;
   1745 
   1746    get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
   1747                              pname, &iparam, true);
   1748 
   1749    *params = (GLfloat) iparam;
   1750 }
   1751 
   1752 void GLAPIENTRY
   1753 _mesa_GetTextureLevelParameteriv(GLuint texture, GLint level,
   1754                                  GLenum pname, GLint *params)
   1755 {
   1756    struct gl_texture_object *texObj;
   1757    GET_CURRENT_CONTEXT(ctx);
   1758 
   1759    texObj = _mesa_lookup_texture_err(ctx, texture,
   1760                                      "glGetTextureLevelParameteriv");
   1761    if (!texObj)
   1762       return;
   1763 
   1764    if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
   1765       return;
   1766 
   1767    get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
   1768                              pname, params, true);
   1769 }
   1770 
   1771 /**
   1772  * This isn't exposed to the rest of the driver because it is a part of the
   1773  * OpenGL API that is rarely used.
   1774  */
   1775 static void
   1776 get_tex_parameterfv(struct gl_context *ctx,
   1777                     struct gl_texture_object *obj,
   1778                     GLenum pname, GLfloat *params, bool dsa)
   1779 {
   1780    _mesa_lock_context_textures(ctx);
   1781    switch (pname) {
   1782       case GL_TEXTURE_MAG_FILTER:
   1783 	 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
   1784 	 break;
   1785       case GL_TEXTURE_MIN_FILTER:
   1786          *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
   1787          break;
   1788       case GL_TEXTURE_WRAP_S:
   1789          *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
   1790          break;
   1791       case GL_TEXTURE_WRAP_T:
   1792          *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
   1793          break;
   1794       case GL_TEXTURE_WRAP_R:
   1795          *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
   1796          break;
   1797       case GL_TEXTURE_BORDER_COLOR:
   1798          if (ctx->API == API_OPENGLES ||
   1799              !ctx->Extensions.ARB_texture_border_clamp)
   1800             goto invalid_pname;
   1801 
   1802          if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
   1803             _mesa_update_state_locked(ctx);
   1804          if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) {
   1805             params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
   1806             params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
   1807             params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
   1808             params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
   1809          }
   1810          else {
   1811             params[0] = obj->Sampler.BorderColor.f[0];
   1812             params[1] = obj->Sampler.BorderColor.f[1];
   1813             params[2] = obj->Sampler.BorderColor.f[2];
   1814             params[3] = obj->Sampler.BorderColor.f[3];
   1815          }
   1816          break;
   1817       case GL_TEXTURE_RESIDENT:
   1818          if (ctx->API != API_OPENGL_COMPAT)
   1819             goto invalid_pname;
   1820 
   1821          *params = 1.0F;
   1822          break;
   1823       case GL_TEXTURE_PRIORITY:
   1824          if (ctx->API != API_OPENGL_COMPAT)
   1825             goto invalid_pname;
   1826 
   1827          *params = obj->Priority;
   1828          break;
   1829       case GL_TEXTURE_MIN_LOD:
   1830          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
   1831             goto invalid_pname;
   1832 
   1833          *params = obj->Sampler.MinLod;
   1834          break;
   1835       case GL_TEXTURE_MAX_LOD:
   1836          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
   1837             goto invalid_pname;
   1838 
   1839          *params = obj->Sampler.MaxLod;
   1840          break;
   1841       case GL_TEXTURE_BASE_LEVEL:
   1842          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
   1843             goto invalid_pname;
   1844 
   1845          *params = (GLfloat) obj->BaseLevel;
   1846          break;
   1847       case GL_TEXTURE_MAX_LEVEL:
   1848          *params = (GLfloat) obj->MaxLevel;
   1849          break;
   1850       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
   1851          if (!ctx->Extensions.EXT_texture_filter_anisotropic)
   1852             goto invalid_pname;
   1853          *params = obj->Sampler.MaxAnisotropy;
   1854          break;
   1855       case GL_GENERATE_MIPMAP_SGIS:
   1856          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
   1857             goto invalid_pname;
   1858 
   1859 	 *params = (GLfloat) obj->GenerateMipmap;
   1860          break;
   1861       case GL_TEXTURE_COMPARE_MODE_ARB:
   1862          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
   1863              && !_mesa_is_gles3(ctx))
   1864             goto invalid_pname;
   1865          *params = (GLfloat) obj->Sampler.CompareMode;
   1866          break;
   1867       case GL_TEXTURE_COMPARE_FUNC_ARB:
   1868          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
   1869              && !_mesa_is_gles3(ctx))
   1870             goto invalid_pname;
   1871          *params = (GLfloat) obj->Sampler.CompareFunc;
   1872          break;
   1873       case GL_DEPTH_TEXTURE_MODE_ARB:
   1874          /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
   1875           * never existed in OpenGL ES.
   1876           */
   1877          if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
   1878             goto invalid_pname;
   1879          *params = (GLfloat) obj->DepthMode;
   1880          break;
   1881       case GL_DEPTH_STENCIL_TEXTURE_MODE:
   1882          if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx))
   1883             goto invalid_pname;
   1884          *params = (GLfloat)
   1885             (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
   1886          break;
   1887       case GL_TEXTURE_LOD_BIAS:
   1888          if (_mesa_is_gles(ctx))
   1889             goto invalid_pname;
   1890 
   1891          *params = obj->Sampler.LodBias;
   1892          break;
   1893       case GL_TEXTURE_CROP_RECT_OES:
   1894          if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
   1895             goto invalid_pname;
   1896 
   1897          params[0] = (GLfloat) obj->CropRect[0];
   1898          params[1] = (GLfloat) obj->CropRect[1];
   1899          params[2] = (GLfloat) obj->CropRect[2];
   1900          params[3] = (GLfloat) obj->CropRect[3];
   1901          break;
   1902 
   1903       case GL_TEXTURE_SWIZZLE_R_EXT:
   1904       case GL_TEXTURE_SWIZZLE_G_EXT:
   1905       case GL_TEXTURE_SWIZZLE_B_EXT:
   1906       case GL_TEXTURE_SWIZZLE_A_EXT:
   1907          if ((!_mesa_is_desktop_gl(ctx)
   1908               || !ctx->Extensions.EXT_texture_swizzle)
   1909              && !_mesa_is_gles3(ctx))
   1910             goto invalid_pname;
   1911          *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
   1912          break;
   1913 
   1914       case GL_TEXTURE_SWIZZLE_RGBA_EXT:
   1915          if ((!_mesa_is_desktop_gl(ctx)
   1916               || !ctx->Extensions.EXT_texture_swizzle)
   1917              && !_mesa_is_gles3(ctx)) {
   1918             goto invalid_pname;
   1919          }
   1920          else {
   1921             GLuint comp;
   1922             for (comp = 0; comp < 4; comp++) {
   1923                params[comp] = (GLfloat) obj->Swizzle[comp];
   1924             }
   1925          }
   1926          break;
   1927 
   1928       case GL_TEXTURE_CUBE_MAP_SEAMLESS:
   1929          if (!_mesa_is_desktop_gl(ctx)
   1930              || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
   1931             goto invalid_pname;
   1932          *params = (GLfloat) obj->Sampler.CubeMapSeamless;
   1933          break;
   1934 
   1935       case GL_TEXTURE_IMMUTABLE_FORMAT:
   1936          *params = (GLfloat) obj->Immutable;
   1937          break;
   1938 
   1939       case GL_TEXTURE_IMMUTABLE_LEVELS:
   1940          if (_mesa_is_gles3(ctx) ||
   1941              (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
   1942             *params = (GLfloat) obj->ImmutableLevels;
   1943          else
   1944             goto invalid_pname;
   1945          break;
   1946 
   1947       case GL_TEXTURE_VIEW_MIN_LEVEL:
   1948          if (!ctx->Extensions.ARB_texture_view)
   1949             goto invalid_pname;
   1950          *params = (GLfloat) obj->MinLevel;
   1951          break;
   1952 
   1953       case GL_TEXTURE_VIEW_NUM_LEVELS:
   1954          if (!ctx->Extensions.ARB_texture_view)
   1955             goto invalid_pname;
   1956          *params = (GLfloat) obj->NumLevels;
   1957          break;
   1958 
   1959       case GL_TEXTURE_VIEW_MIN_LAYER:
   1960          if (!ctx->Extensions.ARB_texture_view)
   1961             goto invalid_pname;
   1962          *params = (GLfloat) obj->MinLayer;
   1963          break;
   1964 
   1965       case GL_TEXTURE_VIEW_NUM_LAYERS:
   1966          if (!ctx->Extensions.ARB_texture_view)
   1967             goto invalid_pname;
   1968          *params = (GLfloat) obj->NumLayers;
   1969          break;
   1970 
   1971       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
   1972          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
   1973             goto invalid_pname;
   1974          *params = (GLfloat) obj->RequiredTextureImageUnits;
   1975          break;
   1976 
   1977       case GL_TEXTURE_SRGB_DECODE_EXT:
   1978          if (!ctx->Extensions.EXT_texture_sRGB_decode)
   1979             goto invalid_pname;
   1980          *params = (GLfloat) obj->Sampler.sRGBDecode;
   1981          break;
   1982 
   1983       case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
   1984          if (!ctx->Extensions.ARB_shader_image_load_store)
   1985             goto invalid_pname;
   1986          *params = (GLfloat) obj->ImageFormatCompatibilityType;
   1987          break;
   1988 
   1989       case GL_TEXTURE_TARGET:
   1990          if (ctx->API != API_OPENGL_CORE)
   1991             goto invalid_pname;
   1992          *params = ENUM_TO_FLOAT(obj->Target);
   1993          break;
   1994 
   1995       default:
   1996          goto invalid_pname;
   1997    }
   1998 
   1999    /* no error if we get here */
   2000    _mesa_unlock_context_textures(ctx);
   2001    return;
   2002 
   2003 invalid_pname:
   2004    _mesa_unlock_context_textures(ctx);
   2005    _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameterfv(pname=0x%x)",
   2006                dsa ? "ture" : "", pname);
   2007 }
   2008 
   2009 
   2010 static void
   2011 get_tex_parameteriv(struct gl_context *ctx,
   2012                     struct gl_texture_object *obj,
   2013                     GLenum pname, GLint *params, bool dsa)
   2014 {
   2015    _mesa_lock_texture(ctx, obj);
   2016    switch (pname) {
   2017       case GL_TEXTURE_MAG_FILTER:
   2018          *params = (GLint) obj->Sampler.MagFilter;
   2019          break;
   2020       case GL_TEXTURE_MIN_FILTER:
   2021          *params = (GLint) obj->Sampler.MinFilter;
   2022          break;
   2023       case GL_TEXTURE_WRAP_S:
   2024          *params = (GLint) obj->Sampler.WrapS;
   2025          break;
   2026       case GL_TEXTURE_WRAP_T:
   2027          *params = (GLint) obj->Sampler.WrapT;
   2028          break;
   2029       case GL_TEXTURE_WRAP_R:
   2030          *params = (GLint) obj->Sampler.WrapR;
   2031          break;
   2032       case GL_TEXTURE_BORDER_COLOR:
   2033          if (ctx->API == API_OPENGLES ||
   2034              !ctx->Extensions.ARB_texture_border_clamp)
   2035             goto invalid_pname;
   2036 
   2037          {
   2038             GLfloat b[4];
   2039             b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
   2040             b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
   2041             b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
   2042             b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
   2043             params[0] = FLOAT_TO_INT(b[0]);
   2044             params[1] = FLOAT_TO_INT(b[1]);
   2045             params[2] = FLOAT_TO_INT(b[2]);
   2046             params[3] = FLOAT_TO_INT(b[3]);
   2047          }
   2048          break;
   2049       case GL_TEXTURE_RESIDENT:
   2050          if (ctx->API != API_OPENGL_COMPAT)
   2051             goto invalid_pname;
   2052 
   2053          *params = 1;
   2054          break;
   2055       case GL_TEXTURE_PRIORITY:
   2056          if (ctx->API != API_OPENGL_COMPAT)
   2057             goto invalid_pname;
   2058 
   2059          *params = FLOAT_TO_INT(obj->Priority);
   2060          break;
   2061       case GL_TEXTURE_MIN_LOD:
   2062          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
   2063             goto invalid_pname;
   2064          /* GL spec 'Data Conversions' section specifies that floating-point
   2065           * value in integer Get function is rounded to nearest integer
   2066           */
   2067          *params = IROUND(obj->Sampler.MinLod);
   2068          break;
   2069       case GL_TEXTURE_MAX_LOD:
   2070          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
   2071             goto invalid_pname;
   2072          /* GL spec 'Data Conversions' section specifies that floating-point
   2073           * value in integer Get function is rounded to nearest integer
   2074           */
   2075          *params = IROUND(obj->Sampler.MaxLod);
   2076          break;
   2077       case GL_TEXTURE_BASE_LEVEL:
   2078          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
   2079             goto invalid_pname;
   2080 
   2081          *params = obj->BaseLevel;
   2082          break;
   2083       case GL_TEXTURE_MAX_LEVEL:
   2084          *params = obj->MaxLevel;
   2085          break;
   2086       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
   2087          if (!ctx->Extensions.EXT_texture_filter_anisotropic)
   2088             goto invalid_pname;
   2089          /* GL spec 'Data Conversions' section specifies that floating-point
   2090           * value in integer Get function is rounded to nearest integer
   2091           */
   2092          *params = IROUND(obj->Sampler.MaxAnisotropy);
   2093          break;
   2094       case GL_GENERATE_MIPMAP_SGIS:
   2095          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
   2096             goto invalid_pname;
   2097 
   2098 	 *params = (GLint) obj->GenerateMipmap;
   2099          break;
   2100       case GL_TEXTURE_COMPARE_MODE_ARB:
   2101          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
   2102              && !_mesa_is_gles3(ctx))
   2103             goto invalid_pname;
   2104          *params = (GLint) obj->Sampler.CompareMode;
   2105          break;
   2106       case GL_TEXTURE_COMPARE_FUNC_ARB:
   2107          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
   2108              && !_mesa_is_gles3(ctx))
   2109             goto invalid_pname;
   2110          *params = (GLint) obj->Sampler.CompareFunc;
   2111          break;
   2112       case GL_DEPTH_TEXTURE_MODE_ARB:
   2113          if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
   2114             goto invalid_pname;
   2115          *params = (GLint) obj->DepthMode;
   2116          break;
   2117       case GL_DEPTH_STENCIL_TEXTURE_MODE:
   2118          if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx))
   2119             goto invalid_pname;
   2120          *params = (GLint)
   2121             (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
   2122          break;
   2123       case GL_TEXTURE_LOD_BIAS:
   2124          if (_mesa_is_gles(ctx))
   2125             goto invalid_pname;
   2126 
   2127          /* GL spec 'Data Conversions' section specifies that floating-point
   2128           * value in integer Get function is rounded to nearest integer
   2129           */
   2130          *params = IROUND(obj->Sampler.LodBias);
   2131          break;
   2132       case GL_TEXTURE_CROP_RECT_OES:
   2133          if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
   2134             goto invalid_pname;
   2135 
   2136          params[0] = obj->CropRect[0];
   2137          params[1] = obj->CropRect[1];
   2138          params[2] = obj->CropRect[2];
   2139          params[3] = obj->CropRect[3];
   2140          break;
   2141       case GL_TEXTURE_SWIZZLE_R_EXT:
   2142       case GL_TEXTURE_SWIZZLE_G_EXT:
   2143       case GL_TEXTURE_SWIZZLE_B_EXT:
   2144       case GL_TEXTURE_SWIZZLE_A_EXT:
   2145          if ((!_mesa_is_desktop_gl(ctx)
   2146               || !ctx->Extensions.EXT_texture_swizzle)
   2147              && !_mesa_is_gles3(ctx))
   2148             goto invalid_pname;
   2149          *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
   2150          break;
   2151 
   2152       case GL_TEXTURE_SWIZZLE_RGBA_EXT:
   2153          if ((!_mesa_is_desktop_gl(ctx)
   2154               || !ctx->Extensions.EXT_texture_swizzle)
   2155              && !_mesa_is_gles3(ctx))
   2156             goto invalid_pname;
   2157          COPY_4V(params, obj->Swizzle);
   2158          break;
   2159 
   2160       case GL_TEXTURE_CUBE_MAP_SEAMLESS:
   2161          if (!_mesa_is_desktop_gl(ctx)
   2162              || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
   2163             goto invalid_pname;
   2164          *params = (GLint) obj->Sampler.CubeMapSeamless;
   2165          break;
   2166 
   2167       case GL_TEXTURE_IMMUTABLE_FORMAT:
   2168          *params = (GLint) obj->Immutable;
   2169          break;
   2170 
   2171       case GL_TEXTURE_IMMUTABLE_LEVELS:
   2172          if (_mesa_is_gles3(ctx) ||
   2173              (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
   2174             *params = obj->ImmutableLevels;
   2175          else
   2176             goto invalid_pname;
   2177          break;
   2178 
   2179       case GL_TEXTURE_VIEW_MIN_LEVEL:
   2180          if (!ctx->Extensions.ARB_texture_view)
   2181             goto invalid_pname;
   2182          *params = (GLint) obj->MinLevel;
   2183          break;
   2184 
   2185       case GL_TEXTURE_VIEW_NUM_LEVELS:
   2186          if (!ctx->Extensions.ARB_texture_view)
   2187             goto invalid_pname;
   2188          *params = (GLint) obj->NumLevels;
   2189          break;
   2190 
   2191       case GL_TEXTURE_VIEW_MIN_LAYER:
   2192          if (!ctx->Extensions.ARB_texture_view)
   2193             goto invalid_pname;
   2194          *params = (GLint) obj->MinLayer;
   2195          break;
   2196 
   2197       case GL_TEXTURE_VIEW_NUM_LAYERS:
   2198          if (!ctx->Extensions.ARB_texture_view)
   2199             goto invalid_pname;
   2200          *params = (GLint) obj->NumLayers;
   2201          break;
   2202 
   2203       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
   2204          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
   2205             goto invalid_pname;
   2206          *params = obj->RequiredTextureImageUnits;
   2207          break;
   2208 
   2209       case GL_TEXTURE_SRGB_DECODE_EXT:
   2210          if (!ctx->Extensions.EXT_texture_sRGB_decode)
   2211             goto invalid_pname;
   2212          *params = obj->Sampler.sRGBDecode;
   2213          break;
   2214 
   2215       case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
   2216          if (!ctx->Extensions.ARB_shader_image_load_store)
   2217             goto invalid_pname;
   2218          *params = obj->ImageFormatCompatibilityType;
   2219          break;
   2220 
   2221       case GL_TEXTURE_TARGET:
   2222          if (ctx->API != API_OPENGL_CORE)
   2223             goto invalid_pname;
   2224          *params = (GLint) obj->Target;
   2225          break;
   2226 
   2227       default:
   2228          goto invalid_pname;
   2229    }
   2230 
   2231    /* no error if we get here */
   2232    _mesa_unlock_texture(ctx, obj);
   2233    return;
   2234 
   2235 invalid_pname:
   2236    _mesa_unlock_texture(ctx, obj);
   2237    _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameteriv(pname=0x%x)",
   2238                dsa ? "ture" : "", pname);
   2239 }
   2240 
   2241 static void
   2242 get_tex_parameterIiv(struct gl_context *ctx,
   2243                      struct gl_texture_object *obj,
   2244                      GLenum pname, GLint *params, bool dsa)
   2245 {
   2246    switch (pname) {
   2247    case GL_TEXTURE_BORDER_COLOR:
   2248       COPY_4V(params, obj->Sampler.BorderColor.i);
   2249       break;
   2250    default:
   2251       get_tex_parameteriv(ctx, obj, pname, params, dsa);
   2252    }
   2253 }
   2254 
   2255 static void
   2256 get_tex_parameterIuiv(struct gl_context *ctx,
   2257                       struct gl_texture_object *obj,
   2258                       GLenum pname, GLuint *params, bool dsa)
   2259 {
   2260    switch (pname) {
   2261    case GL_TEXTURE_BORDER_COLOR:
   2262       COPY_4V(params, obj->Sampler.BorderColor.i);
   2263       break;
   2264    default:
   2265       {
   2266          GLint ip[4];
   2267          get_tex_parameteriv(ctx, obj, pname, ip, dsa);
   2268          params[0] = ip[0];
   2269          if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
   2270              pname == GL_TEXTURE_CROP_RECT_OES) {
   2271             params[1] = ip[1];
   2272             params[2] = ip[2];
   2273             params[3] = ip[3];
   2274          }
   2275       }
   2276    }
   2277 }
   2278 
   2279 void GLAPIENTRY
   2280 _mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
   2281 {
   2282    struct gl_texture_object *obj;
   2283    GET_CURRENT_CONTEXT(ctx);
   2284 
   2285    obj = get_texobj_by_target(ctx, target, GL_TRUE);
   2286    if (!obj)
   2287       return;
   2288 
   2289    get_tex_parameterfv(ctx, obj, pname, params, false);
   2290 }
   2291 
   2292 void GLAPIENTRY
   2293 _mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params)
   2294 {
   2295    struct gl_texture_object *obj;
   2296    GET_CURRENT_CONTEXT(ctx);
   2297 
   2298    obj = get_texobj_by_target(ctx, target, GL_TRUE);
   2299    if (!obj)
   2300       return;
   2301 
   2302    get_tex_parameteriv(ctx, obj, pname, params, false);
   2303 }
   2304 
   2305 /** New in GL 3.0 */
   2306 void GLAPIENTRY
   2307 _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
   2308 {
   2309    struct gl_texture_object *texObj;
   2310    GET_CURRENT_CONTEXT(ctx);
   2311 
   2312    texObj = get_texobj_by_target(ctx, target, GL_TRUE);
   2313    if (!texObj)
   2314       return;
   2315 
   2316    get_tex_parameterIiv(ctx, texObj, pname, params, false);
   2317 }
   2318 
   2319 
   2320 /** New in GL 3.0 */
   2321 void GLAPIENTRY
   2322 _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
   2323 {
   2324    struct gl_texture_object *texObj;
   2325    GET_CURRENT_CONTEXT(ctx);
   2326 
   2327    texObj = get_texobj_by_target(ctx, target, GL_TRUE);
   2328    if (!texObj)
   2329       return;
   2330 
   2331    get_tex_parameterIuiv(ctx, texObj, pname, params, false);
   2332 }
   2333 
   2334 
   2335 void GLAPIENTRY
   2336 _mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params)
   2337 {
   2338    struct gl_texture_object *obj;
   2339    GET_CURRENT_CONTEXT(ctx);
   2340 
   2341    obj = get_texobj_by_name(ctx, texture, GL_TRUE);
   2342    if (!obj) {
   2343       /* User passed a non-generated name. */
   2344       _mesa_error(ctx, GL_INVALID_OPERATION,
   2345                   "glGetTextureParameterfv(texture)");
   2346       return;
   2347    }
   2348 
   2349    get_tex_parameterfv(ctx, obj, pname, params, true);
   2350 }
   2351 
   2352 void GLAPIENTRY
   2353 _mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params)
   2354 {
   2355    struct gl_texture_object *obj;
   2356    GET_CURRENT_CONTEXT(ctx);
   2357 
   2358    obj = get_texobj_by_name(ctx, texture, GL_TRUE);
   2359    if (!obj) {
   2360       /* User passed a non-generated name. */
   2361       _mesa_error(ctx, GL_INVALID_OPERATION,
   2362                   "glGetTextureParameteriv(texture)");
   2363       return;
   2364    }
   2365 
   2366    get_tex_parameteriv(ctx, obj, pname, params, true);
   2367 }
   2368 
   2369 void GLAPIENTRY
   2370 _mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params)
   2371 {
   2372    struct gl_texture_object *texObj;
   2373    GET_CURRENT_CONTEXT(ctx);
   2374 
   2375    texObj = get_texobj_by_name(ctx, texture, GL_TRUE);
   2376    if (!texObj) {
   2377       /* User passed a non-generated name. */
   2378       _mesa_error(ctx, GL_INVALID_OPERATION,
   2379                   "glGetTextureParameterIiv(texture)");
   2380       return;
   2381    }
   2382 
   2383    get_tex_parameterIiv(ctx, texObj, pname, params, true);
   2384 }
   2385 
   2386 
   2387 void GLAPIENTRY
   2388 _mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params)
   2389 {
   2390    struct gl_texture_object *texObj;
   2391    GET_CURRENT_CONTEXT(ctx);
   2392 
   2393    texObj = get_texobj_by_name(ctx, texture, GL_TRUE);
   2394    if (!texObj) {
   2395       /* User passed a non-generated name. */
   2396       _mesa_error(ctx, GL_INVALID_OPERATION,
   2397                   "glGetTextureParameterIuiv(texture)");
   2398       return;
   2399    }
   2400 
   2401    get_tex_parameterIuiv(ctx, texObj, pname, params, true);
   2402 }
   2403