[SDK] Provide .const macro for gas
[reactos.git] / dll / opengl / mesa / main / texparam.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.5
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file texparam.c
28 *
29 * glTexParameter-related functions
30 */
31
32 #include <precomp.h>
33
34 /**
35 * Check if a coordinate wrap mode is supported for the texture target.
36 * \return GL_TRUE if legal, GL_FALSE otherwise
37 */
38 static GLboolean
39 validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
40 {
41 switch (wrap) {
42 case GL_CLAMP:
43 case GL_REPEAT:
44 case GL_MIRRORED_REPEAT:
45 return GL_TRUE;
46 default:
47 break;
48 }
49
50 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
51 return GL_FALSE;
52 }
53
54
55 /**
56 * Get current texture object for given target.
57 * Return NULL if any error (and record the error).
58 * Note that this is different from _mesa_select_tex_object() in that proxy
59 * targets are not accepted.
60 * Only the glGetTexLevelParameter() functions accept proxy targets.
61 */
62 static struct gl_texture_object *
63 get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
64 {
65 struct gl_texture_unit *texUnit;
66
67 texUnit = &ctx->Texture.Unit;
68
69 switch (target) {
70 case GL_TEXTURE_1D:
71 return texUnit->CurrentTex[TEXTURE_1D_INDEX];
72 case GL_TEXTURE_2D:
73 return texUnit->CurrentTex[TEXTURE_2D_INDEX];
74 case GL_TEXTURE_CUBE_MAP:
75 if (ctx->Extensions.ARB_texture_cube_map) {
76 return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
77 }
78 break;
79 default:
80 ;
81 }
82
83 _mesa_error(ctx, GL_INVALID_ENUM,
84 "gl%sTexParameter(target)", get ? "Get" : "");
85 return NULL;
86 }
87
88
89 /**
90 * This is called just prior to changing any texture object state which
91 * will not effect texture completeness.
92 */
93 static inline void
94 flush(struct gl_context *ctx)
95 {
96 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
97 }
98
99
100 /**
101 * This is called just prior to changing any texture object state which
102 * can effect texture completeness (texture base level, max level,
103 * minification filter).
104 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
105 * state flag and then mark the texture object as 'incomplete' so that any
106 * per-texture derived state gets recomputed.
107 */
108 static inline void
109 incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
110 {
111 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
112 texObj->_Complete = GL_FALSE;
113 }
114
115
116 /**
117 * Set an integer-valued texture parameter
118 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
119 */
120 static GLboolean
121 set_tex_parameteri(struct gl_context *ctx,
122 struct gl_texture_object *texObj,
123 GLenum pname, const GLint *params)
124 {
125 switch (pname) {
126 case GL_TEXTURE_MIN_FILTER:
127 if (texObj->Sampler.MinFilter == params[0])
128 return GL_FALSE;
129 switch (params[0]) {
130 case GL_NEAREST:
131 case GL_LINEAR:
132 incomplete(ctx, texObj);
133 texObj->Sampler.MinFilter = params[0];
134 return GL_TRUE;
135 case GL_NEAREST_MIPMAP_NEAREST:
136 case GL_LINEAR_MIPMAP_NEAREST:
137 case GL_NEAREST_MIPMAP_LINEAR:
138 case GL_LINEAR_MIPMAP_LINEAR:
139 incomplete(ctx, texObj);
140 texObj->Sampler.MinFilter = params[0];
141 return GL_TRUE;
142 /* fall-through */
143 default:
144 goto invalid_param;
145 }
146 return GL_FALSE;
147
148 case GL_TEXTURE_MAG_FILTER:
149 if (texObj->Sampler.MagFilter == params[0])
150 return GL_FALSE;
151 switch (params[0]) {
152 case GL_NEAREST:
153 case GL_LINEAR:
154 flush(ctx); /* does not effect completeness */
155 texObj->Sampler.MagFilter = params[0];
156 return GL_TRUE;
157 default:
158 goto invalid_param;
159 }
160 return GL_FALSE;
161
162 case GL_TEXTURE_WRAP_S:
163 if (texObj->Sampler.WrapS == params[0])
164 return GL_FALSE;
165 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
166 flush(ctx);
167 texObj->Sampler.WrapS = params[0];
168 return GL_TRUE;
169 }
170 return GL_FALSE;
171
172 case GL_TEXTURE_WRAP_T:
173 if (texObj->Sampler.WrapT == params[0])
174 return GL_FALSE;
175 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
176 flush(ctx);
177 texObj->Sampler.WrapT = params[0];
178 return GL_TRUE;
179 }
180 return GL_FALSE;
181
182 case GL_TEXTURE_WRAP_R:
183 if (texObj->Sampler.WrapR == params[0])
184 return GL_FALSE;
185 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
186 flush(ctx);
187 texObj->Sampler.WrapR = params[0];
188 return GL_TRUE;
189 }
190 return GL_FALSE;
191
192 default:
193 goto invalid_pname;
194 }
195
196 invalid_pname:
197 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
198 _mesa_lookup_enum_by_nr(pname));
199 return GL_FALSE;
200
201 invalid_param:
202 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)",
203 _mesa_lookup_enum_by_nr(params[0]));
204 return GL_FALSE;
205 }
206
207
208 /**
209 * Set a float-valued texture parameter
210 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
211 */
212 static GLboolean
213 set_tex_parameterf(struct gl_context *ctx,
214 struct gl_texture_object *texObj,
215 GLenum pname, const GLfloat *params)
216 {
217 switch (pname) {
218
219 case GL_TEXTURE_PRIORITY:
220 flush(ctx);
221 texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
222 return GL_TRUE;
223
224 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
225 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
226 if (texObj->Sampler.MaxAnisotropy == params[0])
227 return GL_FALSE;
228 if (params[0] < 1.0) {
229 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
230 return GL_FALSE;
231 }
232 flush(ctx);
233 /* clamp to max, that's what NVIDIA does */
234 texObj->Sampler.MaxAnisotropy = MIN2(params[0],
235 ctx->Const.MaxTextureMaxAnisotropy);
236 return GL_TRUE;
237 }
238 else {
239 static GLuint count = 0;
240 if (count++ < 10)
241 _mesa_error(ctx, GL_INVALID_ENUM,
242 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
243 }
244 return GL_FALSE;
245
246 case GL_TEXTURE_BORDER_COLOR:
247 flush(ctx);
248 texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
249 texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
250 texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
251 texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
252 return GL_TRUE;
253
254 default:
255 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
256 }
257 return GL_FALSE;
258 }
259
260
261 void GLAPIENTRY
262 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
263 {
264 GLboolean need_update;
265 struct gl_texture_object *texObj;
266 GET_CURRENT_CONTEXT(ctx);
267 ASSERT_OUTSIDE_BEGIN_END(ctx);
268
269 texObj = get_texobj(ctx, target, GL_FALSE);
270 if (!texObj)
271 return;
272
273 switch (pname) {
274 case GL_TEXTURE_MIN_FILTER:
275 case GL_TEXTURE_MAG_FILTER:
276 case GL_TEXTURE_WRAP_S:
277 case GL_TEXTURE_WRAP_T:
278 case GL_TEXTURE_WRAP_R:
279 case GL_TEXTURE_COMPARE_MODE_ARB:
280 case GL_TEXTURE_COMPARE_FUNC_ARB:
281 case GL_DEPTH_TEXTURE_MODE_ARB:
282 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
283 {
284 /* convert float param to int */
285 GLint p[4];
286 p[0] = (GLint) param;
287 p[1] = p[2] = p[3] = 0;
288 need_update = set_tex_parameteri(ctx, texObj, pname, p);
289 }
290 break;
291 case GL_TEXTURE_SWIZZLE_R_EXT:
292 case GL_TEXTURE_SWIZZLE_G_EXT:
293 case GL_TEXTURE_SWIZZLE_B_EXT:
294 case GL_TEXTURE_SWIZZLE_A_EXT:
295 {
296 GLint p[4];
297 p[0] = (GLint) param;
298 p[1] = p[2] = p[3] = 0;
299 need_update = set_tex_parameteri(ctx, texObj, pname, p);
300 }
301 break;
302 default:
303 {
304 /* this will generate an error if pname is illegal */
305 GLfloat p[4];
306 p[0] = param;
307 p[1] = p[2] = p[3] = 0.0F;
308 need_update = set_tex_parameterf(ctx, texObj, pname, p);
309 }
310 }
311
312 if (ctx->Driver.TexParameter && need_update) {
313 ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
314 }
315 }
316
317
318 void GLAPIENTRY
319 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
320 {
321 GLboolean need_update;
322 struct gl_texture_object *texObj;
323 GET_CURRENT_CONTEXT(ctx);
324 ASSERT_OUTSIDE_BEGIN_END(ctx);
325
326 texObj = get_texobj(ctx, target, GL_FALSE);
327 if (!texObj)
328 return;
329
330 switch (pname) {
331 case GL_TEXTURE_MIN_FILTER:
332 case GL_TEXTURE_MAG_FILTER:
333 case GL_TEXTURE_WRAP_S:
334 case GL_TEXTURE_WRAP_T:
335 case GL_TEXTURE_WRAP_R:
336 case GL_TEXTURE_COMPARE_MODE_ARB:
337 case GL_TEXTURE_COMPARE_FUNC_ARB:
338 case GL_DEPTH_TEXTURE_MODE_ARB:
339 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
340 {
341 /* convert float param to int */
342 GLint p[4];
343 p[0] = (GLint) params[0];
344 p[1] = p[2] = p[3] = 0;
345 need_update = set_tex_parameteri(ctx, texObj, pname, p);
346 }
347 break;
348
349 case GL_TEXTURE_SWIZZLE_R_EXT:
350 case GL_TEXTURE_SWIZZLE_G_EXT:
351 case GL_TEXTURE_SWIZZLE_B_EXT:
352 case GL_TEXTURE_SWIZZLE_A_EXT:
353 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
354 {
355 GLint p[4] = {0, 0, 0, 0};
356 p[0] = (GLint) params[0];
357 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
358 p[1] = (GLint) params[1];
359 p[2] = (GLint) params[2];
360 p[3] = (GLint) params[3];
361 }
362 need_update = set_tex_parameteri(ctx, texObj, pname, p);
363 }
364 break;
365 default:
366 /* this will generate an error if pname is illegal */
367 need_update = set_tex_parameterf(ctx, texObj, pname, params);
368 }
369
370 if (ctx->Driver.TexParameter && need_update) {
371 ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
372 }
373 }
374
375
376 void GLAPIENTRY
377 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
378 {
379 GLboolean need_update;
380 struct gl_texture_object *texObj;
381 GET_CURRENT_CONTEXT(ctx);
382 ASSERT_OUTSIDE_BEGIN_END(ctx);
383
384 texObj = get_texobj(ctx, target, GL_FALSE);
385 if (!texObj)
386 return;
387
388 switch (pname) {
389 case GL_TEXTURE_MIN_LOD:
390 case GL_TEXTURE_MAX_LOD:
391 case GL_TEXTURE_PRIORITY:
392 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
393 case GL_TEXTURE_LOD_BIAS:
394 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
395 {
396 GLfloat fparam[4];
397 fparam[0] = (GLfloat) param;
398 fparam[1] = fparam[2] = fparam[3] = 0.0F;
399 /* convert int param to float */
400 need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
401 }
402 break;
403 default:
404 /* this will generate an error if pname is illegal */
405 {
406 GLint iparam[4];
407 iparam[0] = param;
408 iparam[1] = iparam[2] = iparam[3] = 0;
409 need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
410 }
411 }
412
413 if (ctx->Driver.TexParameter && need_update) {
414 GLfloat fparam = (GLfloat) param;
415 ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
416 }
417 }
418
419
420 void GLAPIENTRY
421 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
422 {
423 GLboolean need_update;
424 struct gl_texture_object *texObj;
425 GET_CURRENT_CONTEXT(ctx);
426 ASSERT_OUTSIDE_BEGIN_END(ctx);
427
428 texObj = get_texobj(ctx, target, GL_FALSE);
429 if (!texObj)
430 return;
431
432 switch (pname) {
433 case GL_TEXTURE_BORDER_COLOR:
434 {
435 /* convert int params to float */
436 GLfloat fparams[4];
437 fparams[0] = INT_TO_FLOAT(params[0]);
438 fparams[1] = INT_TO_FLOAT(params[1]);
439 fparams[2] = INT_TO_FLOAT(params[2]);
440 fparams[3] = INT_TO_FLOAT(params[3]);
441 need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
442 }
443 break;
444 case GL_TEXTURE_MIN_LOD:
445 case GL_TEXTURE_MAX_LOD:
446 case GL_TEXTURE_PRIORITY:
447 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
448 case GL_TEXTURE_LOD_BIAS:
449 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
450 {
451 /* convert int param to float */
452 GLfloat fparams[4];
453 fparams[0] = (GLfloat) params[0];
454 fparams[1] = fparams[2] = fparams[3] = 0.0F;
455 need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
456 }
457 break;
458 default:
459 /* this will generate an error if pname is illegal */
460 need_update = set_tex_parameteri(ctx, texObj, pname, params);
461 }
462
463 if (ctx->Driver.TexParameter && need_update) {
464 GLfloat fparams[4];
465 fparams[0] = INT_TO_FLOAT(params[0]);
466 if (pname == GL_TEXTURE_BORDER_COLOR ||
467 pname == GL_TEXTURE_CROP_RECT_OES) {
468 fparams[1] = INT_TO_FLOAT(params[1]);
469 fparams[2] = INT_TO_FLOAT(params[2]);
470 fparams[3] = INT_TO_FLOAT(params[3]);
471 }
472 ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
473 }
474 }
475
476
477 /**
478 * Set tex parameter to integer value(s). Primarily intended to set
479 * integer-valued texture border color (for integer-valued textures).
480 * New in GL 3.0.
481 */
482 void GLAPIENTRY
483 _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
484 {
485 struct gl_texture_object *texObj;
486 GET_CURRENT_CONTEXT(ctx);
487 ASSERT_OUTSIDE_BEGIN_END(ctx);
488
489 texObj = get_texobj(ctx, target, GL_FALSE);
490 if (!texObj)
491 return;
492
493 switch (pname) {
494 case GL_TEXTURE_BORDER_COLOR:
495 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
496 /* set the integer-valued border color */
497 COPY_4V(texObj->Sampler.BorderColor.i, params);
498 break;
499 default:
500 _mesa_TexParameteriv(target, pname, params);
501 break;
502 }
503 /* XXX no driver hook for TexParameterIiv() yet */
504 }
505
506
507 /**
508 * Set tex parameter to unsigned integer value(s). Primarily intended to set
509 * uint-valued texture border color (for integer-valued textures).
510 * New in GL 3.0
511 */
512 void GLAPIENTRY
513 _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
514 {
515 struct gl_texture_object *texObj;
516 GET_CURRENT_CONTEXT(ctx);
517 ASSERT_OUTSIDE_BEGIN_END(ctx);
518
519 texObj = get_texobj(ctx, target, GL_FALSE);
520 if (!texObj)
521 return;
522
523 switch (pname) {
524 case GL_TEXTURE_BORDER_COLOR:
525 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
526 /* set the unsigned integer-valued border color */
527 COPY_4V(texObj->Sampler.BorderColor.ui, params);
528 break;
529 default:
530 _mesa_TexParameteriv(target, pname, (const GLint *) params);
531 break;
532 }
533 /* XXX no driver hook for TexParameterIuiv() yet */
534 }
535
536
537 void GLAPIENTRY
538 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
539 GLenum pname, GLfloat *params )
540 {
541 GLint iparam;
542 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
543 *params = (GLfloat) iparam;
544 }
545
546
547 void GLAPIENTRY
548 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
549 GLenum pname, GLint *params )
550 {
551 struct gl_texture_object *texObj;
552 const struct gl_texture_image *img = NULL;
553 GLint maxLevels;
554 gl_format texFormat;
555 GET_CURRENT_CONTEXT(ctx);
556 ASSERT_OUTSIDE_BEGIN_END(ctx);
557
558 /* this will catch bad target values */
559 maxLevels = _mesa_max_texture_levels(ctx, target);
560 if (maxLevels == 0) {
561 _mesa_error(ctx, GL_INVALID_ENUM,
562 "glGetTexLevelParameter[if]v(target=0x%x)", target);
563 return;
564 }
565
566 if (level < 0 || level >= maxLevels) {
567 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
568 return;
569 }
570
571 texObj = _mesa_select_tex_object(ctx, target);
572
573 img = _mesa_select_tex_image(ctx, texObj, target, level);
574 if (!img || img->TexFormat == MESA_FORMAT_NONE) {
575 /* undefined texture image */
576 if (pname == GL_TEXTURE_COMPONENTS)
577 *params = 1;
578 else
579 *params = 0;
580 return;
581 }
582
583 texFormat = img->TexFormat;
584
585 switch (pname) {
586 case GL_TEXTURE_WIDTH:
587 *params = img->Width;
588 break;
589 case GL_TEXTURE_HEIGHT:
590 *params = img->Height;
591 break;
592 case GL_TEXTURE_DEPTH:
593 *params = img->Depth;
594 break;
595 case GL_TEXTURE_INTERNAL_FORMAT:
596 *params = img->InternalFormat;
597 break;
598 case GL_TEXTURE_BORDER:
599 *params = img->Border;
600 break;
601 case GL_TEXTURE_RED_SIZE:
602 case GL_TEXTURE_GREEN_SIZE:
603 case GL_TEXTURE_BLUE_SIZE:
604 case GL_TEXTURE_ALPHA_SIZE:
605 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
606 *params = _mesa_get_format_bits(texFormat, pname);
607 else
608 *params = 0;
609 break;
610 case GL_TEXTURE_INTENSITY_SIZE:
611 case GL_TEXTURE_LUMINANCE_SIZE:
612 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
613 *params = _mesa_get_format_bits(texFormat, pname);
614 if (*params == 0) {
615 /* intensity or luminance is probably stored as RGB[A] */
616 *params = MIN2(_mesa_get_format_bits(texFormat,
617 GL_TEXTURE_RED_SIZE),
618 _mesa_get_format_bits(texFormat,
619 GL_TEXTURE_GREEN_SIZE));
620 }
621 }
622 else {
623 *params = 0;
624 }
625 break;
626
627 default:
628 goto invalid_pname;
629 }
630
631 /* no error if we get here */
632 return;
633
634 invalid_pname:
635 _mesa_error(ctx, GL_INVALID_ENUM,
636 "glGetTexLevelParameter[if]v(pname=%s)",
637 _mesa_lookup_enum_by_nr(pname));
638 }
639
640
641
642 void GLAPIENTRY
643 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
644 {
645 struct gl_texture_object *obj;
646 GET_CURRENT_CONTEXT(ctx);
647 ASSERT_OUTSIDE_BEGIN_END(ctx);
648
649 obj = get_texobj(ctx, target, GL_TRUE);
650 if (!obj)
651 return;
652
653 _mesa_lock_texture(ctx, obj);
654 switch (pname) {
655 case GL_TEXTURE_MAG_FILTER:
656 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
657 break;
658 case GL_TEXTURE_MIN_FILTER:
659 *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
660 break;
661 case GL_TEXTURE_WRAP_S:
662 *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
663 break;
664 case GL_TEXTURE_WRAP_T:
665 *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
666 break;
667 case GL_TEXTURE_WRAP_R:
668 *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
669 break;
670 case GL_TEXTURE_BORDER_COLOR:
671 if (ctx->NewState & _NEW_BUFFERS)
672 _mesa_update_state_locked(ctx);
673 params[0] = obj->Sampler.BorderColor.f[0];
674 params[1] = obj->Sampler.BorderColor.f[1];
675 params[2] = obj->Sampler.BorderColor.f[2];
676 params[3] = obj->Sampler.BorderColor.f[3];
677 break;
678 case GL_TEXTURE_RESIDENT:
679 *params = 1.0F;
680 break;
681 case GL_TEXTURE_PRIORITY:
682 *params = obj->Priority;
683 break;
684 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
685 if (!ctx->Extensions.EXT_texture_filter_anisotropic)
686 goto invalid_pname;
687 *params = obj->Sampler.MaxAnisotropy;
688 break;
689
690 case GL_TEXTURE_IMMUTABLE_FORMAT:
691 if (!ctx->Extensions.ARB_texture_storage)
692 goto invalid_pname;
693 *params = (GLfloat) obj->Immutable;
694 break;
695
696 default:
697 goto invalid_pname;
698 }
699
700 /* no error if we get here */
701 _mesa_unlock_texture(ctx, obj);
702 return;
703
704 invalid_pname:
705 _mesa_unlock_texture(ctx, obj);
706 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname);
707 }
708
709
710 void GLAPIENTRY
711 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
712 {
713 struct gl_texture_object *obj;
714 GET_CURRENT_CONTEXT(ctx);
715 ASSERT_OUTSIDE_BEGIN_END(ctx);
716
717 obj = get_texobj(ctx, target, GL_TRUE);
718 if (!obj)
719 return;
720
721 _mesa_lock_texture(ctx, obj);
722 switch (pname) {
723 case GL_TEXTURE_MAG_FILTER:
724 *params = (GLint) obj->Sampler.MagFilter;
725 break;;
726 case GL_TEXTURE_MIN_FILTER:
727 *params = (GLint) obj->Sampler.MinFilter;
728 break;;
729 case GL_TEXTURE_WRAP_S:
730 *params = (GLint) obj->Sampler.WrapS;
731 break;;
732 case GL_TEXTURE_WRAP_T:
733 *params = (GLint) obj->Sampler.WrapT;
734 break;;
735 case GL_TEXTURE_WRAP_R:
736 *params = (GLint) obj->Sampler.WrapR;
737 break;;
738 case GL_TEXTURE_BORDER_COLOR:
739 {
740 GLfloat b[4];
741 b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
742 b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
743 b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
744 b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
745 params[0] = FLOAT_TO_INT(b[0]);
746 params[1] = FLOAT_TO_INT(b[1]);
747 params[2] = FLOAT_TO_INT(b[2]);
748 params[3] = FLOAT_TO_INT(b[3]);
749 }
750 break;;
751 case GL_TEXTURE_RESIDENT:
752 *params = 1;
753 break;;
754 case GL_TEXTURE_PRIORITY:
755 *params = FLOAT_TO_INT(obj->Priority);
756 break;
757 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
758 if (!ctx->Extensions.EXT_texture_filter_anisotropic)
759 goto invalid_pname;
760 *params = (GLint) obj->Sampler.MaxAnisotropy;
761 break;
762
763 case GL_TEXTURE_IMMUTABLE_FORMAT:
764 if (!ctx->Extensions.ARB_texture_storage)
765 goto invalid_pname;
766 *params = (GLint) obj->Immutable;
767 break;
768
769 default:
770 goto invalid_pname;
771 }
772
773 /* no error if we get here */
774 _mesa_unlock_texture(ctx, obj);
775 return;
776
777 invalid_pname:
778 _mesa_unlock_texture(ctx, obj);
779 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
780 }
781
782
783 /** New in GL 3.0 */
784 void GLAPIENTRY
785 _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
786 {
787 struct gl_texture_object *texObj;
788 GET_CURRENT_CONTEXT(ctx);
789 ASSERT_OUTSIDE_BEGIN_END(ctx);
790
791 texObj = get_texobj(ctx, target, GL_TRUE);
792 if (!texObj)
793 return;
794
795 switch (pname) {
796 case GL_TEXTURE_BORDER_COLOR:
797 COPY_4V(params, texObj->Sampler.BorderColor.i);
798 break;
799 default:
800 _mesa_GetTexParameteriv(target, pname, params);
801 }
802 }
803
804
805 /** New in GL 3.0 */
806 void GLAPIENTRY
807 _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
808 {
809 struct gl_texture_object *texObj;
810 GET_CURRENT_CONTEXT(ctx);
811 ASSERT_OUTSIDE_BEGIN_END(ctx);
812
813 texObj = get_texobj(ctx, target, GL_TRUE);
814 if (!texObj)
815 return;
816
817 switch (pname) {
818 case GL_TEXTURE_BORDER_COLOR:
819 COPY_4V(params, texObj->Sampler.BorderColor.i);
820 break;
821 default:
822 {
823 GLint ip[4];
824 _mesa_GetTexParameteriv(target, pname, ip);
825 params[0] = ip[0];
826 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
827 pname == GL_TEXTURE_CROP_RECT_OES) {
828 params[1] = ip[1];
829 params[2] = ip[2];
830 params[3] = ip[3];
831 }
832 }
833 }
834 }