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