fbobject: add additional fbo completeness checks for GLES
[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 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 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 ASSERT_OUTSIDE_BEGIN_END(ctx);
610
611 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
612 if (!sampObj) {
613 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(sampler %u)",
614 sampler);
615 return;
616 }
617
618 switch (pname) {
619 case GL_TEXTURE_WRAP_S:
620 res = set_sampler_wrap_s(ctx, sampObj, param);
621 break;
622 case GL_TEXTURE_WRAP_T:
623 res = set_sampler_wrap_t(ctx, sampObj, param);
624 break;
625 case GL_TEXTURE_WRAP_R:
626 res = set_sampler_wrap_r(ctx, sampObj, param);
627 break;
628 case GL_TEXTURE_MIN_FILTER:
629 res = set_sampler_min_filter(ctx, sampObj, param);
630 break;
631 case GL_TEXTURE_MAG_FILTER:
632 res = set_sampler_mag_filter(ctx, sampObj, param);
633 break;
634 case GL_TEXTURE_MIN_LOD:
635 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) param);
636 break;
637 case GL_TEXTURE_MAX_LOD:
638 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) param);
639 break;
640 case GL_TEXTURE_LOD_BIAS:
641 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) param);
642 break;
643 case GL_TEXTURE_COMPARE_MODE:
644 res = set_sampler_compare_mode(ctx, sampObj, param);
645 break;
646 case GL_TEXTURE_COMPARE_FUNC:
647 res = set_sampler_compare_func(ctx, sampObj, param);
648 break;
649 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
650 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) param);
651 break;
652 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
653 res = set_sampler_cube_map_seamless(ctx, sampObj, param);
654 break;
655 case GL_TEXTURE_SRGB_DECODE_EXT:
656 res = set_sampler_srgb_decode(ctx, sampObj, param);
657 break;
658 case GL_TEXTURE_BORDER_COLOR:
659 /* fall-through */
660 default:
661 res = INVALID_PNAME;
662 }
663
664 switch (res) {
665 case GL_FALSE:
666 /* no change */
667 break;
668 case GL_TRUE:
669 /* state change - we do nothing special at this time */
670 break;
671 case INVALID_PNAME:
672 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n",
673 _mesa_lookup_enum_by_nr(pname));
674 break;
675 case INVALID_PARAM:
676 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n",
677 param);
678 break;
679 case INVALID_VALUE:
680 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(param=%d)\n",
681 param);
682 break;
683 default:
684 ;
685 }
686 }
687
688
689 void GLAPIENTRY
690 _mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
691 {
692 struct gl_sampler_object *sampObj;
693 GLuint res;
694 GET_CURRENT_CONTEXT(ctx);
695
696 ASSERT_OUTSIDE_BEGIN_END(ctx);
697
698 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
699 if (!sampObj) {
700 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(sampler %u)",
701 sampler);
702 return;
703 }
704
705 switch (pname) {
706 case GL_TEXTURE_WRAP_S:
707 res = set_sampler_wrap_s(ctx, sampObj, (GLint) param);
708 break;
709 case GL_TEXTURE_WRAP_T:
710 res = set_sampler_wrap_t(ctx, sampObj, (GLint) param);
711 break;
712 case GL_TEXTURE_WRAP_R:
713 res = set_sampler_wrap_r(ctx, sampObj, (GLint) param);
714 break;
715 case GL_TEXTURE_MIN_FILTER:
716 res = set_sampler_min_filter(ctx, sampObj, (GLint) param);
717 break;
718 case GL_TEXTURE_MAG_FILTER:
719 res = set_sampler_mag_filter(ctx, sampObj, (GLint) param);
720 break;
721 case GL_TEXTURE_MIN_LOD:
722 res = set_sampler_min_lod(ctx, sampObj, param);
723 break;
724 case GL_TEXTURE_MAX_LOD:
725 res = set_sampler_max_lod(ctx, sampObj, param);
726 break;
727 case GL_TEXTURE_LOD_BIAS:
728 res = set_sampler_lod_bias(ctx, sampObj, param);
729 break;
730 case GL_TEXTURE_COMPARE_MODE:
731 res = set_sampler_compare_mode(ctx, sampObj, (GLint) param);
732 break;
733 case GL_TEXTURE_COMPARE_FUNC:
734 res = set_sampler_compare_func(ctx, sampObj, (GLint) param);
735 break;
736 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
737 res = set_sampler_max_anisotropy(ctx, sampObj, param);
738 break;
739 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
740 res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param);
741 break;
742 case GL_TEXTURE_SRGB_DECODE_EXT:
743 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param);
744 break;
745 case GL_TEXTURE_BORDER_COLOR:
746 /* fall-through */
747 default:
748 res = INVALID_PNAME;
749 }
750
751 switch (res) {
752 case GL_FALSE:
753 /* no change */
754 break;
755 case GL_TRUE:
756 /* state change - we do nothing special at this time */
757 break;
758 case INVALID_PNAME:
759 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n",
760 _mesa_lookup_enum_by_nr(pname));
761 break;
762 case INVALID_PARAM:
763 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n",
764 param);
765 break;
766 case INVALID_VALUE:
767 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(param=%f)\n",
768 param);
769 break;
770 default:
771 ;
772 }
773 }
774
775 void GLAPIENTRY
776 _mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
777 {
778 struct gl_sampler_object *sampObj;
779 GLuint res;
780 GET_CURRENT_CONTEXT(ctx);
781
782 ASSERT_OUTSIDE_BEGIN_END(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 ASSERT_OUTSIDE_BEGIN_END(ctx);
877
878 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
879 if (!sampObj) {
880 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(sampler %u)",
881 sampler);
882 return;
883 }
884
885 switch (pname) {
886 case GL_TEXTURE_WRAP_S:
887 res = set_sampler_wrap_s(ctx, sampObj, (GLint) params[0]);
888 break;
889 case GL_TEXTURE_WRAP_T:
890 res = set_sampler_wrap_t(ctx, sampObj, (GLint) params[0]);
891 break;
892 case GL_TEXTURE_WRAP_R:
893 res = set_sampler_wrap_r(ctx, sampObj, (GLint) params[0]);
894 break;
895 case GL_TEXTURE_MIN_FILTER:
896 res = set_sampler_min_filter(ctx, sampObj, (GLint) params[0]);
897 break;
898 case GL_TEXTURE_MAG_FILTER:
899 res = set_sampler_mag_filter(ctx, sampObj, (GLint) params[0]);
900 break;
901 case GL_TEXTURE_MIN_LOD:
902 res = set_sampler_min_lod(ctx, sampObj, params[0]);
903 break;
904 case GL_TEXTURE_MAX_LOD:
905 res = set_sampler_max_lod(ctx, sampObj, params[0]);
906 break;
907 case GL_TEXTURE_LOD_BIAS:
908 res = set_sampler_lod_bias(ctx, sampObj, params[0]);
909 break;
910 case GL_TEXTURE_COMPARE_MODE:
911 res = set_sampler_compare_mode(ctx, sampObj, (GLint) params[0]);
912 break;
913 case GL_TEXTURE_COMPARE_FUNC:
914 res = set_sampler_compare_func(ctx, sampObj, (GLint) params[0]);
915 break;
916 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
917 res = set_sampler_max_anisotropy(ctx, sampObj, params[0]);
918 break;
919 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
920 res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]);
921 break;
922 case GL_TEXTURE_SRGB_DECODE_EXT:
923 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
924 break;
925 case GL_TEXTURE_BORDER_COLOR:
926 res = set_sampler_border_colorf(ctx, sampObj, params);
927 break;
928 default:
929 res = INVALID_PNAME;
930 }
931
932 switch (res) {
933 case GL_FALSE:
934 /* no change */
935 break;
936 case GL_TRUE:
937 /* state change - we do nothing special at this time */
938 break;
939 case INVALID_PNAME:
940 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n",
941 _mesa_lookup_enum_by_nr(pname));
942 break;
943 case INVALID_PARAM:
944 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n",
945 params[0]);
946 break;
947 case INVALID_VALUE:
948 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(param=%f)\n",
949 params[0]);
950 break;
951 default:
952 ;
953 }
954 }
955
956 void GLAPIENTRY
957 _mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
958 {
959 struct gl_sampler_object *sampObj;
960 GLuint res;
961 GET_CURRENT_CONTEXT(ctx);
962
963 ASSERT_OUTSIDE_BEGIN_END(ctx);
964
965 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
966 if (!sampObj) {
967 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(sampler %u)",
968 sampler);
969 return;
970 }
971
972 switch (pname) {
973 case GL_TEXTURE_WRAP_S:
974 res = set_sampler_wrap_s(ctx, sampObj, params[0]);
975 break;
976 case GL_TEXTURE_WRAP_T:
977 res = set_sampler_wrap_t(ctx, sampObj, params[0]);
978 break;
979 case GL_TEXTURE_WRAP_R:
980 res = set_sampler_wrap_r(ctx, sampObj, params[0]);
981 break;
982 case GL_TEXTURE_MIN_FILTER:
983 res = set_sampler_min_filter(ctx, sampObj, params[0]);
984 break;
985 case GL_TEXTURE_MAG_FILTER:
986 res = set_sampler_mag_filter(ctx, sampObj, params[0]);
987 break;
988 case GL_TEXTURE_MIN_LOD:
989 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
990 break;
991 case GL_TEXTURE_MAX_LOD:
992 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
993 break;
994 case GL_TEXTURE_LOD_BIAS:
995 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
996 break;
997 case GL_TEXTURE_COMPARE_MODE:
998 res = set_sampler_compare_mode(ctx, sampObj, params[0]);
999 break;
1000 case GL_TEXTURE_COMPARE_FUNC:
1001 res = set_sampler_compare_func(ctx, sampObj, params[0]);
1002 break;
1003 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1004 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
1005 break;
1006 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1007 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
1008 break;
1009 case GL_TEXTURE_SRGB_DECODE_EXT:
1010 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
1011 break;
1012 case GL_TEXTURE_BORDER_COLOR:
1013 res = set_sampler_border_colori(ctx, sampObj, params);
1014 break;
1015 default:
1016 res = INVALID_PNAME;
1017 }
1018
1019 switch (res) {
1020 case GL_FALSE:
1021 /* no change */
1022 break;
1023 case GL_TRUE:
1024 /* state change - we do nothing special at this time */
1025 break;
1026 case INVALID_PNAME:
1027 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n",
1028 _mesa_lookup_enum_by_nr(pname));
1029 break;
1030 case INVALID_PARAM:
1031 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n",
1032 params[0]);
1033 break;
1034 case INVALID_VALUE:
1035 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(param=%d)\n",
1036 params[0]);
1037 break;
1038 default:
1039 ;
1040 }
1041 }
1042
1043
1044 void GLAPIENTRY
1045 _mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
1046 {
1047 struct gl_sampler_object *sampObj;
1048 GLuint res;
1049 GET_CURRENT_CONTEXT(ctx);
1050
1051 ASSERT_OUTSIDE_BEGIN_END(ctx);
1052
1053 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1054 if (!sampObj) {
1055 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(sampler %u)",
1056 sampler);
1057 return;
1058 }
1059
1060 switch (pname) {
1061 case GL_TEXTURE_WRAP_S:
1062 res = set_sampler_wrap_s(ctx, sampObj, params[0]);
1063 break;
1064 case GL_TEXTURE_WRAP_T:
1065 res = set_sampler_wrap_t(ctx, sampObj, params[0]);
1066 break;
1067 case GL_TEXTURE_WRAP_R:
1068 res = set_sampler_wrap_r(ctx, sampObj, params[0]);
1069 break;
1070 case GL_TEXTURE_MIN_FILTER:
1071 res = set_sampler_min_filter(ctx, sampObj, params[0]);
1072 break;
1073 case GL_TEXTURE_MAG_FILTER:
1074 res = set_sampler_mag_filter(ctx, sampObj, params[0]);
1075 break;
1076 case GL_TEXTURE_MIN_LOD:
1077 res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
1078 break;
1079 case GL_TEXTURE_MAX_LOD:
1080 res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
1081 break;
1082 case GL_TEXTURE_LOD_BIAS:
1083 res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
1084 break;
1085 case GL_TEXTURE_COMPARE_MODE:
1086 res = set_sampler_compare_mode(ctx, sampObj, params[0]);
1087 break;
1088 case GL_TEXTURE_COMPARE_FUNC:
1089 res = set_sampler_compare_func(ctx, sampObj, params[0]);
1090 break;
1091 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1092 res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
1093 break;
1094 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1095 res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
1096 break;
1097 case GL_TEXTURE_SRGB_DECODE_EXT:
1098 res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
1099 break;
1100 case GL_TEXTURE_BORDER_COLOR:
1101 res = set_sampler_border_colorui(ctx, sampObj, params);
1102 break;
1103 default:
1104 res = INVALID_PNAME;
1105 }
1106
1107 switch (res) {
1108 case GL_FALSE:
1109 /* no change */
1110 break;
1111 case GL_TRUE:
1112 /* state change - we do nothing special at this time */
1113 break;
1114 case INVALID_PNAME:
1115 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n",
1116 _mesa_lookup_enum_by_nr(pname));
1117 break;
1118 case INVALID_PARAM:
1119 _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n",
1120 params[0]);
1121 break;
1122 case INVALID_VALUE:
1123 _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n",
1124 params[0]);
1125 break;
1126 default:
1127 ;
1128 }
1129 }
1130
1131
1132 void GLAPIENTRY
1133 _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
1134 {
1135 struct gl_sampler_object *sampObj;
1136 GET_CURRENT_CONTEXT(ctx);
1137
1138 ASSERT_OUTSIDE_BEGIN_END(ctx);
1139
1140 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1141 if (!sampObj) {
1142 _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameteriv(sampler %u)",
1143 sampler);
1144 return;
1145 }
1146
1147 switch (pname) {
1148 case GL_TEXTURE_WRAP_S:
1149 *params = sampObj->WrapS;
1150 break;
1151 case GL_TEXTURE_WRAP_T:
1152 *params = sampObj->WrapT;
1153 break;
1154 case GL_TEXTURE_WRAP_R:
1155 *params = sampObj->WrapR;
1156 break;
1157 case GL_TEXTURE_MIN_FILTER:
1158 *params = sampObj->MinFilter;
1159 break;
1160 case GL_TEXTURE_MAG_FILTER:
1161 *params = sampObj->MagFilter;
1162 break;
1163 case GL_TEXTURE_MIN_LOD:
1164 *params = (GLint) sampObj->MinLod;
1165 break;
1166 case GL_TEXTURE_MAX_LOD:
1167 *params = (GLint) sampObj->MaxLod;
1168 break;
1169 case GL_TEXTURE_LOD_BIAS:
1170 *params = (GLint) sampObj->LodBias;
1171 break;
1172 case GL_TEXTURE_COMPARE_MODE:
1173 if (!ctx->Extensions.ARB_shadow)
1174 goto invalid_pname;
1175 *params = sampObj->CompareMode;
1176 break;
1177 case GL_TEXTURE_COMPARE_FUNC:
1178 if (!ctx->Extensions.ARB_shadow)
1179 goto invalid_pname;
1180 *params = sampObj->CompareFunc;
1181 break;
1182 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1183 *params = (GLint) sampObj->MaxAnisotropy;
1184 break;
1185 case GL_TEXTURE_BORDER_COLOR:
1186 params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]);
1187 params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]);
1188 params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]);
1189 params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]);
1190 break;
1191 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1192 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1193 goto invalid_pname;
1194 *params = sampObj->CubeMapSeamless;
1195 break;
1196 case GL_TEXTURE_SRGB_DECODE_EXT:
1197 if (!ctx->Extensions.EXT_texture_sRGB_decode)
1198 goto invalid_pname;
1199 *params = (GLenum) sampObj->sRGBDecode;
1200 break;
1201 default:
1202 goto invalid_pname;
1203 }
1204 return;
1205
1206 invalid_pname:
1207 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)",
1208 _mesa_lookup_enum_by_nr(pname));
1209 }
1210
1211
1212 void GLAPIENTRY
1213 _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
1214 {
1215 struct gl_sampler_object *sampObj;
1216 GET_CURRENT_CONTEXT(ctx);
1217
1218 ASSERT_OUTSIDE_BEGIN_END(ctx);
1219
1220 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1221 if (!sampObj) {
1222 _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameterfv(sampler %u)",
1223 sampler);
1224 return;
1225 }
1226
1227 switch (pname) {
1228 case GL_TEXTURE_WRAP_S:
1229 *params = (GLfloat) sampObj->WrapS;
1230 break;
1231 case GL_TEXTURE_WRAP_T:
1232 *params = (GLfloat) sampObj->WrapT;
1233 break;
1234 case GL_TEXTURE_WRAP_R:
1235 *params = (GLfloat) sampObj->WrapR;
1236 break;
1237 case GL_TEXTURE_MIN_FILTER:
1238 *params = (GLfloat) sampObj->MinFilter;
1239 break;
1240 case GL_TEXTURE_MAG_FILTER:
1241 *params = (GLfloat) sampObj->MagFilter;
1242 break;
1243 case GL_TEXTURE_MIN_LOD:
1244 *params = sampObj->MinLod;
1245 break;
1246 case GL_TEXTURE_MAX_LOD:
1247 *params = sampObj->MaxLod;
1248 break;
1249 case GL_TEXTURE_LOD_BIAS:
1250 *params = sampObj->LodBias;
1251 break;
1252 case GL_TEXTURE_COMPARE_MODE:
1253 if (!ctx->Extensions.ARB_shadow)
1254 goto invalid_pname;
1255 *params = (GLfloat) sampObj->CompareMode;
1256 break;
1257 case GL_TEXTURE_COMPARE_FUNC:
1258 if (!ctx->Extensions.ARB_shadow)
1259 goto invalid_pname;
1260 *params = (GLfloat) sampObj->CompareFunc;
1261 break;
1262 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1263 *params = sampObj->MaxAnisotropy;
1264 break;
1265 case GL_TEXTURE_BORDER_COLOR:
1266 params[0] = sampObj->BorderColor.f[0];
1267 params[1] = sampObj->BorderColor.f[1];
1268 params[2] = sampObj->BorderColor.f[2];
1269 params[3] = sampObj->BorderColor.f[3];
1270 break;
1271 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1272 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1273 goto invalid_pname;
1274 *params = (GLfloat) sampObj->CubeMapSeamless;
1275 break;
1276 case GL_TEXTURE_SRGB_DECODE_EXT:
1277 if (!ctx->Extensions.EXT_texture_sRGB_decode)
1278 goto invalid_pname;
1279 *params = (GLfloat) sampObj->sRGBDecode;
1280 break;
1281 default:
1282 goto invalid_pname;
1283 }
1284 return;
1285
1286 invalid_pname:
1287 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)",
1288 _mesa_lookup_enum_by_nr(pname));
1289 }
1290
1291
1292 void GLAPIENTRY
1293 _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
1294 {
1295 struct gl_sampler_object *sampObj;
1296 GET_CURRENT_CONTEXT(ctx);
1297
1298 ASSERT_OUTSIDE_BEGIN_END(ctx);
1299
1300 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1301 if (!sampObj) {
1302 _mesa_error(ctx, GL_INVALID_VALUE,
1303 "glGetSamplerParameterIiv(sampler %u)",
1304 sampler);
1305 return;
1306 }
1307
1308 switch (pname) {
1309 case GL_TEXTURE_WRAP_S:
1310 *params = sampObj->WrapS;
1311 break;
1312 case GL_TEXTURE_WRAP_T:
1313 *params = sampObj->WrapT;
1314 break;
1315 case GL_TEXTURE_WRAP_R:
1316 *params = sampObj->WrapR;
1317 break;
1318 case GL_TEXTURE_MIN_FILTER:
1319 *params = sampObj->MinFilter;
1320 break;
1321 case GL_TEXTURE_MAG_FILTER:
1322 *params = sampObj->MagFilter;
1323 break;
1324 case GL_TEXTURE_MIN_LOD:
1325 *params = (GLint) sampObj->MinLod;
1326 break;
1327 case GL_TEXTURE_MAX_LOD:
1328 *params = (GLint) sampObj->MaxLod;
1329 break;
1330 case GL_TEXTURE_LOD_BIAS:
1331 *params = (GLint) sampObj->LodBias;
1332 break;
1333 case GL_TEXTURE_COMPARE_MODE:
1334 if (!ctx->Extensions.ARB_shadow)
1335 goto invalid_pname;
1336 *params = sampObj->CompareMode;
1337 break;
1338 case GL_TEXTURE_COMPARE_FUNC:
1339 if (!ctx->Extensions.ARB_shadow)
1340 goto invalid_pname;
1341 *params = sampObj->CompareFunc;
1342 break;
1343 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1344 *params = (GLint) sampObj->MaxAnisotropy;
1345 break;
1346 case GL_TEXTURE_BORDER_COLOR:
1347 params[0] = sampObj->BorderColor.i[0];
1348 params[1] = sampObj->BorderColor.i[1];
1349 params[2] = sampObj->BorderColor.i[2];
1350 params[3] = sampObj->BorderColor.i[3];
1351 break;
1352 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1353 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1354 goto invalid_pname;
1355 *params = sampObj->CubeMapSeamless;
1356 break;
1357 case GL_TEXTURE_SRGB_DECODE_EXT:
1358 if (!ctx->Extensions.EXT_texture_sRGB_decode)
1359 goto invalid_pname;
1360 *params = (GLenum) sampObj->sRGBDecode;
1361 break;
1362 default:
1363 goto invalid_pname;
1364 }
1365 return;
1366
1367 invalid_pname:
1368 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)",
1369 _mesa_lookup_enum_by_nr(pname));
1370 }
1371
1372
1373 void GLAPIENTRY
1374 _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
1375 {
1376 struct gl_sampler_object *sampObj;
1377 GET_CURRENT_CONTEXT(ctx);
1378
1379 ASSERT_OUTSIDE_BEGIN_END(ctx);
1380
1381 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1382 if (!sampObj) {
1383 _mesa_error(ctx, GL_INVALID_VALUE,
1384 "glGetSamplerParameterIuiv(sampler %u)",
1385 sampler);
1386 return;
1387 }
1388
1389 switch (pname) {
1390 case GL_TEXTURE_WRAP_S:
1391 *params = sampObj->WrapS;
1392 break;
1393 case GL_TEXTURE_WRAP_T:
1394 *params = sampObj->WrapT;
1395 break;
1396 case GL_TEXTURE_WRAP_R:
1397 *params = sampObj->WrapR;
1398 break;
1399 case GL_TEXTURE_MIN_FILTER:
1400 *params = sampObj->MinFilter;
1401 break;
1402 case GL_TEXTURE_MAG_FILTER:
1403 *params = sampObj->MagFilter;
1404 break;
1405 case GL_TEXTURE_MIN_LOD:
1406 *params = (GLuint) sampObj->MinLod;
1407 break;
1408 case GL_TEXTURE_MAX_LOD:
1409 *params = (GLuint) sampObj->MaxLod;
1410 break;
1411 case GL_TEXTURE_LOD_BIAS:
1412 *params = (GLuint) sampObj->LodBias;
1413 break;
1414 case GL_TEXTURE_COMPARE_MODE:
1415 if (!ctx->Extensions.ARB_shadow)
1416 goto invalid_pname;
1417 *params = sampObj->CompareMode;
1418 break;
1419 case GL_TEXTURE_COMPARE_FUNC:
1420 if (!ctx->Extensions.ARB_shadow)
1421 goto invalid_pname;
1422 *params = sampObj->CompareFunc;
1423 break;
1424 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1425 *params = (GLuint) sampObj->MaxAnisotropy;
1426 break;
1427 case GL_TEXTURE_BORDER_COLOR:
1428 params[0] = sampObj->BorderColor.ui[0];
1429 params[1] = sampObj->BorderColor.ui[1];
1430 params[2] = sampObj->BorderColor.ui[2];
1431 params[3] = sampObj->BorderColor.ui[3];
1432 break;
1433 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1434 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1435 goto invalid_pname;
1436 *params = sampObj->CubeMapSeamless;
1437 break;
1438 case GL_TEXTURE_SRGB_DECODE_EXT:
1439 if (!ctx->Extensions.EXT_texture_sRGB_decode)
1440 goto invalid_pname;
1441 *params = (GLenum) sampObj->sRGBDecode;
1442 break;
1443 default:
1444 goto invalid_pname;
1445 }
1446 return;
1447
1448 invalid_pname:
1449 _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)",
1450 _mesa_lookup_enum_by_nr(pname));
1451 }
1452
1453
1454 void
1455 _mesa_init_sampler_object_functions(struct dd_function_table *driver)
1456 {
1457 driver->NewSamplerObject = _mesa_new_sampler_object;
1458 driver->DeleteSamplerObject = _mesa_delete_sampler_object;
1459 }
1460
1461
1462 void
1463 _mesa_init_sampler_object_dispatch(const struct gl_context *ctx,
1464 struct _glapi_table *disp)
1465 {
1466 SET_GenSamplers(disp, _mesa_GenSamplers);
1467 SET_DeleteSamplers(disp, _mesa_DeleteSamplers);
1468 SET_IsSampler(disp, _mesa_IsSampler);
1469 SET_BindSampler(disp, _mesa_BindSampler);
1470 SET_SamplerParameteri(disp, _mesa_SamplerParameteri);
1471 SET_SamplerParameterf(disp, _mesa_SamplerParameterf);
1472 SET_SamplerParameteriv(disp, _mesa_SamplerParameteriv);
1473 SET_SamplerParameterfv(disp, _mesa_SamplerParameterfv);
1474 SET_GetSamplerParameteriv(disp, _mesa_GetSamplerParameteriv);
1475 SET_GetSamplerParameterfv(disp, _mesa_GetSamplerParameterfv);
1476
1477 if (_mesa_is_desktop_gl(ctx)) {
1478 SET_SamplerParameterIiv(disp, _mesa_SamplerParameterIiv);
1479 SET_SamplerParameterIuiv(disp, _mesa_SamplerParameterIuiv);
1480 SET_GetSamplerParameterIiv(disp, _mesa_GetSamplerParameterIiv);
1481 SET_GetSamplerParameterIuiv(disp, _mesa_GetSamplerParameterIuiv);
1482 }
1483 }