2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 1999-2009 VMware, Inc. All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
29 * glTexParameter-related functions
33 #include "main/glheader.h"
34 #include "main/context.h"
35 #include "main/enums.h"
36 #include "main/colormac.h"
37 #include "main/macros.h"
38 #include "main/texcompress.h"
39 #include "main/texparam.h"
40 #include "main/teximage.h"
44 * Check if a coordinate wrap mode is supported for the texture target.
45 * \return GL_TRUE if legal, GL_FALSE otherwise
48 validate_texture_wrap_mode(GLcontext
* ctx
, GLenum target
, GLenum wrap
)
50 const struct gl_extensions
* const e
= & ctx
->Extensions
;
52 if (wrap
== GL_CLAMP
|| wrap
== GL_CLAMP_TO_EDGE
||
53 (wrap
== GL_CLAMP_TO_BORDER
&& e
->ARB_texture_border_clamp
)) {
54 /* any texture target */
57 else if (target
!= GL_TEXTURE_RECTANGLE_NV
&&
59 (wrap
== GL_MIRRORED_REPEAT
&&
60 e
->ARB_texture_mirrored_repeat
) ||
61 (wrap
== GL_MIRROR_CLAMP_EXT
&&
62 (e
->ATI_texture_mirror_once
|| e
->EXT_texture_mirror_clamp
)) ||
63 (wrap
== GL_MIRROR_CLAMP_TO_EDGE_EXT
&&
64 (e
->ATI_texture_mirror_once
|| e
->EXT_texture_mirror_clamp
)) ||
65 (wrap
== GL_MIRROR_CLAMP_TO_BORDER_EXT
&&
66 (e
->EXT_texture_mirror_clamp
)))) {
67 /* non-rectangle texture */
71 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexParameter(param)" );
77 * Get current texture object for given target.
78 * Return NULL if any error.
80 static struct gl_texture_object
*
81 get_texobj(GLcontext
*ctx
, GLenum target
)
83 struct gl_texture_unit
*texUnit
;
85 if (ctx
->Texture
.CurrentUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
86 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexParameter(current unit)");
90 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
94 return texUnit
->Current1D
;
96 return texUnit
->Current2D
;
98 return texUnit
->Current3D
;
99 case GL_TEXTURE_CUBE_MAP
:
100 if (ctx
->Extensions
.ARB_texture_cube_map
) {
101 return texUnit
->CurrentCubeMap
;
104 case GL_TEXTURE_RECTANGLE_NV
:
105 if (ctx
->Extensions
.NV_texture_rectangle
) {
106 return texUnit
->CurrentRect
;
109 case GL_TEXTURE_1D_ARRAY_EXT
:
110 if (ctx
->Extensions
.MESA_texture_array
) {
111 return texUnit
->Current1DArray
;
114 case GL_TEXTURE_2D_ARRAY_EXT
:
115 if (ctx
->Extensions
.MESA_texture_array
) {
116 return texUnit
->Current2DArray
;
123 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexParameter(target)");
128 /** Set an integer-valued texture parameter */
130 set_tex_parameteri(GLcontext
*ctx
,
131 struct gl_texture_object
*texObj
,
132 GLenum pname
, const GLint
*params
)
135 case GL_TEXTURE_MIN_FILTER
:
136 if (texObj
->MinFilter
== params
[0])
141 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
142 texObj
->MinFilter
= params
[0];
144 case GL_NEAREST_MIPMAP_NEAREST
:
145 case GL_LINEAR_MIPMAP_NEAREST
:
146 case GL_NEAREST_MIPMAP_LINEAR
:
147 case GL_LINEAR_MIPMAP_LINEAR
:
148 if (texObj
->Target
!= GL_TEXTURE_RECTANGLE_NV
) {
149 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
150 texObj
->MinFilter
= params
[0];
155 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexParameter(param)" );
159 case GL_TEXTURE_MAG_FILTER
:
160 if (texObj
->MagFilter
== params
[0])
165 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
166 texObj
->MagFilter
= params
[0];
169 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexParameter(param)" );
173 case GL_TEXTURE_WRAP_S
:
174 if (texObj
->WrapS
== params
[0])
176 if (validate_texture_wrap_mode(ctx
, texObj
->Target
, params
[0])) {
177 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
178 texObj
->WrapS
= params
[0];
182 case GL_TEXTURE_WRAP_T
:
183 if (texObj
->WrapT
== params
[0])
185 if (validate_texture_wrap_mode(ctx
, texObj
->Target
, params
[0])) {
186 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
187 texObj
->WrapT
= params
[0];
191 case GL_TEXTURE_WRAP_R
:
192 if (texObj
->WrapR
== params
[0])
194 if (validate_texture_wrap_mode(ctx
, texObj
->Target
, params
[0])) {
195 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
196 texObj
->WrapR
= params
[0];
200 case GL_TEXTURE_BASE_LEVEL
:
201 if (texObj
->BaseLevel
== params
[0])
204 (texObj
->Target
== GL_TEXTURE_RECTANGLE_ARB
&& params
[0] != 0)) {
205 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexParameter(param)");
208 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
209 texObj
->BaseLevel
= params
[0];
212 case GL_TEXTURE_MAX_LEVEL
:
213 if (texObj
->MaxLevel
== params
[0])
215 if (params
[0] < 0 || texObj
->Target
== GL_TEXTURE_RECTANGLE_ARB
) {
216 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexParameter(param)");
219 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
220 texObj
->MaxLevel
= params
[0];
223 case GL_TEXTURE_COMPARE_SGIX
:
224 if (ctx
->Extensions
.SGIX_shadow
) {
225 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
226 texObj
->CompareFlag
= params
[0] ? GL_TRUE
: GL_FALSE
;
229 _mesa_error(ctx
, GL_INVALID_ENUM
,
230 "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
234 case GL_TEXTURE_COMPARE_OPERATOR_SGIX
:
235 if (ctx
->Extensions
.SGIX_shadow
&&
236 (params
[0] == GL_TEXTURE_LEQUAL_R_SGIX
||
237 params
[0] == GL_TEXTURE_GEQUAL_R_SGIX
)) {
238 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
239 texObj
->CompareOperator
= params
[0];
242 _mesa_error(ctx
, GL_INVALID_ENUM
,
243 "glTexParameter(GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
247 case GL_GENERATE_MIPMAP_SGIS
:
248 if (ctx
->Extensions
.SGIS_generate_mipmap
) {
249 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
250 texObj
->GenerateMipmap
= params
[0] ? GL_TRUE
: GL_FALSE
;
253 _mesa_error(ctx
, GL_INVALID_ENUM
,
254 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
258 case GL_TEXTURE_COMPARE_MODE_ARB
:
259 if (ctx
->Extensions
.ARB_shadow
&&
260 (params
[0] == GL_NONE
||
261 params
[0] == GL_COMPARE_R_TO_TEXTURE_ARB
)) {
262 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
263 texObj
->CompareMode
= params
[0];
266 _mesa_error(ctx
, GL_INVALID_ENUM
,
267 "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)");
271 case GL_TEXTURE_COMPARE_FUNC_ARB
:
272 if (ctx
->Extensions
.ARB_shadow
) {
276 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
277 texObj
->CompareFunc
= params
[0];
285 if (ctx
->Extensions
.EXT_shadow_funcs
) {
286 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
287 texObj
->CompareFunc
= params
[0];
292 _mesa_error(ctx
, GL_INVALID_ENUM
,
293 "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)");
297 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexParameter(param)");
301 case GL_DEPTH_TEXTURE_MODE_ARB
:
302 if (ctx
->Extensions
.ARB_depth_texture
&&
303 (params
[0] == GL_LUMINANCE
||
304 params
[0] == GL_INTENSITY
||
305 params
[0] == GL_ALPHA
)) {
306 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
307 texObj
->DepthMode
= params
[0];
310 _mesa_error(ctx
, GL_INVALID_ENUM
,
311 "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)");
315 #ifdef FEATURE_OES_draw_texture
316 case GL_TEXTURE_CROP_RECT_OES
:
317 texObj
->CropRect
[0] = params
[0];
318 texObj
->CropRect
[1] = params
[1];
319 texObj
->CropRect
[2] = params
[2];
320 texObj
->CropRect
[3] = params
[3];
325 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexParameter(pname=0x%x)", pname
);
330 /** Set a float-valued texture parameter */
332 set_tex_parameterf(GLcontext
*ctx
,
333 struct gl_texture_object
*texObj
,
334 GLenum pname
, const GLfloat
*params
)
337 case GL_TEXTURE_MIN_LOD
:
338 if (texObj
->MinLod
== params
[0])
340 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
341 texObj
->MinLod
= params
[0];
344 case GL_TEXTURE_MAX_LOD
:
345 if (texObj
->MaxLod
== params
[0])
347 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
348 texObj
->MaxLod
= params
[0];
351 case GL_TEXTURE_PRIORITY
:
352 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
353 texObj
->Priority
= CLAMP(params
[0], 0.0F
, 1.0F
);
356 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
357 if (ctx
->Extensions
.EXT_texture_filter_anisotropic
) {
358 if (params
[0] < 1.0) {
359 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexParameter(param)" );
362 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
363 /* clamp to max, that's what NVIDIA does */
364 texObj
->MaxAnisotropy
= MIN2(params
[0],
365 ctx
->Const
.MaxTextureMaxAnisotropy
);
368 _mesa_error(ctx
, GL_INVALID_ENUM
,
369 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
373 case GL_SHADOW_AMBIENT_SGIX
: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
374 if (ctx
->Extensions
.SGIX_shadow_ambient
) {
375 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
376 texObj
->ShadowAmbient
= CLAMP(params
[0], 0.0F
, 1.0F
);
379 _mesa_error(ctx
, GL_INVALID_ENUM
,
380 "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
384 case GL_TEXTURE_LOD_BIAS
:
385 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
386 if (ctx
->Extensions
.EXT_texture_lod_bias
) {
387 if (texObj
->LodBias
!= params
[0]) {
388 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
389 texObj
->LodBias
= params
[0];
394 case GL_TEXTURE_BORDER_COLOR
:
395 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
396 texObj
->BorderColor
[RCOMP
] = params
[0];
397 texObj
->BorderColor
[GCOMP
] = params
[1];
398 texObj
->BorderColor
[BCOMP
] = params
[2];
399 texObj
->BorderColor
[ACOMP
] = params
[3];
400 UNCLAMPED_FLOAT_TO_CHAN(texObj
->_BorderChan
[RCOMP
], params
[0]);
401 UNCLAMPED_FLOAT_TO_CHAN(texObj
->_BorderChan
[GCOMP
], params
[1]);
402 UNCLAMPED_FLOAT_TO_CHAN(texObj
->_BorderChan
[BCOMP
], params
[2]);
403 UNCLAMPED_FLOAT_TO_CHAN(texObj
->_BorderChan
[ACOMP
], params
[3]);
407 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexParameter(pname=0x%x)", pname
);
413 _mesa_TexParameterf(GLenum target
, GLenum pname
, GLfloat param
)
415 struct gl_texture_object
*texObj
;
416 GET_CURRENT_CONTEXT(ctx
);
417 ASSERT_OUTSIDE_BEGIN_END(ctx
);
419 texObj
= get_texobj(ctx
, target
);
424 case GL_TEXTURE_MIN_FILTER
:
425 case GL_TEXTURE_MAG_FILTER
:
426 case GL_TEXTURE_WRAP_S
:
427 case GL_TEXTURE_WRAP_T
:
428 case GL_TEXTURE_WRAP_R
:
429 case GL_TEXTURE_BASE_LEVEL
:
430 case GL_TEXTURE_MAX_LEVEL
:
431 case GL_TEXTURE_COMPARE_SGIX
:
432 case GL_TEXTURE_COMPARE_OPERATOR_SGIX
:
433 case GL_GENERATE_MIPMAP_SGIS
:
434 case GL_TEXTURE_COMPARE_MODE_ARB
:
435 case GL_TEXTURE_COMPARE_FUNC_ARB
:
436 case GL_DEPTH_TEXTURE_MODE_ARB
:
438 /* convert float param to int */
439 GLint p
= (GLint
) param
;
440 set_tex_parameteri(ctx
, texObj
, pname
, &p
);
444 /* this will generate an error if pname is illegal */
445 set_tex_parameterf(ctx
, texObj
, pname
, ¶m
);
448 texObj
->_Complete
= GL_FALSE
;
450 if (ctx
->Driver
.TexParameter
&& ctx
->ErrorValue
== GL_NO_ERROR
) {
451 ctx
->Driver
.TexParameter(ctx
, target
, texObj
, pname
, ¶m
);
457 _mesa_TexParameterfv(GLenum target
, GLenum pname
, const GLfloat
*params
)
459 struct gl_texture_object
*texObj
;
460 GET_CURRENT_CONTEXT(ctx
);
461 ASSERT_OUTSIDE_BEGIN_END(ctx
);
463 texObj
= get_texobj(ctx
, target
);
468 case GL_TEXTURE_MIN_FILTER
:
469 case GL_TEXTURE_MAG_FILTER
:
470 case GL_TEXTURE_WRAP_S
:
471 case GL_TEXTURE_WRAP_T
:
472 case GL_TEXTURE_WRAP_R
:
473 case GL_TEXTURE_BASE_LEVEL
:
474 case GL_TEXTURE_MAX_LEVEL
:
475 case GL_TEXTURE_COMPARE_SGIX
:
476 case GL_TEXTURE_COMPARE_OPERATOR_SGIX
:
477 case GL_GENERATE_MIPMAP_SGIS
:
478 case GL_TEXTURE_COMPARE_MODE_ARB
:
479 case GL_TEXTURE_COMPARE_FUNC_ARB
:
480 case GL_DEPTH_TEXTURE_MODE_ARB
:
482 /* convert float param to int */
483 GLint p
= (GLint
) params
[0];
484 set_tex_parameteri(ctx
, texObj
, pname
, &p
);
488 #ifdef FEATURE_OES_draw_texture
489 case GL_TEXTURE_CROP_RECT_OES
:
491 /* convert float params to int */
493 iparams
[0] = (GLint
) params
[0];
494 iparams
[1] = (GLint
) params
[1];
495 iparams
[2] = (GLint
) params
[2];
496 iparams
[3] = (GLint
) params
[3];
497 set_tex_parameteri(ctx
, target
, iparams
);
503 /* this will generate an error if pname is illegal */
504 set_tex_parameterf(ctx
, texObj
, pname
, params
);
507 texObj
->_Complete
= GL_FALSE
;
509 if (ctx
->Driver
.TexParameter
&& ctx
->ErrorValue
== GL_NO_ERROR
) {
510 ctx
->Driver
.TexParameter(ctx
, target
, texObj
, pname
, params
);
516 _mesa_TexParameteri(GLenum target
, GLenum pname
, GLint param
)
518 struct gl_texture_object
*texObj
;
519 GET_CURRENT_CONTEXT(ctx
);
520 ASSERT_OUTSIDE_BEGIN_END(ctx
);
522 texObj
= get_texobj(ctx
, target
);
527 case GL_TEXTURE_MIN_LOD
:
528 case GL_TEXTURE_MAX_LOD
:
529 case GL_TEXTURE_PRIORITY
:
530 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
531 case GL_TEXTURE_LOD_BIAS
:
532 case GL_SHADOW_AMBIENT_SGIX
: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
534 GLfloat fparam
= (GLfloat
) param
;
535 /* convert int param to float */
536 set_tex_parameterf(ctx
, texObj
, pname
, &fparam
);
540 /* this will generate an error if pname is illegal */
541 set_tex_parameteri(ctx
, texObj
, pname
, ¶m
);
544 texObj
->_Complete
= GL_FALSE
;
546 if (ctx
->Driver
.TexParameter
&& ctx
->ErrorValue
== GL_NO_ERROR
) {
547 GLfloat fparam
= (GLfloat
) param
;
548 ctx
->Driver
.TexParameter(ctx
, target
, texObj
, pname
, &fparam
);
554 _mesa_TexParameteriv(GLenum target
, GLenum pname
, const GLint
*params
)
556 struct gl_texture_object
*texObj
;
557 GET_CURRENT_CONTEXT(ctx
);
558 ASSERT_OUTSIDE_BEGIN_END(ctx
);
560 texObj
= get_texobj(ctx
, target
);
565 case GL_TEXTURE_BORDER_COLOR
:
567 /* convert int params to float */
569 fparams
[0] = INT_TO_FLOAT(params
[0]);
570 fparams
[1] = INT_TO_FLOAT(params
[1]);
571 fparams
[2] = INT_TO_FLOAT(params
[2]);
572 fparams
[3] = INT_TO_FLOAT(params
[3]);
573 set_tex_parameterf(ctx
, texObj
, pname
, fparams
);
576 case GL_TEXTURE_MIN_LOD
:
577 case GL_TEXTURE_MAX_LOD
:
578 case GL_TEXTURE_PRIORITY
:
579 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
580 case GL_TEXTURE_LOD_BIAS
:
581 case GL_SHADOW_AMBIENT_SGIX
: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
583 /* convert int param to float */
584 GLfloat fparam
= (GLfloat
) params
[0];
585 set_tex_parameterf(ctx
, texObj
, pname
, &fparam
);
589 /* this will generate an error if pname is illegal */
590 set_tex_parameteri(ctx
, texObj
, pname
, params
);
593 texObj
->_Complete
= GL_FALSE
;
595 if (ctx
->Driver
.TexParameter
&& ctx
->ErrorValue
== GL_NO_ERROR
) {
597 fparams
[0] = INT_TO_FLOAT(params
[0]);
598 if (pname
== GL_TEXTURE_BORDER_COLOR
||
599 pname
== GL_TEXTURE_CROP_RECT_OES
) {
600 fparams
[1] = INT_TO_FLOAT(params
[1]);
601 fparams
[2] = INT_TO_FLOAT(params
[2]);
602 fparams
[3] = INT_TO_FLOAT(params
[3]);
604 ctx
->Driver
.TexParameter(ctx
, target
, texObj
, pname
, fparams
);
610 _mesa_GetTexLevelParameterfv( GLenum target
, GLint level
,
611 GLenum pname
, GLfloat
*params
)
614 _mesa_GetTexLevelParameteriv( target
, level
, pname
, &iparam
);
615 *params
= (GLfloat
) iparam
;
620 tex_image_dimensions(GLcontext
*ctx
, GLenum target
)
624 case GL_PROXY_TEXTURE_1D
:
627 case GL_PROXY_TEXTURE_2D
:
630 case GL_PROXY_TEXTURE_3D
:
632 case GL_TEXTURE_CUBE_MAP
:
633 case GL_PROXY_TEXTURE_CUBE_MAP
:
634 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
635 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
636 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
637 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
638 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
639 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
640 return ctx
->Extensions
.ARB_texture_cube_map
? 2 : 0;
641 case GL_TEXTURE_RECTANGLE_NV
:
642 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
643 return ctx
->Extensions
.NV_texture_rectangle
? 2 : 0;
644 case GL_TEXTURE_1D_ARRAY_EXT
:
645 case GL_PROXY_TEXTURE_1D_ARRAY_EXT
:
646 return ctx
->Extensions
.MESA_texture_array
? 2 : 0;
647 case GL_TEXTURE_2D_ARRAY_EXT
:
648 case GL_PROXY_TEXTURE_2D_ARRAY_EXT
:
649 return ctx
->Extensions
.MESA_texture_array
? 3 : 0;
651 _mesa_problem(ctx
, "bad target in _mesa_tex_target_dimensions()");
658 _mesa_GetTexLevelParameteriv( GLenum target
, GLint level
,
659 GLenum pname
, GLint
*params
)
661 const struct gl_texture_unit
*texUnit
;
662 struct gl_texture_object
*texObj
;
663 const struct gl_texture_image
*img
= NULL
;
667 GET_CURRENT_CONTEXT(ctx
);
668 ASSERT_OUTSIDE_BEGIN_END(ctx
);
670 if (ctx
->Texture
.CurrentUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
671 _mesa_error(ctx
, GL_INVALID_OPERATION
,
672 "glGetTexLevelParameteriv(current unit)");
676 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
678 /* this will catch bad target values */
679 dimensions
= tex_image_dimensions(ctx
, target
); /* 1, 2 or 3 */
680 if (dimensions
== 0) {
681 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexLevelParameter[if]v(target)");
685 maxLevels
= _mesa_max_texture_levels(ctx
, target
);
686 if (maxLevels
== 0) {
687 /* should not happen since <target> was just checked above */
688 _mesa_problem(ctx
, "maxLevels=0 in _mesa_GetTexLevelParameter");
692 if (level
< 0 || level
>= maxLevels
) {
693 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexLevelParameter[if]v" );
697 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
698 _mesa_lock_texture(ctx
, texObj
);
700 img
= _mesa_select_tex_image(ctx
, texObj
, target
, level
);
701 if (!img
|| !img
->TexFormat
) {
702 /* undefined texture image */
703 if (pname
== GL_TEXTURE_COMPONENTS
)
710 isProxy
= _mesa_is_proxy_texture(target
);
713 case GL_TEXTURE_WIDTH
:
714 *params
= img
->Width
;
716 case GL_TEXTURE_HEIGHT
:
717 *params
= img
->Height
;
719 case GL_TEXTURE_DEPTH
:
720 *params
= img
->Depth
;
722 case GL_TEXTURE_INTERNAL_FORMAT
:
723 *params
= img
->InternalFormat
;
725 case GL_TEXTURE_BORDER
:
726 *params
= img
->Border
;
728 case GL_TEXTURE_RED_SIZE
:
729 if (img
->_BaseFormat
== GL_RGB
|| img
->_BaseFormat
== GL_RGBA
)
730 *params
= img
->TexFormat
->RedBits
;
734 case GL_TEXTURE_GREEN_SIZE
:
735 if (img
->_BaseFormat
== GL_RGB
|| img
->_BaseFormat
== GL_RGBA
)
736 *params
= img
->TexFormat
->GreenBits
;
740 case GL_TEXTURE_BLUE_SIZE
:
741 if (img
->_BaseFormat
== GL_RGB
|| img
->_BaseFormat
== GL_RGBA
)
742 *params
= img
->TexFormat
->BlueBits
;
746 case GL_TEXTURE_ALPHA_SIZE
:
747 if (img
->_BaseFormat
== GL_ALPHA
||
748 img
->_BaseFormat
== GL_LUMINANCE_ALPHA
||
749 img
->_BaseFormat
== GL_RGBA
)
750 *params
= img
->TexFormat
->AlphaBits
;
754 case GL_TEXTURE_INTENSITY_SIZE
:
755 if (img
->_BaseFormat
!= GL_INTENSITY
)
757 else if (img
->TexFormat
->IntensityBits
> 0)
758 *params
= img
->TexFormat
->IntensityBits
;
759 else /* intensity probably stored as rgb texture */
760 *params
= MIN2(img
->TexFormat
->RedBits
, img
->TexFormat
->GreenBits
);
762 case GL_TEXTURE_LUMINANCE_SIZE
:
763 if (img
->_BaseFormat
!= GL_LUMINANCE
&&
764 img
->_BaseFormat
!= GL_LUMINANCE_ALPHA
)
766 else if (img
->TexFormat
->LuminanceBits
> 0)
767 *params
= img
->TexFormat
->LuminanceBits
;
768 else /* luminance probably stored as rgb texture */
769 *params
= MIN2(img
->TexFormat
->RedBits
, img
->TexFormat
->GreenBits
);
771 case GL_TEXTURE_INDEX_SIZE_EXT
:
772 if (img
->_BaseFormat
== GL_COLOR_INDEX
)
773 *params
= img
->TexFormat
->IndexBits
;
777 case GL_TEXTURE_DEPTH_SIZE_ARB
:
778 if (ctx
->Extensions
.ARB_depth_texture
)
779 *params
= img
->TexFormat
->DepthBits
;
781 _mesa_error(ctx
, GL_INVALID_ENUM
,
782 "glGetTexLevelParameter[if]v(pname)");
784 case GL_TEXTURE_STENCIL_SIZE_EXT
:
785 if (ctx
->Extensions
.EXT_packed_depth_stencil
) {
786 *params
= img
->TexFormat
->StencilBits
;
789 _mesa_error(ctx
, GL_INVALID_ENUM
,
790 "glGetTexLevelParameter[if]v(pname)");
794 /* GL_ARB_texture_compression */
795 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE
:
796 if (ctx
->Extensions
.ARB_texture_compression
) {
797 if (img
->IsCompressed
&& !isProxy
) {
798 /* Don't use ctx->Driver.CompressedTextureSize() since that
799 * may returned a padded hardware size.
801 *params
= _mesa_compressed_texture_size(ctx
, img
->Width
,
802 img
->Height
, img
->Depth
,
803 img
->TexFormat
->MesaFormat
);
806 _mesa_error(ctx
, GL_INVALID_OPERATION
,
807 "glGetTexLevelParameter[if]v(pname)");
811 _mesa_error(ctx
, GL_INVALID_ENUM
,
812 "glGetTexLevelParameter[if]v(pname)");
815 case GL_TEXTURE_COMPRESSED
:
816 if (ctx
->Extensions
.ARB_texture_compression
) {
817 *params
= (GLint
) img
->IsCompressed
;
820 _mesa_error(ctx
, GL_INVALID_ENUM
,
821 "glGetTexLevelParameter[if]v(pname)");
825 /* GL_ARB_texture_float */
826 case GL_TEXTURE_RED_TYPE_ARB
:
827 if (ctx
->Extensions
.ARB_texture_float
) {
828 *params
= img
->TexFormat
->RedBits
? img
->TexFormat
->DataType
: GL_NONE
;
831 _mesa_error(ctx
, GL_INVALID_ENUM
,
832 "glGetTexLevelParameter[if]v(pname)");
835 case GL_TEXTURE_GREEN_TYPE_ARB
:
836 if (ctx
->Extensions
.ARB_texture_float
) {
837 *params
= img
->TexFormat
->GreenBits
? img
->TexFormat
->DataType
: GL_NONE
;
840 _mesa_error(ctx
, GL_INVALID_ENUM
,
841 "glGetTexLevelParameter[if]v(pname)");
844 case GL_TEXTURE_BLUE_TYPE_ARB
:
845 if (ctx
->Extensions
.ARB_texture_float
) {
846 *params
= img
->TexFormat
->BlueBits
? img
->TexFormat
->DataType
: GL_NONE
;
849 _mesa_error(ctx
, GL_INVALID_ENUM
,
850 "glGetTexLevelParameter[if]v(pname)");
853 case GL_TEXTURE_ALPHA_TYPE_ARB
:
854 if (ctx
->Extensions
.ARB_texture_float
) {
855 *params
= img
->TexFormat
->AlphaBits
? img
->TexFormat
->DataType
: GL_NONE
;
858 _mesa_error(ctx
, GL_INVALID_ENUM
,
859 "glGetTexLevelParameter[if]v(pname)");
862 case GL_TEXTURE_LUMINANCE_TYPE_ARB
:
863 if (ctx
->Extensions
.ARB_texture_float
) {
864 *params
= img
->TexFormat
->LuminanceBits
? img
->TexFormat
->DataType
: GL_NONE
;
867 _mesa_error(ctx
, GL_INVALID_ENUM
,
868 "glGetTexLevelParameter[if]v(pname)");
871 case GL_TEXTURE_INTENSITY_TYPE_ARB
:
872 if (ctx
->Extensions
.ARB_texture_float
) {
873 *params
= img
->TexFormat
->IntensityBits
? img
->TexFormat
->DataType
: GL_NONE
;
876 _mesa_error(ctx
, GL_INVALID_ENUM
,
877 "glGetTexLevelParameter[if]v(pname)");
880 case GL_TEXTURE_DEPTH_TYPE_ARB
:
881 if (ctx
->Extensions
.ARB_texture_float
) {
882 *params
= img
->TexFormat
->DepthBits
? img
->TexFormat
->DataType
: GL_NONE
;
885 _mesa_error(ctx
, GL_INVALID_ENUM
,
886 "glGetTexLevelParameter[if]v(pname)");
891 _mesa_error(ctx
, GL_INVALID_ENUM
,
892 "glGetTexLevelParameter[if]v(pname)");
896 _mesa_unlock_texture(ctx
, texObj
);
902 _mesa_GetTexParameterfv( GLenum target
, GLenum pname
, GLfloat
*params
)
904 struct gl_texture_unit
*texUnit
;
905 struct gl_texture_object
*obj
;
906 GLboolean error
= GL_FALSE
;
907 GET_CURRENT_CONTEXT(ctx
);
908 ASSERT_OUTSIDE_BEGIN_END(ctx
);
910 if (ctx
->Texture
.CurrentUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
911 _mesa_error(ctx
, GL_INVALID_OPERATION
,
912 "glGetTexParameterfv(current unit)");
916 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
918 obj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
920 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexParameterfv(target)");
924 _mesa_lock_texture(ctx
, obj
);
926 case GL_TEXTURE_MAG_FILTER
:
927 *params
= ENUM_TO_FLOAT(obj
->MagFilter
);
929 case GL_TEXTURE_MIN_FILTER
:
930 *params
= ENUM_TO_FLOAT(obj
->MinFilter
);
932 case GL_TEXTURE_WRAP_S
:
933 *params
= ENUM_TO_FLOAT(obj
->WrapS
);
935 case GL_TEXTURE_WRAP_T
:
936 *params
= ENUM_TO_FLOAT(obj
->WrapT
);
938 case GL_TEXTURE_WRAP_R
:
939 *params
= ENUM_TO_FLOAT(obj
->WrapR
);
941 case GL_TEXTURE_BORDER_COLOR
:
942 params
[0] = CLAMP(obj
->BorderColor
[0], 0.0F
, 1.0F
);
943 params
[1] = CLAMP(obj
->BorderColor
[1], 0.0F
, 1.0F
);
944 params
[2] = CLAMP(obj
->BorderColor
[2], 0.0F
, 1.0F
);
945 params
[3] = CLAMP(obj
->BorderColor
[3], 0.0F
, 1.0F
);
947 case GL_TEXTURE_RESIDENT
:
950 if (ctx
->Driver
.IsTextureResident
)
951 resident
= ctx
->Driver
.IsTextureResident(ctx
, obj
);
954 *params
= ENUM_TO_FLOAT(resident
);
957 case GL_TEXTURE_PRIORITY
:
958 *params
= obj
->Priority
;
960 case GL_TEXTURE_MIN_LOD
:
961 *params
= obj
->MinLod
;
963 case GL_TEXTURE_MAX_LOD
:
964 *params
= obj
->MaxLod
;
966 case GL_TEXTURE_BASE_LEVEL
:
967 *params
= (GLfloat
) obj
->BaseLevel
;
969 case GL_TEXTURE_MAX_LEVEL
:
970 *params
= (GLfloat
) obj
->MaxLevel
;
972 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
973 if (ctx
->Extensions
.EXT_texture_filter_anisotropic
) {
974 *params
= obj
->MaxAnisotropy
;
979 case GL_TEXTURE_COMPARE_SGIX
:
980 if (ctx
->Extensions
.SGIX_shadow
) {
981 *params
= (GLfloat
) obj
->CompareFlag
;
986 case GL_TEXTURE_COMPARE_OPERATOR_SGIX
:
987 if (ctx
->Extensions
.SGIX_shadow
) {
988 *params
= (GLfloat
) obj
->CompareOperator
;
993 case GL_SHADOW_AMBIENT_SGIX
: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
994 if (ctx
->Extensions
.SGIX_shadow_ambient
) {
995 *params
= obj
->ShadowAmbient
;
1000 case GL_GENERATE_MIPMAP_SGIS
:
1001 if (ctx
->Extensions
.SGIS_generate_mipmap
) {
1002 *params
= (GLfloat
) obj
->GenerateMipmap
;
1007 case GL_TEXTURE_COMPARE_MODE_ARB
:
1008 if (ctx
->Extensions
.ARB_shadow
) {
1009 *params
= (GLfloat
) obj
->CompareMode
;
1014 case GL_TEXTURE_COMPARE_FUNC_ARB
:
1015 if (ctx
->Extensions
.ARB_shadow
) {
1016 *params
= (GLfloat
) obj
->CompareFunc
;
1021 case GL_DEPTH_TEXTURE_MODE_ARB
:
1022 if (ctx
->Extensions
.ARB_depth_texture
) {
1023 *params
= (GLfloat
) obj
->DepthMode
;
1028 case GL_TEXTURE_LOD_BIAS
:
1029 if (ctx
->Extensions
.EXT_texture_lod_bias
) {
1030 *params
= obj
->LodBias
;
1035 #ifdef FEATURE_OES_draw_texture
1036 case GL_TEXTURE_CROP_RECT_OES
:
1037 params
[0] = obj
->CropRect
[0];
1038 params
[1] = obj
->CropRect
[1];
1039 params
[2] = obj
->CropRect
[2];
1040 params
[3] = obj
->CropRect
[3];
1048 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexParameterfv(pname=0x%x)",
1051 _mesa_unlock_texture(ctx
, obj
);
1056 _mesa_GetTexParameteriv( GLenum target
, GLenum pname
, GLint
*params
)
1058 struct gl_texture_unit
*texUnit
;
1059 struct gl_texture_object
*obj
;
1060 GET_CURRENT_CONTEXT(ctx
);
1061 ASSERT_OUTSIDE_BEGIN_END(ctx
);
1063 if (ctx
->Texture
.CurrentUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1064 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1065 "glGetTexParameteriv(current unit)");
1069 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1071 obj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1073 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexParameteriv(target)");
1078 case GL_TEXTURE_MAG_FILTER
:
1079 *params
= (GLint
) obj
->MagFilter
;
1081 case GL_TEXTURE_MIN_FILTER
:
1082 *params
= (GLint
) obj
->MinFilter
;
1084 case GL_TEXTURE_WRAP_S
:
1085 *params
= (GLint
) obj
->WrapS
;
1087 case GL_TEXTURE_WRAP_T
:
1088 *params
= (GLint
) obj
->WrapT
;
1090 case GL_TEXTURE_WRAP_R
:
1091 *params
= (GLint
) obj
->WrapR
;
1093 case GL_TEXTURE_BORDER_COLOR
:
1096 b
[0] = CLAMP(obj
->BorderColor
[0], 0.0F
, 1.0F
);
1097 b
[1] = CLAMP(obj
->BorderColor
[1], 0.0F
, 1.0F
);
1098 b
[2] = CLAMP(obj
->BorderColor
[2], 0.0F
, 1.0F
);
1099 b
[3] = CLAMP(obj
->BorderColor
[3], 0.0F
, 1.0F
);
1100 params
[0] = FLOAT_TO_INT(b
[0]);
1101 params
[1] = FLOAT_TO_INT(b
[1]);
1102 params
[2] = FLOAT_TO_INT(b
[2]);
1103 params
[3] = FLOAT_TO_INT(b
[3]);
1106 case GL_TEXTURE_RESIDENT
:
1109 if (ctx
->Driver
.IsTextureResident
)
1110 resident
= ctx
->Driver
.IsTextureResident(ctx
, obj
);
1113 *params
= (GLint
) resident
;
1116 case GL_TEXTURE_PRIORITY
:
1117 *params
= FLOAT_TO_INT(obj
->Priority
);
1119 case GL_TEXTURE_MIN_LOD
:
1120 *params
= (GLint
) obj
->MinLod
;
1122 case GL_TEXTURE_MAX_LOD
:
1123 *params
= (GLint
) obj
->MaxLod
;
1125 case GL_TEXTURE_BASE_LEVEL
:
1126 *params
= obj
->BaseLevel
;
1128 case GL_TEXTURE_MAX_LEVEL
:
1129 *params
= obj
->MaxLevel
;
1131 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
1132 if (ctx
->Extensions
.EXT_texture_filter_anisotropic
) {
1133 *params
= (GLint
) obj
->MaxAnisotropy
;
1137 case GL_TEXTURE_COMPARE_SGIX
:
1138 if (ctx
->Extensions
.SGIX_shadow
) {
1139 *params
= (GLint
) obj
->CompareFlag
;
1143 case GL_TEXTURE_COMPARE_OPERATOR_SGIX
:
1144 if (ctx
->Extensions
.SGIX_shadow
) {
1145 *params
= (GLint
) obj
->CompareOperator
;
1149 case GL_SHADOW_AMBIENT_SGIX
: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1150 if (ctx
->Extensions
.SGIX_shadow_ambient
) {
1151 *params
= (GLint
) FLOAT_TO_INT(obj
->ShadowAmbient
);
1155 case GL_GENERATE_MIPMAP_SGIS
:
1156 if (ctx
->Extensions
.SGIS_generate_mipmap
) {
1157 *params
= (GLint
) obj
->GenerateMipmap
;
1161 case GL_TEXTURE_COMPARE_MODE_ARB
:
1162 if (ctx
->Extensions
.ARB_shadow
) {
1163 *params
= (GLint
) obj
->CompareMode
;
1167 case GL_TEXTURE_COMPARE_FUNC_ARB
:
1168 if (ctx
->Extensions
.ARB_shadow
) {
1169 *params
= (GLint
) obj
->CompareFunc
;
1173 case GL_DEPTH_TEXTURE_MODE_ARB
:
1174 if (ctx
->Extensions
.ARB_depth_texture
) {
1175 *params
= (GLint
) obj
->DepthMode
;
1179 case GL_TEXTURE_LOD_BIAS
:
1180 if (ctx
->Extensions
.EXT_texture_lod_bias
) {
1181 *params
= (GLint
) obj
->LodBias
;
1185 #ifdef FEATURE_OES_draw_texture
1186 case GL_TEXTURE_CROP_RECT_OES
:
1187 params
[0] = obj
->CropRect
[0];
1188 params
[1] = obj
->CropRect
[1];
1189 params
[2] = obj
->CropRect
[2];
1190 params
[3] = obj
->CropRect
[3];
1194 ; /* silence warnings */
1196 /* If we get here, pname was an unrecognized enum */
1197 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexParameteriv(pname=0x%x)", pname
);