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