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