1 /* $Id: teximage.c,v 1.79 2001/02/26 18:24:55 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 #include "swrast/s_span.h" /* XXX SWRAST hack */
49 * Mesa's native texture datatype is GLchan. Native formats are
50 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
52 * Device drivers are free to implement any internal format they want.
57 static void PrintTexture(const struct gl_texture_image
*img
)
60 GLchan
*data
= img
->Data
;
63 printf("No texture data\n");
67 switch (img
->Format
) {
74 case GL_LUMINANCE_ALPHA
:
84 gl_problem(NULL
, "error in PrintTexture\n");
89 for (i
= 0; i
< img
->Height
; i
++) {
90 for (j
= 0; j
< img
->Width
; j
++) {
92 printf("%02x ", data
[0]);
94 printf("%02x%02x ", data
[0], data
[1]);
96 printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
98 printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
109 * Compute log base 2 of n.
110 * If n isn't an exact power of two return -1.
138 * Given an internal texture format enum or 1, 2, 3, 4 return the
139 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
140 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
141 * Return -1 if invalid enum.
144 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
147 * Ask the driver for the base format, if it doesn't
148 * know, it will return -1;
150 if (ctx
->Driver
.BaseCompressedTexFormat
) {
151 GLint ifmt
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, format
);
171 case GL_LUMINANCE_ALPHA
:
172 case GL_LUMINANCE4_ALPHA4
:
173 case GL_LUMINANCE6_ALPHA2
:
174 case GL_LUMINANCE8_ALPHA8
:
175 case GL_LUMINANCE12_ALPHA4
:
176 case GL_LUMINANCE12_ALPHA12
:
177 case GL_LUMINANCE16_ALPHA16
:
178 return GL_LUMINANCE_ALPHA
;
206 case GL_COLOR_INDEX1_EXT
:
207 case GL_COLOR_INDEX2_EXT
:
208 case GL_COLOR_INDEX4_EXT
:
209 case GL_COLOR_INDEX8_EXT
:
210 case GL_COLOR_INDEX12_EXT
:
211 case GL_COLOR_INDEX16_EXT
:
212 return GL_COLOR_INDEX
;
213 case GL_DEPTH_COMPONENT
:
214 case GL_DEPTH_COMPONENT16_SGIX
:
215 case GL_DEPTH_COMPONENT24_SGIX
:
216 case GL_DEPTH_COMPONENT32_SGIX
:
217 if (ctx
->Extensions
.SGIX_depth_texture
)
218 return GL_DEPTH_COMPONENT
;
222 return -1; /* error */
228 * Test if the given image format is a color/rgba format. That is,
229 * not color index, depth, stencil, etc.
232 is_color_format(GLenum format
)
247 case GL_LUMINANCE_ALPHA
:
248 case GL_LUMINANCE4_ALPHA4
:
249 case GL_LUMINANCE6_ALPHA2
:
250 case GL_LUMINANCE8_ALPHA8
:
251 case GL_LUMINANCE12_ALPHA4
:
252 case GL_LUMINANCE12_ALPHA12
:
253 case GL_LUMINANCE16_ALPHA16
:
285 is_index_format(GLenum format
)
289 case GL_COLOR_INDEX1_EXT
:
290 case GL_COLOR_INDEX2_EXT
:
291 case GL_COLOR_INDEX4_EXT
:
292 case GL_COLOR_INDEX8_EXT
:
293 case GL_COLOR_INDEX12_EXT
:
294 case GL_COLOR_INDEX16_EXT
:
303 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
307 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
309 if (ctx
->Driver
.IsCompressedFormat
) {
310 return (*ctx
->Driver
.IsCompressedFormat
)(ctx
, internalFormat
);
318 * Store a gl_texture_image pointer in a gl_texture_object structure
319 * according to the target and level parameters.
320 * This was basically prompted by the introduction of cube maps.
323 set_tex_image(struct gl_texture_object
*tObj
,
324 GLenum target
, GLint level
,
325 struct gl_texture_image
*texImage
)
331 tObj
->Image
[level
] = texImage
;
333 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
334 tObj
->Image
[level
] = texImage
;
336 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
337 tObj
->NegX
[level
] = texImage
;
339 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
340 tObj
->PosY
[level
] = texImage
;
342 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
343 tObj
->NegY
[level
] = texImage
;
345 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
346 tObj
->PosZ
[level
] = texImage
;
348 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
349 tObj
->NegZ
[level
] = texImage
;
352 gl_problem(NULL
, "bad target in set_tex_image()");
360 * Return new gl_texture_image struct with all fields initialized to zero.
362 struct gl_texture_image
*
363 _mesa_alloc_texture_image( void )
365 return CALLOC_STRUCT(gl_texture_image
);
371 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
373 if (teximage
->Data
) {
374 FREE( teximage
->Data
);
375 teximage
->Data
= NULL
;
382 * Return GL_TRUE if the target is a proxy target.
385 is_proxy_target(GLenum target
)
387 return (target
== GL_PROXY_TEXTURE_1D
||
388 target
== GL_PROXY_TEXTURE_2D
||
389 target
== GL_PROXY_TEXTURE_3D
||
390 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
395 * Given a texture unit and a texture target, return the corresponding
398 struct gl_texture_object
*
399 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
404 return texUnit
->Current1D
;
405 case GL_PROXY_TEXTURE_1D
:
406 return ctx
->Texture
.Proxy1D
;
408 return texUnit
->Current2D
;
409 case GL_PROXY_TEXTURE_2D
:
410 return ctx
->Texture
.Proxy2D
;
412 return texUnit
->Current3D
;
413 case GL_PROXY_TEXTURE_3D
:
414 return ctx
->Texture
.Proxy3D
;
415 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
416 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
417 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
418 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
419 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
420 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
421 return ctx
->Extensions
.ARB_texture_cube_map
422 ? texUnit
->CurrentCubeMap
: NULL
;
423 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
424 return ctx
->Extensions
.ARB_texture_cube_map
425 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
427 gl_problem(NULL
, "bad target in _mesa_select_tex_object()");
434 * Return the texture image struct which corresponds to target and level
435 * for the given texture unit.
437 struct gl_texture_image
*
438 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
439 GLenum target
, GLint level
)
444 return texUnit
->Current1D
->Image
[level
];
445 case GL_PROXY_TEXTURE_1D
:
446 return ctx
->Texture
.Proxy1D
->Image
[level
];
448 return texUnit
->Current2D
->Image
[level
];
449 case GL_PROXY_TEXTURE_2D
:
450 return ctx
->Texture
.Proxy2D
->Image
[level
];
452 return texUnit
->Current3D
->Image
[level
];
453 case GL_PROXY_TEXTURE_3D
:
454 return ctx
->Texture
.Proxy3D
->Image
[level
];
455 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
456 if (ctx
->Extensions
.ARB_texture_cube_map
)
457 return texUnit
->CurrentCubeMap
->Image
[level
];
460 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
461 if (ctx
->Extensions
.ARB_texture_cube_map
)
462 return texUnit
->CurrentCubeMap
->NegX
[level
];
465 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
466 if (ctx
->Extensions
.ARB_texture_cube_map
)
467 return texUnit
->CurrentCubeMap
->PosY
[level
];
470 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
471 if (ctx
->Extensions
.ARB_texture_cube_map
)
472 return texUnit
->CurrentCubeMap
->NegY
[level
];
475 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
476 if (ctx
->Extensions
.ARB_texture_cube_map
)
477 return texUnit
->CurrentCubeMap
->PosZ
[level
];
480 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
481 if (ctx
->Extensions
.ARB_texture_cube_map
)
482 return texUnit
->CurrentCubeMap
->NegZ
[level
];
485 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
486 if (ctx
->Extensions
.ARB_texture_cube_map
)
487 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
491 gl_problem(ctx
, "bad target in _mesa_select_tex_image()");
499 * glTexImage[123]D can accept a NULL image pointer. In this case we
500 * create a texture image with unspecified image contents per the OpenGL
504 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
506 const GLint components
= _mesa_components_in_format(format
);
507 const GLint numPixels
= width
* height
* depth
;
508 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
511 * Let's see if anyone finds this. If glTexImage2D() is called with
512 * a NULL image pointer then load the texture image with something
513 * interesting instead of leaving it indeterminate.
516 static const char message
[8][32] = {
520 " X X XXXX XXX XXXXX ",
523 " X X XXXXX XXX X X ",
527 GLubyte
*imgPtr
= data
;
529 for (h
= 0; h
< depth
; h
++) {
530 for (i
= 0; i
< height
; i
++) {
531 GLint srcRow
= 7 - (i
% 8);
532 for (j
= 0; j
< width
; j
++) {
533 GLint srcCol
= j
% 32;
534 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
535 for (k
= 0; k
< components
; k
++) {
549 * Reset the fields of a gl_texture_image struct to zero.
550 * This is called when a proxy texture test fails, we set all the
551 * image members (except DriverData) to zero.
552 * It's also used in glTexImage[123]D as a safeguard to be sure all
553 * required fields get initialized properly by the Driver.TexImage[123]D
557 clear_teximage_fields(struct gl_texture_image
*img
)
567 img
->IntensityBits
= 0;
568 img
->LuminanceBits
= 0;
581 img
->IsCompressed
= 0;
582 img
->CompressedSize
= 0;
583 img
->FetchTexel
= NULL
;
588 * Initialize basic fields of the gl_texture_image struct.
591 init_teximage_fields(GLcontext
*ctx
,
592 struct gl_texture_image
*img
,
593 GLsizei width
, GLsizei height
, GLsizei depth
,
594 GLint border
, GLenum internalFormat
)
598 img
->IntFormat
= internalFormat
;
599 img
->Border
= border
;
601 img
->Height
= height
;
603 img
->WidthLog2
= logbase2(width
- 2 * border
);
604 if (height
== 1) /* 1-D texture */
607 img
->HeightLog2
= logbase2(height
- 2 * border
);
608 if (depth
== 1) /* 2-D texture */
611 img
->DepthLog2
= logbase2(depth
- 2 * border
);
612 img
->Width2
= 1 << img
->WidthLog2
;
613 img
->Height2
= 1 << img
->HeightLog2
;
614 img
->Depth2
= 1 << img
->DepthLog2
;
615 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
616 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
622 * Test glTexImage[123]D() parameters for errors.
624 * dimensions - must be 1 or 2 or 3
625 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
628 texture_error_check( GLcontext
*ctx
, GLenum target
,
629 GLint level
, GLint internalFormat
,
630 GLenum format
, GLenum type
,
632 GLint width
, GLint height
,
633 GLint depth
, GLint border
)
638 if (dimensions
== 1) {
639 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
640 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
641 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
645 else if (dimensions
== 2) {
646 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
||
647 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
648 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
649 !(ctx
->Extensions
.ARB_texture_cube_map
&&
650 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
651 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
652 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
656 else if (dimensions
== 3) {
657 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
658 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
659 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
664 gl_problem( ctx
, "bad dims in texture_error_check" );
669 if (border
!= 0 && border
!= 1) {
672 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
673 gl_error(ctx
, GL_INVALID_VALUE
, message
);
679 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
680 || logbase2( width
- 2 * border
) < 0) {
683 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
684 gl_error(ctx
, GL_INVALID_VALUE
, message
);
690 if (dimensions
>= 2) {
691 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
692 || logbase2( height
- 2 * border
) < 0) {
695 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
696 gl_error(ctx
, GL_INVALID_VALUE
, message
);
702 /* For cube map, width must equal height */
703 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
704 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
705 if (width
!= height
) {
707 gl_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
714 if (dimensions
>= 3) {
715 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
716 || logbase2( depth
- 2 * border
) < 0) {
719 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
720 gl_error( ctx
, GL_INVALID_VALUE
, message
);
727 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
730 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
731 gl_error(ctx
, GL_INVALID_VALUE
, message
);
736 /* For cube map, width must equal height */
737 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
738 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
739 if (width
!= height
) {
740 gl_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
745 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
749 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
751 gl_error(ctx
, GL_INVALID_VALUE
, message
);
756 if (!is_compressed_format(ctx
, internalFormat
)) {
757 if (!_mesa_is_legal_format_and_type( format
, type
)) {
758 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
759 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
763 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
764 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
770 /* if we get here, the parameters are OK */
777 * Test glTexSubImage[123]D() parameters for errors.
779 * dimensions - must be 1 or 2 or 3
780 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
783 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
784 GLenum target
, GLint level
,
785 GLint xoffset
, GLint yoffset
, GLint zoffset
,
786 GLint width
, GLint height
, GLint depth
,
787 GLenum format
, GLenum type
)
789 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
790 struct gl_texture_image
*destTex
;
792 if (dimensions
== 1) {
793 if (target
!= GL_TEXTURE_1D
) {
794 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
798 else if (dimensions
== 2) {
799 if (ctx
->Extensions
.ARB_texture_cube_map
) {
800 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
801 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
802 target
!= GL_TEXTURE_2D
) {
803 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
807 else if (target
!= GL_TEXTURE_2D
) {
808 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
812 else if (dimensions
== 3) {
813 if (target
!= GL_TEXTURE_3D
) {
814 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
819 gl_problem( ctx
, "bad dims in texture_error_check" );
823 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
825 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
826 gl_error(ctx
, GL_INVALID_ENUM
, message
);
832 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
833 gl_error(ctx
, GL_INVALID_VALUE
, message
);
836 if (height
< 0 && dimensions
> 1) {
838 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
839 gl_error(ctx
, GL_INVALID_VALUE
, message
);
842 if (depth
< 0 && dimensions
> 2) {
844 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
845 gl_error(ctx
, GL_INVALID_VALUE
, message
);
849 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
852 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
856 if (xoffset
< -((GLint
)destTex
->Border
)) {
857 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
860 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
861 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
864 if (dimensions
> 1) {
865 if (yoffset
< -((GLint
)destTex
->Border
)) {
866 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
869 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
870 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
874 if (dimensions
> 2) {
875 if (zoffset
< -((GLint
)destTex
->Border
)) {
876 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
879 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
880 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
885 if (!is_compressed_format(ctx
, destTex
->IntFormat
)) {
886 if (!_mesa_is_legal_format_and_type(format
, type
)) {
888 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
889 gl_error(ctx
, GL_INVALID_ENUM
, message
);
899 * Test glCopyTexImage[12]D() parameters for errors.
900 * Input: dimensions - must be 1 or 2 or 3
901 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
904 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
905 GLenum target
, GLint level
, GLint internalFormat
,
906 GLint width
, GLint height
, GLint border
)
910 if (dimensions
== 1) {
911 if (target
!= GL_TEXTURE_1D
) {
912 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
916 else if (dimensions
== 2) {
917 if (ctx
->Extensions
.ARB_texture_cube_map
) {
918 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
919 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
920 target
!= GL_TEXTURE_2D
) {
921 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
925 else if (target
!= GL_TEXTURE_2D
) {
926 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
932 if (border
!=0 && border
!=1) {
934 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
935 gl_error(ctx
, GL_INVALID_VALUE
, message
);
940 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
941 || logbase2( width
- 2 * border
) < 0) {
943 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
944 gl_error(ctx
, GL_INVALID_VALUE
, message
);
949 if (dimensions
>= 2) {
950 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
951 || logbase2( height
- 2 * border
) < 0) {
953 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
954 gl_error(ctx
, GL_INVALID_VALUE
, message
);
959 /* For cube map, width must equal height */
960 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
961 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
962 if (width
!= height
) {
963 gl_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
969 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
971 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
972 gl_error(ctx
, GL_INVALID_VALUE
, message
);
976 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
979 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
980 gl_error(ctx
, GL_INVALID_VALUE
, message
);
984 /* if we get here, the parameters are OK */
990 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
991 GLenum target
, GLint level
,
992 GLint xoffset
, GLint yoffset
, GLint zoffset
,
993 GLsizei width
, GLsizei height
)
995 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
996 struct gl_texture_image
*teximage
;
998 if (dimensions
== 1) {
999 if (target
!= GL_TEXTURE_1D
) {
1000 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1004 else if (dimensions
== 2) {
1005 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1006 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1007 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1008 target
!= GL_TEXTURE_2D
) {
1009 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1013 else if (target
!= GL_TEXTURE_2D
) {
1014 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1018 else if (dimensions
== 3) {
1019 if (target
!= GL_TEXTURE_3D
) {
1020 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1025 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1027 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1028 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1034 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1035 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1038 if (dimensions
> 1 && height
< 0) {
1040 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1041 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1045 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1048 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1049 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1053 if (xoffset
< -((GLint
)teximage
->Border
)) {
1055 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1056 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1059 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1061 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1062 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1065 if (dimensions
> 1) {
1066 if (yoffset
< -((GLint
)teximage
->Border
)) {
1068 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1069 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1072 /* NOTE: we're adding the border here, not subtracting! */
1073 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1075 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1076 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1081 if (dimensions
> 2) {
1082 if (zoffset
< -((GLint
)teximage
->Border
)) {
1084 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1085 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1088 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1090 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1091 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1096 /* if we get here, the parameters are OK */
1103 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1104 GLenum type
, GLvoid
*pixels
)
1106 GET_CURRENT_CONTEXT(ctx
);
1107 const struct gl_texture_unit
*texUnit
;
1108 const struct gl_texture_object
*texObj
;
1109 struct gl_texture_image
*texImage
;
1111 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1113 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1114 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1118 if (_mesa_sizeof_type(type
) <= 0) {
1119 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1123 if (_mesa_components_in_format(format
) <= 0 ||
1124 format
== GL_STENCIL_INDEX
) {
1125 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1129 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1130 gl_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1133 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1134 gl_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1137 /* XXX what if format/type doesn't match texture format/type? */
1142 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1143 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1144 if (!texObj
|| is_proxy_target(target
)) {
1145 gl_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1149 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1151 /* invalid mipmap level, not an error */
1155 if (!texImage
->Data
) {
1156 /* no image data, not an error */
1160 if (ctx
->NewState
& _NEW_PIXEL
)
1161 gl_update_state(ctx
);
1163 if (is_color_format(format
) &&
1164 ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
1165 /* convert texture image to GL_RGBA, GL_FLOAT */
1166 GLint width
= texImage
->Width
;
1167 GLint height
= texImage
->Height
;
1168 GLint depth
= texImage
->Depth
;
1170 GLfloat
*tmpImage
, *convImage
;
1171 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1173 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1176 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1179 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1183 for (img
= 0; img
< depth
; img
++) {
1184 GLint convWidth
, convHeight
;
1186 /* convert texture data to GLfloat/GL_RGBA */
1187 for (row
= 0; row
< height
; row
++) {
1188 GLchan texels
[1 << MAX_TEXTURE_LEVELS
][4];
1190 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
1191 for (col
= 0; col
< width
; col
++) {
1192 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1195 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
1196 GL_RGBA
, CHAN_TYPE
, texels
,
1197 &_mesa_native_packing
,
1198 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
1203 convHeight
= height
;
1206 if (target
== GL_TEXTURE_1D
) {
1207 if (ctx
->Pixel
.Convolution1DEnabled
) {
1208 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
1212 if (ctx
->Pixel
.Convolution2DEnabled
) {
1213 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
1214 tmpImage
, convImage
);
1216 else if (ctx
->Pixel
.Separable2DEnabled
) {
1217 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
1218 tmpImage
, convImage
);
1222 /* pack convolved image */
1223 for (row
= 0; row
< convHeight
; row
++) {
1224 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
1225 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
1226 convWidth
, convHeight
,
1227 format
, type
, img
, row
, 0);
1228 _mesa_pack_float_rgba_span(ctx
, convWidth
,
1229 (const GLfloat(*)[4]) src
,
1230 format
, type
, dest
, &ctx
->Pack
,
1231 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
1239 /* no convolution, or non-rgba image */
1240 GLint width
= texImage
->Width
;
1241 GLint height
= texImage
->Height
;
1242 GLint depth
= texImage
->Depth
;
1244 for (img
= 0; img
< depth
; img
++) {
1245 for (row
= 0; row
< height
; row
++) {
1246 /* compute destination address in client memory */
1247 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1248 width
, height
, format
, type
,
1252 if (format
== GL_COLOR_INDEX
) {
1253 GLuint indexRow
[MAX_WIDTH
];
1255 for (col
= 0; col
< width
; col
++) {
1256 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1257 (GLvoid
*) &indexRow
[col
]);
1259 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1260 indexRow
, &ctx
->Pack
,
1261 ctx
->_ImageTransferState
);
1263 else if (format
== GL_DEPTH_COMPONENT
) {
1264 GLfloat depthRow
[MAX_WIDTH
];
1266 for (col
= 0; col
< width
; col
++) {
1267 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1268 (GLvoid
*) &depthRow
[col
]);
1270 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1271 depthRow
, &ctx
->Pack
);
1274 /* general case: convert row to RGBA format */
1275 GLchan rgba
[MAX_WIDTH
][4];
1277 for (col
= 0; col
< width
; col
++) {
1278 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1279 (GLvoid
*) rgba
[col
]);
1281 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1282 format
, type
, dest
, &ctx
->Pack
,
1283 ctx
->_ImageTransferState
);
1293 * Called from the API. Note that width includes the border.
1296 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1297 GLsizei width
, GLint border
, GLenum format
,
1298 GLenum type
, const GLvoid
*pixels
)
1300 GLsizei postConvWidth
= width
;
1301 GET_CURRENT_CONTEXT(ctx
);
1302 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1304 if (is_color_format(internalFormat
)) {
1305 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1308 if (target
== GL_TEXTURE_1D
) {
1309 struct gl_texture_unit
*texUnit
;
1310 struct gl_texture_object
*texObj
;
1311 struct gl_texture_image
*texImage
;
1313 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1314 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1315 return; /* error was recorded */
1318 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1319 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1320 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1323 texImage
= _mesa_alloc_texture_image();
1324 texObj
->Image
[level
] = texImage
;
1326 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1330 else if (texImage
->Data
) {
1331 /* free the old texture data */
1332 FREE(texImage
->Data
);
1333 texImage
->Data
= NULL
;
1335 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1336 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1337 border
, internalFormat
);
1339 if (ctx
->NewState
& _NEW_PIXEL
)
1340 gl_update_state(ctx
);
1342 ASSERT(ctx
->Driver
.TexImage1D
);
1344 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1345 width
, border
, format
, type
, pixels
,
1346 &ctx
->Unpack
, texObj
, texImage
);
1349 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1351 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1353 format
, GL_UNSIGNED_BYTE
, dummy
,
1354 &_mesa_native_packing
, texObj
, texImage
);
1359 /* one of these has to be non-zero! */
1360 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1361 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1362 texImage
->DepthBits
);
1363 ASSERT(texImage
->FetchTexel
);
1366 texObj
->Complete
= GL_FALSE
;
1367 ctx
->NewState
|= _NEW_TEXTURE
;
1369 else if (target
== GL_PROXY_TEXTURE_1D
) {
1370 /* Proxy texture: check for errors and update proxy state */
1371 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1373 postConvWidth
, 1, 1, border
);
1375 struct gl_texture_unit
*texUnit
;
1376 struct gl_texture_image
*texImage
;
1377 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1378 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1379 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1380 border
, internalFormat
);
1381 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1382 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1383 internalFormat
, format
, type
,
1384 postConvWidth
, 1, 1, border
);
1387 /* if error, clear all proxy texture image parameters */
1388 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1389 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1394 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1401 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1402 GLsizei width
, GLsizei height
, GLint border
,
1403 GLenum format
, GLenum type
,
1404 const GLvoid
*pixels
)
1406 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1407 GET_CURRENT_CONTEXT(ctx
);
1408 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1410 if (is_color_format(internalFormat
)) {
1411 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1415 if (target
== GL_TEXTURE_2D
||
1416 (ctx
->Extensions
.ARB_texture_cube_map
&&
1417 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1418 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1419 /* non-proxy target */
1420 struct gl_texture_unit
*texUnit
;
1421 struct gl_texture_object
*texObj
;
1422 struct gl_texture_image
*texImage
;
1424 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1425 format
, type
, 2, postConvWidth
, postConvHeight
,
1427 return; /* error was recorded */
1430 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1431 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1432 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1435 texImage
= _mesa_alloc_texture_image();
1436 set_tex_image(texObj
, target
, level
, texImage
);
1438 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1442 else if (texImage
->Data
) {
1443 /* free the old texture data */
1444 FREE(texImage
->Data
);
1445 texImage
->Data
= NULL
;
1447 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1448 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1449 border
, internalFormat
);
1451 if (ctx
->NewState
& _NEW_PIXEL
)
1452 gl_update_state(ctx
);
1454 ASSERT(ctx
->Driver
.TexImage2D
);
1456 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1457 width
, height
, border
, format
, type
, pixels
,
1458 &ctx
->Unpack
, texObj
, texImage
);
1461 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1463 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1464 width
, height
, border
,
1465 format
, GL_UNSIGNED_BYTE
, dummy
,
1466 &_mesa_native_packing
, texObj
, texImage
);
1471 /* one of these has to be non-zero! */
1472 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1473 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1474 texImage
->DepthBits
);
1475 ASSERT(texImage
->FetchTexel
);
1478 texObj
->Complete
= GL_FALSE
;
1479 ctx
->NewState
|= _NEW_TEXTURE
;
1481 else if (target
== GL_PROXY_TEXTURE_2D
) {
1482 /* Proxy texture: check for errors and update proxy state */
1483 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1485 postConvWidth
, postConvHeight
, 1, border
);
1487 struct gl_texture_unit
*texUnit
;
1488 struct gl_texture_image
*texImage
;
1489 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1490 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1491 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1492 border
, internalFormat
);
1493 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1494 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1495 internalFormat
, format
, type
,
1496 postConvWidth
, postConvHeight
, 1, border
);
1499 /* if error, clear all proxy texture image parameters */
1500 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1501 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1506 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1513 * Called by the API or display list executor.
1514 * Note that width and height include the border.
1517 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1518 GLsizei width
, GLsizei height
, GLsizei depth
,
1519 GLint border
, GLenum format
, GLenum type
,
1520 const GLvoid
*pixels
)
1522 GET_CURRENT_CONTEXT(ctx
);
1523 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1525 if (target
== GL_TEXTURE_3D
) {
1526 struct gl_texture_unit
*texUnit
;
1527 struct gl_texture_object
*texObj
;
1528 struct gl_texture_image
*texImage
;
1530 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1531 format
, type
, 3, width
, height
, depth
, border
)) {
1532 return; /* error was recorded */
1535 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1536 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1537 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1540 texImage
= _mesa_alloc_texture_image();
1541 texObj
->Image
[level
] = texImage
;
1543 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1547 else if (texImage
->Data
) {
1548 FREE(texImage
->Data
);
1549 texImage
->Data
= NULL
;
1551 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1552 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
1555 if (ctx
->NewState
& _NEW_PIXEL
)
1556 gl_update_state(ctx
);
1558 ASSERT(ctx
->Driver
.TexImage3D
);
1560 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1561 width
, height
, depth
, border
,
1562 format
, type
, pixels
,
1563 &ctx
->Unpack
, texObj
, texImage
);
1566 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1568 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1569 width
, height
, depth
, border
,
1570 format
, GL_UNSIGNED_BYTE
, dummy
,
1571 &_mesa_native_packing
, texObj
, texImage
);
1576 /* one of these has to be non-zero! */
1577 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1578 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1579 texImage
->DepthBits
);
1580 ASSERT(texImage
->FetchTexel
);
1583 texObj
->Complete
= GL_FALSE
;
1584 ctx
->NewState
|= _NEW_TEXTURE
;
1586 else if (target
== GL_PROXY_TEXTURE_3D
) {
1587 /* Proxy texture: check for errors and update proxy state */
1588 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1589 format
, type
, 3, width
, height
, depth
, border
);
1591 struct gl_texture_unit
*texUnit
;
1592 struct gl_texture_image
*texImage
;
1593 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1594 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1595 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
1596 border
, internalFormat
);
1597 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1598 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1599 internalFormat
, format
, type
,
1600 width
, height
, depth
, border
);
1603 /* if error, clear all proxy texture image parameters */
1604 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1605 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1610 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1617 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1618 GLsizei width
, GLsizei height
, GLsizei depth
,
1619 GLint border
, GLenum format
, GLenum type
,
1620 const GLvoid
*pixels
)
1622 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1623 depth
, border
, format
, type
, pixels
);
1629 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1630 GLint xoffset
, GLsizei width
,
1631 GLenum format
, GLenum type
,
1632 const GLvoid
*pixels
)
1634 GLsizei postConvWidth
= width
;
1635 GET_CURRENT_CONTEXT(ctx
);
1636 struct gl_texture_unit
*texUnit
;
1637 struct gl_texture_object
*texObj
;
1638 struct gl_texture_image
*texImage
;
1640 if (ctx
->NewState
& _NEW_PIXEL
)
1641 gl_update_state(ctx
);
1643 /* XXX should test internal format */
1644 if (is_color_format(format
)) {
1645 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1648 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1649 postConvWidth
, 1, 1, format
, type
)) {
1650 return; /* error was detected */
1653 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1654 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1655 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1658 if (width
== 0 || !pixels
)
1659 return; /* no-op, not an error */
1661 ASSERT(ctx
->Driver
.TexSubImage1D
);
1662 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1663 format
, type
, pixels
, &ctx
->Unpack
,
1669 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1670 GLint xoffset
, GLint yoffset
,
1671 GLsizei width
, GLsizei height
,
1672 GLenum format
, GLenum type
,
1673 const GLvoid
*pixels
)
1675 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1676 GET_CURRENT_CONTEXT(ctx
);
1677 struct gl_texture_unit
*texUnit
;
1678 struct gl_texture_object
*texObj
;
1679 struct gl_texture_image
*texImage
;
1681 if (ctx
->NewState
& _NEW_PIXEL
)
1682 gl_update_state(ctx
);
1684 /* XXX should test internal format */
1685 if (is_color_format(format
)) {
1686 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1690 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1691 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1692 return; /* error was detected */
1695 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1696 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1697 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1700 if (width
== 0 || height
== 0 || !pixels
)
1701 return; /* no-op, not an error */
1703 ASSERT(ctx
->Driver
.TexSubImage2D
);
1704 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1705 width
, height
, format
, type
, pixels
,
1706 &ctx
->Unpack
, texObj
, texImage
);
1712 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1713 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1714 GLsizei width
, GLsizei height
, GLsizei depth
,
1715 GLenum format
, GLenum type
,
1716 const GLvoid
*pixels
)
1718 GET_CURRENT_CONTEXT(ctx
);
1719 struct gl_texture_unit
*texUnit
;
1720 struct gl_texture_object
*texObj
;
1721 struct gl_texture_image
*texImage
;
1723 if (ctx
->NewState
& _NEW_PIXEL
)
1724 gl_update_state(ctx
);
1726 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1727 width
, height
, depth
, format
, type
)) {
1728 return; /* error was detected */
1731 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1732 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1733 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1736 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1737 return; /* no-op, not an error */
1739 ASSERT(ctx
->Driver
.TexSubImage3D
);
1740 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1741 xoffset
, yoffset
, zoffset
,
1742 width
, height
, depth
,
1743 format
, type
, pixels
,
1744 &ctx
->Unpack
, texObj
, texImage
);
1750 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1751 GLenum internalFormat
,
1753 GLsizei width
, GLint border
)
1755 struct gl_texture_unit
*texUnit
;
1756 struct gl_texture_object
*texObj
;
1757 struct gl_texture_image
*texImage
;
1758 GLsizei postConvWidth
= width
;
1759 GET_CURRENT_CONTEXT(ctx
);
1760 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1762 if (ctx
->NewState
& _NEW_PIXEL
)
1763 gl_update_state(ctx
);
1765 if (is_color_format(internalFormat
)) {
1766 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1769 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1770 postConvWidth
, 1, border
))
1773 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1774 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1775 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1777 texImage
= _mesa_alloc_texture_image();
1778 set_tex_image(texObj
, target
, level
, texImage
);
1780 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1784 else if (texImage
->Data
) {
1785 /* free the old texture data */
1786 FREE(texImage
->Data
);
1787 texImage
->Data
= NULL
;
1790 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1791 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1792 border
, internalFormat
);
1795 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1796 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1797 x
, y
, width
, border
);
1800 texObj
->Complete
= GL_FALSE
;
1801 ctx
->NewState
|= _NEW_TEXTURE
;
1807 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1808 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1811 struct gl_texture_unit
*texUnit
;
1812 struct gl_texture_object
*texObj
;
1813 struct gl_texture_image
*texImage
;
1814 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1815 GET_CURRENT_CONTEXT(ctx
);
1816 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1818 if (ctx
->NewState
& _NEW_PIXEL
)
1819 gl_update_state(ctx
);
1821 if (is_color_format(internalFormat
)) {
1822 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1826 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1827 postConvWidth
, postConvHeight
, border
))
1830 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1831 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1832 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1834 texImage
= _mesa_alloc_texture_image();
1835 set_tex_image(texObj
, target
, level
, texImage
);
1837 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1841 else if (texImage
->Data
) {
1842 /* free the old texture data */
1843 FREE(texImage
->Data
);
1844 texImage
->Data
= NULL
;
1847 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1848 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1849 border
, internalFormat
);
1851 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1852 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1853 x
, y
, width
, height
, border
);
1856 texObj
->Complete
= GL_FALSE
;
1857 ctx
->NewState
|= _NEW_TEXTURE
;
1863 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1864 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1866 GLsizei postConvWidth
= width
;
1867 GET_CURRENT_CONTEXT(ctx
);
1868 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1870 if (ctx
->NewState
& _NEW_PIXEL
)
1871 gl_update_state(ctx
);
1873 /* XXX should test internal format */
1874 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1876 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1877 xoffset
, 0, 0, postConvWidth
, 1))
1880 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1881 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1887 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1888 GLint xoffset
, GLint yoffset
,
1889 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1891 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1892 GET_CURRENT_CONTEXT(ctx
);
1893 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1895 if (ctx
->NewState
& _NEW_PIXEL
)
1896 gl_update_state(ctx
);
1898 /* XXX should test internal format */
1899 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1901 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1902 postConvWidth
, postConvHeight
))
1905 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1906 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1907 xoffset
, yoffset
, x
, y
, width
, height
);
1913 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1914 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1915 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1917 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1918 GET_CURRENT_CONTEXT(ctx
);
1919 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1921 if (ctx
->NewState
& _NEW_PIXEL
)
1922 gl_update_state(ctx
);
1924 /* XXX should test internal format */
1925 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1927 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1928 zoffset
, postConvWidth
, postConvHeight
))
1931 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1932 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1933 xoffset
, yoffset
, zoffset
,
1934 x
, y
, width
, height
);
1940 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
1941 GLenum internalFormat
, GLsizei width
,
1942 GLint border
, GLsizei imageSize
,
1945 GET_CURRENT_CONTEXT(ctx
);
1946 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1948 switch (internalFormat
) {
1949 case GL_COMPRESSED_ALPHA_ARB
:
1950 case GL_COMPRESSED_LUMINANCE_ARB
:
1951 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1952 case GL_COMPRESSED_INTENSITY_ARB
:
1953 case GL_COMPRESSED_RGB_ARB
:
1954 case GL_COMPRESSED_RGBA_ARB
:
1955 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
1958 /* silence compiler warning */
1962 if (target
== GL_TEXTURE_1D
) {
1963 struct gl_texture_unit
*texUnit
;
1964 struct gl_texture_object
*texObj
;
1965 struct gl_texture_image
*texImage
;
1967 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1968 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
1969 return; /* error in texture image was detected */
1972 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1973 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1974 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1977 texImage
= _mesa_alloc_texture_image();
1978 texObj
->Image
[level
] = texImage
;
1980 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
1984 else if (texImage
->Data
) {
1985 FREE(texImage
->Data
);
1986 texImage
->Data
= NULL
;
1989 init_teximage_fields(ctx
, texImage
, width
, 1, 1, border
, internalFormat
);
1991 if (ctx
->Extensions
.ARB_texture_compression
) {
1992 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
1993 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
1994 internalFormat
, width
, border
,
1997 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2001 texObj
->Complete
= GL_FALSE
;
2002 ctx
->NewState
|= _NEW_TEXTURE
;
2004 else if (target
== GL_PROXY_TEXTURE_1D
) {
2005 /* Proxy texture: check for errors and update proxy state */
2006 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2007 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2009 struct gl_texture_unit
*texUnit
;
2010 struct gl_texture_image
*texImage
;
2011 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2012 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2013 init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2014 border
, internalFormat
);
2015 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2016 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2017 internalFormat
, GL_NONE
, GL_NONE
,
2018 width
, 1, 1, border
);
2021 /* if error, clear all proxy texture image parameters */
2022 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2023 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2028 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2035 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2036 GLenum internalFormat
, GLsizei width
,
2037 GLsizei height
, GLint border
, GLsizei imageSize
,
2040 GET_CURRENT_CONTEXT(ctx
);
2041 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2043 switch (internalFormat
) {
2044 case GL_COMPRESSED_ALPHA_ARB
:
2045 case GL_COMPRESSED_LUMINANCE_ARB
:
2046 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2047 case GL_COMPRESSED_INTENSITY_ARB
:
2048 case GL_COMPRESSED_RGB_ARB
:
2049 case GL_COMPRESSED_RGBA_ARB
:
2050 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2053 /* silence compiler warning */
2057 if (target
== GL_TEXTURE_2D
||
2058 (ctx
->Extensions
.ARB_texture_cube_map
&&
2059 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2060 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2061 struct gl_texture_unit
*texUnit
;
2062 struct gl_texture_object
*texObj
;
2063 struct gl_texture_image
*texImage
;
2065 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2066 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2067 return; /* error in texture image was detected */
2070 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2071 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2072 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2075 texImage
= _mesa_alloc_texture_image();
2076 texObj
->Image
[level
] = texImage
;
2078 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2082 else if (texImage
->Data
) {
2083 FREE(texImage
->Data
);
2084 texImage
->Data
= NULL
;
2087 init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2090 if (ctx
->Extensions
.ARB_texture_compression
) {
2091 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2092 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2093 internalFormat
, width
, height
,
2094 border
, imageSize
, data
,
2096 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2100 texObj
->Complete
= GL_FALSE
;
2101 ctx
->NewState
|= _NEW_TEXTURE
;
2103 else if (target
== GL_PROXY_TEXTURE_2D
) {
2104 /* Proxy texture: check for errors and update proxy state */
2105 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2106 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2108 struct gl_texture_unit
*texUnit
;
2109 struct gl_texture_image
*texImage
;
2110 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2111 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2112 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2113 border
, internalFormat
);
2114 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2115 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2116 internalFormat
, GL_NONE
, GL_NONE
,
2117 width
, height
, 1, border
);
2120 /* if error, clear all proxy texture image parameters */
2121 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2122 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2127 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2134 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2135 GLenum internalFormat
, GLsizei width
,
2136 GLsizei height
, GLsizei depth
, GLint border
,
2137 GLsizei imageSize
, const GLvoid
*data
)
2139 GET_CURRENT_CONTEXT(ctx
);
2140 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2142 switch (internalFormat
) {
2143 case GL_COMPRESSED_ALPHA_ARB
:
2144 case GL_COMPRESSED_LUMINANCE_ARB
:
2145 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2146 case GL_COMPRESSED_INTENSITY_ARB
:
2147 case GL_COMPRESSED_RGB_ARB
:
2148 case GL_COMPRESSED_RGBA_ARB
:
2149 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2152 /* silence compiler warning */
2156 if (target
== GL_TEXTURE_3D
) {
2157 struct gl_texture_unit
*texUnit
;
2158 struct gl_texture_object
*texObj
;
2159 struct gl_texture_image
*texImage
;
2161 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2162 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2163 return; /* error in texture image was detected */
2166 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2167 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2168 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2171 texImage
= _mesa_alloc_texture_image();
2172 texObj
->Image
[level
] = texImage
;
2174 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2178 else if (texImage
->Data
) {
2179 FREE(texImage
->Data
);
2180 texImage
->Data
= NULL
;
2183 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2186 if (ctx
->Extensions
.ARB_texture_compression
) {
2187 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2188 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2190 width
, height
, depth
,
2191 border
, imageSize
, data
,
2193 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2197 texObj
->Complete
= GL_FALSE
;
2198 ctx
->NewState
|= _NEW_TEXTURE
;
2200 else if (target
== GL_PROXY_TEXTURE_3D
) {
2201 /* Proxy texture: check for errors and update proxy state */
2202 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2203 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2205 struct gl_texture_unit
*texUnit
;
2206 struct gl_texture_image
*texImage
;
2207 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2208 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2209 init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2210 border
, internalFormat
);
2211 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2212 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2213 internalFormat
, GL_NONE
, GL_NONE
,
2214 width
, height
, depth
, border
);
2217 /* if error, clear all proxy texture image parameters */
2218 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2219 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2224 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2231 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2232 GLsizei width
, GLenum format
,
2233 GLsizei imageSize
, const GLvoid
*data
)
2235 struct gl_texture_unit
*texUnit
;
2236 struct gl_texture_object
*texObj
;
2237 struct gl_texture_image
*texImage
;
2238 GET_CURRENT_CONTEXT(ctx
);
2240 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2241 width
, 1, 1, format
, GL_NONE
)) {
2242 return; /* error was detected */
2245 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2246 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2247 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2250 if (width
== 0 || !data
)
2251 return; /* no-op, not an error */
2253 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2254 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2256 format
, imageSize
, data
,
2263 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2264 GLint yoffset
, GLsizei width
, GLsizei height
,
2265 GLenum format
, GLsizei imageSize
,
2268 struct gl_texture_unit
*texUnit
;
2269 struct gl_texture_object
*texObj
;
2270 struct gl_texture_image
*texImage
;
2271 GET_CURRENT_CONTEXT(ctx
);
2273 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2274 width
, height
, 1, format
, GL_NONE
)) {
2275 return; /* error was detected */
2278 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2279 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2280 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2283 if (width
== 0 || height
== 0 || !data
)
2284 return; /* no-op, not an error */
2286 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2287 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2288 xoffset
, yoffset
, width
, height
,
2289 format
, imageSize
, data
,
2296 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2297 GLint yoffset
, GLint zoffset
, GLsizei width
,
2298 GLsizei height
, GLsizei depth
, GLenum format
,
2299 GLsizei imageSize
, const GLvoid
*data
)
2301 struct gl_texture_unit
*texUnit
;
2302 struct gl_texture_object
*texObj
;
2303 struct gl_texture_image
*texImage
;
2304 GET_CURRENT_CONTEXT(ctx
);
2306 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2307 width
, height
, depth
, format
, GL_NONE
)) {
2308 return; /* error was detected */
2311 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2312 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2313 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2316 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2317 return; /* no-op, not an error */
2319 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2320 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2321 xoffset
, yoffset
, zoffset
,
2322 width
, height
, depth
,
2323 format
, imageSize
, data
,
2330 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2332 const struct gl_texture_unit
*texUnit
;
2333 const struct gl_texture_object
*texObj
;
2334 struct gl_texture_image
*texImage
;
2335 GET_CURRENT_CONTEXT(ctx
);
2337 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2339 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2340 gl_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2344 if (is_proxy_target(target
)) {
2345 gl_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2349 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2350 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2351 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2354 /* invalid mipmap level */
2355 gl_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2359 if (!texImage
->IsCompressed
) {
2360 gl_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2367 if (ctx
->Extensions
.ARB_texture_compression
) {
2368 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2369 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,