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