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