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) 2011  VMware, Inc.  All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. /**
  27.  * \file samplerobj.c
  28.  * \brief Functions for the GL_ARB_sampler_objects extension.
  29.  * \author Brian Paul
  30.  */
  31.  
  32.  
  33. #include "main/glheader.h"
  34. #include "main/context.h"
  35. #include "main/dispatch.h"
  36. #include "main/enums.h"
  37. #include "main/hash.h"
  38. #include "main/macros.h"
  39. #include "main/mtypes.h"
  40. #include "main/samplerobj.h"
  41.  
  42.  
  43. struct gl_sampler_object *
  44. _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name)
  45. {
  46.    if (name == 0)
  47.       return NULL;
  48.    else
  49.       return (struct gl_sampler_object *)
  50.          _mesa_HashLookup(ctx->Shared->SamplerObjects, name);
  51. }
  52.  
  53.  
  54. /**
  55.  * Handle reference counting.
  56.  */
  57. void
  58. _mesa_reference_sampler_object_(struct gl_context *ctx,
  59.                                 struct gl_sampler_object **ptr,
  60.                                 struct gl_sampler_object *samp)
  61. {
  62.    assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */
  63.  
  64.    if (*ptr) {
  65.       /* Unreference the old sampler */
  66.       GLboolean deleteFlag = GL_FALSE;
  67.       struct gl_sampler_object *oldSamp = *ptr;
  68.  
  69.       /*_glthread_LOCK_MUTEX(oldSamp->Mutex);*/
  70.       ASSERT(oldSamp->RefCount > 0);
  71.       oldSamp->RefCount--;
  72. #if 0
  73.       printf("SamplerObj %p %d DECR to %d\n",
  74.              (void *) oldSamp, oldSamp->Name, oldSamp->RefCount);
  75. #endif
  76.       deleteFlag = (oldSamp->RefCount == 0);
  77.       /*_glthread_UNLOCK_MUTEX(oldSamp->Mutex);*/
  78.  
  79.       if (deleteFlag) {
  80.          ASSERT(ctx->Driver.DeleteSamplerObject);
  81.          ctx->Driver.DeleteSamplerObject(ctx, oldSamp);
  82.       }
  83.  
  84.       *ptr = NULL;
  85.    }
  86.    ASSERT(!*ptr);
  87.  
  88.    if (samp) {
  89.       /* reference new sampler */
  90.       /*_glthread_LOCK_MUTEX(samp->Mutex);*/
  91.       if (samp->RefCount == 0) {
  92.          /* this sampler's being deleted (look just above) */
  93.          /* Not sure this can every really happen.  Warn if it does. */
  94.          _mesa_problem(NULL, "referencing deleted sampler object");
  95.          *ptr = NULL;
  96.       }
  97.       else {
  98.          samp->RefCount++;
  99. #if 0
  100.          printf("SamplerObj %p %d INCR to %d\n",
  101.                 (void *) samp, samp->Name, samp->RefCount);
  102. #endif
  103.          *ptr = samp;
  104.       }
  105.       /*_glthread_UNLOCK_MUTEX(samp->Mutex);*/
  106.    }
  107. }
  108.  
  109.  
  110. /**
  111.  * Initialize the fields of the given sampler object.
  112.  */
  113. static void
  114. _mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name)
  115. {
  116.    sampObj->Name = name;
  117.    sampObj->RefCount = 1;
  118.    sampObj->WrapS = GL_REPEAT;
  119.    sampObj->WrapT = GL_REPEAT;
  120.    sampObj->WrapR = GL_REPEAT;
  121.    sampObj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
  122.    sampObj->MagFilter = GL_LINEAR;
  123.    sampObj->BorderColor.f[0] = 0.0;
  124.    sampObj->BorderColor.f[1] = 0.0;
  125.    sampObj->BorderColor.f[2] = 0.0;
  126.    sampObj->BorderColor.f[3] = 0.0;
  127.    sampObj->MinLod = -1000.0F;
  128.    sampObj->MaxLod = 1000.0F;
  129.    sampObj->LodBias = 0.0F;
  130.    sampObj->MaxAnisotropy = 1.0F;
  131.    sampObj->CompareMode = GL_NONE;
  132.    sampObj->CompareFunc = GL_LEQUAL;
  133.    sampObj->sRGBDecode = GL_DECODE_EXT;
  134.    sampObj->CubeMapSeamless = GL_FALSE;
  135. }
  136.  
  137. /**
  138.  * Fallback for ctx->Driver.NewSamplerObject();
  139.  */
  140. struct gl_sampler_object *
  141. _mesa_new_sampler_object(struct gl_context *ctx, GLuint name)
  142. {
  143.    struct gl_sampler_object *sampObj = CALLOC_STRUCT(gl_sampler_object);
  144.    if (sampObj) {
  145.       _mesa_init_sampler_object(sampObj, name);
  146.    }
  147.    return sampObj;
  148. }
  149.  
  150.  
  151. /**
  152.  * Fallback for ctx->Driver.DeleteSamplerObject();
  153.  */
  154. static void
  155. _mesa_delete_sampler_object(struct gl_context *ctx,
  156.                             struct gl_sampler_object *sampObj)
  157. {
  158.    free(sampObj);
  159. }
  160.  
  161.  
  162. void GLAPIENTRY
  163. _mesa_GenSamplers(GLsizei count, GLuint *samplers)
  164. {
  165.    GET_CURRENT_CONTEXT(ctx);
  166.    GLuint first;
  167.    GLint i;
  168.  
  169.    if (MESA_VERBOSE & VERBOSE_API)
  170.       _mesa_debug(ctx, "glGenSamplers(%d)\n", count);
  171.  
  172.    if (count < 0) {
  173.       _mesa_error(ctx, GL_INVALID_VALUE, "glGenSamplers");
  174.       return;
  175.    }
  176.  
  177.    if (!samplers)
  178.       return;
  179.  
  180.    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count);
  181.  
  182.    /* Insert the ID and pointer to new sampler object into hash table */
  183.    for (i = 0; i < count; i++) {
  184.       struct gl_sampler_object *sampObj =
  185.          ctx->Driver.NewSamplerObject(ctx, first + i);
  186.       _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj);
  187.       samplers[i] = first + i;
  188.    }
  189. }
  190.  
  191.  
  192. void GLAPIENTRY
  193. _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
  194. {
  195.    GET_CURRENT_CONTEXT(ctx);
  196.    GLsizei i;
  197.  
  198.    FLUSH_VERTICES(ctx, 0);
  199.  
  200.    if (count < 0) {
  201.       _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteSamplers(count)");
  202.       return;
  203.    }
  204.  
  205.    _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
  206.  
  207.    for (i = 0; i < count; i++) {
  208.       if (samplers[i]) {
  209.          GLuint j;
  210.          struct gl_sampler_object *sampObj =
  211.             _mesa_lookup_samplerobj(ctx, samplers[i]);
  212.    
  213.          if (sampObj) {
  214.             /* If the sampler is currently bound, unbind it. */
  215.             for (j = 0; j < ctx->Const.MaxCombinedTextureImageUnits; j++) {
  216.                if (ctx->Texture.Unit[j].Sampler == sampObj) {
  217.                   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
  218.                   _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL);
  219.                }
  220.             }
  221.  
  222.             /* The ID is immediately freed for re-use */
  223.             _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]);
  224.             /* But the object exists until its reference count goes to zero */
  225.             _mesa_reference_sampler_object(ctx, &sampObj, NULL);
  226.          }
  227.       }
  228.    }
  229.  
  230.    _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
  231. }
  232.  
  233.  
  234. GLboolean GLAPIENTRY
  235. _mesa_IsSampler(GLuint sampler)
  236. {
  237.    struct gl_sampler_object *sampObj;
  238.    GET_CURRENT_CONTEXT(ctx);
  239.  
  240.    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
  241.  
  242.    if (sampler == 0)
  243.       return GL_FALSE;
  244.  
  245.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  246.  
  247.    return sampObj != NULL;
  248. }
  249.  
  250.  
  251. void GLAPIENTRY
  252. _mesa_BindSampler(GLuint unit, GLuint sampler)
  253. {
  254.    struct gl_sampler_object *sampObj;
  255.    GET_CURRENT_CONTEXT(ctx);
  256.  
  257.    if (unit >= ctx->Const.MaxCombinedTextureImageUnits) {
  258.       _mesa_error(ctx, GL_INVALID_VALUE, "glBindSampler(unit %u)", unit);
  259.       return;
  260.    }
  261.  
  262.    if (sampler == 0) {
  263.       /* Use the default sampler object, the one contained in the texture
  264.        * object.
  265.        */
  266.       sampObj = NULL;
  267.    }
  268.    else {
  269.       /* user-defined sampler object */
  270.       sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  271.       if (!sampObj) {
  272.          _mesa_error(ctx, GL_INVALID_OPERATION, "glBindSampler(sampler)");
  273.          return;
  274.       }
  275.    }
  276.    
  277.    if (ctx->Texture.Unit[unit].Sampler != sampObj) {
  278.       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
  279.    }
  280.  
  281.    /* bind new sampler */
  282.    _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler,
  283.                                   sampObj);
  284. }
  285.  
  286.  
  287. /**
  288.  * Check if a coordinate wrap mode is legal.
  289.  * \return GL_TRUE if legal, GL_FALSE otherwise
  290.  */
  291. static GLboolean
  292. validate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap)
  293. {
  294.    const struct gl_extensions * const e = &ctx->Extensions;
  295.  
  296.    switch (wrap) {
  297.    case GL_CLAMP:
  298.    case GL_CLAMP_TO_EDGE:
  299.    case GL_REPEAT:
  300.    case GL_MIRRORED_REPEAT:
  301.       return GL_TRUE;
  302.    case GL_CLAMP_TO_BORDER:
  303.       return e->ARB_texture_border_clamp;
  304.    case GL_MIRROR_CLAMP_EXT:
  305.       return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp;
  306.    case GL_MIRROR_CLAMP_TO_EDGE_EXT:
  307.       return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp;
  308.    case GL_MIRROR_CLAMP_TO_BORDER_EXT:
  309.       return e->EXT_texture_mirror_clamp;
  310.    default:
  311.       return GL_FALSE;
  312.    }
  313. }
  314.  
  315.  
  316. /**
  317.  * This is called just prior to changing any sampler object state.
  318.  */
  319. static inline void
  320. flush(struct gl_context *ctx)
  321. {
  322.    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
  323. }
  324.  
  325.  
  326. #define INVALID_PARAM 0x100
  327. #define INVALID_PNAME 0x101
  328. #define INVALID_VALUE 0x102
  329.  
  330. static GLuint
  331. set_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp,
  332.                    GLint param)
  333. {
  334.    if (samp->WrapS == param)
  335.       return GL_FALSE;
  336.    if (validate_texture_wrap_mode(ctx, param)) {
  337.       flush(ctx);
  338.       samp->WrapS = param;
  339.       return GL_TRUE;
  340.    }
  341.    return INVALID_PARAM;
  342. }
  343.  
  344.  
  345. static GLuint
  346. set_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp,
  347.                    GLint param)
  348. {
  349.    if (samp->WrapT == param)
  350.       return GL_FALSE;
  351.    if (validate_texture_wrap_mode(ctx, param)) {
  352.       flush(ctx);
  353.       samp->WrapT = param;
  354.       return GL_TRUE;
  355.    }
  356.    return INVALID_PARAM;
  357. }
  358.  
  359.  
  360. static GLuint
  361. set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp,
  362.                    GLint param)
  363. {
  364.    if (samp->WrapR == param)
  365.       return GL_FALSE;
  366.    if (validate_texture_wrap_mode(ctx, param)) {
  367.       flush(ctx);
  368.       samp->WrapR = param;
  369.       return GL_TRUE;
  370.    }
  371.    return INVALID_PARAM;
  372. }
  373.  
  374.  
  375. static GLuint
  376. set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp,
  377.                        GLint param)
  378. {
  379.    if (samp->MinFilter == param)
  380.       return GL_FALSE;
  381.  
  382.    switch (param) {
  383.    case GL_NEAREST:
  384.    case GL_LINEAR:
  385.    case GL_NEAREST_MIPMAP_NEAREST:
  386.    case GL_LINEAR_MIPMAP_NEAREST:
  387.    case GL_NEAREST_MIPMAP_LINEAR:
  388.    case GL_LINEAR_MIPMAP_LINEAR:
  389.       flush(ctx);
  390.       samp->MinFilter = param;
  391.       return GL_TRUE;
  392.    default:
  393.       return INVALID_PARAM;
  394.    }
  395. }
  396.  
  397.  
  398. static GLuint
  399. set_sampler_mag_filter(struct gl_context *ctx, struct gl_sampler_object *samp,
  400.                        GLint param)
  401. {
  402.    if (samp->MagFilter == param)
  403.       return GL_FALSE;
  404.  
  405.    switch (param) {
  406.    case GL_NEAREST:
  407.    case GL_LINEAR:
  408.       flush(ctx);
  409.       samp->MagFilter = param;
  410.       return GL_TRUE;
  411.    default:
  412.       return INVALID_PARAM;
  413.    }
  414. }
  415.  
  416.  
  417. static GLuint
  418. set_sampler_lod_bias(struct gl_context *ctx, struct gl_sampler_object *samp,
  419.                      GLfloat param)
  420. {
  421.    if (samp->LodBias == param)
  422.       return GL_FALSE;
  423.  
  424.    flush(ctx);
  425.    samp->LodBias = param;
  426.    return GL_TRUE;
  427. }
  428.  
  429.  
  430. static GLuint
  431. set_sampler_border_colorf(struct gl_context *ctx,
  432.                           struct gl_sampler_object *samp,
  433.                           const GLfloat params[4])
  434. {
  435.    flush(ctx);
  436.    samp->BorderColor.f[RCOMP] = params[0];
  437.    samp->BorderColor.f[GCOMP] = params[1];
  438.    samp->BorderColor.f[BCOMP] = params[2];
  439.    samp->BorderColor.f[ACOMP] = params[3];
  440.    return GL_TRUE;
  441. }
  442.  
  443.  
  444. static GLuint
  445. set_sampler_border_colori(struct gl_context *ctx,
  446.                           struct gl_sampler_object *samp,
  447.                           const GLint params[4])
  448. {
  449.    flush(ctx);
  450.    samp->BorderColor.i[RCOMP] = params[0];
  451.    samp->BorderColor.i[GCOMP] = params[1];
  452.    samp->BorderColor.i[BCOMP] = params[2];
  453.    samp->BorderColor.i[ACOMP] = params[3];
  454.    return GL_TRUE;
  455. }
  456.  
  457.  
  458. static GLuint
  459. set_sampler_border_colorui(struct gl_context *ctx,
  460.                            struct gl_sampler_object *samp,
  461.                            const GLuint params[4])
  462. {
  463.    flush(ctx);
  464.    samp->BorderColor.ui[RCOMP] = params[0];
  465.    samp->BorderColor.ui[GCOMP] = params[1];
  466.    samp->BorderColor.ui[BCOMP] = params[2];
  467.    samp->BorderColor.ui[ACOMP] = params[3];
  468.    return GL_TRUE;
  469. }
  470.  
  471.  
  472. static GLuint
  473. set_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp,
  474.                     GLfloat param)
  475. {
  476.    if (samp->MinLod == param)
  477.       return GL_FALSE;
  478.  
  479.    flush(ctx);
  480.    samp->MinLod = param;
  481.    return GL_TRUE;
  482. }
  483.  
  484.  
  485. static GLuint
  486. set_sampler_max_lod(struct gl_context *ctx, struct gl_sampler_object *samp,
  487.                     GLfloat param)
  488. {
  489.    if (samp->MaxLod == param)
  490.       return GL_FALSE;
  491.  
  492.    flush(ctx);
  493.    samp->MaxLod = param;
  494.    return GL_TRUE;
  495. }
  496.  
  497.  
  498. static GLuint
  499. set_sampler_compare_mode(struct gl_context *ctx,
  500.                          struct gl_sampler_object *samp, GLint param)
  501. {
  502.    if (!ctx->Extensions.ARB_shadow)
  503.       return INVALID_PNAME;
  504.  
  505.    if (samp->CompareMode == param)
  506.       return GL_FALSE;
  507.  
  508.    if (param == GL_NONE ||
  509.        param == GL_COMPARE_R_TO_TEXTURE_ARB) {
  510.       flush(ctx);
  511.       samp->CompareMode = param;
  512.       return GL_TRUE;
  513.    }
  514.  
  515.    return INVALID_PARAM;
  516. }
  517.  
  518.  
  519. static GLuint
  520. set_sampler_compare_func(struct gl_context *ctx,
  521.                          struct gl_sampler_object *samp, GLint param)
  522. {
  523.    if (!ctx->Extensions.ARB_shadow)
  524.       return INVALID_PNAME;
  525.  
  526.    if (samp->CompareFunc == param)
  527.       return GL_FALSE;
  528.  
  529.    switch (param) {
  530.    case GL_LEQUAL:
  531.    case GL_GEQUAL:
  532.    case GL_EQUAL:
  533.    case GL_NOTEQUAL:
  534.    case GL_LESS:
  535.    case GL_GREATER:
  536.    case GL_ALWAYS:
  537.    case GL_NEVER:
  538.       flush(ctx);
  539.       samp->CompareFunc = param;
  540.       return GL_TRUE;
  541.    default:
  542.       return INVALID_PARAM;
  543.    }
  544. }
  545.  
  546.  
  547. static GLuint
  548. set_sampler_max_anisotropy(struct gl_context *ctx,
  549.                            struct gl_sampler_object *samp, GLfloat param)
  550. {
  551.    if (!ctx->Extensions.EXT_texture_filter_anisotropic)
  552.       return INVALID_PNAME;
  553.  
  554.    if (samp->MaxAnisotropy == param)
  555.       return GL_FALSE;
  556.  
  557.    if (param < 1.0)
  558.       return INVALID_VALUE;
  559.  
  560.    flush(ctx);
  561.    /* clamp to max, that's what NVIDIA does */
  562.    samp->MaxAnisotropy = MIN2(param, ctx->Const.MaxTextureMaxAnisotropy);
  563.    return GL_TRUE;
  564. }
  565.  
  566.  
  567. static GLuint
  568. set_sampler_cube_map_seamless(struct gl_context *ctx,
  569.                               struct gl_sampler_object *samp, GLboolean param)
  570. {
  571.    if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
  572.       return INVALID_PNAME;
  573.  
  574.    if (samp->CubeMapSeamless == param)
  575.       return GL_FALSE;
  576.  
  577.    if (param != GL_TRUE && param != GL_FALSE)
  578.       return INVALID_VALUE;
  579.  
  580.    flush(ctx);
  581.    samp->CubeMapSeamless = param;
  582.    return GL_TRUE;
  583. }
  584.  
  585. static GLuint
  586. set_sampler_srgb_decode(struct gl_context *ctx,
  587.                               struct gl_sampler_object *samp, GLenum param)
  588. {
  589.    if (!ctx->Extensions.EXT_texture_sRGB_decode)
  590.       return INVALID_PNAME;
  591.  
  592.    if (samp->sRGBDecode == param)
  593.       return GL_FALSE;
  594.  
  595.    if (param != GL_DECODE_EXT && param != GL_SKIP_DECODE_EXT)
  596.       return INVALID_VALUE;
  597.  
  598.    flush(ctx);
  599.    samp->sRGBDecode = param;
  600.    return GL_TRUE;
  601. }
  602.  
  603. void GLAPIENTRY
  604. _mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
  605. {
  606.    struct gl_sampler_object *sampObj;
  607.    GLuint res;
  608.    GET_CURRENT_CONTEXT(ctx);
  609.  
  610.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  611.    if (!sampObj) {
  612.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(sampler %u)",
  613.                   sampler);
  614.       return;
  615.    }
  616.  
  617.    switch (pname) {
  618.    case GL_TEXTURE_WRAP_S:
  619.       res = set_sampler_wrap_s(ctx, sampObj, param);
  620.       break;
  621.    case GL_TEXTURE_WRAP_T:
  622.       res = set_sampler_wrap_t(ctx, sampObj, param);
  623.       break;
  624.    case GL_TEXTURE_WRAP_R:
  625.       res = set_sampler_wrap_r(ctx, sampObj, param);
  626.       break;
  627.    case GL_TEXTURE_MIN_FILTER:
  628.       res = set_sampler_min_filter(ctx, sampObj, param);
  629.       break;
  630.    case GL_TEXTURE_MAG_FILTER:
  631.       res = set_sampler_mag_filter(ctx, sampObj, param);
  632.       break;
  633.    case GL_TEXTURE_MIN_LOD:
  634.       res = set_sampler_min_lod(ctx, sampObj, (GLfloat) param);
  635.       break;
  636.    case GL_TEXTURE_MAX_LOD:
  637.       res = set_sampler_max_lod(ctx, sampObj, (GLfloat) param);
  638.       break;
  639.    case GL_TEXTURE_LOD_BIAS:
  640.       res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) param);
  641.       break;
  642.    case GL_TEXTURE_COMPARE_MODE:
  643.       res = set_sampler_compare_mode(ctx, sampObj, param);
  644.       break;
  645.    case GL_TEXTURE_COMPARE_FUNC:
  646.       res = set_sampler_compare_func(ctx, sampObj, param);
  647.       break;
  648.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  649.       res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) param);
  650.       break;
  651.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  652.       res = set_sampler_cube_map_seamless(ctx, sampObj, param);
  653.       break;
  654.    case GL_TEXTURE_SRGB_DECODE_EXT:
  655.       res = set_sampler_srgb_decode(ctx, sampObj, param);
  656.       break;
  657.    case GL_TEXTURE_BORDER_COLOR:
  658.       /* fall-through */
  659.    default:
  660.       res = INVALID_PNAME;
  661.    }
  662.  
  663.    switch (res) {
  664.    case GL_FALSE:
  665.       /* no change */
  666.       break;
  667.    case GL_TRUE:
  668.       /* state change - we do nothing special at this time */
  669.       break;
  670.    case INVALID_PNAME:
  671.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n",
  672.                   _mesa_lookup_enum_by_nr(pname));
  673.       break;
  674.    case INVALID_PARAM:
  675.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n",
  676.                   param);
  677.       break;
  678.    case INVALID_VALUE:
  679.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(param=%d)\n",
  680.                   param);
  681.       break;
  682.    default:
  683.       ;
  684.    }
  685. }
  686.  
  687.  
  688. void GLAPIENTRY
  689. _mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
  690. {
  691.    struct gl_sampler_object *sampObj;
  692.    GLuint res;
  693.    GET_CURRENT_CONTEXT(ctx);
  694.  
  695.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  696.    if (!sampObj) {
  697.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(sampler %u)",
  698.                   sampler);
  699.       return;
  700.    }
  701.  
  702.    switch (pname) {
  703.    case GL_TEXTURE_WRAP_S:
  704.       res = set_sampler_wrap_s(ctx, sampObj, (GLint) param);
  705.       break;
  706.    case GL_TEXTURE_WRAP_T:
  707.       res = set_sampler_wrap_t(ctx, sampObj, (GLint) param);
  708.       break;
  709.    case GL_TEXTURE_WRAP_R:
  710.       res = set_sampler_wrap_r(ctx, sampObj, (GLint) param);
  711.       break;
  712.    case GL_TEXTURE_MIN_FILTER:
  713.       res = set_sampler_min_filter(ctx, sampObj, (GLint) param);
  714.       break;
  715.    case GL_TEXTURE_MAG_FILTER:
  716.       res = set_sampler_mag_filter(ctx, sampObj, (GLint) param);
  717.       break;
  718.    case GL_TEXTURE_MIN_LOD:
  719.       res = set_sampler_min_lod(ctx, sampObj, param);
  720.       break;
  721.    case GL_TEXTURE_MAX_LOD:
  722.       res = set_sampler_max_lod(ctx, sampObj, param);
  723.       break;
  724.    case GL_TEXTURE_LOD_BIAS:
  725.       res = set_sampler_lod_bias(ctx, sampObj, param);
  726.       break;
  727.    case GL_TEXTURE_COMPARE_MODE:
  728.       res = set_sampler_compare_mode(ctx, sampObj, (GLint) param);
  729.       break;
  730.    case GL_TEXTURE_COMPARE_FUNC:
  731.       res = set_sampler_compare_func(ctx, sampObj, (GLint) param);
  732.       break;
  733.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  734.       res = set_sampler_max_anisotropy(ctx, sampObj, param);
  735.       break;
  736.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  737.       res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param);
  738.       break;
  739.    case GL_TEXTURE_SRGB_DECODE_EXT:
  740.       res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param);
  741.       break;
  742.    case GL_TEXTURE_BORDER_COLOR:
  743.       /* fall-through */
  744.    default:
  745.       res = INVALID_PNAME;
  746.    }
  747.  
  748.    switch (res) {
  749.    case GL_FALSE:
  750.       /* no change */
  751.       break;
  752.    case GL_TRUE:
  753.       /* state change - we do nothing special at this time */
  754.       break;
  755.    case INVALID_PNAME:
  756.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n",
  757.                   _mesa_lookup_enum_by_nr(pname));
  758.       break;
  759.    case INVALID_PARAM:
  760.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n",
  761.                   param);
  762.       break;
  763.    case INVALID_VALUE:
  764.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(param=%f)\n",
  765.                   param);
  766.       break;
  767.    default:
  768.       ;
  769.    }
  770. }
  771.  
  772. void GLAPIENTRY
  773. _mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
  774. {
  775.    struct gl_sampler_object *sampObj;
  776.    GLuint res;
  777.    GET_CURRENT_CONTEXT(ctx);
  778.  
  779.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  780.    if (!sampObj) {
  781.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(sampler %u)",
  782.                   sampler);
  783.       return;
  784.    }
  785.  
  786.    switch (pname) {
  787.    case GL_TEXTURE_WRAP_S:
  788.       res = set_sampler_wrap_s(ctx, sampObj, params[0]);
  789.       break;
  790.    case GL_TEXTURE_WRAP_T:
  791.       res = set_sampler_wrap_t(ctx, sampObj, params[0]);
  792.       break;
  793.    case GL_TEXTURE_WRAP_R:
  794.       res = set_sampler_wrap_r(ctx, sampObj, params[0]);
  795.       break;
  796.    case GL_TEXTURE_MIN_FILTER:
  797.       res = set_sampler_min_filter(ctx, sampObj, params[0]);
  798.       break;
  799.    case GL_TEXTURE_MAG_FILTER:
  800.       res = set_sampler_mag_filter(ctx, sampObj, params[0]);
  801.       break;
  802.    case GL_TEXTURE_MIN_LOD:
  803.       res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
  804.       break;
  805.    case GL_TEXTURE_MAX_LOD:
  806.       res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
  807.       break;
  808.    case GL_TEXTURE_LOD_BIAS:
  809.       res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
  810.       break;
  811.    case GL_TEXTURE_COMPARE_MODE:
  812.       res = set_sampler_compare_mode(ctx, sampObj, params[0]);
  813.       break;
  814.    case GL_TEXTURE_COMPARE_FUNC:
  815.       res = set_sampler_compare_func(ctx, sampObj, params[0]);
  816.       break;
  817.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  818.       res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
  819.       break;
  820.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  821.       res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
  822.       break;
  823.    case GL_TEXTURE_SRGB_DECODE_EXT:
  824.       res = set_sampler_srgb_decode(ctx, sampObj, params[0]);
  825.       break;
  826.    case GL_TEXTURE_BORDER_COLOR:
  827.       {
  828.          GLfloat c[4];
  829.          c[0] = INT_TO_FLOAT(params[0]);
  830.          c[1] = INT_TO_FLOAT(params[1]);
  831.          c[2] = INT_TO_FLOAT(params[2]);
  832.          c[3] = INT_TO_FLOAT(params[3]);
  833.          res = set_sampler_border_colorf(ctx, sampObj, c);
  834.       }
  835.       break;
  836.    default:
  837.       res = INVALID_PNAME;
  838.    }
  839.  
  840.    switch (res) {
  841.    case GL_FALSE:
  842.       /* no change */
  843.       break;
  844.    case GL_TRUE:
  845.       /* state change - we do nothing special at this time */
  846.       break;
  847.    case INVALID_PNAME:
  848.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(pname=%s)\n",
  849.                   _mesa_lookup_enum_by_nr(pname));
  850.       break;
  851.    case INVALID_PARAM:
  852.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n",
  853.                   params[0]);
  854.       break;
  855.    case INVALID_VALUE:
  856.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(param=%d)\n",
  857.                   params[0]);
  858.       break;
  859.    default:
  860.       ;
  861.    }
  862. }
  863.  
  864. void GLAPIENTRY
  865. _mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
  866. {
  867.    struct gl_sampler_object *sampObj;
  868.    GLuint res;
  869.    GET_CURRENT_CONTEXT(ctx);
  870.  
  871.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  872.    if (!sampObj) {
  873.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(sampler %u)",
  874.                   sampler);
  875.       return;
  876.    }
  877.  
  878.    switch (pname) {
  879.    case GL_TEXTURE_WRAP_S:
  880.       res = set_sampler_wrap_s(ctx, sampObj, (GLint) params[0]);
  881.       break;
  882.    case GL_TEXTURE_WRAP_T:
  883.       res = set_sampler_wrap_t(ctx, sampObj, (GLint) params[0]);
  884.       break;
  885.    case GL_TEXTURE_WRAP_R:
  886.       res = set_sampler_wrap_r(ctx, sampObj, (GLint) params[0]);
  887.       break;
  888.    case GL_TEXTURE_MIN_FILTER:
  889.       res = set_sampler_min_filter(ctx, sampObj, (GLint) params[0]);
  890.       break;
  891.    case GL_TEXTURE_MAG_FILTER:
  892.       res = set_sampler_mag_filter(ctx, sampObj, (GLint) params[0]);
  893.       break;
  894.    case GL_TEXTURE_MIN_LOD:
  895.       res = set_sampler_min_lod(ctx, sampObj, params[0]);
  896.       break;
  897.    case GL_TEXTURE_MAX_LOD:
  898.       res = set_sampler_max_lod(ctx, sampObj, params[0]);
  899.       break;
  900.    case GL_TEXTURE_LOD_BIAS:
  901.       res = set_sampler_lod_bias(ctx, sampObj, params[0]);
  902.       break;
  903.    case GL_TEXTURE_COMPARE_MODE:
  904.       res = set_sampler_compare_mode(ctx, sampObj, (GLint) params[0]);
  905.       break;
  906.    case GL_TEXTURE_COMPARE_FUNC:
  907.       res = set_sampler_compare_func(ctx, sampObj, (GLint) params[0]);
  908.       break;
  909.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  910.       res = set_sampler_max_anisotropy(ctx, sampObj, params[0]);
  911.       break;
  912.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  913.       res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]);
  914.       break;
  915.    case GL_TEXTURE_SRGB_DECODE_EXT:
  916.       res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
  917.       break;
  918.    case GL_TEXTURE_BORDER_COLOR:
  919.       res = set_sampler_border_colorf(ctx, sampObj, params);
  920.       break;
  921.    default:
  922.       res = INVALID_PNAME;
  923.    }
  924.  
  925.    switch (res) {
  926.    case GL_FALSE:
  927.       /* no change */
  928.       break;
  929.    case GL_TRUE:
  930.       /* state change - we do nothing special at this time */
  931.       break;
  932.    case INVALID_PNAME:
  933.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n",
  934.                   _mesa_lookup_enum_by_nr(pname));
  935.       break;
  936.    case INVALID_PARAM:
  937.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n",
  938.                   params[0]);
  939.       break;
  940.    case INVALID_VALUE:
  941.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(param=%f)\n",
  942.                   params[0]);
  943.       break;
  944.    default:
  945.       ;
  946.    }
  947. }
  948.  
  949. void GLAPIENTRY
  950. _mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
  951. {
  952.    struct gl_sampler_object *sampObj;
  953.    GLuint res;
  954.    GET_CURRENT_CONTEXT(ctx);
  955.  
  956.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  957.    if (!sampObj) {
  958.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(sampler %u)",
  959.                   sampler);
  960.       return;
  961.    }
  962.  
  963.    switch (pname) {
  964.    case GL_TEXTURE_WRAP_S:
  965.       res = set_sampler_wrap_s(ctx, sampObj, params[0]);
  966.       break;
  967.    case GL_TEXTURE_WRAP_T:
  968.       res = set_sampler_wrap_t(ctx, sampObj, params[0]);
  969.       break;
  970.    case GL_TEXTURE_WRAP_R:
  971.       res = set_sampler_wrap_r(ctx, sampObj, params[0]);
  972.       break;
  973.    case GL_TEXTURE_MIN_FILTER:
  974.       res = set_sampler_min_filter(ctx, sampObj, params[0]);
  975.       break;
  976.    case GL_TEXTURE_MAG_FILTER:
  977.       res = set_sampler_mag_filter(ctx, sampObj, params[0]);
  978.       break;
  979.    case GL_TEXTURE_MIN_LOD:
  980.       res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
  981.       break;
  982.    case GL_TEXTURE_MAX_LOD:
  983.       res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
  984.       break;
  985.    case GL_TEXTURE_LOD_BIAS:
  986.       res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
  987.       break;
  988.    case GL_TEXTURE_COMPARE_MODE:
  989.       res = set_sampler_compare_mode(ctx, sampObj, params[0]);
  990.       break;
  991.    case GL_TEXTURE_COMPARE_FUNC:
  992.       res = set_sampler_compare_func(ctx, sampObj, params[0]);
  993.       break;
  994.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  995.       res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
  996.       break;
  997.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  998.       res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
  999.       break;
  1000.    case GL_TEXTURE_SRGB_DECODE_EXT:
  1001.       res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
  1002.       break;
  1003.    case GL_TEXTURE_BORDER_COLOR:
  1004.       res = set_sampler_border_colori(ctx, sampObj, params);
  1005.       break;
  1006.    default:
  1007.       res = INVALID_PNAME;
  1008.    }
  1009.  
  1010.    switch (res) {
  1011.    case GL_FALSE:
  1012.       /* no change */
  1013.       break;
  1014.    case GL_TRUE:
  1015.       /* state change - we do nothing special at this time */
  1016.       break;
  1017.    case INVALID_PNAME:
  1018.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n",
  1019.                   _mesa_lookup_enum_by_nr(pname));
  1020.       break;
  1021.    case INVALID_PARAM:
  1022.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n",
  1023.                   params[0]);
  1024.       break;
  1025.    case INVALID_VALUE:
  1026.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(param=%d)\n",
  1027.                   params[0]);
  1028.       break;
  1029.    default:
  1030.       ;
  1031.    }
  1032. }
  1033.  
  1034.  
  1035. void GLAPIENTRY
  1036. _mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
  1037. {
  1038.    struct gl_sampler_object *sampObj;
  1039.    GLuint res;
  1040.    GET_CURRENT_CONTEXT(ctx);
  1041.  
  1042.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  1043.    if (!sampObj) {
  1044.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(sampler %u)",
  1045.                   sampler);
  1046.       return;
  1047.    }
  1048.  
  1049.    switch (pname) {
  1050.    case GL_TEXTURE_WRAP_S:
  1051.       res = set_sampler_wrap_s(ctx, sampObj, params[0]);
  1052.       break;
  1053.    case GL_TEXTURE_WRAP_T:
  1054.       res = set_sampler_wrap_t(ctx, sampObj, params[0]);
  1055.       break;
  1056.    case GL_TEXTURE_WRAP_R:
  1057.       res = set_sampler_wrap_r(ctx, sampObj, params[0]);
  1058.       break;
  1059.    case GL_TEXTURE_MIN_FILTER:
  1060.       res = set_sampler_min_filter(ctx, sampObj, params[0]);
  1061.       break;
  1062.    case GL_TEXTURE_MAG_FILTER:
  1063.       res = set_sampler_mag_filter(ctx, sampObj, params[0]);
  1064.       break;
  1065.    case GL_TEXTURE_MIN_LOD:
  1066.       res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
  1067.       break;
  1068.    case GL_TEXTURE_MAX_LOD:
  1069.       res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
  1070.       break;
  1071.    case GL_TEXTURE_LOD_BIAS:
  1072.       res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
  1073.       break;
  1074.    case GL_TEXTURE_COMPARE_MODE:
  1075.       res = set_sampler_compare_mode(ctx, sampObj, params[0]);
  1076.       break;
  1077.    case GL_TEXTURE_COMPARE_FUNC:
  1078.       res = set_sampler_compare_func(ctx, sampObj, params[0]);
  1079.       break;
  1080.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  1081.       res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
  1082.       break;
  1083.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  1084.       res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
  1085.       break;
  1086.    case GL_TEXTURE_SRGB_DECODE_EXT:
  1087.       res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
  1088.       break;
  1089.    case GL_TEXTURE_BORDER_COLOR:
  1090.       res = set_sampler_border_colorui(ctx, sampObj, params);
  1091.       break;
  1092.    default:
  1093.       res = INVALID_PNAME;
  1094.    }
  1095.  
  1096.    switch (res) {
  1097.    case GL_FALSE:
  1098.       /* no change */
  1099.       break;
  1100.    case GL_TRUE:
  1101.       /* state change - we do nothing special at this time */
  1102.       break;
  1103.    case INVALID_PNAME:
  1104.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n",
  1105.                   _mesa_lookup_enum_by_nr(pname));
  1106.       break;
  1107.    case INVALID_PARAM:
  1108.       _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n",
  1109.                   params[0]);
  1110.       break;
  1111.    case INVALID_VALUE:
  1112.       _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n",
  1113.                   params[0]);
  1114.       break;
  1115.    default:
  1116.       ;
  1117.    }
  1118. }
  1119.  
  1120.  
  1121. void GLAPIENTRY
  1122. _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
  1123. {
  1124.    struct gl_sampler_object *sampObj;
  1125.    GET_CURRENT_CONTEXT(ctx);
  1126.  
  1127.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  1128.    if (!sampObj) {
  1129.       _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameteriv(sampler %u)",
  1130.                   sampler);
  1131.       return;
  1132.    }
  1133.  
  1134.    switch (pname) {
  1135.    case GL_TEXTURE_WRAP_S:
  1136.       *params = sampObj->WrapS;
  1137.       break;
  1138.    case GL_TEXTURE_WRAP_T:
  1139.       *params = sampObj->WrapT;
  1140.       break;
  1141.    case GL_TEXTURE_WRAP_R:
  1142.       *params = sampObj->WrapR;
  1143.       break;
  1144.    case GL_TEXTURE_MIN_FILTER:
  1145.       *params = sampObj->MinFilter;
  1146.       break;
  1147.    case GL_TEXTURE_MAG_FILTER:
  1148.       *params = sampObj->MagFilter;
  1149.       break;
  1150.    case GL_TEXTURE_MIN_LOD:
  1151.       *params = (GLint) sampObj->MinLod;
  1152.       break;
  1153.    case GL_TEXTURE_MAX_LOD:
  1154.       *params = (GLint) sampObj->MaxLod;
  1155.       break;
  1156.    case GL_TEXTURE_LOD_BIAS:
  1157.       *params = (GLint) sampObj->LodBias;
  1158.       break;
  1159.    case GL_TEXTURE_COMPARE_MODE:
  1160.       if (!ctx->Extensions.ARB_shadow)
  1161.          goto invalid_pname;
  1162.       *params = sampObj->CompareMode;
  1163.       break;
  1164.    case GL_TEXTURE_COMPARE_FUNC:
  1165.       if (!ctx->Extensions.ARB_shadow)
  1166.          goto invalid_pname;
  1167.       *params = sampObj->CompareFunc;
  1168.       break;
  1169.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  1170.       *params = (GLint) sampObj->MaxAnisotropy;
  1171.       break;
  1172.    case GL_TEXTURE_BORDER_COLOR:
  1173.       params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]);
  1174.       params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]);
  1175.       params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]);
  1176.       params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]);
  1177.       break;
  1178.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  1179.       if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
  1180.          goto invalid_pname;
  1181.       *params = sampObj->CubeMapSeamless;
  1182.       break;
  1183.    case GL_TEXTURE_SRGB_DECODE_EXT:
  1184.       if (!ctx->Extensions.EXT_texture_sRGB_decode)
  1185.          goto invalid_pname;
  1186.       *params = (GLenum) sampObj->sRGBDecode;
  1187.       break;
  1188.    default:
  1189.       goto invalid_pname;
  1190.    }
  1191.    return;
  1192.  
  1193. invalid_pname:
  1194.    _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)",
  1195.                _mesa_lookup_enum_by_nr(pname));
  1196. }
  1197.  
  1198.  
  1199. void GLAPIENTRY
  1200. _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
  1201. {
  1202.    struct gl_sampler_object *sampObj;
  1203.    GET_CURRENT_CONTEXT(ctx);
  1204.  
  1205.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  1206.    if (!sampObj) {
  1207.       _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameterfv(sampler %u)",
  1208.                   sampler);
  1209.       return;
  1210.    }
  1211.  
  1212.    switch (pname) {
  1213.    case GL_TEXTURE_WRAP_S:
  1214.       *params = (GLfloat) sampObj->WrapS;
  1215.       break;
  1216.    case GL_TEXTURE_WRAP_T:
  1217.       *params = (GLfloat) sampObj->WrapT;
  1218.       break;
  1219.    case GL_TEXTURE_WRAP_R:
  1220.       *params = (GLfloat) sampObj->WrapR;
  1221.       break;
  1222.    case GL_TEXTURE_MIN_FILTER:
  1223.       *params = (GLfloat) sampObj->MinFilter;
  1224.       break;
  1225.    case GL_TEXTURE_MAG_FILTER:
  1226.       *params = (GLfloat) sampObj->MagFilter;
  1227.       break;
  1228.    case GL_TEXTURE_MIN_LOD:
  1229.       *params = sampObj->MinLod;
  1230.       break;
  1231.    case GL_TEXTURE_MAX_LOD:
  1232.       *params = sampObj->MaxLod;
  1233.       break;
  1234.    case GL_TEXTURE_LOD_BIAS:
  1235.       *params = sampObj->LodBias;
  1236.       break;
  1237.    case GL_TEXTURE_COMPARE_MODE:
  1238.       if (!ctx->Extensions.ARB_shadow)
  1239.          goto invalid_pname;
  1240.       *params = (GLfloat) sampObj->CompareMode;
  1241.       break;
  1242.    case GL_TEXTURE_COMPARE_FUNC:
  1243.       if (!ctx->Extensions.ARB_shadow)
  1244.          goto invalid_pname;
  1245.       *params = (GLfloat) sampObj->CompareFunc;
  1246.       break;
  1247.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  1248.       *params = sampObj->MaxAnisotropy;
  1249.       break;
  1250.    case GL_TEXTURE_BORDER_COLOR:
  1251.       params[0] = sampObj->BorderColor.f[0];
  1252.       params[1] = sampObj->BorderColor.f[1];
  1253.       params[2] = sampObj->BorderColor.f[2];
  1254.       params[3] = sampObj->BorderColor.f[3];
  1255.       break;
  1256.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  1257.       if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
  1258.          goto invalid_pname;
  1259.       *params = (GLfloat) sampObj->CubeMapSeamless;
  1260.       break;
  1261.    case GL_TEXTURE_SRGB_DECODE_EXT:
  1262.       if (!ctx->Extensions.EXT_texture_sRGB_decode)
  1263.          goto invalid_pname;
  1264.       *params = (GLfloat) sampObj->sRGBDecode;
  1265.       break;
  1266.    default:
  1267.       goto invalid_pname;
  1268.    }
  1269.    return;
  1270.  
  1271. invalid_pname:
  1272.    _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)",
  1273.                _mesa_lookup_enum_by_nr(pname));
  1274. }
  1275.  
  1276.  
  1277. void GLAPIENTRY
  1278. _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
  1279. {
  1280.    struct gl_sampler_object *sampObj;
  1281.    GET_CURRENT_CONTEXT(ctx);
  1282.  
  1283.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  1284.    if (!sampObj) {
  1285.       _mesa_error(ctx, GL_INVALID_VALUE,
  1286.                   "glGetSamplerParameterIiv(sampler %u)",
  1287.                   sampler);
  1288.       return;
  1289.    }
  1290.  
  1291.    switch (pname) {
  1292.    case GL_TEXTURE_WRAP_S:
  1293.       *params = sampObj->WrapS;
  1294.       break;
  1295.    case GL_TEXTURE_WRAP_T:
  1296.       *params = sampObj->WrapT;
  1297.       break;
  1298.    case GL_TEXTURE_WRAP_R:
  1299.       *params = sampObj->WrapR;
  1300.       break;
  1301.    case GL_TEXTURE_MIN_FILTER:
  1302.       *params = sampObj->MinFilter;
  1303.       break;
  1304.    case GL_TEXTURE_MAG_FILTER:
  1305.       *params = sampObj->MagFilter;
  1306.       break;
  1307.    case GL_TEXTURE_MIN_LOD:
  1308.       *params = (GLint) sampObj->MinLod;
  1309.       break;
  1310.    case GL_TEXTURE_MAX_LOD:
  1311.       *params = (GLint) sampObj->MaxLod;
  1312.       break;
  1313.    case GL_TEXTURE_LOD_BIAS:
  1314.       *params = (GLint) sampObj->LodBias;
  1315.       break;
  1316.    case GL_TEXTURE_COMPARE_MODE:
  1317.       if (!ctx->Extensions.ARB_shadow)
  1318.          goto invalid_pname;
  1319.       *params = sampObj->CompareMode;
  1320.       break;
  1321.    case GL_TEXTURE_COMPARE_FUNC:
  1322.       if (!ctx->Extensions.ARB_shadow)
  1323.          goto invalid_pname;
  1324.       *params = sampObj->CompareFunc;
  1325.       break;
  1326.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  1327.       *params = (GLint) sampObj->MaxAnisotropy;
  1328.       break;
  1329.    case GL_TEXTURE_BORDER_COLOR:
  1330.       params[0] = sampObj->BorderColor.i[0];
  1331.       params[1] = sampObj->BorderColor.i[1];
  1332.       params[2] = sampObj->BorderColor.i[2];
  1333.       params[3] = sampObj->BorderColor.i[3];
  1334.       break;
  1335.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  1336.       if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
  1337.          goto invalid_pname;
  1338.       *params = sampObj->CubeMapSeamless;
  1339.       break;
  1340.    case GL_TEXTURE_SRGB_DECODE_EXT:
  1341.       if (!ctx->Extensions.EXT_texture_sRGB_decode)
  1342.          goto invalid_pname;
  1343.       *params = (GLenum) sampObj->sRGBDecode;
  1344.       break;
  1345.    default:
  1346.       goto invalid_pname;
  1347.    }
  1348.    return;
  1349.  
  1350. invalid_pname:
  1351.    _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)",
  1352.                _mesa_lookup_enum_by_nr(pname));
  1353. }
  1354.  
  1355.  
  1356. void GLAPIENTRY
  1357. _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
  1358. {
  1359.    struct gl_sampler_object *sampObj;
  1360.    GET_CURRENT_CONTEXT(ctx);
  1361.  
  1362.    sampObj = _mesa_lookup_samplerobj(ctx, sampler);
  1363.    if (!sampObj) {
  1364.       _mesa_error(ctx, GL_INVALID_VALUE,
  1365.                   "glGetSamplerParameterIuiv(sampler %u)",
  1366.                   sampler);
  1367.       return;
  1368.    }
  1369.  
  1370.    switch (pname) {
  1371.    case GL_TEXTURE_WRAP_S:
  1372.       *params = sampObj->WrapS;
  1373.       break;
  1374.    case GL_TEXTURE_WRAP_T:
  1375.       *params = sampObj->WrapT;
  1376.       break;
  1377.    case GL_TEXTURE_WRAP_R:
  1378.       *params = sampObj->WrapR;
  1379.       break;
  1380.    case GL_TEXTURE_MIN_FILTER:
  1381.       *params = sampObj->MinFilter;
  1382.       break;
  1383.    case GL_TEXTURE_MAG_FILTER:
  1384.       *params = sampObj->MagFilter;
  1385.       break;
  1386.    case GL_TEXTURE_MIN_LOD:
  1387.       *params = (GLuint) sampObj->MinLod;
  1388.       break;
  1389.    case GL_TEXTURE_MAX_LOD:
  1390.       *params = (GLuint) sampObj->MaxLod;
  1391.       break;
  1392.    case GL_TEXTURE_LOD_BIAS:
  1393.       *params = (GLuint) sampObj->LodBias;
  1394.       break;
  1395.    case GL_TEXTURE_COMPARE_MODE:
  1396.       if (!ctx->Extensions.ARB_shadow)
  1397.          goto invalid_pname;
  1398.       *params = sampObj->CompareMode;
  1399.       break;
  1400.    case GL_TEXTURE_COMPARE_FUNC:
  1401.       if (!ctx->Extensions.ARB_shadow)
  1402.          goto invalid_pname;
  1403.       *params = sampObj->CompareFunc;
  1404.       break;
  1405.    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  1406.       *params = (GLuint) sampObj->MaxAnisotropy;
  1407.       break;
  1408.    case GL_TEXTURE_BORDER_COLOR:
  1409.       params[0] = sampObj->BorderColor.ui[0];
  1410.       params[1] = sampObj->BorderColor.ui[1];
  1411.       params[2] = sampObj->BorderColor.ui[2];
  1412.       params[3] = sampObj->BorderColor.ui[3];
  1413.       break;
  1414.    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
  1415.       if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
  1416.          goto invalid_pname;
  1417.       *params = sampObj->CubeMapSeamless;
  1418.       break;
  1419.    case GL_TEXTURE_SRGB_DECODE_EXT:
  1420.       if (!ctx->Extensions.EXT_texture_sRGB_decode)
  1421.          goto invalid_pname;
  1422.       *params = (GLenum) sampObj->sRGBDecode;
  1423.       break;
  1424.    default:
  1425.       goto invalid_pname;
  1426.    }
  1427.    return;
  1428.  
  1429. invalid_pname:
  1430.    _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)",
  1431.                _mesa_lookup_enum_by_nr(pname));
  1432. }
  1433.  
  1434.  
  1435. void
  1436. _mesa_init_sampler_object_functions(struct dd_function_table *driver)
  1437. {
  1438.    driver->NewSamplerObject = _mesa_new_sampler_object;
  1439.    driver->DeleteSamplerObject = _mesa_delete_sampler_object;
  1440. }
  1441.