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