Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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