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