2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Texture image-related functions.
33 #include "bufferobj.h"
37 #include "framebuffer.h"
42 #include "texcompress.h"
43 #include "texformat.h"
51 * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE
55 _mesa_alloc_texmemory(GLsizei bytes
)
57 return _mesa_align_malloc(bytes
, 512);
62 * Free texture memory allocated with _mesa_alloc_texmemory()
65 _mesa_free_texmemory(void *m
)
74 static void PrintTexture(GLcontext
*ctx
, const struct gl_texture_image
*img
)
76 #if CHAN_TYPE == GL_FLOAT
77 _mesa_problem(NULL
, "PrintTexture doesn't support float channels");
80 const GLchan
*data
= (const GLchan
*) img
->Data
;
83 _mesa_printf("No texture data\n");
87 switch (img
->Format
) {
94 case GL_LUMINANCE_ALPHA
:
104 _mesa_problem(NULL
, "error in PrintTexture\n");
108 for (i
= 0; i
< img
->Height
; i
++) {
109 for (j
= 0; j
< img
->Width
; j
++) {
111 _mesa_printf("%02x ", data
[0]);
113 _mesa_printf("%02x%02x ", data
[0], data
[1]);
115 _mesa_printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
117 _mesa_printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
118 data
+= (img
->RowStride
- img
->Width
) * c
;
120 /* XXX use img->ImageStride here */
129 * Compute floor(log_base_2(n)).
130 * If n < 0 return -1.
159 * Return the simple base format for a given internal texture format.
160 * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
162 * \param ctx GL context.
163 * \param internalFormat the internal texture format token or 1, 2, 3, or 4.
165 * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
166 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
168 * This is the format which is used during texture application (i.e. the
169 * texture format and env mode determine the arithmetic used.
172 _mesa_base_tex_format( GLcontext
*ctx
, GLint internalFormat
)
174 switch (internalFormat
) {
189 case GL_LUMINANCE_ALPHA
:
190 case GL_LUMINANCE4_ALPHA4
:
191 case GL_LUMINANCE6_ALPHA2
:
192 case GL_LUMINANCE8_ALPHA8
:
193 case GL_LUMINANCE12_ALPHA4
:
194 case GL_LUMINANCE12_ALPHA12
:
195 case GL_LUMINANCE16_ALPHA16
:
196 return GL_LUMINANCE_ALPHA
;
227 if (ctx
->Extensions
.EXT_paletted_texture
) {
228 switch (internalFormat
) {
230 case GL_COLOR_INDEX1_EXT
:
231 case GL_COLOR_INDEX2_EXT
:
232 case GL_COLOR_INDEX4_EXT
:
233 case GL_COLOR_INDEX8_EXT
:
234 case GL_COLOR_INDEX12_EXT
:
235 case GL_COLOR_INDEX16_EXT
:
236 return GL_COLOR_INDEX
;
242 if (ctx
->Extensions
.SGIX_depth_texture
||
243 ctx
->Extensions
.ARB_depth_texture
) {
244 switch (internalFormat
) {
245 case GL_DEPTH_COMPONENT
:
246 case GL_DEPTH_COMPONENT16_SGIX
:
247 case GL_DEPTH_COMPONENT24_SGIX
:
248 case GL_DEPTH_COMPONENT32_SGIX
:
249 return GL_DEPTH_COMPONENT
;
255 if (ctx
->Extensions
.ARB_texture_compression
) {
256 switch (internalFormat
) {
257 case GL_COMPRESSED_ALPHA
:
259 case GL_COMPRESSED_LUMINANCE
:
261 case GL_COMPRESSED_LUMINANCE_ALPHA
:
262 return GL_LUMINANCE_ALPHA
;
263 case GL_COMPRESSED_INTENSITY
:
265 case GL_COMPRESSED_RGB
:
267 case GL_COMPRESSED_RGBA
:
274 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
) {
275 switch (internalFormat
) {
276 case GL_COMPRESSED_RGB_FXT1_3DFX
:
278 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
285 if (ctx
->Extensions
.EXT_texture_compression_s3tc
) {
286 switch (internalFormat
) {
287 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
289 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
290 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
291 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
298 if (ctx
->Extensions
.S3_s3tc
) {
299 switch (internalFormat
) {
311 if (ctx
->Extensions
.MESA_ycbcr_texture
) {
312 if (internalFormat
== GL_YCBCR_MESA
)
313 return GL_YCBCR_MESA
;
316 if (ctx
->Extensions
.ARB_texture_float
) {
317 switch (internalFormat
) {
318 case GL_ALPHA16F_ARB
:
319 case GL_ALPHA32F_ARB
:
327 case GL_INTENSITY16F_ARB
:
328 case GL_INTENSITY32F_ARB
:
330 case GL_LUMINANCE16F_ARB
:
331 case GL_LUMINANCE32F_ARB
:
333 case GL_LUMINANCE_ALPHA16F_ARB
:
334 case GL_LUMINANCE_ALPHA32F_ARB
:
335 return GL_LUMINANCE_ALPHA
;
341 if (ctx
->Extensions
.EXT_packed_depth_stencil
) {
342 switch (internalFormat
) {
343 case GL_DEPTH_STENCIL_EXT
:
344 case GL_DEPTH24_STENCIL8_EXT
:
345 return GL_DEPTH_STENCIL_EXT
;
351 return -1; /* error */
356 * Test if the given image format is a color/RGBA format (i.e., not color
357 * index, depth, stencil, etc).
358 * \param format the image format value (may by an internal texture format)
359 * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
362 is_color_format(GLenum format
)
380 case GL_LUMINANCE_ALPHA
:
381 case GL_LUMINANCE4_ALPHA4
:
382 case GL_LUMINANCE6_ALPHA2
:
383 case GL_LUMINANCE8_ALPHA8
:
384 case GL_LUMINANCE12_ALPHA4
:
385 case GL_LUMINANCE12_ALPHA12
:
386 case GL_LUMINANCE16_ALPHA16
:
413 /* float texture formats */
414 case GL_ALPHA16F_ARB
:
415 case GL_ALPHA32F_ARB
:
416 case GL_LUMINANCE16F_ARB
:
417 case GL_LUMINANCE32F_ARB
:
418 case GL_LUMINANCE_ALPHA16F_ARB
:
419 case GL_LUMINANCE_ALPHA32F_ARB
:
420 case GL_INTENSITY16F_ARB
:
421 case GL_INTENSITY32F_ARB
:
426 /* compressed formats */
427 case GL_COMPRESSED_ALPHA
:
428 case GL_COMPRESSED_LUMINANCE
:
429 case GL_COMPRESSED_LUMINANCE_ALPHA
:
430 case GL_COMPRESSED_INTENSITY
:
431 case GL_COMPRESSED_RGB
:
432 case GL_COMPRESSED_RGBA
:
437 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
438 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
439 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
440 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
441 case GL_COMPRESSED_RGB_FXT1_3DFX
:
442 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
444 case GL_YCBCR_MESA
: /* not considered to be RGB */
452 * Test if the given image format is a color index format.
455 is_index_format(GLenum format
)
459 case GL_COLOR_INDEX1_EXT
:
460 case GL_COLOR_INDEX2_EXT
:
461 case GL_COLOR_INDEX4_EXT
:
462 case GL_COLOR_INDEX8_EXT
:
463 case GL_COLOR_INDEX12_EXT
:
464 case GL_COLOR_INDEX16_EXT
:
473 * Test if the given image format is a depth component format.
476 is_depth_format(GLenum format
)
479 case GL_DEPTH_COMPONENT16_ARB
:
480 case GL_DEPTH_COMPONENT24_ARB
:
481 case GL_DEPTH_COMPONENT32_ARB
:
482 case GL_DEPTH_COMPONENT
:
491 * Test if the given image format is a YCbCr format.
494 is_ycbcr_format(GLenum format
)
506 * Test if the given image format is a Depth/Stencil format.
509 is_depthstencil_format(GLenum format
)
512 case GL_DEPTH24_STENCIL8_EXT
:
513 case GL_DEPTH_STENCIL_EXT
:
523 * Test if it is a supported compressed format.
525 * \param internalFormat the internal format token provided by the user.
527 * \ret GL_TRUE if \p internalFormat is a supported compressed format, or
528 * GL_FALSE otherwise.
530 * Currently only GL_COMPRESSED_RGB_FXT1_3DFX and GL_COMPRESSED_RGBA_FXT1_3DFX
534 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
536 GLint supported
[100]; /* 100 should be plenty */
539 n
= _mesa_get_compressed_formats(ctx
, supported
, GL_TRUE
);
541 for (i
= 0; i
< n
; i
++) {
542 if ((GLint
) internalFormat
== supported
[i
]) {
551 texture_face(GLenum target
)
553 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
554 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)
555 return (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
563 * Store a gl_texture_image pointer in a gl_texture_object structure
564 * according to the target and level parameters.
566 * \param tObj texture object.
567 * \param target texture target.
568 * \param level image level.
569 * \param texImage texture image.
571 * This was basically prompted by the introduction of cube maps.
574 _mesa_set_tex_image(struct gl_texture_object
*tObj
,
575 GLenum target
, GLint level
,
576 struct gl_texture_image
*texImage
)
584 tObj
->Image
[0][level
] = texImage
;
586 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
587 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
588 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
589 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
590 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
591 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
593 GLuint face
= ((GLuint
) target
-
594 (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
);
595 tObj
->Image
[face
][level
] = texImage
;
598 case GL_TEXTURE_RECTANGLE_NV
:
600 tObj
->Image
[0][level
] = texImage
;
603 _mesa_problem(NULL
, "bad target in _mesa_set_tex_image()");
606 /* Set the 'back' pointer */
607 texImage
->TexObject
= tObj
;
612 * Allocate a texture image structure.
614 * Called via ctx->Driver.NewTextureImage() unless overriden by a device
617 * \return a pointer to gl_texture_image struct with all fields initialized to
620 struct gl_texture_image
*
621 _mesa_new_texture_image( GLcontext
*ctx
)
624 return CALLOC_STRUCT(gl_texture_image
);
629 * Free texture image data.
630 * This function is a fallback called via ctx->Driver.FreeTexImageData().
632 * \param teximage texture image.
634 * Free the texture image data if it's not marked as client data.
637 _mesa_free_texture_image_data(GLcontext
*ctx
,
638 struct gl_texture_image
*texImage
)
642 if (texImage
->Data
&& !texImage
->IsClientData
) {
643 /* free the old texture data */
644 _mesa_free_texmemory(texImage
->Data
);
647 texImage
->Data
= NULL
;
652 * Free texture image.
654 * \param teximage texture image.
656 * Free the texture image structure and the associated image data.
659 _mesa_delete_texture_image( GLcontext
*ctx
, struct gl_texture_image
*texImage
)
661 if (texImage
->Data
) {
662 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
664 ASSERT(texImage
->Data
== NULL
);
670 * Test if a target is a proxy target.
672 * \param target texture target.
674 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
677 _mesa_is_proxy_texture(GLenum target
)
679 return (target
== GL_PROXY_TEXTURE_1D
||
680 target
== GL_PROXY_TEXTURE_2D
||
681 target
== GL_PROXY_TEXTURE_3D
||
682 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
||
683 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
);
688 * Get the texture object that corresponds to the target of the given texture unit.
690 * \param ctx GL context.
691 * \param texUnit texture unit.
692 * \param target texture target.
694 * \return pointer to the texture object on success, or NULL on failure.
696 * \sa gl_texture_unit.
698 struct gl_texture_object
*
699 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
704 return texUnit
->Current1D
;
705 case GL_PROXY_TEXTURE_1D
:
706 return ctx
->Texture
.Proxy1D
;
708 return texUnit
->Current2D
;
709 case GL_PROXY_TEXTURE_2D
:
710 return ctx
->Texture
.Proxy2D
;
712 return texUnit
->Current3D
;
713 case GL_PROXY_TEXTURE_3D
:
714 return ctx
->Texture
.Proxy3D
;
715 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
716 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
717 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
718 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
719 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
720 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
721 case GL_TEXTURE_CUBE_MAP_ARB
:
722 return ctx
->Extensions
.ARB_texture_cube_map
723 ? texUnit
->CurrentCubeMap
: NULL
;
724 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
725 return ctx
->Extensions
.ARB_texture_cube_map
726 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
727 case GL_TEXTURE_RECTANGLE_NV
:
728 return ctx
->Extensions
.NV_texture_rectangle
729 ? texUnit
->CurrentRect
: NULL
;
730 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
731 return ctx
->Extensions
.NV_texture_rectangle
732 ? ctx
->Texture
.ProxyRect
: NULL
;
734 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
741 * Get the texture image struct which corresponds to target and level
742 * of the given texture unit.
744 * \param ctx GL context.
745 * \param texUnit texture unit.
746 * \param target texture target.
747 * \param level image level.
749 * \return pointer to the texture image structure on success, or NULL on failure.
751 * \sa gl_texture_unit.
753 struct gl_texture_image
*
754 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
755 GLenum target
, GLint level
)
758 ASSERT(level
< MAX_TEXTURE_LEVELS
);
761 return texUnit
->Current1D
->Image
[0][level
];
762 case GL_PROXY_TEXTURE_1D
:
763 return ctx
->Texture
.Proxy1D
->Image
[0][level
];
765 return texUnit
->Current2D
->Image
[0][level
];
766 case GL_PROXY_TEXTURE_2D
:
767 return ctx
->Texture
.Proxy2D
->Image
[0][level
];
769 return texUnit
->Current3D
->Image
[0][level
];
770 case GL_PROXY_TEXTURE_3D
:
771 return ctx
->Texture
.Proxy3D
->Image
[0][level
];
772 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
773 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
774 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
775 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
776 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
777 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
778 if (ctx
->Extensions
.ARB_texture_cube_map
) {
779 GLuint face
= ((GLuint
) target
-
780 (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
);
781 return texUnit
->CurrentCubeMap
->Image
[face
][level
];
785 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
786 if (ctx
->Extensions
.ARB_texture_cube_map
)
787 return ctx
->Texture
.ProxyCubeMap
->Image
[0][level
];
790 case GL_TEXTURE_RECTANGLE_NV
:
791 if (ctx
->Extensions
.NV_texture_rectangle
) {
793 return texUnit
->CurrentRect
->Image
[0][level
];
798 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
799 if (ctx
->Extensions
.NV_texture_rectangle
) {
801 return ctx
->Texture
.ProxyRect
->Image
[0][level
];
807 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
814 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
815 * it and install it. Only return NULL if passed a bad parameter or run
818 struct gl_texture_image
*
819 _mesa_get_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
820 GLenum target
, GLint level
)
822 struct gl_texture_image
*texImage
;
823 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
825 struct gl_texture_object
*texObj
;
826 texImage
= ctx
->Driver
.NewTextureImage(ctx
);
828 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "texture image allocation");
831 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
833 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
840 * Return pointer to the specified proxy texture image.
841 * Note that proxy textures are per-context, not per-texture unit.
842 * \return pointer to texture image or NULL if invalid target, invalid
843 * level, or out of memory.
845 struct gl_texture_image
*
846 _mesa_get_proxy_tex_image(GLcontext
*ctx
, GLenum target
, GLint level
)
848 struct gl_texture_image
*texImage
;
854 case GL_PROXY_TEXTURE_1D
:
855 if (level
>= ctx
->Const
.MaxTextureLevels
)
857 texImage
= ctx
->Texture
.Proxy1D
->Image
[0][level
];
859 texImage
= ctx
->Driver
.NewTextureImage(ctx
);
861 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "proxy texture allocation");
864 ctx
->Texture
.Proxy1D
->Image
[0][level
] = texImage
;
865 /* Set the 'back' pointer */
866 texImage
->TexObject
= ctx
->Texture
.Proxy1D
;
869 case GL_PROXY_TEXTURE_2D
:
870 if (level
>= ctx
->Const
.MaxTextureLevels
)
872 texImage
= ctx
->Texture
.Proxy2D
->Image
[0][level
];
874 texImage
= ctx
->Driver
.NewTextureImage(ctx
);
876 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "proxy texture allocation");
879 ctx
->Texture
.Proxy2D
->Image
[0][level
] = texImage
;
880 /* Set the 'back' pointer */
881 texImage
->TexObject
= ctx
->Texture
.Proxy2D
;
884 case GL_PROXY_TEXTURE_3D
:
885 if (level
>= ctx
->Const
.Max3DTextureLevels
)
887 texImage
= ctx
->Texture
.Proxy3D
->Image
[0][level
];
889 texImage
= ctx
->Driver
.NewTextureImage(ctx
);
891 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "proxy texture allocation");
894 ctx
->Texture
.Proxy3D
->Image
[0][level
] = texImage
;
895 /* Set the 'back' pointer */
896 texImage
->TexObject
= ctx
->Texture
.Proxy3D
;
899 case GL_PROXY_TEXTURE_CUBE_MAP
:
900 if (level
>= ctx
->Const
.MaxCubeTextureLevels
)
902 texImage
= ctx
->Texture
.ProxyCubeMap
->Image
[0][level
];
904 texImage
= ctx
->Driver
.NewTextureImage(ctx
);
906 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "proxy texture allocation");
909 ctx
->Texture
.ProxyCubeMap
->Image
[0][level
] = texImage
;
910 /* Set the 'back' pointer */
911 texImage
->TexObject
= ctx
->Texture
.ProxyCubeMap
;
914 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
917 texImage
= ctx
->Texture
.ProxyRect
->Image
[0][level
];
919 texImage
= ctx
->Driver
.NewTextureImage(ctx
);
921 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "proxy texture allocation");
924 ctx
->Texture
.ProxyRect
->Image
[0][level
] = texImage
;
925 /* Set the 'back' pointer */
926 texImage
->TexObject
= ctx
->Texture
.ProxyRect
;
936 * Get the maximum number of allowed mipmap levels.
938 * \param ctx GL context.
939 * \param target texture target.
941 * \return the maximum number of allowed mipmap levels for the given
942 * texture target, or zero if passed a bad target.
947 _mesa_max_texture_levels(GLcontext
*ctx
, GLenum target
)
951 case GL_PROXY_TEXTURE_1D
:
953 case GL_PROXY_TEXTURE_2D
:
954 return ctx
->Const
.MaxTextureLevels
;
956 case GL_PROXY_TEXTURE_3D
:
957 return ctx
->Const
.Max3DTextureLevels
;
958 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
959 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
960 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
961 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
962 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
963 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
964 case GL_TEXTURE_CUBE_MAP_ARB
:
965 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
966 return ctx
->Const
.MaxCubeTextureLevels
;
967 case GL_TEXTURE_RECTANGLE_NV
:
968 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
971 return 0; /* bad target */
977 #if 000 /* not used anymore */
979 * glTexImage[123]D can accept a NULL image pointer. In this case we
980 * create a texture image with unspecified image contents per the OpenGL
984 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
986 const GLint components
= _mesa_components_in_format(format
);
987 const GLint numPixels
= width
* height
* depth
;
988 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
992 * Let's see if anyone finds this. If glTexImage2D() is called with
993 * a NULL image pointer then load the texture image with something
994 * interesting instead of leaving it indeterminate.
997 static const char message
[8][32] = {
1001 " X X XXXX XXX XXXXX ",
1004 " X X XXXXX XXX X X ",
1008 GLubyte
*imgPtr
= data
;
1010 for (h
= 0; h
< depth
; h
++) {
1011 for (i
= 0; i
< height
; i
++) {
1012 GLint srcRow
= 7 - (i
% 8);
1013 for (j
= 0; j
< width
; j
++) {
1014 GLint srcCol
= j
% 32;
1015 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
1016 for (k
= 0; k
< components
; k
++) {
1032 * Reset the fields of a gl_texture_image struct to zero.
1034 * \param img texture image structure.
1036 * This is called when a proxy texture test fails, we set all the
1037 * image members (except DriverData) to zero.
1038 * It's also used in glTexImage[123]D as a safeguard to be sure all
1039 * required fields get initialized properly by the Driver.TexImage[123]D
1043 clear_teximage_fields(struct gl_texture_image
*img
)
1046 img
->_BaseFormat
= 0;
1047 img
->InternalFormat
= 0;
1053 img
->ImageStride
= 0;
1058 img
->HeightLog2
= 0;
1061 img
->TexFormat
= &_mesa_null_texformat
;
1062 img
->FetchTexelc
= NULL
;
1063 img
->FetchTexelf
= NULL
;
1064 img
->IsCompressed
= 0;
1065 img
->CompressedSize
= 0;
1070 * Initialize basic fields of the gl_texture_image struct.
1072 * \param ctx GL context.
1073 * \param target texture target.
1074 * \param img texture image structure to be initialized.
1075 * \param width image width.
1076 * \param height image height.
1077 * \param depth image depth.
1078 * \param border image border.
1079 * \param internalFormat internal format.
1081 * Fills in the fields of \p img with the given information.
1082 * Note: width, height and depth include the border.
1085 _mesa_init_teximage_fields(GLcontext
*ctx
, GLenum target
,
1086 struct gl_texture_image
*img
,
1087 GLsizei width
, GLsizei height
, GLsizei depth
,
1088 GLint border
, GLenum internalFormat
)
1091 img
->_BaseFormat
= _mesa_base_tex_format( ctx
, internalFormat
);
1092 ASSERT(img
->_BaseFormat
> 0);
1093 img
->InternalFormat
= internalFormat
;
1094 img
->Border
= border
;
1096 img
->Height
= height
;
1098 img
->RowStride
= width
;
1099 img
->ImageStride
= width
* height
;
1100 img
->Width2
= width
- 2 * border
; /* == 1 << img->WidthLog2; */
1101 img
->Height2
= height
- 2 * border
; /* == 1 << img->HeightLog2; */
1102 img
->Depth2
= depth
- 2 * border
; /* == 1 << img->DepthLog2; */
1103 img
->WidthLog2
= logbase2(img
->Width2
);
1104 if (height
== 1) /* 1-D texture */
1105 img
->HeightLog2
= 0;
1107 img
->HeightLog2
= logbase2(img
->Height2
);
1108 if (depth
== 1) /* 2-D texture */
1111 img
->DepthLog2
= logbase2(img
->Depth2
);
1112 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
1113 img
->IsCompressed
= GL_FALSE
;
1114 img
->CompressedSize
= 0;
1116 if ((width
== 1 || _mesa_bitcount(img
->Width2
) == 1) &&
1117 (height
== 1 || _mesa_bitcount(img
->Height2
) == 1) &&
1118 (depth
== 1 || _mesa_bitcount(img
->Depth2
) == 1))
1119 img
->_IsPowerOfTwo
= GL_TRUE
;
1121 img
->_IsPowerOfTwo
= GL_FALSE
;
1123 /* Compute Width/Height/DepthScale for mipmap lod computation */
1124 if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1125 /* scale = 1.0 since texture coords directly map to texels */
1126 img
->WidthScale
= 1.0;
1127 img
->HeightScale
= 1.0;
1128 img
->DepthScale
= 1.0;
1131 img
->WidthScale
= (GLfloat
) img
->Width
;
1132 img
->HeightScale
= (GLfloat
) img
->Height
;
1133 img
->DepthScale
= (GLfloat
) img
->Depth
;
1139 * This is the fallback for Driver.TestProxyTexImage(). Test the texture
1140 * level, width, height and depth against the ctx->Const limits for textures.
1142 * A hardware driver might override this function if, for example, the
1143 * max 3D texture size is 512x512x64 (i.e. not a cube).
1145 * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
1146 * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
1147 * GL_PROXY_TEXTURE_CUBE_MAP_ARB.
1148 * \param level as passed to glTexImage
1149 * \param internalFormat as passed to glTexImage
1150 * \param format as passed to glTexImage
1151 * \param type as passed to glTexImage
1152 * \param width as passed to glTexImage
1153 * \param height as passed to glTexImage
1154 * \param depth as passed to glTexImage
1155 * \param border as passed to glTexImage
1156 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
1159 _mesa_test_proxy_teximage(GLcontext
*ctx
, GLenum target
, GLint level
,
1160 GLint internalFormat
, GLenum format
, GLenum type
,
1161 GLint width
, GLint height
, GLint depth
, GLint border
)
1165 (void) internalFormat
;
1170 case GL_PROXY_TEXTURE_1D
:
1171 maxSize
= 1 << (ctx
->Const
.MaxTextureLevels
- 1);
1172 if (width
< 2 * border
|| width
> 2 + maxSize
||
1173 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&&
1174 _mesa_bitcount(width
- 2 * border
) != 1) ||
1175 level
>= ctx
->Const
.MaxTextureLevels
) {
1176 /* bad width or level */
1180 case GL_PROXY_TEXTURE_2D
:
1181 maxSize
= 1 << (ctx
->Const
.MaxTextureLevels
- 1);
1182 if (width
< 2 * border
|| width
> 2 + maxSize
||
1183 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&&
1184 _mesa_bitcount(width
- 2 * border
) != 1) ||
1185 height
< 2 * border
|| height
> 2 + maxSize
||
1186 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&&
1187 _mesa_bitcount(height
- 2 * border
) != 1) ||
1188 level
>= ctx
->Const
.MaxTextureLevels
) {
1189 /* bad width or height or level */
1193 case GL_PROXY_TEXTURE_3D
:
1194 maxSize
= 1 << (ctx
->Const
.Max3DTextureLevels
- 1);
1195 if (width
< 2 * border
|| width
> 2 + maxSize
||
1196 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&&
1197 _mesa_bitcount(width
- 2 * border
) != 1) ||
1198 height
< 2 * border
|| height
> 2 + maxSize
||
1199 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&&
1200 _mesa_bitcount(height
- 2 * border
) != 1) ||
1201 depth
< 2 * border
|| depth
> 2 + maxSize
||
1202 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&&
1203 _mesa_bitcount(depth
- 2 * border
) != 1) ||
1204 level
>= ctx
->Const
.Max3DTextureLevels
) {
1205 /* bad width or height or depth or level */
1209 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
1210 if (width
< 1 || width
> ctx
->Const
.MaxTextureRectSize
||
1211 height
< 1 || height
> ctx
->Const
.MaxTextureRectSize
||
1213 /* bad width or height or level */
1217 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
1218 maxSize
= 1 << (ctx
->Const
.MaxCubeTextureLevels
- 1);
1219 if (width
< 2 * border
|| width
> 2 + maxSize
||
1220 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&&
1221 _mesa_bitcount(width
- 2 * border
) != 1) ||
1222 height
< 2 * border
|| height
> 2 + maxSize
||
1223 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&&
1224 _mesa_bitcount(height
- 2 * border
) != 1) ||
1225 level
>= ctx
->Const
.MaxCubeTextureLevels
) {
1226 /* bad width or height */
1231 _mesa_problem(ctx
, "Invalid target in _mesa_test_proxy_teximage");
1238 * Test the glTexImage[123]D() parameters for errors.
1240 * \param ctx GL context.
1241 * \param target texture target given by the user.
1242 * \param level image level given by the user.
1243 * \param internalFormat internal format given by the user.
1244 * \param format pixel data format given by the user.
1245 * \param type pixel data type given by the user.
1246 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1247 * \param width image width given by the user.
1248 * \param height image height given by the user.
1249 * \param depth image depth given by the user.
1250 * \param border image border given by the user.
1252 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1254 * Verifies each of the parameters against the constants specified in
1255 * __GLcontextRec::Const and the supported extensions, and according to the
1256 * OpenGL specification.
1259 texture_error_check( GLcontext
*ctx
, GLenum target
,
1260 GLint level
, GLint internalFormat
,
1261 GLenum format
, GLenum type
,
1263 GLint width
, GLint height
,
1264 GLint depth
, GLint border
)
1266 const GLboolean isProxy
= _mesa_is_proxy_texture(target
);
1268 GLboolean colorFormat
, indexFormat
;
1270 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1271 if (level
< 0 || level
>= MAX_TEXTURE_LEVELS
) {
1273 _mesa_error(ctx
, GL_INVALID_VALUE
,
1274 "glTexImage%dD(level=%d)", dimensions
, level
);
1280 if (border
< 0 || border
> 1 ||
1281 ((target
== GL_TEXTURE_RECTANGLE_NV
||
1282 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) && border
!= 0)) {
1284 _mesa_error(ctx
, GL_INVALID_VALUE
,
1285 "glTexImage%dD(border=%d)", dimensions
, border
);
1290 if (width
< 0 || height
< 0 || depth
< 0) {
1292 _mesa_error(ctx
, GL_INVALID_VALUE
,
1293 "glTexImage%dD(width, height or depth < 0)", dimensions
);
1298 /* Check target and call ctx->Driver.TestProxyTexImage() to check the
1299 * level, width, height and depth.
1301 if (dimensions
== 1) {
1302 if (target
== GL_PROXY_TEXTURE_1D
|| target
== GL_TEXTURE_1D
) {
1303 sizeOK
= ctx
->Driver
.TestProxyTexImage(ctx
, GL_PROXY_TEXTURE_1D
,
1304 level
, internalFormat
,
1306 width
, 1, 1, border
);
1309 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1313 else if (dimensions
== 2) {
1314 if (target
== GL_PROXY_TEXTURE_2D
|| target
== GL_TEXTURE_2D
) {
1315 sizeOK
= ctx
->Driver
.TestProxyTexImage(ctx
, GL_PROXY_TEXTURE_2D
,
1316 level
, internalFormat
,
1318 width
, height
, 1, border
);
1320 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
||
1321 (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1322 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1323 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
1324 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
1327 sizeOK
= (width
== height
) &&
1328 ctx
->Driver
.TestProxyTexImage(ctx
, GL_PROXY_TEXTURE_CUBE_MAP_ARB
,
1329 level
, internalFormat
, format
, type
,
1330 width
, height
, 1, border
);
1332 else if (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
||
1333 target
== GL_TEXTURE_RECTANGLE_NV
) {
1334 if (!ctx
->Extensions
.NV_texture_rectangle
) {
1335 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
1338 sizeOK
= ctx
->Driver
.TestProxyTexImage(ctx
,
1339 GL_PROXY_TEXTURE_RECTANGLE_NV
,
1340 level
, internalFormat
,
1342 width
, height
, 1, border
);
1345 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
1349 else if (dimensions
== 3) {
1350 if (target
== GL_PROXY_TEXTURE_3D
|| target
== GL_TEXTURE_3D
) {
1351 sizeOK
= ctx
->Driver
.TestProxyTexImage(ctx
, GL_PROXY_TEXTURE_3D
,
1352 level
, internalFormat
,
1354 width
, height
, depth
, border
);
1357 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1362 _mesa_problem( ctx
, "bad dims in texture_error_check" );
1368 _mesa_error(ctx
, GL_INVALID_VALUE
,
1369 "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
1370 dimensions
, level
, width
, height
, depth
);
1375 /* Check internalFormat */
1376 if (_mesa_base_tex_format(ctx
, internalFormat
) < 0) {
1378 _mesa_error(ctx
, GL_INVALID_VALUE
,
1379 "glTexImage%dD(internalFormat=0x%x)",
1380 dimensions
, internalFormat
);
1385 /* Check incoming image format and type */
1386 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
1387 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
1388 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
1391 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1392 "glTexImage%dD(format or type)", dimensions
);
1397 /* make sure internal format and format basically agree */
1398 colorFormat
= is_color_format(format
);
1399 indexFormat
= is_index_format(format
);
1400 if ((is_color_format(internalFormat
) && !colorFormat
&& !indexFormat
) ||
1401 (is_index_format(internalFormat
) && !indexFormat
) ||
1402 (is_depth_format(internalFormat
) != is_depth_format(format
)) ||
1403 (is_ycbcr_format(internalFormat
) != is_ycbcr_format(format
)) ||
1404 (is_depthstencil_format(internalFormat
) != is_depthstencil_format(format
))) {
1406 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1407 "glTexImage(internalFormat/format)");
1411 /* additional checks for ycbcr textures */
1412 if (internalFormat
== GL_YCBCR_MESA
) {
1413 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
1414 if (type
!= GL_UNSIGNED_SHORT_8_8_MESA
&&
1415 type
!= GL_UNSIGNED_SHORT_8_8_REV_MESA
) {
1417 _mesa_sprintf(message
,
1418 "glTexImage%d(format/type YCBCR mismatch", dimensions
);
1419 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
1420 return GL_TRUE
; /* error */
1422 if (target
!= GL_TEXTURE_2D
&&
1423 target
!= GL_PROXY_TEXTURE_2D
&&
1424 target
!= GL_TEXTURE_RECTANGLE_NV
&&
1425 target
!= GL_PROXY_TEXTURE_RECTANGLE_NV
) {
1427 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage(target)");
1433 _mesa_sprintf(message
,
1434 "glTexImage%d(format=GL_YCBCR_MESA and border=%d)",
1435 dimensions
, border
);
1436 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1442 /* additional checks for depth textures */
1443 if (_mesa_base_tex_format(ctx
, internalFormat
) == GL_DEPTH_COMPONENT
) {
1444 /* Only 1D and 2D textures supported */
1445 if (target
!= GL_TEXTURE_1D
&&
1446 target
!= GL_PROXY_TEXTURE_1D
&&
1447 target
!= GL_TEXTURE_2D
&&
1448 target
!= GL_PROXY_TEXTURE_2D
) {
1450 _mesa_error(ctx
, GL_INVALID_ENUM
,
1451 "glTexImage(target/internalFormat)");
1456 /* additional checks for compressed textures */
1457 if (is_compressed_format(ctx
, internalFormat
)) {
1458 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
1461 else if (ctx
->Extensions
.ARB_texture_cube_map
&&
1462 (target
== GL_PROXY_TEXTURE_CUBE_MAP
||
1463 (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X
&&
1464 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
))) {
1469 _mesa_error(ctx
, GL_INVALID_ENUM
,
1470 "glTexImage%d(target)", dimensions
);
1476 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1477 "glTexImage%D(border!=0)", dimensions
);
1483 /* if we get here, the parameters are OK */
1489 * Test glTexSubImage[123]D() parameters for errors.
1491 * \param ctx GL context.
1492 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1493 * \param target texture target given by the user.
1494 * \param level image level given by the user.
1495 * \param xoffset sub-image x offset given by the user.
1496 * \param yoffset sub-image y offset given by the user.
1497 * \param zoffset sub-image z offset given by the user.
1498 * \param format pixel data format given by the user.
1499 * \param type pixel data type given by the user.
1500 * \param width image width given by the user.
1501 * \param height image height given by the user.
1502 * \param depth image depth given by the user.
1504 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1506 * Verifies each of the parameters against the constants specified in
1507 * __GLcontextRec::Const and the supported extensions, and according to the
1508 * OpenGL specification.
1511 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1512 GLenum target
, GLint level
,
1513 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1514 GLint width
, GLint height
, GLint depth
,
1515 GLenum format
, GLenum type
)
1517 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1518 struct gl_texture_image
*destTex
;
1521 if (dimensions
== 1) {
1522 if (target
!= GL_TEXTURE_1D
) {
1523 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1527 else if (dimensions
== 2) {
1528 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1529 target
<=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1530 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
1531 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1535 else if (ctx
->Extensions
.NV_texture_rectangle
&&
1536 target
== GL_TEXTURE_RECTANGLE_NV
) {
1537 if (!ctx
->Extensions
.NV_texture_rectangle
) {
1538 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1542 else if (target
!= GL_TEXTURE_2D
) {
1543 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1547 else if (dimensions
== 3) {
1548 if (target
!= GL_TEXTURE_3D
) {
1549 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
1554 _mesa_problem( ctx
, "invalid dims in texture_error_check" );
1558 /* Basic level check */
1559 if (level
< 0 || level
>= MAX_TEXTURE_LEVELS
) {
1560 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level=%d)", level
);
1565 _mesa_error(ctx
, GL_INVALID_VALUE
,
1566 "glTexSubImage%dD(width=%d)", dimensions
, width
);
1569 if (height
< 0 && dimensions
> 1) {
1570 _mesa_error(ctx
, GL_INVALID_VALUE
,
1571 "glTexSubImage%dD(height=%d)", dimensions
, height
);
1574 if (depth
< 0 && dimensions
> 2) {
1575 _mesa_error(ctx
, GL_INVALID_VALUE
,
1576 "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
1580 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1583 /* undefined image level */
1584 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage%dD", dimensions
);
1588 if (xoffset
< -((GLint
)destTex
->Border
)) {
1589 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage%dD(xoffset)",
1593 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1594 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage%dD(xoffset+width)",
1598 if (dimensions
> 1) {
1599 if (yoffset
< -((GLint
)destTex
->Border
)) {
1600 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage%dD(yoffset)",
1604 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1605 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage%dD(yoffset+height)",
1610 if (dimensions
> 2) {
1611 if (zoffset
< -((GLint
)destTex
->Border
)) {
1612 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1615 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
1616 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1621 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
1622 _mesa_error(ctx
, GL_INVALID_ENUM
,
1623 "glTexSubImage%dD(format or type)", dimensions
);
1627 if (destTex
->IsCompressed
) {
1628 const struct gl_texture_unit
*texUnit
;
1629 const struct gl_texture_image
*texImage
;
1630 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1631 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1633 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
1636 else if (ctx
->Extensions
.ARB_texture_cube_map
&&
1637 (target
== GL_PROXY_TEXTURE_CUBE_MAP
||
1638 (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X
&&
1639 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
))) {
1643 _mesa_error(ctx
, GL_INVALID_ENUM
,
1644 "glTexSubImage%D(target)", dimensions
);
1647 /* offset must be multiple of 4 */
1648 if ((xoffset
& 3) || (yoffset
& 3)) {
1649 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1650 "glTexSubImage%D(xoffset or yoffset)", dimensions
);
1653 /* size must be multiple of 4 or equal to whole texture size */
1654 if ((width
& 3) && (GLuint
) width
!= texImage
->Width
) {
1655 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1656 "glTexSubImage%D(width)", dimensions
);
1659 if ((height
& 3) && (GLuint
) height
!= texImage
->Height
) {
1660 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1661 "glTexSubImage%D(width)", dimensions
);
1671 * Test glCopyTexImage[12]D() parameters for errors.
1673 * \param ctx GL context.
1674 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1675 * \param target texture target given by the user.
1676 * \param level image level given by the user.
1677 * \param internalFormat internal format given by the user.
1678 * \param width image width given by the user.
1679 * \param height image height given by the user.
1680 * \param depth image depth given by the user.
1681 * \param border texture border.
1683 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1685 * Verifies each of the parameters against the constants specified in
1686 * __GLcontextRec::Const and the supported extensions, and according to the
1687 * OpenGL specification.
1690 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1691 GLenum target
, GLint level
, GLint internalFormat
,
1692 GLint width
, GLint height
, GLint border
)
1698 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1699 if (level
< 0 || level
>= MAX_TEXTURE_LEVELS
) {
1700 /* Check that the source buffer is complete */
1701 if (ctx
->ReadBuffer
->Name
) {
1702 _mesa_test_framebuffer_completeness(ctx
, ctx
->ReadBuffer
);
1703 if (ctx
->ReadBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
1704 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
1705 "glCopyTexImage%dD(invalid readbuffer)", dimensions
);
1710 _mesa_error(ctx
, GL_INVALID_VALUE
,
1711 "glCopyTexImage%dD(level=%d)", dimensions
, level
);
1716 if (border
< 0 || border
> 1 ||
1717 ((target
== GL_TEXTURE_RECTANGLE_NV
||
1718 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) && border
!= 0)) {
1722 format
= _mesa_base_tex_format(ctx
, internalFormat
);
1724 _mesa_error(ctx
, GL_INVALID_VALUE
,
1725 "glCopyTexImage%dD(internalFormat)", dimensions
);
1729 /* NOTE: the format and type aren't really significant for
1730 * TestProxyTexImage(). Only the internalformat really matters.
1731 if (!_mesa_source_buffer_exists(ctx, format)) {
1732 _mesa_error(ctx, GL_INVALID_OPERATION,
1733 "glCopyTexImage%dD(missing readbuffer)", dimensions);
1740 /* Check target and call ctx->Driver.TestProxyTexImage() to check the
1741 * level, width, height and depth.
1743 if (dimensions
== 1) {
1744 if (target
== GL_TEXTURE_1D
) {
1745 sizeOK
= ctx
->Driver
.TestProxyTexImage(ctx
, GL_PROXY_TEXTURE_1D
,
1746 level
, internalFormat
,
1748 width
, 1, 1, border
);
1751 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1755 else if (dimensions
== 2) {
1756 if (target
== GL_TEXTURE_2D
) {
1757 sizeOK
= ctx
->Driver
.TestProxyTexImage(ctx
, GL_PROXY_TEXTURE_2D
,
1758 level
, internalFormat
,
1760 width
, height
, 1, border
);
1762 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1763 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1764 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
1765 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1768 sizeOK
= (width
== height
) &&
1769 ctx
->Driver
.TestProxyTexImage(ctx
, GL_PROXY_TEXTURE_CUBE_MAP_ARB
,
1770 level
, internalFormat
, format
, type
,
1771 width
, height
, 1, border
);
1773 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1774 if (!ctx
->Extensions
.NV_texture_rectangle
) {
1775 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1778 sizeOK
= ctx
->Driver
.TestProxyTexImage(ctx
,
1779 GL_PROXY_TEXTURE_RECTANGLE_NV
,
1780 level
, internalFormat
,
1782 width
, height
, 1, border
);
1785 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1790 _mesa_problem(ctx
, "invalid dimensions in copytexture_error_check");
1795 if (dimensions
== 1) {
1796 _mesa_error(ctx
, GL_INVALID_VALUE
,
1797 "glCopyTexImage1D(width=%d)", width
);
1800 ASSERT(dimensions
== 2);
1801 _mesa_error(ctx
, GL_INVALID_VALUE
,
1802 "glCopyTexImage2D(width=%d, height=%d)", width
, height
);
1807 if (is_compressed_format(ctx
, internalFormat
)) {
1808 if (target
!= GL_TEXTURE_2D
) {
1809 _mesa_error(ctx
, GL_INVALID_ENUM
,
1810 "glCopyTexImage%d(target)", dimensions
);
1814 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1815 "glCopyTexImage%D(border!=0)", dimensions
);
1819 else if (is_depth_format(internalFormat
)) {
1820 /* make sure we have depth/stencil buffers */
1821 if (!ctx
->ReadBuffer
->_DepthBuffer
) {
1822 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1823 "glCopyTexImage%D(no depth)", dimensions
);
1827 else if (is_depthstencil_format(internalFormat
)) {
1828 /* make sure we have depth/stencil buffers */
1829 if (!ctx
->ReadBuffer
->_DepthBuffer
|| !ctx
->ReadBuffer
->_StencilBuffer
) {
1830 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1831 "glCopyTexImage%D(no depth/stencil buffer)", dimensions
);
1836 /* if we get here, the parameters are OK */
1842 * Test glCopyTexSubImage[12]D() parameters for errors.
1844 * \param ctx GL context.
1845 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1846 * \param target texture target given by the user.
1847 * \param level image level given by the user.
1848 * \param xoffset sub-image x offset given by the user.
1849 * \param yoffset sub-image y offset given by the user.
1850 * \param zoffset sub-image z offset given by the user.
1851 * \param width image width given by the user.
1852 * \param height image height given by the user.
1854 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1856 * Verifies each of the parameters against the constants specified in
1857 * __GLcontextRec::Const and the supported extensions, and according to the
1858 * OpenGL specification.
1861 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1862 GLenum target
, GLint level
,
1863 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1864 GLsizei width
, GLsizei height
)
1866 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1867 struct gl_texture_image
*teximage
;
1870 /* Check that the source buffer is complete */
1871 if (ctx
->ReadBuffer
->Name
) {
1872 _mesa_test_framebuffer_completeness(ctx
, ctx
->ReadBuffer
);
1873 if (ctx
->ReadBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
1874 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
1875 "glCopyTexImage%dD(invalid readbuffer)", dimensions
);
1880 if (dimensions
== 1) {
1881 if (target
!= GL_TEXTURE_1D
) {
1882 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1886 else if (dimensions
== 2) {
1887 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1888 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1889 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
1890 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1894 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1895 if (!ctx
->Extensions
.NV_texture_rectangle
) {
1896 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1900 else if (target
!= GL_TEXTURE_2D
) {
1901 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1905 else if (dimensions
== 3) {
1906 if (target
!= GL_TEXTURE_3D
) {
1907 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1913 if (level
< 0 || level
>= MAX_TEXTURE_LEVELS
) {
1914 _mesa_error(ctx
, GL_INVALID_VALUE
,
1915 "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1921 _mesa_error(ctx
, GL_INVALID_VALUE
,
1922 "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1925 if (dimensions
> 1 && height
< 0) {
1926 _mesa_error(ctx
, GL_INVALID_VALUE
,
1927 "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1931 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1933 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1934 "glCopyTexSubImage%dD(undefined texture level: %d)",
1939 if (xoffset
< -((GLint
)teximage
->Border
)) {
1940 _mesa_error(ctx
, GL_INVALID_VALUE
,
1941 "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1944 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1945 _mesa_error(ctx
, GL_INVALID_VALUE
,
1946 "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1949 if (dimensions
> 1) {
1950 if (yoffset
< -((GLint
)teximage
->Border
)) {
1951 _mesa_error(ctx
, GL_INVALID_VALUE
,
1952 "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1955 /* NOTE: we're adding the border here, not subtracting! */
1956 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1957 _mesa_error(ctx
, GL_INVALID_VALUE
,
1958 "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1963 if (dimensions
> 2) {
1964 if (zoffset
< -((GLint
)teximage
->Border
)) {
1965 _mesa_error(ctx
, GL_INVALID_VALUE
,
1966 "glCopyTexSubImage%dD(zoffset)", dimensions
);
1969 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1970 _mesa_error(ctx
, GL_INVALID_VALUE
,
1971 "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1976 if (teximage
->IsCompressed
) {
1977 if (!_mesa_source_buffer_exists(ctx
, teximage
->_BaseFormat
)) {
1978 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1979 "glCopyTexSubImage%dD(missing readbuffer)", dimensions
);
1983 if (target
!= GL_TEXTURE_2D
) {
1984 _mesa_error(ctx
, GL_INVALID_ENUM
,
1985 "glCopyTexSubImage%d(target)", dimensions
);
1988 /* offset must be multiple of 4 */
1989 if ((xoffset
& 3) || (yoffset
& 3)) {
1990 _mesa_error(ctx
, GL_INVALID_VALUE
,
1991 "glCopyTexSubImage%D(xoffset or yoffset)", dimensions
);
1994 /* size must be multiple of 4 */
1995 if ((width
& 3) != 0 && (GLuint
) width
!= teximage
->Width
) {
1996 _mesa_error(ctx
, GL_INVALID_VALUE
,
1997 "glCopyTexSubImage%D(width)", dimensions
);
2000 if ((height
& 3) != 0 && (GLuint
) height
!= teximage
->Height
) {
2001 _mesa_error(ctx
, GL_INVALID_VALUE
,
2002 "glCopyTexSubImage%D(height)", dimensions
);
2007 if (teximage
->InternalFormat
== GL_YCBCR_MESA
) {
2008 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glCopyTexSubImage2D");
2012 if (teximage
->_BaseFormat
== GL_DEPTH_COMPONENT
) {
2013 if (!ctx
->ReadBuffer
->_DepthBuffer
) {
2014 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2015 "glCopyTexSubImage%D(no depth buffer)",
2020 else if (teximage
->_BaseFormat
== GL_DEPTH_STENCIL_EXT
) {
2021 if (!ctx
->ReadBuffer
->_DepthBuffer
|| !ctx
->ReadBuffer
->_StencilBuffer
) {
2022 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2023 "glCopyTexSubImage%D(no depth/stencil buffer)",
2029 /* if we get here, the parameters are OK */
2035 * Get texture image. Called by glGetTexImage.
2037 * \param target texture target.
2038 * \param level image level.
2039 * \param format pixel data format for returned image.
2040 * \param type pixel data type for returned image.
2041 * \param pixels returned pixel data.
2044 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
2045 GLenum type
, GLvoid
*pixels
)
2047 const struct gl_texture_unit
*texUnit
;
2048 struct gl_texture_object
*texObj
;
2049 struct gl_texture_image
*texImage
;
2050 GLint maxLevels
= 0;
2051 GET_CURRENT_CONTEXT(ctx
);
2052 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2054 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
2055 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2056 if (!texObj
|| _mesa_is_proxy_texture(target
)) {
2057 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
2061 maxLevels
= _mesa_max_texture_levels(ctx
, target
);
2062 ASSERT(maxLevels
> 0); /* 0 indicates bad target, caught above */
2064 if (level
< 0 || level
>= maxLevels
) {
2065 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
2069 if (_mesa_sizeof_packed_type(type
) <= 0) {
2070 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
2074 if (_mesa_components_in_format(format
) <= 0 ||
2075 format
== GL_STENCIL_INDEX
) {
2076 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
2080 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
2081 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
2084 if (!ctx
->Extensions
.SGIX_depth_texture
&&
2085 !ctx
->Extensions
.ARB_depth_texture
&& is_depth_format(format
)) {
2086 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
2089 if (!ctx
->Extensions
.MESA_ycbcr_texture
&& is_ycbcr_format(format
)) {
2090 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
2093 if (!ctx
->Extensions
.EXT_packed_depth_stencil
2094 && is_depthstencil_format(format
)) {
2095 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
2101 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2103 /* invalid mipmap level, not an error */
2107 /* Make sure the requested image format is compatible with the
2108 * texture's format. Note that a color index texture can be converted
2109 * to RGBA so that combo is allowed.
2111 if (is_color_format(format
)
2112 && !is_color_format(texImage
->TexFormat
->BaseFormat
)
2113 && !is_index_format(texImage
->TexFormat
->BaseFormat
)) {
2114 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexImage(format mismatch)");
2117 else if (is_index_format(format
)
2118 && !is_index_format(texImage
->TexFormat
->BaseFormat
)) {
2119 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexImage(format mismatch)");
2122 else if (is_depth_format(format
)
2123 && !is_depth_format(texImage
->TexFormat
->BaseFormat
)
2124 && !is_depthstencil_format(texImage
->TexFormat
->BaseFormat
)) {
2125 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexImage(format mismatch)");
2128 else if (is_ycbcr_format(format
)
2129 && !is_ycbcr_format(texImage
->TexFormat
->BaseFormat
)) {
2130 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexImage(format mismatch)");
2133 else if (is_depthstencil_format(format
)
2134 && !is_depthstencil_format(texImage
->TexFormat
->BaseFormat
)) {
2135 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexImage(format mismatch)");
2139 /* typically, this will call _mesa_get_teximage() */
2140 ctx
->Driver
.GetTexImage(ctx
, target
, level
, format
, type
, pixels
,
2147 * Check if the given texture image is bound to any framebuffer objects
2148 * and update/invalidate them.
2149 * XXX We're only checking the currently bound framebuffer object for now.
2150 * In the future, perhaps struct gl_texture_image should have a pointer (or
2151 * list of pointers (yikes)) to the gl_framebuffer(s) which it's bound to.
2154 update_fbo_texture(GLcontext
*ctx
, struct gl_texture_object
*texObj
,
2155 GLuint face
, GLuint level
)
2157 if (ctx
->DrawBuffer
->Name
) {
2159 for (i
= 0; i
< BUFFER_COUNT
; i
++) {
2160 struct gl_renderbuffer_attachment
*att
=
2161 ctx
->DrawBuffer
->Attachment
+ i
;
2162 if (att
->Type
== GL_TEXTURE
&&
2163 att
->Texture
== texObj
&&
2164 att
->TextureLevel
== level
&&
2165 att
->CubeMapFace
== face
) {
2166 ASSERT(att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
]);
2167 /* Tell driver about the new renderbuffer texture */
2168 ctx
->Driver
.RenderTexture(ctx
, ctx
->DrawBuffer
, att
);
2177 * Called from the API. Note that width includes the border.
2180 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
2181 GLsizei width
, GLint border
, GLenum format
,
2182 GLenum type
, const GLvoid
*pixels
)
2184 GLsizei postConvWidth
= width
;
2185 GET_CURRENT_CONTEXT(ctx
);
2186 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2188 if (is_color_format(internalFormat
)) {
2189 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2192 if (target
== GL_TEXTURE_1D
) {
2193 /* non-proxy target */
2194 struct gl_texture_unit
*texUnit
;
2195 struct gl_texture_object
*texObj
;
2196 struct gl_texture_image
*texImage
;
2197 const GLuint face
= texture_face(target
);
2199 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2200 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
2201 return; /* error was recorded */
2204 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2205 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2206 texImage
= _mesa_get_tex_image(ctx
, texUnit
, target
, level
);
2209 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
2212 else if (texImage
->Data
) {
2213 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
2215 ASSERT(texImage
->Data
== NULL
);
2216 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2217 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2218 postConvWidth
, 1, 1,
2219 border
, internalFormat
);
2221 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2222 _mesa_update_state(ctx
);
2224 ASSERT(ctx
->Driver
.TexImage1D
);
2226 /* Give the texture to the driver! <pixels> may be null! */
2227 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
2228 width
, border
, format
, type
, pixels
,
2229 &ctx
->Unpack
, texObj
, texImage
);
2231 ASSERT(texImage
->TexFormat
);
2233 update_fbo_texture(ctx
, texObj
, face
, level
);
2236 texObj
->Complete
= GL_FALSE
;
2237 ctx
->NewState
|= _NEW_TEXTURE
;
2239 else if (target
== GL_PROXY_TEXTURE_1D
) {
2240 /* Proxy texture: check for errors and update proxy state */
2241 struct gl_texture_image
*texImage
;
2242 texImage
= _mesa_get_proxy_tex_image(ctx
, target
, level
);
2243 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2244 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
2245 /* when error, clear all proxy texture image parameters */
2247 clear_teximage_fields(texImage
);
2250 /* no error, set the tex image parameters */
2252 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2253 postConvWidth
, 1, 1,
2254 border
, internalFormat
);
2255 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
2256 internalFormat
, format
, type
);
2260 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
2267 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
2268 GLsizei width
, GLsizei height
, GLint border
,
2269 GLenum format
, GLenum type
,
2270 const GLvoid
*pixels
)
2272 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2273 GET_CURRENT_CONTEXT(ctx
);
2274 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2276 if (is_color_format(internalFormat
)) {
2277 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
2281 if (target
== GL_TEXTURE_2D
||
2282 (ctx
->Extensions
.ARB_texture_cube_map
&&
2283 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2284 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) ||
2285 (ctx
->Extensions
.NV_texture_rectangle
&&
2286 target
== GL_TEXTURE_RECTANGLE_NV
)) {
2287 /* non-proxy target */
2288 struct gl_texture_unit
*texUnit
;
2289 struct gl_texture_object
*texObj
;
2290 struct gl_texture_image
*texImage
;
2291 const GLuint face
= texture_face(target
);
2293 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2294 format
, type
, 2, postConvWidth
, postConvHeight
,
2296 return; /* error was recorded */
2299 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2300 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2301 texImage
= _mesa_get_tex_image(ctx
, texUnit
, target
, level
);
2303 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
2306 else if (texImage
->Data
) {
2307 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
2309 ASSERT(texImage
->Data
== NULL
);
2310 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2311 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2312 postConvWidth
, postConvHeight
, 1,
2313 border
, internalFormat
);
2315 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2316 _mesa_update_state(ctx
);
2318 ASSERT(ctx
->Driver
.TexImage2D
);
2320 /* Give the texture to the driver! <pixels> may be null! */
2321 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
2322 width
, height
, border
, format
, type
, pixels
,
2323 &ctx
->Unpack
, texObj
, texImage
);
2325 ASSERT(texImage
->TexFormat
);
2327 update_fbo_texture(ctx
, texObj
, face
, level
);
2330 texObj
->Complete
= GL_FALSE
;
2331 ctx
->NewState
|= _NEW_TEXTURE
;
2333 else if (target
== GL_PROXY_TEXTURE_2D
||
2334 (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
&&
2335 ctx
->Extensions
.ARB_texture_cube_map
) ||
2336 (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
&&
2337 ctx
->Extensions
.NV_texture_rectangle
)) {
2338 /* Proxy texture: check for errors and update proxy state */
2339 struct gl_texture_image
*texImage
;
2340 texImage
= _mesa_get_proxy_tex_image(ctx
, target
, level
);
2341 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2342 format
, type
, 2, postConvWidth
, postConvHeight
,
2344 /* when error, clear all proxy texture image parameters */
2346 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[0][level
]);
2349 /* no error, set the tex image parameters */
2350 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2351 postConvWidth
, postConvHeight
, 1,
2352 border
, internalFormat
);
2353 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
2354 internalFormat
, format
, type
);
2358 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
2365 * Called by the API or display list executor.
2366 * Note that width and height include the border.
2369 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
2370 GLsizei width
, GLsizei height
, GLsizei depth
,
2371 GLint border
, GLenum format
, GLenum type
,
2372 const GLvoid
*pixels
)
2374 GET_CURRENT_CONTEXT(ctx
);
2375 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2377 if (target
== GL_TEXTURE_3D
) {
2378 /* non-proxy target */
2379 struct gl_texture_unit
*texUnit
;
2380 struct gl_texture_object
*texObj
;
2381 struct gl_texture_image
*texImage
;
2382 const GLuint face
= texture_face(target
);
2384 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
2385 format
, type
, 3, width
, height
, depth
, border
)) {
2386 return; /* error was recorded */
2389 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2390 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2391 texImage
= _mesa_get_tex_image(ctx
, texUnit
, target
, level
);
2393 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
2396 else if (texImage
->Data
) {
2397 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
2399 ASSERT(texImage
->Data
== NULL
);
2400 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2401 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2402 width
, height
, depth
,
2403 border
, internalFormat
);
2405 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2406 _mesa_update_state(ctx
);
2408 ASSERT(ctx
->Driver
.TexImage3D
);
2410 /* Give the texture to the driver! <pixels> may be null! */
2411 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
2412 width
, height
, depth
, border
, format
, type
,
2413 pixels
, &ctx
->Unpack
, texObj
, texImage
);
2415 ASSERT(texImage
->TexFormat
);
2417 update_fbo_texture(ctx
, texObj
, face
, level
);
2420 texObj
->Complete
= GL_FALSE
;
2421 ctx
->NewState
|= _NEW_TEXTURE
;
2423 else if (target
== GL_PROXY_TEXTURE_3D
) {
2424 /* Proxy texture: check for errors and update proxy state */
2425 struct gl_texture_image
*texImage
;
2426 texImage
= _mesa_get_proxy_tex_image(ctx
, target
, level
);
2427 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2428 format
, type
, 3, width
, height
, depth
, border
)) {
2429 /* when error, clear all proxy texture image parameters */
2431 clear_teximage_fields(texImage
);
2434 /* no error, set the tex image parameters */
2435 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2436 border
, internalFormat
);
2437 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
2438 internalFormat
, format
, type
);
2442 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
2449 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
2450 GLsizei width
, GLsizei height
, GLsizei depth
,
2451 GLint border
, GLenum format
, GLenum type
,
2452 const GLvoid
*pixels
)
2454 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
2455 depth
, border
, format
, type
, pixels
);
2461 _mesa_TexSubImage1D( GLenum target
, GLint level
,
2462 GLint xoffset
, GLsizei width
,
2463 GLenum format
, GLenum type
,
2464 const GLvoid
*pixels
)
2466 GLsizei postConvWidth
= width
;
2467 struct gl_texture_unit
*texUnit
;
2468 struct gl_texture_object
*texObj
;
2469 struct gl_texture_image
*texImage
;
2470 GET_CURRENT_CONTEXT(ctx
);
2471 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2473 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2474 _mesa_update_state(ctx
);
2476 /* XXX should test internal format */
2477 if (is_color_format(format
)) {
2478 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2481 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2482 postConvWidth
, 1, 1, format
, type
)) {
2483 return; /* error was detected */
2486 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2487 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2488 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2492 return; /* no-op, not an error */
2494 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2495 xoffset
+= texImage
->Border
;
2497 ASSERT(ctx
->Driver
.TexSubImage1D
);
2498 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
2499 format
, type
, pixels
, &ctx
->Unpack
,
2501 ctx
->NewState
|= _NEW_TEXTURE
;
2506 _mesa_TexSubImage2D( GLenum target
, GLint level
,
2507 GLint xoffset
, GLint yoffset
,
2508 GLsizei width
, GLsizei height
,
2509 GLenum format
, GLenum type
,
2510 const GLvoid
*pixels
)
2512 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2513 struct gl_texture_unit
*texUnit
;
2514 struct gl_texture_object
*texObj
;
2515 struct gl_texture_image
*texImage
;
2516 GET_CURRENT_CONTEXT(ctx
);
2517 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2519 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2520 _mesa_update_state(ctx
);
2522 /* XXX should test internal format */
2523 if (is_color_format(format
)) {
2524 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
2528 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2529 postConvWidth
, postConvHeight
, 1, format
, type
)) {
2530 return; /* error was detected */
2533 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2534 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2535 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2538 if (width
== 0 || height
== 0)
2539 return; /* no-op, not an error */
2541 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2542 xoffset
+= texImage
->Border
;
2543 yoffset
+= texImage
->Border
;
2545 ASSERT(ctx
->Driver
.TexSubImage2D
);
2546 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
2547 width
, height
, format
, type
, pixels
,
2548 &ctx
->Unpack
, texObj
, texImage
);
2549 ctx
->NewState
|= _NEW_TEXTURE
;
2555 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2556 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2557 GLsizei width
, GLsizei height
, GLsizei depth
,
2558 GLenum format
, GLenum type
,
2559 const GLvoid
*pixels
)
2561 struct gl_texture_unit
*texUnit
;
2562 struct gl_texture_object
*texObj
;
2563 struct gl_texture_image
*texImage
;
2564 GET_CURRENT_CONTEXT(ctx
);
2565 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2567 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2568 _mesa_update_state(ctx
);
2570 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2571 width
, height
, depth
, format
, type
)) {
2572 return; /* error was detected */
2575 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2576 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2577 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2580 if (width
== 0 || height
== 0 || height
== 0)
2581 return; /* no-op, not an error */
2583 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2584 xoffset
+= texImage
->Border
;
2585 yoffset
+= texImage
->Border
;
2586 zoffset
+= texImage
->Border
;
2588 ASSERT(ctx
->Driver
.TexSubImage3D
);
2589 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
2590 xoffset
, yoffset
, zoffset
,
2591 width
, height
, depth
,
2592 format
, type
, pixels
,
2593 &ctx
->Unpack
, texObj
, texImage
);
2594 ctx
->NewState
|= _NEW_TEXTURE
;
2600 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2601 GLenum internalFormat
,
2603 GLsizei width
, GLint border
)
2605 struct gl_texture_unit
*texUnit
;
2606 struct gl_texture_object
*texObj
;
2607 struct gl_texture_image
*texImage
;
2608 GLsizei postConvWidth
= width
;
2609 const GLuint face
= texture_face(target
);
2610 GET_CURRENT_CONTEXT(ctx
);
2611 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2613 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2614 _mesa_update_state(ctx
);
2616 if (is_color_format(internalFormat
)) {
2617 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2620 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2621 postConvWidth
, 1, border
))
2624 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2625 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2626 texImage
= _mesa_get_tex_image(ctx
, texUnit
, target
, level
);
2628 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
2631 else if (texImage
->Data
) {
2632 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
2634 ASSERT(texImage
->Data
== NULL
);
2636 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2637 _mesa_init_teximage_fields(ctx
, target
, texImage
, postConvWidth
, 1, 1,
2638 border
, internalFormat
);
2641 ASSERT(ctx
->Driver
.CopyTexImage1D
);
2642 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
2643 x
, y
, width
, border
);
2645 ASSERT(texImage
->TexFormat
);
2647 update_fbo_texture(ctx
, texObj
, face
, level
);
2650 texObj
->Complete
= GL_FALSE
;
2651 ctx
->NewState
|= _NEW_TEXTURE
;
2657 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2658 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2661 struct gl_texture_unit
*texUnit
;
2662 struct gl_texture_object
*texObj
;
2663 struct gl_texture_image
*texImage
;
2664 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2665 const GLuint face
= texture_face(target
);
2666 GET_CURRENT_CONTEXT(ctx
);
2667 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2669 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2670 _mesa_update_state(ctx
);
2672 if (is_color_format(internalFormat
)) {
2673 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
2677 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2678 postConvWidth
, postConvHeight
, border
))
2681 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2682 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2683 texImage
= _mesa_get_tex_image(ctx
, texUnit
, target
, level
);
2685 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
2688 else if (texImage
->Data
) {
2689 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
2691 ASSERT(texImage
->Data
== NULL
);
2693 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2694 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2695 postConvWidth
, postConvHeight
, 1,
2696 border
, internalFormat
);
2698 ASSERT(ctx
->Driver
.CopyTexImage2D
);
2699 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
2700 x
, y
, width
, height
, border
);
2702 ASSERT(texImage
->TexFormat
);
2704 update_fbo_texture(ctx
, texObj
, face
, level
);
2707 texObj
->Complete
= GL_FALSE
;
2708 ctx
->NewState
|= _NEW_TEXTURE
;
2714 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2715 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2717 struct gl_texture_unit
*texUnit
;
2718 struct gl_texture_image
*texImage
;
2719 GLsizei postConvWidth
= width
;
2720 GET_CURRENT_CONTEXT(ctx
);
2721 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2723 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2724 _mesa_update_state(ctx
);
2726 /* XXX should test internal format */
2727 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2729 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2730 xoffset
, 0, 0, postConvWidth
, 1))
2733 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2734 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2737 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2738 xoffset
+= texImage
->Border
;
2740 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
2741 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
2742 ctx
->NewState
|= _NEW_TEXTURE
;
2748 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2749 GLint xoffset
, GLint yoffset
,
2750 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2752 struct gl_texture_unit
*texUnit
;
2753 struct gl_texture_image
*texImage
;
2754 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2755 GET_CURRENT_CONTEXT(ctx
);
2756 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2758 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2759 _mesa_update_state(ctx
);
2761 /* XXX should test internal format */
2762 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2764 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2765 postConvWidth
, postConvHeight
))
2768 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2769 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2772 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2773 xoffset
+= texImage
->Border
;
2774 yoffset
+= texImage
->Border
;
2776 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
2777 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2778 xoffset
, yoffset
, x
, y
, width
, height
);
2779 ctx
->NewState
|= _NEW_TEXTURE
;
2785 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2786 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2787 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2789 struct gl_texture_unit
*texUnit
;
2790 struct gl_texture_image
*texImage
;
2791 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2792 GET_CURRENT_CONTEXT(ctx
);
2793 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2795 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2796 _mesa_update_state(ctx
);
2798 /* XXX should test internal format */
2799 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2801 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
2802 zoffset
, postConvWidth
, postConvHeight
))
2805 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2806 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2809 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2810 xoffset
+= texImage
->Border
;
2811 yoffset
+= texImage
->Border
;
2812 zoffset
+= texImage
->Border
;
2814 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
2815 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2816 xoffset
, yoffset
, zoffset
,
2817 x
, y
, width
, height
);
2818 ctx
->NewState
|= _NEW_TEXTURE
;
2824 /**********************************************************************/
2825 /****** Compressed Textures ******/
2826 /**********************************************************************/
2830 * Error checking for glCompressedTexImage[123]D().
2831 * \return error code or GL_NO_ERROR.
2834 compressed_texture_error_check(GLcontext
*ctx
, GLint dimensions
,
2835 GLenum target
, GLint level
,
2836 GLenum internalFormat
, GLsizei width
,
2837 GLsizei height
, GLsizei depth
, GLint border
,
2840 GLint expectedSize
, maxLevels
= 0, maxTextureSize
;
2842 if (dimensions
== 1) {
2843 /* 1D compressed textures not allowed */
2844 return GL_INVALID_ENUM
;
2846 else if (dimensions
== 2) {
2847 if (target
== GL_PROXY_TEXTURE_2D
) {
2848 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2850 else if (target
== GL_TEXTURE_2D
) {
2851 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2853 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
2854 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2855 return GL_INVALID_ENUM
; /*target*/
2856 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2858 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2859 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
2860 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2861 return GL_INVALID_ENUM
; /*target*/
2862 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2865 return GL_INVALID_ENUM
; /*target*/
2868 else if (dimensions
== 3) {
2869 /* 3D compressed textures not allowed */
2870 return GL_INVALID_ENUM
;
2873 maxTextureSize
= 1 << (maxLevels
- 1);
2875 /* This will detect any invalid internalFormat value */
2876 if (!is_compressed_format(ctx
, internalFormat
))
2877 return GL_INVALID_ENUM
;
2879 /* This should really never fail */
2880 if (_mesa_base_tex_format(ctx
, internalFormat
) < 0)
2881 return GL_INVALID_ENUM
;
2884 return GL_INVALID_VALUE
;
2887 * XXX We should probably use the proxy texture error check function here.
2889 if (width
< 1 || width
> maxTextureSize
||
2890 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&& _mesa_bitcount(width
) != 1))
2891 return GL_INVALID_VALUE
;
2893 if ((height
< 1 || height
> maxTextureSize
||
2894 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&& _mesa_bitcount(height
) != 1))
2896 return GL_INVALID_VALUE
;
2898 if ((depth
< 1 || depth
> maxTextureSize
||
2899 (!ctx
->Extensions
.ARB_texture_non_power_of_two
&& _mesa_bitcount(depth
) != 1))
2901 return GL_INVALID_VALUE
;
2903 /* For cube map, width must equal height */
2904 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2905 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
&& width
!= height
)
2906 return GL_INVALID_VALUE
;
2908 if (level
< 0 || level
>= maxLevels
)
2909 return GL_INVALID_VALUE
;
2911 expectedSize
= _mesa_compressed_texture_size_glenum(ctx
, width
, height
,
2912 depth
, internalFormat
);
2913 if (expectedSize
!= imageSize
)
2914 return GL_INVALID_VALUE
;
2921 * Error checking for glCompressedTexSubImage[123]D().
2922 * \warning There are some bad assumptions here about the size of compressed
2923 * texture tiles (multiple of 4) used to test the validity of the
2924 * offset and size parameters.
2925 * \return error code or GL_NO_ERROR.
2928 compressed_subtexture_error_check(GLcontext
*ctx
, GLint dimensions
,
2929 GLenum target
, GLint level
,
2930 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2931 GLsizei width
, GLsizei height
, GLsizei depth
,
2932 GLenum format
, GLsizei imageSize
)
2934 GLint expectedSize
, maxLevels
= 0, maxTextureSize
;
2937 if (dimensions
== 1) {
2938 /* 1D compressed textures not allowed */
2939 return GL_INVALID_ENUM
;
2941 else if (dimensions
== 2) {
2942 if (target
== GL_PROXY_TEXTURE_2D
) {
2943 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2945 else if (target
== GL_TEXTURE_2D
) {
2946 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2948 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
2949 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2950 return GL_INVALID_ENUM
; /*target*/
2951 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2953 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2954 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
2955 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2956 return GL_INVALID_ENUM
; /*target*/
2957 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2960 return GL_INVALID_ENUM
; /*target*/
2963 else if (dimensions
== 3) {
2964 /* 3D compressed textures not allowed */
2965 return GL_INVALID_ENUM
;
2968 maxTextureSize
= 1 << (maxLevels
- 1);
2970 /* this will catch any invalid compressed format token */
2971 if (!is_compressed_format(ctx
, format
))
2972 return GL_INVALID_ENUM
;
2974 if (width
< 1 || width
> maxTextureSize
)
2975 return GL_INVALID_VALUE
;
2977 if ((height
< 1 || height
> maxTextureSize
)
2979 return GL_INVALID_VALUE
;
2981 if (level
< 0 || level
>= maxLevels
)
2982 return GL_INVALID_VALUE
;
2984 /* XXX these tests are specific to the compressed format.
2985 * this code should be generalized in some way.
2987 if ((xoffset
& 3) != 0 || (yoffset
& 3) != 0)
2988 return GL_INVALID_VALUE
;
2990 if ((width
& 3) != 0 && width
!= 2 && width
!= 1)
2991 return GL_INVALID_VALUE
;
2993 if ((height
& 3) != 0 && height
!= 2 && height
!= 1)
2994 return GL_INVALID_VALUE
;
2996 expectedSize
= _mesa_compressed_texture_size_glenum(ctx
, width
, height
,
2998 if (expectedSize
!= imageSize
)
2999 return GL_INVALID_VALUE
;
3007 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
3008 GLenum internalFormat
, GLsizei width
,
3009 GLint border
, GLsizei imageSize
,
3012 GET_CURRENT_CONTEXT(ctx
);
3013 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3015 if (target
== GL_TEXTURE_1D
) {
3016 /* non-proxy target */
3017 struct gl_texture_unit
*texUnit
;
3018 struct gl_texture_object
*texObj
;
3019 struct gl_texture_image
*texImage
;
3020 GLenum error
= compressed_texture_error_check(ctx
, 1, target
, level
,
3021 internalFormat
, width
, 1, 1, border
, imageSize
);
3023 _mesa_error(ctx
, error
, "glCompressedTexImage1D");
3027 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3028 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3029 texImage
= _mesa_get_tex_image(ctx
, texUnit
, target
, level
);
3031 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1D");
3034 else if (texImage
->Data
) {
3035 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
3037 ASSERT(texImage
->Data
== NULL
);
3039 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
3040 border
, internalFormat
);
3042 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
3043 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
3044 internalFormat
, width
, border
,
3049 texObj
->Complete
= GL_FALSE
;
3050 ctx
->NewState
|= _NEW_TEXTURE
;
3052 else if (target
== GL_PROXY_TEXTURE_1D
) {
3053 /* Proxy texture: check for errors and update proxy state */
3054 GLenum error
= compressed_texture_error_check(ctx
, 1, target
, level
,
3055 internalFormat
, width
, 1, 1, border
, imageSize
);
3057 ASSERT(ctx
->Driver
.TestProxyTexImage
);
3058 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3059 internalFormat
, GL_NONE
, GL_NONE
,
3060 width
, 1, 1, border
);
3063 /* if error, clear all proxy texture image parameters */
3064 struct gl_texture_image
*texImage
;
3065 texImage
= _mesa_get_proxy_tex_image(ctx
, target
, level
);
3067 clear_teximage_fields(texImage
);
3070 /* store the teximage parameters */
3071 struct gl_texture_unit
*texUnit
;
3072 struct gl_texture_image
*texImage
;
3073 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3074 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
3075 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
3076 border
, internalFormat
);
3080 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1D(target)");
3087 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
3088 GLenum internalFormat
, GLsizei width
,
3089 GLsizei height
, GLint border
, GLsizei imageSize
,
3092 GET_CURRENT_CONTEXT(ctx
);
3093 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3095 if (target
== GL_TEXTURE_2D
||
3096 (ctx
->Extensions
.ARB_texture_cube_map
&&
3097 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
3098 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3099 /* non-proxy target */
3100 struct gl_texture_unit
*texUnit
;
3101 struct gl_texture_object
*texObj
;
3102 struct gl_texture_image
*texImage
;
3103 GLenum error
= compressed_texture_error_check(ctx
, 2, target
, level
,
3104 internalFormat
, width
, height
, 1, border
, imageSize
);
3106 _mesa_error(ctx
, error
, "glCompressedTexImage2D");
3110 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3111 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3112 texImage
= _mesa_get_tex_image(ctx
, texUnit
, target
, level
);
3114 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
3117 else if (texImage
->Data
) {
3118 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
3120 ASSERT(texImage
->Data
== NULL
);
3122 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
3123 border
, internalFormat
);
3125 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
3126 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
3127 internalFormat
, width
, height
,
3128 border
, imageSize
, data
,
3132 texObj
->Complete
= GL_FALSE
;
3133 ctx
->NewState
|= _NEW_TEXTURE
;
3135 else if (target
== GL_PROXY_TEXTURE_2D
||
3136 (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
&&
3137 ctx
->Extensions
.ARB_texture_cube_map
)) {
3138 /* Proxy texture: check for errors and update proxy state */
3139 GLenum error
= compressed_texture_error_check(ctx
, 2, target
, level
,
3140 internalFormat
, width
, height
, 1, border
, imageSize
);
3142 ASSERT(ctx
->Driver
.TestProxyTexImage
);
3143 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3144 internalFormat
, GL_NONE
, GL_NONE
,
3145 width
, height
, 1, border
);
3148 /* if error, clear all proxy texture image parameters */
3149 struct gl_texture_image
*texImage
;
3150 texImage
= _mesa_get_proxy_tex_image(ctx
, target
, level
);
3152 clear_teximage_fields(texImage
);
3155 /* store the teximage parameters */
3156 struct gl_texture_unit
*texUnit
;
3157 struct gl_texture_image
*texImage
;
3158 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3159 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
3160 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
3161 border
, internalFormat
);
3165 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2D(target)");
3172 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
3173 GLenum internalFormat
, GLsizei width
,
3174 GLsizei height
, GLsizei depth
, GLint border
,
3175 GLsizei imageSize
, const GLvoid
*data
)
3177 GET_CURRENT_CONTEXT(ctx
);
3178 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3180 if (target
== GL_TEXTURE_3D
) {
3181 /* non-proxy target */
3182 struct gl_texture_unit
*texUnit
;
3183 struct gl_texture_object
*texObj
;
3184 struct gl_texture_image
*texImage
;
3185 GLenum error
= compressed_texture_error_check(ctx
, 3, target
, level
,
3186 internalFormat
, width
, height
, depth
, border
, imageSize
);
3188 _mesa_error(ctx
, error
, "glCompressedTexImage3D");
3192 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3193 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3194 texImage
= _mesa_get_tex_image(ctx
, texUnit
, target
, level
);
3196 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3D");
3199 else if (texImage
->Data
) {
3200 ctx
->Driver
.FreeTexImageData( ctx
, texImage
);
3202 ASSERT(texImage
->Data
== NULL
);
3204 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, depth
,
3205 border
, internalFormat
);
3207 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
3208 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
3210 width
, height
, depth
,
3211 border
, imageSize
, data
,
3215 texObj
->Complete
= GL_FALSE
;
3216 ctx
->NewState
|= _NEW_TEXTURE
;
3218 else if (target
== GL_PROXY_TEXTURE_3D
) {
3219 /* Proxy texture: check for errors and update proxy state */
3220 GLenum error
= compressed_texture_error_check(ctx
, 3, target
, level
,
3221 internalFormat
, width
, height
, depth
, border
, imageSize
);
3223 ASSERT(ctx
->Driver
.TestProxyTexImage
);
3224 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3225 internalFormat
, GL_NONE
, GL_NONE
,
3226 width
, height
, depth
, border
);
3229 /* if error, clear all proxy texture image parameters */
3230 struct gl_texture_image
*texImage
;
3231 texImage
= _mesa_get_proxy_tex_image(ctx
, target
, level
);
3233 clear_teximage_fields(texImage
);
3236 /* store the teximage parameters */
3237 struct gl_texture_unit
*texUnit
;
3238 struct gl_texture_image
*texImage
;
3239 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3240 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
3241 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
,
3242 depth
, border
, internalFormat
);
3246 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3D(target)");
3253 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
3254 GLsizei width
, GLenum format
,
3255 GLsizei imageSize
, const GLvoid
*data
)
3257 struct gl_texture_unit
*texUnit
;
3258 struct gl_texture_object
*texObj
;
3259 struct gl_texture_image
*texImage
;
3261 GET_CURRENT_CONTEXT(ctx
);
3262 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3264 error
= compressed_subtexture_error_check(ctx
, 1, target
, level
,
3265 xoffset
, 0, 0, /* pos */
3266 width
, 1, 1, /* size */
3269 _mesa_error(ctx
, error
, "glCompressedTexSubImage1D");
3273 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3274 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3275 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
3278 if ((GLint
) format
!= texImage
->InternalFormat
) {
3279 _mesa_error(ctx
, GL_INVALID_OPERATION
,
3280 "glCompressedTexSubImage1D(format)");
3284 if ((width
== 1 || width
== 2) && (GLuint
) width
!= texImage
->Width
) {
3285 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage1D(width)");
3290 return; /* no-op, not an error */
3292 if (ctx
->Driver
.CompressedTexSubImage1D
) {
3293 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
3295 format
, imageSize
, data
,
3298 ctx
->NewState
|= _NEW_TEXTURE
;
3303 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
3304 GLint yoffset
, GLsizei width
, GLsizei height
,
3305 GLenum format
, GLsizei imageSize
,
3308 struct gl_texture_unit
*texUnit
;
3309 struct gl_texture_object
*texObj
;
3310 struct gl_texture_image
*texImage
;
3312 GET_CURRENT_CONTEXT(ctx
);
3313 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3315 error
= compressed_subtexture_error_check(ctx
, 2, target
, level
,
3316 xoffset
, yoffset
, 0, /* pos */
3317 width
, height
, 1, /* size */
3320 /* XXX proxy target? */
3321 _mesa_error(ctx
, error
, "glCompressedTexSubImage2D");
3325 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3326 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3327 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
3330 if ((GLint
) format
!= texImage
->InternalFormat
) {
3331 _mesa_error(ctx
, GL_INVALID_OPERATION
,
3332 "glCompressedTexSubImage2D(format)");
3336 if (((width
== 1 || width
== 2) && (GLuint
) width
!= texImage
->Width
) ||
3337 ((height
== 1 || height
== 2) && (GLuint
) height
!= texImage
->Height
)) {
3338 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage2D(size)");
3342 if (width
== 0 || height
== 0)
3343 return; /* no-op, not an error */
3345 if (ctx
->Driver
.CompressedTexSubImage2D
) {
3346 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
3347 xoffset
, yoffset
, width
, height
,
3348 format
, imageSize
, data
,
3351 ctx
->NewState
|= _NEW_TEXTURE
;
3356 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
3357 GLint yoffset
, GLint zoffset
, GLsizei width
,
3358 GLsizei height
, GLsizei depth
, GLenum format
,
3359 GLsizei imageSize
, const GLvoid
*data
)
3361 struct gl_texture_unit
*texUnit
;
3362 struct gl_texture_object
*texObj
;
3363 struct gl_texture_image
*texImage
;
3365 GET_CURRENT_CONTEXT(ctx
);
3366 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3368 error
= compressed_subtexture_error_check(ctx
, 3, target
, level
,
3369 xoffset
, yoffset
, zoffset
,/*pos*/
3370 width
, height
, depth
, /*size*/
3373 _mesa_error(ctx
, error
, "glCompressedTexSubImage2D");
3377 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3378 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3379 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
3382 if ((GLint
) format
!= texImage
->InternalFormat
) {
3383 _mesa_error(ctx
, GL_INVALID_OPERATION
,
3384 "glCompressedTexSubImage3D(format)");
3388 if (((width
== 1 || width
== 2) && (GLuint
) width
!= texImage
->Width
) ||
3389 ((height
== 1 || height
== 2) && (GLuint
) height
!= texImage
->Height
) ||
3390 ((depth
== 1 || depth
== 2) && (GLuint
) depth
!= texImage
->Depth
)) {
3391 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage3D(size)");
3395 if (width
== 0 || height
== 0 || depth
== 0)
3396 return; /* no-op, not an error */
3398 if (ctx
->Driver
.CompressedTexSubImage3D
) {
3399 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
3400 xoffset
, yoffset
, zoffset
,
3401 width
, height
, depth
,
3402 format
, imageSize
, data
,
3405 ctx
->NewState
|= _NEW_TEXTURE
;
3410 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
3412 const struct gl_texture_unit
*texUnit
;
3413 const struct gl_texture_object
*texObj
;
3414 struct gl_texture_image
*texImage
;
3416 GET_CURRENT_CONTEXT(ctx
);
3417 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3419 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3420 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3422 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB");
3426 maxLevels
= _mesa_max_texture_levels(ctx
, target
);
3427 ASSERT(maxLevels
> 0); /* 0 indicates bad target, caught above */
3429 if (level
< 0 || level
>= maxLevels
) {
3430 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
3434 if (_mesa_is_proxy_texture(target
)) {
3435 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
3439 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
3441 /* probably invalid mipmap level */
3442 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
3446 if (!texImage
->IsCompressed
) {
3447 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
3451 /* this typically calls _mesa_get_compressed_teximage() */
3452 ctx
->Driver
.GetCompressedTexImage(ctx
, target
, level
, img
, texObj
,texImage
);