Subversion Repositories Kolibri OS

Rev

Rev 4358 | 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.       if (_mesa_is_gles(ctx))
  665.          goto invalid_pname;
  666.  
  667.       if (!target_allows_setting_sampler_parameters(texObj->Target))
  668.          goto invalid_operation;
  669.  
  670.       if (texObj->Sampler.LodBias != params[0]) {
  671.          flush(ctx);
  672.          texObj->Sampler.LodBias = params[0];
  673.          return GL_TRUE;
  674.       }
  675.       break;
  676.  
  677.    case GL_TEXTURE_BORDER_COLOR:
  678.       if (!_mesa_is_desktop_gl(ctx))
  679.          goto invalid_pname;
  680.  
  681.       if (!target_allows_setting_sampler_parameters(texObj->Target))
  682.          goto invalid_operation;
  683.  
  684.       flush(ctx);
  685.       /* ARB_texture_float disables clamping */
  686.       if (ctx->Extensions.ARB_texture_float) {
  687.          texObj->Sampler.BorderColor.f[RCOMP] = params[0];
  688.          texObj->Sampler.BorderColor.f[GCOMP] = params[1];
  689.          texObj->Sampler.BorderColor.f[BCOMP] = params[2];
  690.          texObj->Sampler.BorderColor.f[ACOMP] = params[3];
  691.       } else {
  692.          texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
  693.          texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
  694.          texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
  695.          texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
  696.       }
  697.       return GL_TRUE;
  698.  
  699.    default:
  700.       goto invalid_pname;
  701.    }
  702.    return GL_FALSE;
  703.  
  704. invalid_pname:
  705.    _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
  706.                _mesa_lookup_enum_by_nr(pname));
  707.    return GL_FALSE;
  708.  
  709. invalid_operation:
  710.    _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
  711.                _mesa_lookup_enum_by_nr(pname));
  712.    return GL_FALSE;
  713. }
  714.  
  715.  
  716. void GLAPIENTRY
  717. _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
  718. {
  719.    GLboolean need_update;
  720.    struct gl_texture_object *texObj;
  721.    GET_CURRENT_CONTEXT(ctx);
  722.  
  723.    texObj = get_texobj(ctx, target, GL_FALSE);
  724.    if (!texObj)
  725.       return;
  726.  
  727.    switch (pname) {
  728.    case GL_TEXTURE_MIN_FILTER:
  729.    case GL_TEXTURE_MAG_FILTER:
  730.    case GL_TEXTURE_WRAP_S:
  731.    case GL_TEXTURE_WRAP_T:
  732.    case GL_TEXTURE_WRAP_R:
  733.    case GL_TEXTURE_BASE_LEVEL:
  734.    case GL_TEXTURE_MAX_LEVEL:
  735.    case GL_GENERATE_MIPMAP_SGIS:
  736.    case GL_TEXTURE_COMPARE_MODE_ARB:
  737.    case GL_TEXTURE_COMPARE_FUNC_ARB:
  738.    case GL_DEPTH_TEXTURE_MODE_ARB:
  739.    case GL_TEXTURE_SRGB_DECODE_EXT:
  740.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  741.    case GL_TEXTURE_SWIZZLE_R_EXT:
  742.    case GL_TEXTURE_SWIZZLE_G_EXT:
  743.    case GL_TEXTURE_SWIZZLE_B_EXT:
  744.    case GL_TEXTURE_SWIZZLE_A_EXT:
  745.       {
  746.          GLint p[4];
  747.          p[0] = (param > 0) ?
  748.                 ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
  749.                 ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
  750.  
  751.          p[1] = p[2] = p[3] = 0;
  752.          need_update = set_tex_parameteri(ctx, texObj, pname, p);
  753.       }
  754.       break;
  755.    default:
  756.       {
  757.          /* this will generate an error if pname is illegal */
  758.          GLfloat p[4];
  759.          p[0] = param;
  760.          p[1] = p[2] = p[3] = 0.0F;
  761.          need_update = set_tex_parameterf(ctx, texObj, pname, p);
  762.       }
  763.    }
  764.  
  765.    if (ctx->Driver.TexParameter && need_update) {
  766.       ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
  767.    }
  768. }
  769.  
  770.  
  771. void GLAPIENTRY
  772. _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
  773. {
  774.    GLboolean need_update;
  775.    struct gl_texture_object *texObj;
  776.    GET_CURRENT_CONTEXT(ctx);
  777.  
  778.    texObj = get_texobj(ctx, target, GL_FALSE);
  779.    if (!texObj)
  780.       return;
  781.  
  782.    switch (pname) {
  783.    case GL_TEXTURE_MIN_FILTER:
  784.    case GL_TEXTURE_MAG_FILTER:
  785.    case GL_TEXTURE_WRAP_S:
  786.    case GL_TEXTURE_WRAP_T:
  787.    case GL_TEXTURE_WRAP_R:
  788.    case GL_TEXTURE_BASE_LEVEL:
  789.    case GL_TEXTURE_MAX_LEVEL:
  790.    case GL_GENERATE_MIPMAP_SGIS:
  791.    case GL_TEXTURE_COMPARE_MODE_ARB:
  792.    case GL_TEXTURE_COMPARE_FUNC_ARB:
  793.    case GL_DEPTH_TEXTURE_MODE_ARB:
  794.    case GL_TEXTURE_SRGB_DECODE_EXT:
  795.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  796.       {
  797.          /* convert float param to int */
  798.          GLint p[4];
  799.          p[0] = (GLint) params[0];
  800.          p[1] = p[2] = p[3] = 0;
  801.          need_update = set_tex_parameteri(ctx, texObj, pname, p);
  802.       }
  803.       break;
  804.    case GL_TEXTURE_CROP_RECT_OES:
  805.       {
  806.          /* convert float params to int */
  807.          GLint iparams[4];
  808.          iparams[0] = (GLint) params[0];
  809.          iparams[1] = (GLint) params[1];
  810.          iparams[2] = (GLint) params[2];
  811.          iparams[3] = (GLint) params[3];
  812.          need_update = set_tex_parameteri(ctx, texObj, pname, iparams);
  813.       }
  814.       break;
  815.    case GL_TEXTURE_SWIZZLE_R_EXT:
  816.    case GL_TEXTURE_SWIZZLE_G_EXT:
  817.    case GL_TEXTURE_SWIZZLE_B_EXT:
  818.    case GL_TEXTURE_SWIZZLE_A_EXT:
  819.    case GL_TEXTURE_SWIZZLE_RGBA_EXT:
  820.       {
  821.          GLint p[4] = {0, 0, 0, 0};
  822.          p[0] = (GLint) params[0];
  823.          if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
  824.             p[1] = (GLint) params[1];
  825.             p[2] = (GLint) params[2];
  826.             p[3] = (GLint) params[3];
  827.          }
  828.          need_update = set_tex_parameteri(ctx, texObj, pname, p);
  829.       }
  830.       break;
  831.    default:
  832.       /* this will generate an error if pname is illegal */
  833.       need_update = set_tex_parameterf(ctx, texObj, pname, params);
  834.    }
  835.  
  836.    if (ctx->Driver.TexParameter && need_update) {
  837.       ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
  838.    }
  839. }
  840.  
  841.  
  842. void GLAPIENTRY
  843. _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
  844. {
  845.    GLboolean need_update;
  846.    struct gl_texture_object *texObj;
  847.    GET_CURRENT_CONTEXT(ctx);
  848.  
  849.    texObj = get_texobj(ctx, target, GL_FALSE);
  850.    if (!texObj)
  851.       return;
  852.  
  853.    switch (pname) {
  854.    case GL_TEXTURE_MIN_LOD:
  855.    case GL_TEXTURE_MAX_LOD:
  856.    case GL_TEXTURE_PRIORITY:
  857.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  858.    case GL_TEXTURE_LOD_BIAS:
  859.    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
  860.       {
  861.          GLfloat fparam[4];
  862.          fparam[0] = (GLfloat) param;
  863.          fparam[1] = fparam[2] = fparam[3] = 0.0F;
  864.          /* convert int param to float */
  865.          need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
  866.       }
  867.       break;
  868.    default:
  869.       /* this will generate an error if pname is illegal */
  870.       {
  871.          GLint iparam[4];
  872.          iparam[0] = param;
  873.          iparam[1] = iparam[2] = iparam[3] = 0;
  874.          need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
  875.       }
  876.    }
  877.  
  878.    if (ctx->Driver.TexParameter && need_update) {
  879.       GLfloat fparam = (GLfloat) param;
  880.       ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
  881.    }
  882. }
  883.  
  884.  
  885. void GLAPIENTRY
  886. _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
  887. {
  888.    GLboolean need_update;
  889.    struct gl_texture_object *texObj;
  890.    GET_CURRENT_CONTEXT(ctx);
  891.  
  892.    texObj = get_texobj(ctx, target, GL_FALSE);
  893.    if (!texObj)
  894.       return;
  895.  
  896.    switch (pname) {
  897.    case GL_TEXTURE_BORDER_COLOR:
  898.       {
  899.          /* convert int params to float */
  900.          GLfloat fparams[4];
  901.          fparams[0] = INT_TO_FLOAT(params[0]);
  902.          fparams[1] = INT_TO_FLOAT(params[1]);
  903.          fparams[2] = INT_TO_FLOAT(params[2]);
  904.          fparams[3] = INT_TO_FLOAT(params[3]);
  905.          need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
  906.       }
  907.       break;
  908.    case GL_TEXTURE_MIN_LOD:
  909.    case GL_TEXTURE_MAX_LOD:
  910.    case GL_TEXTURE_PRIORITY:
  911.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  912.    case GL_TEXTURE_LOD_BIAS:
  913.    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
  914.       {
  915.          /* convert int param to float */
  916.          GLfloat fparams[4];
  917.          fparams[0] = (GLfloat) params[0];
  918.          fparams[1] = fparams[2] = fparams[3] = 0.0F;
  919.          need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
  920.       }
  921.       break;
  922.    default:
  923.       /* this will generate an error if pname is illegal */
  924.       need_update = set_tex_parameteri(ctx, texObj, pname, params);
  925.    }
  926.  
  927.    if (ctx->Driver.TexParameter && need_update) {
  928.       GLfloat fparams[4];
  929.       fparams[0] = INT_TO_FLOAT(params[0]);
  930.       if (pname == GL_TEXTURE_BORDER_COLOR ||
  931.           pname == GL_TEXTURE_CROP_RECT_OES) {
  932.          fparams[1] = INT_TO_FLOAT(params[1]);
  933.          fparams[2] = INT_TO_FLOAT(params[2]);
  934.          fparams[3] = INT_TO_FLOAT(params[3]);
  935.       }
  936.       ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
  937.    }
  938. }
  939.  
  940.  
  941. /**
  942.  * Set tex parameter to integer value(s).  Primarily intended to set
  943.  * integer-valued texture border color (for integer-valued textures).
  944.  * New in GL 3.0.
  945.  */
  946. void GLAPIENTRY
  947. _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
  948. {
  949.    struct gl_texture_object *texObj;
  950.    GET_CURRENT_CONTEXT(ctx);
  951.  
  952.    texObj = get_texobj(ctx, target, GL_FALSE);
  953.    if (!texObj)
  954.       return;
  955.  
  956.    switch (pname) {
  957.    case GL_TEXTURE_BORDER_COLOR:
  958.       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
  959.       /* set the integer-valued border color */
  960.       COPY_4V(texObj->Sampler.BorderColor.i, params);
  961.       break;
  962.    default:
  963.       _mesa_TexParameteriv(target, pname, params);
  964.       break;
  965.    }
  966.    /* XXX no driver hook for TexParameterIiv() yet */
  967. }
  968.  
  969.  
  970. /**
  971.  * Set tex parameter to unsigned integer value(s).  Primarily intended to set
  972.  * uint-valued texture border color (for integer-valued textures).
  973.  * New in GL 3.0
  974.  */
  975. void GLAPIENTRY
  976. _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
  977. {
  978.    struct gl_texture_object *texObj;
  979.    GET_CURRENT_CONTEXT(ctx);
  980.  
  981.    texObj = get_texobj(ctx, target, GL_FALSE);
  982.    if (!texObj)
  983.       return;
  984.  
  985.    switch (pname) {
  986.    case GL_TEXTURE_BORDER_COLOR:
  987.       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
  988.       /* set the unsigned integer-valued border color */
  989.       COPY_4V(texObj->Sampler.BorderColor.ui, params);
  990.       break;
  991.    default:
  992.       _mesa_TexParameteriv(target, pname, (const GLint *) params);
  993.       break;
  994.    }
  995.    /* XXX no driver hook for TexParameterIuiv() yet */
  996. }
  997.  
  998.  
  999. static GLboolean
  1000. legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
  1001. {
  1002.    switch (target) {
  1003.    case GL_TEXTURE_1D:
  1004.    case GL_PROXY_TEXTURE_1D:
  1005.    case GL_TEXTURE_2D:
  1006.    case GL_PROXY_TEXTURE_2D:
  1007.    case GL_TEXTURE_3D:
  1008.    case GL_PROXY_TEXTURE_3D:
  1009.       return GL_TRUE;
  1010.    case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
  1011.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
  1012.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
  1013.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
  1014.    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
  1015.    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
  1016.    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
  1017.       return ctx->Extensions.ARB_texture_cube_map;
  1018.    case GL_TEXTURE_RECTANGLE_NV:
  1019.    case GL_PROXY_TEXTURE_RECTANGLE_NV:
  1020.       return ctx->Extensions.NV_texture_rectangle;
  1021.    case GL_TEXTURE_1D_ARRAY_EXT:
  1022.    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
  1023.    case GL_TEXTURE_2D_ARRAY_EXT:
  1024.    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
  1025.       return (ctx->Extensions.MESA_texture_array ||
  1026.               ctx->Extensions.EXT_texture_array);
  1027.    case GL_TEXTURE_BUFFER:
  1028.       /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
  1029.        * but not in earlier versions that expose ARB_texture_buffer_object.
  1030.        *
  1031.        * From the ARB_texture_buffer_object spec:
  1032.        * "(7) Do buffer textures support texture parameters (TexParameter) or
  1033.        *      queries (GetTexParameter, GetTexLevelParameter, GetTexImage)?
  1034.        *
  1035.        *    RESOLVED:  No. [...] Note that the spec edits above don't add
  1036.        *    explicit error language for any of these cases.  That is because
  1037.        *    each of the functions enumerate the set of valid <target>
  1038.        *    parameters.  Not editing the spec to allow TEXTURE_BUFFER_ARB in
  1039.        *    these cases means that target is not legal, and an INVALID_ENUM
  1040.        *    error should be generated."
  1041.        *
  1042.        * From the OpenGL 3.1 spec:
  1043.        * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
  1044.        */
  1045.       return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
  1046.    case GL_TEXTURE_2D_MULTISAMPLE:
  1047.    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
  1048.    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
  1049.    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
  1050.       return ctx->Extensions.ARB_texture_multisample;
  1051.    default:
  1052.       return GL_FALSE;
  1053.    }
  1054. }
  1055.  
  1056.  
  1057. static void
  1058. get_tex_level_parameter_image(struct gl_context *ctx,
  1059.                               const struct gl_texture_object *texObj,
  1060.                               GLenum target, GLint level,
  1061.                               GLenum pname, GLint *params)
  1062. {
  1063.    const struct gl_texture_image *img = NULL;
  1064.    gl_format texFormat;
  1065.  
  1066.    img = _mesa_select_tex_image(ctx, texObj, target, level);
  1067.    if (!img || img->TexFormat == MESA_FORMAT_NONE) {
  1068.       /* undefined texture image */
  1069.       if (pname == GL_TEXTURE_COMPONENTS)
  1070.          *params = 1;
  1071.       else
  1072.          *params = 0;
  1073.       return;
  1074.    }
  1075.  
  1076.    texFormat = img->TexFormat;
  1077.  
  1078.    switch (pname) {
  1079.       case GL_TEXTURE_WIDTH:
  1080.          *params = img->Width;
  1081.          break;
  1082.       case GL_TEXTURE_HEIGHT:
  1083.          *params = img->Height;
  1084.          break;
  1085.       case GL_TEXTURE_DEPTH:
  1086.          *params = img->Depth;
  1087.          break;
  1088.       case GL_TEXTURE_INTERNAL_FORMAT:
  1089.          if (_mesa_is_format_compressed(texFormat)) {
  1090.             /* need to return the actual compressed format */
  1091.             *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
  1092.          }
  1093.          else {
  1094.             /* If the true internal format is not compressed but the user
  1095.              * requested a generic compressed format, we have to return the
  1096.              * generic base format that matches.
  1097.              *
  1098.              * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
  1099.              *
  1100.              *     "If no specific compressed format is available,
  1101.              *     internalformat is instead replaced by the corresponding base
  1102.              *     internal format."
  1103.              *
  1104.              * Otherwise just return the user's requested internal format
  1105.              */
  1106.             const GLenum f =
  1107.                _mesa_gl_compressed_format_base_format(img->InternalFormat);
  1108.  
  1109.             *params = (f != 0) ? f : img->InternalFormat;
  1110.          }
  1111.          break;
  1112.       case GL_TEXTURE_BORDER:
  1113.          *params = img->Border;
  1114.          break;
  1115.       case GL_TEXTURE_RED_SIZE:
  1116.       case GL_TEXTURE_GREEN_SIZE:
  1117.       case GL_TEXTURE_BLUE_SIZE:
  1118.       case GL_TEXTURE_ALPHA_SIZE:
  1119.          if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
  1120.             *params = _mesa_get_format_bits(texFormat, pname);
  1121.          else
  1122.             *params = 0;
  1123.          break;
  1124.       case GL_TEXTURE_INTENSITY_SIZE:
  1125.       case GL_TEXTURE_LUMINANCE_SIZE:
  1126.          if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
  1127.             *params = _mesa_get_format_bits(texFormat, pname);
  1128.             if (*params == 0) {
  1129.                /* intensity or luminance is probably stored as RGB[A] */
  1130.                *params = MIN2(_mesa_get_format_bits(texFormat,
  1131.                                                     GL_TEXTURE_RED_SIZE),
  1132.                               _mesa_get_format_bits(texFormat,
  1133.                                                     GL_TEXTURE_GREEN_SIZE));
  1134.             }
  1135.          }
  1136.          else {
  1137.             *params = 0;
  1138.          }
  1139.          break;
  1140.       case GL_TEXTURE_DEPTH_SIZE_ARB:
  1141.          if (!ctx->Extensions.ARB_depth_texture)
  1142.             goto invalid_pname;
  1143.          *params = _mesa_get_format_bits(texFormat, pname);
  1144.          break;
  1145.       case GL_TEXTURE_STENCIL_SIZE_EXT:
  1146.          if (!ctx->Extensions.EXT_packed_depth_stencil &&
  1147.              !ctx->Extensions.ARB_framebuffer_object)
  1148.             goto invalid_pname;
  1149.          *params = _mesa_get_format_bits(texFormat, pname);
  1150.          break;
  1151.       case GL_TEXTURE_SHARED_SIZE:
  1152.          if (ctx->Version < 30 &&
  1153.              !ctx->Extensions.EXT_texture_shared_exponent)
  1154.             goto invalid_pname;
  1155.          *params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0;
  1156.          break;
  1157.  
  1158.       /* GL_ARB_texture_compression */
  1159.       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
  1160.          if (_mesa_is_format_compressed(texFormat) &&
  1161.              !_mesa_is_proxy_texture(target)) {
  1162.             *params = _mesa_format_image_size(texFormat, img->Width,
  1163.                                               img->Height, img->Depth);
  1164.          }
  1165.          else {
  1166.             _mesa_error(ctx, GL_INVALID_OPERATION,
  1167.                         "glGetTexLevelParameter[if]v(pname)");
  1168.          }
  1169.          break;
  1170.       case GL_TEXTURE_COMPRESSED:
  1171.          *params = (GLint) _mesa_is_format_compressed(texFormat);
  1172.          break;
  1173.  
  1174.       /* GL_ARB_texture_float */
  1175.       case GL_TEXTURE_RED_TYPE_ARB:
  1176.       case GL_TEXTURE_GREEN_TYPE_ARB:
  1177.       case GL_TEXTURE_BLUE_TYPE_ARB:
  1178.       case GL_TEXTURE_ALPHA_TYPE_ARB:
  1179.       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
  1180.       case GL_TEXTURE_INTENSITY_TYPE_ARB:
  1181.       case GL_TEXTURE_DEPTH_TYPE_ARB:
  1182.          if (!ctx->Extensions.ARB_texture_float)
  1183.             goto invalid_pname;
  1184.          if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
  1185.             *params = _mesa_get_format_datatype(texFormat);
  1186.          else
  1187.             *params = GL_NONE;
  1188.          break;
  1189.  
  1190.       /* GL_ARB_texture_multisample */
  1191.       case GL_TEXTURE_SAMPLES:
  1192.          if (!ctx->Extensions.ARB_texture_multisample)
  1193.             goto invalid_pname;
  1194.          *params = img->NumSamples;
  1195.          break;
  1196.  
  1197.       case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
  1198.          if (!ctx->Extensions.ARB_texture_multisample)
  1199.             goto invalid_pname;
  1200.          *params = img->FixedSampleLocations;
  1201.          break;
  1202.  
  1203.       default:
  1204.          goto invalid_pname;
  1205.    }
  1206.  
  1207.    /* no error if we get here */
  1208.    return;
  1209.  
  1210. invalid_pname:
  1211.    _mesa_error(ctx, GL_INVALID_ENUM,
  1212.                "glGetTexLevelParameter[if]v(pname=%s)",
  1213.                _mesa_lookup_enum_by_nr(pname));
  1214. }
  1215.  
  1216.  
  1217. static void
  1218. get_tex_level_parameter_buffer(struct gl_context *ctx,
  1219.                                const struct gl_texture_object *texObj,
  1220.                                GLenum pname, GLint *params)
  1221. {
  1222.    const struct gl_buffer_object *bo = texObj->BufferObject;
  1223.    gl_format texFormat = texObj->_BufferObjectFormat;
  1224.    GLenum internalFormat = texObj->BufferObjectFormat;
  1225.    GLenum baseFormat = _mesa_get_format_base_format(texFormat);
  1226.  
  1227.    if (!bo) {
  1228.       /* undefined texture buffer object */
  1229.       *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0;
  1230.       return;
  1231.    }
  1232.  
  1233.    switch (pname) {
  1234.       case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
  1235.          *params = bo->Name;
  1236.          break;
  1237.       case GL_TEXTURE_WIDTH:
  1238.          *params = bo->Size;
  1239.          break;
  1240.       case GL_TEXTURE_HEIGHT:
  1241.       case GL_TEXTURE_DEPTH:
  1242.       case GL_TEXTURE_BORDER:
  1243.       case GL_TEXTURE_SHARED_SIZE:
  1244.       case GL_TEXTURE_COMPRESSED:
  1245.          *params = 0;
  1246.          break;
  1247.       case GL_TEXTURE_INTERNAL_FORMAT:
  1248.          *params = internalFormat;
  1249.          break;
  1250.       case GL_TEXTURE_RED_SIZE:
  1251.       case GL_TEXTURE_GREEN_SIZE:
  1252.       case GL_TEXTURE_BLUE_SIZE:
  1253.       case GL_TEXTURE_ALPHA_SIZE:
  1254.          if (_mesa_base_format_has_channel(baseFormat, pname))
  1255.             *params = _mesa_get_format_bits(texFormat, pname);
  1256.          else
  1257.             *params = 0;
  1258.          break;
  1259.       case GL_TEXTURE_INTENSITY_SIZE:
  1260.       case GL_TEXTURE_LUMINANCE_SIZE:
  1261.          if (_mesa_base_format_has_channel(baseFormat, pname)) {
  1262.             *params = _mesa_get_format_bits(texFormat, pname);
  1263.             if (*params == 0) {
  1264.                /* intensity or luminance is probably stored as RGB[A] */
  1265.                *params = MIN2(_mesa_get_format_bits(texFormat,
  1266.                                                     GL_TEXTURE_RED_SIZE),
  1267.                               _mesa_get_format_bits(texFormat,
  1268.                                                     GL_TEXTURE_GREEN_SIZE));
  1269.             }
  1270.          } else {
  1271.             *params = 0;
  1272.          }
  1273.          break;
  1274.       case GL_TEXTURE_DEPTH_SIZE_ARB:
  1275.       case GL_TEXTURE_STENCIL_SIZE_EXT:
  1276.          *params = _mesa_get_format_bits(texFormat, pname);
  1277.          break;
  1278.  
  1279.       /* GL_ARB_texture_buffer_range */
  1280.       case GL_TEXTURE_BUFFER_OFFSET:
  1281.          if (!ctx->Extensions.ARB_texture_buffer_range)
  1282.             goto invalid_pname;
  1283.          *params = texObj->BufferOffset;
  1284.          break;
  1285.       case GL_TEXTURE_BUFFER_SIZE:
  1286.          if (!ctx->Extensions.ARB_texture_buffer_range)
  1287.             goto invalid_pname;
  1288.          *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
  1289.          break;
  1290.  
  1291.       /* GL_ARB_texture_compression */
  1292.       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
  1293.          /* Always illegal for GL_TEXTURE_BUFFER */
  1294.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1295.                      "glGetTexLevelParameter[if]v(pname)");
  1296.          break;
  1297.  
  1298.       /* GL_ARB_texture_float */
  1299.       case GL_TEXTURE_RED_TYPE_ARB:
  1300.       case GL_TEXTURE_GREEN_TYPE_ARB:
  1301.       case GL_TEXTURE_BLUE_TYPE_ARB:
  1302.       case GL_TEXTURE_ALPHA_TYPE_ARB:
  1303.       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
  1304.       case GL_TEXTURE_INTENSITY_TYPE_ARB:
  1305.       case GL_TEXTURE_DEPTH_TYPE_ARB:
  1306.          if (!ctx->Extensions.ARB_texture_float)
  1307.             goto invalid_pname;
  1308.          if (_mesa_base_format_has_channel(baseFormat, pname))
  1309.             *params = _mesa_get_format_datatype(texFormat);
  1310.          else
  1311.             *params = GL_NONE;
  1312.          break;
  1313.  
  1314.       default:
  1315.          goto invalid_pname;
  1316.    }
  1317.  
  1318.    /* no error if we get here */
  1319.    return;
  1320.  
  1321. invalid_pname:
  1322.    _mesa_error(ctx, GL_INVALID_ENUM,
  1323.                "glGetTexLevelParameter[if]v(pname=%s)",
  1324.                _mesa_lookup_enum_by_nr(pname));
  1325. }
  1326.  
  1327.  
  1328. void GLAPIENTRY
  1329. _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
  1330.                               GLenum pname, GLfloat *params )
  1331. {
  1332.    GLint iparam;
  1333.    _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
  1334.    *params = (GLfloat) iparam;
  1335. }
  1336.  
  1337.  
  1338. void GLAPIENTRY
  1339. _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
  1340.                               GLenum pname, GLint *params )
  1341. {
  1342.    const struct gl_texture_unit *texUnit;
  1343.    struct gl_texture_object *texObj;
  1344.    GLint maxLevels;
  1345.    GET_CURRENT_CONTEXT(ctx);
  1346.  
  1347.    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
  1348.       _mesa_error(ctx, GL_INVALID_OPERATION,
  1349.                   "glGetTexLevelParameteriv(current unit)");
  1350.       return;
  1351.    }
  1352.  
  1353.    texUnit = _mesa_get_current_tex_unit(ctx);
  1354.  
  1355.    if (!legal_get_tex_level_parameter_target(ctx, target)) {
  1356.       _mesa_error(ctx, GL_INVALID_ENUM,
  1357.                   "glGetTexLevelParameter[if]v(target=0x%x)", target);
  1358.       return;
  1359.    }
  1360.  
  1361.    maxLevels = _mesa_max_texture_levels(ctx, target);
  1362.    assert(maxLevels != 0);
  1363.  
  1364.    if (level < 0 || level >= maxLevels) {
  1365.       _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
  1366.       return;
  1367.    }
  1368.  
  1369.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  1370.  
  1371.    if (target == GL_TEXTURE_BUFFER)
  1372.       get_tex_level_parameter_buffer(ctx, texObj, pname, params);
  1373.    else
  1374.       get_tex_level_parameter_image(ctx, texObj, target, level, pname, params);
  1375. }
  1376.  
  1377.  
  1378. void GLAPIENTRY
  1379. _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
  1380. {
  1381.    struct gl_texture_object *obj;
  1382.    GET_CURRENT_CONTEXT(ctx);
  1383.  
  1384.    obj = get_texobj(ctx, target, GL_TRUE);
  1385.    if (!obj)
  1386.       return;
  1387.  
  1388.    _mesa_lock_texture(ctx, obj);
  1389.    switch (pname) {
  1390.       case GL_TEXTURE_MAG_FILTER:
  1391.          *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
  1392.          break;
  1393.       case GL_TEXTURE_MIN_FILTER:
  1394.          *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
  1395.          break;
  1396.       case GL_TEXTURE_WRAP_S:
  1397.          *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
  1398.          break;
  1399.       case GL_TEXTURE_WRAP_T:
  1400.          *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
  1401.          break;
  1402.       case GL_TEXTURE_WRAP_R:
  1403.          *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
  1404.          break;
  1405.       case GL_TEXTURE_BORDER_COLOR:
  1406.          if (!_mesa_is_desktop_gl(ctx))
  1407.             goto invalid_pname;
  1408.  
  1409.          if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
  1410.             _mesa_update_state_locked(ctx);
  1411.          if (_mesa_get_clamp_fragment_color(ctx)) {
  1412.             params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
  1413.             params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
  1414.             params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
  1415.             params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
  1416.          }
  1417.          else {
  1418.             params[0] = obj->Sampler.BorderColor.f[0];
  1419.             params[1] = obj->Sampler.BorderColor.f[1];
  1420.             params[2] = obj->Sampler.BorderColor.f[2];
  1421.             params[3] = obj->Sampler.BorderColor.f[3];
  1422.          }
  1423.          break;
  1424.       case GL_TEXTURE_RESIDENT:
  1425.          if (ctx->API != API_OPENGL_COMPAT)
  1426.             goto invalid_pname;
  1427.  
  1428.          *params = 1.0F;
  1429.          break;
  1430.       case GL_TEXTURE_PRIORITY:
  1431.          if (ctx->API != API_OPENGL_COMPAT)
  1432.             goto invalid_pname;
  1433.  
  1434.          *params = obj->Priority;
  1435.          break;
  1436.       case GL_TEXTURE_MIN_LOD:
  1437.          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
  1438.             goto invalid_pname;
  1439.  
  1440.          *params = obj->Sampler.MinLod;
  1441.          break;
  1442.       case GL_TEXTURE_MAX_LOD:
  1443.          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
  1444.             goto invalid_pname;
  1445.  
  1446.          *params = obj->Sampler.MaxLod;
  1447.          break;
  1448.       case GL_TEXTURE_BASE_LEVEL:
  1449.          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
  1450.             goto invalid_pname;
  1451.  
  1452.          *params = (GLfloat) obj->BaseLevel;
  1453.          break;
  1454.       case GL_TEXTURE_MAX_LEVEL:
  1455.          *params = (GLfloat) obj->MaxLevel;
  1456.          break;
  1457.       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  1458.          if (!ctx->Extensions.EXT_texture_filter_anisotropic)
  1459.             goto invalid_pname;
  1460.          *params = obj->Sampler.MaxAnisotropy;
  1461.          break;
  1462.       case GL_GENERATE_MIPMAP_SGIS:
  1463.          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
  1464.             goto invalid_pname;
  1465.  
  1466.          *params = (GLfloat) obj->GenerateMipmap;
  1467.          break;
  1468.       case GL_TEXTURE_COMPARE_MODE_ARB:
  1469.          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
  1470.              && !_mesa_is_gles3(ctx))
  1471.             goto invalid_pname;
  1472.          *params = (GLfloat) obj->Sampler.CompareMode;
  1473.          break;
  1474.       case GL_TEXTURE_COMPARE_FUNC_ARB:
  1475.          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
  1476.              && !_mesa_is_gles3(ctx))
  1477.             goto invalid_pname;
  1478.          *params = (GLfloat) obj->Sampler.CompareFunc;
  1479.          break;
  1480.       case GL_DEPTH_TEXTURE_MODE_ARB:
  1481.          /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
  1482.           * never existed in OpenGL ES.
  1483.           */
  1484.          if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
  1485.             goto invalid_pname;
  1486.          *params = (GLfloat) obj->DepthMode;
  1487.          break;
  1488.       case GL_TEXTURE_LOD_BIAS:
  1489.          if (_mesa_is_gles(ctx))
  1490.             goto invalid_pname;
  1491.  
  1492.          *params = obj->Sampler.LodBias;
  1493.          break;
  1494.       case GL_TEXTURE_CROP_RECT_OES:
  1495.          if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
  1496.             goto invalid_pname;
  1497.  
  1498.          params[0] = (GLfloat) obj->CropRect[0];
  1499.          params[1] = (GLfloat) obj->CropRect[1];
  1500.          params[2] = (GLfloat) obj->CropRect[2];
  1501.          params[3] = (GLfloat) obj->CropRect[3];
  1502.          break;
  1503.  
  1504.       case GL_TEXTURE_SWIZZLE_R_EXT:
  1505.       case GL_TEXTURE_SWIZZLE_G_EXT:
  1506.       case GL_TEXTURE_SWIZZLE_B_EXT:
  1507.       case GL_TEXTURE_SWIZZLE_A_EXT:
  1508.          if ((!_mesa_is_desktop_gl(ctx)
  1509.               || !ctx->Extensions.EXT_texture_swizzle)
  1510.              && !_mesa_is_gles3(ctx))
  1511.             goto invalid_pname;
  1512.          *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
  1513.          break;
  1514.  
  1515.       case GL_TEXTURE_SWIZZLE_RGBA_EXT:
  1516.          if ((!_mesa_is_desktop_gl(ctx)
  1517.               || !ctx->Extensions.EXT_texture_swizzle)
  1518.              && !_mesa_is_gles3(ctx)) {
  1519.             goto invalid_pname;
  1520.          }
  1521.          else {
  1522.             GLuint comp;
  1523.             for (comp = 0; comp < 4; comp++) {
  1524.                params[comp] = (GLfloat) obj->Swizzle[comp];
  1525.             }
  1526.          }
  1527.          break;
  1528.  
  1529.       case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  1530.          if (!_mesa_is_desktop_gl(ctx)
  1531.              || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
  1532.             goto invalid_pname;
  1533.          *params = (GLfloat) obj->Sampler.CubeMapSeamless;
  1534.          break;
  1535.  
  1536.       case GL_TEXTURE_IMMUTABLE_FORMAT:
  1537.          *params = (GLfloat) obj->Immutable;
  1538.          break;
  1539.  
  1540.       case GL_TEXTURE_IMMUTABLE_LEVELS:
  1541.          if (!_mesa_is_gles3(ctx))
  1542.             goto invalid_pname;
  1543.          *params = (GLfloat) obj->ImmutableLevels;
  1544.          break;
  1545.  
  1546.       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
  1547.          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
  1548.             goto invalid_pname;
  1549.          *params = (GLfloat) obj->RequiredTextureImageUnits;
  1550.          break;
  1551.  
  1552.       case GL_TEXTURE_SRGB_DECODE_EXT:
  1553.          if (!ctx->Extensions.EXT_texture_sRGB_decode)
  1554.             goto invalid_pname;
  1555.          *params = (GLfloat) obj->Sampler.sRGBDecode;
  1556.          break;
  1557.  
  1558.       default:
  1559.          goto invalid_pname;
  1560.    }
  1561.  
  1562.    /* no error if we get here */
  1563.    _mesa_unlock_texture(ctx, obj);
  1564.    return;
  1565.  
  1566. invalid_pname:
  1567.    _mesa_unlock_texture(ctx, obj);
  1568.    _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname);
  1569. }
  1570.  
  1571.  
  1572. void GLAPIENTRY
  1573. _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
  1574. {
  1575.    struct gl_texture_object *obj;
  1576.    GET_CURRENT_CONTEXT(ctx);
  1577.  
  1578.    obj = get_texobj(ctx, target, GL_TRUE);
  1579.    if (!obj)
  1580.       return;
  1581.  
  1582.    _mesa_lock_texture(ctx, obj);
  1583.    switch (pname) {
  1584.       case GL_TEXTURE_MAG_FILTER:
  1585.          *params = (GLint) obj->Sampler.MagFilter;
  1586.          break;
  1587.       case GL_TEXTURE_MIN_FILTER:
  1588.          *params = (GLint) obj->Sampler.MinFilter;
  1589.          break;
  1590.       case GL_TEXTURE_WRAP_S:
  1591.          *params = (GLint) obj->Sampler.WrapS;
  1592.          break;
  1593.       case GL_TEXTURE_WRAP_T:
  1594.          *params = (GLint) obj->Sampler.WrapT;
  1595.          break;
  1596.       case GL_TEXTURE_WRAP_R:
  1597.          *params = (GLint) obj->Sampler.WrapR;
  1598.          break;
  1599.       case GL_TEXTURE_BORDER_COLOR:
  1600.          if (!_mesa_is_desktop_gl(ctx))
  1601.             goto invalid_pname;
  1602.  
  1603.          {
  1604.             GLfloat b[4];
  1605.             b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
  1606.             b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
  1607.             b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
  1608.             b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
  1609.             params[0] = FLOAT_TO_INT(b[0]);
  1610.             params[1] = FLOAT_TO_INT(b[1]);
  1611.             params[2] = FLOAT_TO_INT(b[2]);
  1612.             params[3] = FLOAT_TO_INT(b[3]);
  1613.          }
  1614.          break;
  1615.       case GL_TEXTURE_RESIDENT:
  1616.          if (ctx->API != API_OPENGL_COMPAT)
  1617.             goto invalid_pname;
  1618.  
  1619.          *params = 1;
  1620.          break;
  1621.       case GL_TEXTURE_PRIORITY:
  1622.          if (ctx->API != API_OPENGL_COMPAT)
  1623.             goto invalid_pname;
  1624.  
  1625.          *params = FLOAT_TO_INT(obj->Priority);
  1626.          break;
  1627.       case GL_TEXTURE_MIN_LOD:
  1628.          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
  1629.             goto invalid_pname;
  1630.  
  1631.          *params = (GLint) obj->Sampler.MinLod;
  1632.          break;
  1633.       case GL_TEXTURE_MAX_LOD:
  1634.          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
  1635.             goto invalid_pname;
  1636.  
  1637.          *params = (GLint) obj->Sampler.MaxLod;
  1638.          break;
  1639.       case GL_TEXTURE_BASE_LEVEL:
  1640.          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
  1641.             goto invalid_pname;
  1642.  
  1643.          *params = obj->BaseLevel;
  1644.          break;
  1645.       case GL_TEXTURE_MAX_LEVEL:
  1646.          *params = obj->MaxLevel;
  1647.          break;
  1648.       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  1649.          if (!ctx->Extensions.EXT_texture_filter_anisotropic)
  1650.             goto invalid_pname;
  1651.          *params = (GLint) obj->Sampler.MaxAnisotropy;
  1652.          break;
  1653.       case GL_GENERATE_MIPMAP_SGIS:
  1654.          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
  1655.             goto invalid_pname;
  1656.  
  1657.          *params = (GLint) obj->GenerateMipmap;
  1658.          break;
  1659.       case GL_TEXTURE_COMPARE_MODE_ARB:
  1660.          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
  1661.              && !_mesa_is_gles3(ctx))
  1662.             goto invalid_pname;
  1663.          *params = (GLint) obj->Sampler.CompareMode;
  1664.          break;
  1665.       case GL_TEXTURE_COMPARE_FUNC_ARB:
  1666.          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
  1667.              && !_mesa_is_gles3(ctx))
  1668.             goto invalid_pname;
  1669.          *params = (GLint) obj->Sampler.CompareFunc;
  1670.          break;
  1671.       case GL_DEPTH_TEXTURE_MODE_ARB:
  1672.          if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
  1673.             goto invalid_pname;
  1674.          *params = (GLint) obj->DepthMode;
  1675.          break;
  1676.       case GL_TEXTURE_LOD_BIAS:
  1677.          if (_mesa_is_gles(ctx))
  1678.             goto invalid_pname;
  1679.  
  1680.          /* GL spec 'Data Conversions' section specifies that floating-point
  1681.           * value in integer Get function is rounded to nearest integer
  1682.           */
  1683.          *params = (GLint) roundf(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.