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