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