1 /* $Id: teximage.c,v 1.87 2001/03/26 20:02:38 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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.
39 #include "texformat.h"
43 #include "swrast/s_span.h" /* XXX SWRAST hack */
50 * Mesa's native texture datatype is GLchan. Native formats are
51 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
53 * Device drivers are free to implement any internal format they want.
58 static void PrintTexture(const struct gl_texture_image
*img
)
61 const GLchan
*data
= (const GLchan
*) img
->Data
;
64 printf("No texture data\n");
68 switch (img
->Format
) {
75 case GL_LUMINANCE_ALPHA
:
85 _mesa_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 _mesa_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 _mesa_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 _mesa_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
)
574 img
->TexFormat
= &_mesa_null_texformat
;
575 img
->FetchTexel
= NULL
;
576 img
->IsCompressed
= 0;
577 img
->CompressedSize
= 0;
582 * Initialize basic fields of the gl_texture_image struct.
585 init_teximage_fields(GLcontext
*ctx
,
586 struct gl_texture_image
*img
,
587 GLsizei width
, GLsizei height
, GLsizei depth
,
588 GLint border
, GLenum internalFormat
)
592 img
->IntFormat
= internalFormat
;
593 img
->Border
= border
;
595 img
->Height
= height
;
597 img
->WidthLog2
= logbase2(width
- 2 * border
);
598 if (height
== 1) /* 1-D texture */
601 img
->HeightLog2
= logbase2(height
- 2 * border
);
602 if (depth
== 1) /* 2-D texture */
605 img
->DepthLog2
= logbase2(depth
- 2 * border
);
606 img
->Width2
= 1 << img
->WidthLog2
;
607 img
->Height2
= 1 << img
->HeightLog2
;
608 img
->Depth2
= 1 << img
->DepthLog2
;
609 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
610 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
616 * Test glTexImage[123]D() parameters for errors.
618 * dimensions - must be 1 or 2 or 3
619 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
622 texture_error_check( GLcontext
*ctx
, GLenum target
,
623 GLint level
, GLint internalFormat
,
624 GLenum format
, GLenum type
,
626 GLint width
, GLint height
,
627 GLint depth
, GLint border
)
632 if (dimensions
== 1) {
633 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
634 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
635 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
639 else if (dimensions
== 2) {
640 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
||
641 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
642 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
643 !(ctx
->Extensions
.ARB_texture_cube_map
&&
644 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
645 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
646 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
650 else if (dimensions
== 3) {
651 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
652 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
653 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
658 _mesa_problem( ctx
, "bad dims in texture_error_check" );
663 if (border
!= 0 && border
!= 1) {
666 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
667 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
673 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
674 || logbase2( width
- 2 * border
) < 0) {
677 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
678 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
684 if (dimensions
>= 2) {
685 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
686 || logbase2( height
- 2 * border
) < 0) {
689 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
690 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
696 /* For cube map, width must equal height */
697 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
698 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
699 if (width
!= height
) {
701 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
708 if (dimensions
>= 3) {
709 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
710 || logbase2( depth
- 2 * border
) < 0) {
713 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
714 _mesa_error( ctx
, GL_INVALID_VALUE
, message
);
721 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
724 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
725 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
730 /* For cube map, width must equal height */
731 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
732 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
733 if (width
!= height
) {
734 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
739 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
743 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
745 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
750 if (!is_compressed_format(ctx
, internalFormat
)) {
751 if (!_mesa_is_legal_format_and_type( format
, type
)) {
752 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
753 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
757 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
758 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
764 /* if we get here, the parameters are OK */
771 * Test glTexSubImage[123]D() parameters for errors.
773 * dimensions - must be 1 or 2 or 3
774 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
777 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
778 GLenum target
, GLint level
,
779 GLint xoffset
, GLint yoffset
, GLint zoffset
,
780 GLint width
, GLint height
, GLint depth
,
781 GLenum format
, GLenum type
)
783 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
784 struct gl_texture_image
*destTex
;
786 if (dimensions
== 1) {
787 if (target
!= GL_TEXTURE_1D
) {
788 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
792 else if (dimensions
== 2) {
793 if (ctx
->Extensions
.ARB_texture_cube_map
) {
794 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
795 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
796 target
!= GL_TEXTURE_2D
) {
797 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
801 else if (target
!= GL_TEXTURE_2D
) {
802 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
806 else if (dimensions
== 3) {
807 if (target
!= GL_TEXTURE_3D
) {
808 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
813 _mesa_problem( ctx
, "bad dims in texture_error_check" );
817 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
819 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
820 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
826 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
827 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
830 if (height
< 0 && dimensions
> 1) {
832 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
833 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
836 if (depth
< 0 && dimensions
> 2) {
838 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
839 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
843 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
846 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
850 if (xoffset
< -((GLint
)destTex
->Border
)) {
851 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
854 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
855 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
858 if (dimensions
> 1) {
859 if (yoffset
< -((GLint
)destTex
->Border
)) {
860 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
863 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
864 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
868 if (dimensions
> 2) {
869 if (zoffset
< -((GLint
)destTex
->Border
)) {
870 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
873 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
874 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
879 if (!is_compressed_format(ctx
, destTex
->IntFormat
)) {
880 if (!_mesa_is_legal_format_and_type(format
, type
)) {
882 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
883 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
893 * Test glCopyTexImage[12]D() parameters for errors.
894 * Input: dimensions - must be 1 or 2 or 3
895 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
898 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
899 GLenum target
, GLint level
, GLint internalFormat
,
900 GLint width
, GLint height
, GLint border
)
904 if (dimensions
== 1) {
905 if (target
!= GL_TEXTURE_1D
) {
906 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
910 else if (dimensions
== 2) {
911 if (ctx
->Extensions
.ARB_texture_cube_map
) {
912 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
913 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
914 target
!= GL_TEXTURE_2D
) {
915 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
919 else if (target
!= GL_TEXTURE_2D
) {
920 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
926 if (border
!=0 && border
!=1) {
928 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
929 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
934 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
935 || logbase2( width
- 2 * border
) < 0) {
937 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
938 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
943 if (dimensions
>= 2) {
944 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
945 || logbase2( height
- 2 * border
) < 0) {
947 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
948 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
953 /* For cube map, width must equal height */
954 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
955 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
956 if (width
!= height
) {
957 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
963 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
965 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
966 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
970 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
973 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
974 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
978 /* if we get here, the parameters are OK */
984 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
985 GLenum target
, GLint level
,
986 GLint xoffset
, GLint yoffset
, GLint zoffset
,
987 GLsizei width
, GLsizei height
)
989 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
990 struct gl_texture_image
*teximage
;
992 if (dimensions
== 1) {
993 if (target
!= GL_TEXTURE_1D
) {
994 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
998 else if (dimensions
== 2) {
999 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1000 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1001 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1002 target
!= GL_TEXTURE_2D
) {
1003 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1007 else if (target
!= GL_TEXTURE_2D
) {
1008 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1012 else if (dimensions
== 3) {
1013 if (target
!= GL_TEXTURE_3D
) {
1014 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1019 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1021 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1022 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1028 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1029 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1032 if (dimensions
> 1 && height
< 0) {
1034 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1035 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1039 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1042 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1043 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
1047 if (xoffset
< -((GLint
)teximage
->Border
)) {
1049 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1050 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1053 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1055 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1056 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1059 if (dimensions
> 1) {
1060 if (yoffset
< -((GLint
)teximage
->Border
)) {
1062 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1063 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1066 /* NOTE: we're adding the border here, not subtracting! */
1067 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1069 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1070 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1075 if (dimensions
> 2) {
1076 if (zoffset
< -((GLint
)teximage
->Border
)) {
1078 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1079 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1082 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1084 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1085 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1090 /* if we get here, the parameters are OK */
1097 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1098 GLenum type
, GLvoid
*pixels
)
1100 const struct gl_texture_unit
*texUnit
;
1101 const struct gl_texture_object
*texObj
;
1102 struct gl_texture_image
*texImage
;
1103 GET_CURRENT_CONTEXT(ctx
);
1104 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1106 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1107 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1111 if (_mesa_sizeof_type(type
) <= 0) {
1112 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1116 if (_mesa_components_in_format(format
) <= 0 ||
1117 format
== GL_STENCIL_INDEX
) {
1118 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1122 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1123 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1126 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1127 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1130 /* XXX what if format/type doesn't match texture format/type? */
1135 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1136 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1137 if (!texObj
|| is_proxy_target(target
)) {
1138 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1142 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1144 /* invalid mipmap level, not an error */
1148 if (!texImage
->Data
) {
1149 /* no image data, not an error */
1153 if (ctx
->NewState
& _NEW_PIXEL
)
1154 _mesa_update_state(ctx
);
1156 if (is_color_format(format
) &&
1157 ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
1158 /* convert texture image to GL_RGBA, GL_FLOAT */
1159 GLint width
= texImage
->Width
;
1160 GLint height
= texImage
->Height
;
1161 GLint depth
= texImage
->Depth
;
1163 GLfloat
*tmpImage
, *convImage
;
1164 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1166 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1169 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1172 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1176 for (img
= 0; img
< depth
; img
++) {
1177 GLint convWidth
, convHeight
;
1179 /* convert texture data to GLfloat/GL_RGBA */
1180 for (row
= 0; row
< height
; row
++) {
1181 GLchan texels
[1 << MAX_TEXTURE_LEVELS
][4];
1183 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
1184 for (col
= 0; col
< width
; col
++) {
1185 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1188 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
1189 GL_RGBA
, CHAN_TYPE
, texels
,
1190 &_mesa_native_packing
,
1191 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
1196 convHeight
= height
;
1199 if (target
== GL_TEXTURE_1D
) {
1200 if (ctx
->Pixel
.Convolution1DEnabled
) {
1201 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
1205 if (ctx
->Pixel
.Convolution2DEnabled
) {
1206 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
1207 tmpImage
, convImage
);
1209 else if (ctx
->Pixel
.Separable2DEnabled
) {
1210 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
1211 tmpImage
, convImage
);
1215 /* pack convolved image */
1216 for (row
= 0; row
< convHeight
; row
++) {
1217 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
1218 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
1219 convWidth
, convHeight
,
1220 format
, type
, img
, row
, 0);
1221 _mesa_pack_float_rgba_span(ctx
, convWidth
,
1222 (const GLfloat(*)[4]) src
,
1223 format
, type
, dest
, &ctx
->Pack
,
1224 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
1232 /* no convolution, or non-rgba image */
1233 GLint width
= texImage
->Width
;
1234 GLint height
= texImage
->Height
;
1235 GLint depth
= texImage
->Depth
;
1237 for (img
= 0; img
< depth
; img
++) {
1238 for (row
= 0; row
< height
; row
++) {
1239 /* compute destination address in client memory */
1240 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1241 width
, height
, format
, type
,
1245 if (format
== GL_COLOR_INDEX
) {
1246 GLuint indexRow
[MAX_WIDTH
];
1248 for (col
= 0; col
< width
; col
++) {
1249 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1250 (GLvoid
*) &indexRow
[col
]);
1252 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1253 indexRow
, &ctx
->Pack
,
1254 ctx
->_ImageTransferState
);
1256 else if (format
== GL_DEPTH_COMPONENT
) {
1257 GLfloat depthRow
[MAX_WIDTH
];
1259 for (col
= 0; col
< width
; col
++) {
1260 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1261 (GLvoid
*) &depthRow
[col
]);
1263 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1264 depthRow
, &ctx
->Pack
);
1267 /* general case: convert row to RGBA format */
1268 GLchan rgba
[MAX_WIDTH
][4];
1270 for (col
= 0; col
< width
; col
++) {
1271 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1272 (GLvoid
*) rgba
[col
]);
1274 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1275 format
, type
, dest
, &ctx
->Pack
,
1276 ctx
->_ImageTransferState
);
1286 * Called from the API. Note that width includes the border.
1289 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1290 GLsizei width
, GLint border
, GLenum format
,
1291 GLenum type
, const GLvoid
*pixels
)
1293 GLsizei postConvWidth
= width
;
1294 GET_CURRENT_CONTEXT(ctx
);
1295 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1297 if (is_color_format(internalFormat
)) {
1298 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1301 if (target
== GL_TEXTURE_1D
) {
1302 struct gl_texture_unit
*texUnit
;
1303 struct gl_texture_object
*texObj
;
1304 struct gl_texture_image
*texImage
;
1306 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1307 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1308 return; /* error was recorded */
1311 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1312 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1313 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1316 texImage
= _mesa_alloc_texture_image();
1317 texObj
->Image
[level
] = texImage
;
1319 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1323 else if (texImage
->Data
) {
1324 /* free the old texture data */
1325 FREE(texImage
->Data
);
1326 texImage
->Data
= NULL
;
1328 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1329 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1330 border
, internalFormat
);
1332 if (ctx
->NewState
& _NEW_PIXEL
)
1333 _mesa_update_state(ctx
);
1335 ASSERT(ctx
->Driver
.TexImage1D
);
1337 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1338 width
, border
, format
, type
, pixels
,
1339 &ctx
->Unpack
, texObj
, texImage
);
1342 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1344 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1346 format
, GL_UNSIGNED_BYTE
, dummy
,
1347 &_mesa_native_packing
, texObj
, texImage
);
1353 /* one of these has to be non-zero! */
1354 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1355 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1356 texImage
->DepthBits
);
1357 ASSERT(texImage
->FetchTexel
);
1361 texObj
->Complete
= GL_FALSE
;
1362 ctx
->NewState
|= _NEW_TEXTURE
;
1364 else if (target
== GL_PROXY_TEXTURE_1D
) {
1365 /* Proxy texture: check for errors and update proxy state */
1366 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1368 postConvWidth
, 1, 1, border
);
1370 struct gl_texture_unit
*texUnit
;
1371 struct gl_texture_image
*texImage
;
1372 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1373 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1374 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1375 border
, internalFormat
);
1376 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1377 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1378 internalFormat
, format
, type
,
1379 postConvWidth
, 1, 1, border
);
1382 /* if error, clear all proxy texture image parameters */
1383 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1384 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1389 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1396 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1397 GLsizei width
, GLsizei height
, GLint border
,
1398 GLenum format
, GLenum type
,
1399 const GLvoid
*pixels
)
1401 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1402 GET_CURRENT_CONTEXT(ctx
);
1403 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1405 if (is_color_format(internalFormat
)) {
1406 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1410 if (target
== GL_TEXTURE_2D
||
1411 (ctx
->Extensions
.ARB_texture_cube_map
&&
1412 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1413 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1414 /* non-proxy target */
1415 struct gl_texture_unit
*texUnit
;
1416 struct gl_texture_object
*texObj
;
1417 struct gl_texture_image
*texImage
;
1419 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1420 format
, type
, 2, postConvWidth
, postConvHeight
,
1422 return; /* error was recorded */
1425 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1426 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1427 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1430 texImage
= _mesa_alloc_texture_image();
1431 set_tex_image(texObj
, target
, level
, texImage
);
1433 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1437 else if (texImage
->Data
) {
1438 /* free the old texture data */
1439 FREE(texImage
->Data
);
1440 texImage
->Data
= NULL
;
1442 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1443 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1444 border
, internalFormat
);
1446 if (ctx
->NewState
& _NEW_PIXEL
)
1447 _mesa_update_state(ctx
);
1449 ASSERT(ctx
->Driver
.TexImage2D
);
1451 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1452 width
, height
, border
, format
, type
, pixels
,
1453 &ctx
->Unpack
, texObj
, texImage
);
1456 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1458 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1459 width
, height
, border
,
1460 format
, GL_UNSIGNED_BYTE
, dummy
,
1461 &_mesa_native_packing
, texObj
, texImage
);
1467 /* one of these has to be non-zero! */
1468 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1469 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1470 texImage
->DepthBits
);
1471 ASSERT(texImage
->FetchTexel
);
1475 texObj
->Complete
= GL_FALSE
;
1476 ctx
->NewState
|= _NEW_TEXTURE
;
1478 else if (target
== GL_PROXY_TEXTURE_2D
) {
1479 /* Proxy texture: check for errors and update proxy state */
1480 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1482 postConvWidth
, postConvHeight
, 1, border
);
1484 struct gl_texture_unit
*texUnit
;
1485 struct gl_texture_image
*texImage
;
1486 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1487 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1488 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1489 border
, internalFormat
);
1490 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1491 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1492 internalFormat
, format
, type
,
1493 postConvWidth
, postConvHeight
, 1, border
);
1496 /* if error, clear all proxy texture image parameters */
1497 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1498 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1503 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1510 * Called by the API or display list executor.
1511 * Note that width and height include the border.
1514 _mesa_TexImage3D( GLenum target
, GLint level
, GLenum internalFormat
,
1515 GLsizei width
, GLsizei height
, GLsizei depth
,
1516 GLint border
, GLenum format
, GLenum type
,
1517 const GLvoid
*pixels
)
1519 GET_CURRENT_CONTEXT(ctx
);
1520 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1522 if (target
== GL_TEXTURE_3D
) {
1523 struct gl_texture_unit
*texUnit
;
1524 struct gl_texture_object
*texObj
;
1525 struct gl_texture_image
*texImage
;
1527 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1528 format
, type
, 3, width
, height
, depth
, border
)) {
1529 return; /* error was recorded */
1532 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1533 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1534 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1537 texImage
= _mesa_alloc_texture_image();
1538 texObj
->Image
[level
] = texImage
;
1540 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1544 else if (texImage
->Data
) {
1545 FREE(texImage
->Data
);
1546 texImage
->Data
= NULL
;
1548 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1549 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
1552 if (ctx
->NewState
& _NEW_PIXEL
)
1553 _mesa_update_state(ctx
);
1555 ASSERT(ctx
->Driver
.TexImage3D
);
1557 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, (GLint
) internalFormat
,
1558 width
, height
, depth
, border
,
1559 format
, type
, pixels
,
1560 &ctx
->Unpack
, texObj
, texImage
);
1563 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1565 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
,
1566 (GLint
) internalFormat
,
1567 width
, height
, depth
, border
,
1568 format
, GL_UNSIGNED_BYTE
, dummy
,
1569 &_mesa_native_packing
, texObj
, texImage
);
1575 /* one of these has to be non-zero! */
1576 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1577 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1578 texImage
->DepthBits
);
1579 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 _mesa_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
, 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 struct gl_texture_unit
*texUnit
;
1636 struct gl_texture_object
*texObj
;
1637 struct gl_texture_image
*texImage
;
1638 GET_CURRENT_CONTEXT(ctx
);
1639 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1641 if (ctx
->NewState
& _NEW_PIXEL
)
1642 _mesa_update_state(ctx
);
1644 /* XXX should test internal format */
1645 if (is_color_format(format
)) {
1646 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1649 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1650 postConvWidth
, 1, 1, format
, type
)) {
1651 return; /* error was detected */
1654 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1655 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1656 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1659 if (width
== 0 || !pixels
)
1660 return; /* no-op, not an error */
1662 ASSERT(ctx
->Driver
.TexSubImage1D
);
1663 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1664 format
, type
, pixels
, &ctx
->Unpack
,
1666 ctx
->NewState
|= _NEW_TEXTURE
;
1671 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1672 GLint xoffset
, GLint yoffset
,
1673 GLsizei width
, GLsizei height
,
1674 GLenum format
, GLenum type
,
1675 const GLvoid
*pixels
)
1677 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1678 struct gl_texture_unit
*texUnit
;
1679 struct gl_texture_object
*texObj
;
1680 struct gl_texture_image
*texImage
;
1681 GET_CURRENT_CONTEXT(ctx
);
1682 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1684 if (ctx
->NewState
& _NEW_PIXEL
)
1685 _mesa_update_state(ctx
);
1687 /* XXX should test internal format */
1688 if (is_color_format(format
)) {
1689 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1693 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1694 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1695 return; /* error was detected */
1698 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1699 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1700 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1703 if (width
== 0 || height
== 0 || !pixels
)
1704 return; /* no-op, not an error */
1706 ASSERT(ctx
->Driver
.TexSubImage2D
);
1707 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1708 width
, height
, format
, type
, pixels
,
1709 &ctx
->Unpack
, texObj
, texImage
);
1710 ctx
->NewState
|= _NEW_TEXTURE
;
1716 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1717 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1718 GLsizei width
, GLsizei height
, GLsizei depth
,
1719 GLenum format
, GLenum type
,
1720 const GLvoid
*pixels
)
1722 struct gl_texture_unit
*texUnit
;
1723 struct gl_texture_object
*texObj
;
1724 struct gl_texture_image
*texImage
;
1725 GET_CURRENT_CONTEXT(ctx
);
1726 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1728 if (ctx
->NewState
& _NEW_PIXEL
)
1729 _mesa_update_state(ctx
);
1731 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1732 width
, height
, depth
, format
, type
)) {
1733 return; /* error was detected */
1736 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1737 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1738 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1741 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1742 return; /* no-op, not an error */
1744 ASSERT(ctx
->Driver
.TexSubImage3D
);
1745 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1746 xoffset
, yoffset
, zoffset
,
1747 width
, height
, depth
,
1748 format
, type
, pixels
,
1749 &ctx
->Unpack
, texObj
, texImage
);
1750 ctx
->NewState
|= _NEW_TEXTURE
;
1756 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1757 GLenum internalFormat
,
1759 GLsizei width
, GLint border
)
1761 struct gl_texture_unit
*texUnit
;
1762 struct gl_texture_object
*texObj
;
1763 struct gl_texture_image
*texImage
;
1764 GLsizei postConvWidth
= width
;
1765 GET_CURRENT_CONTEXT(ctx
);
1766 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1768 if (ctx
->NewState
& _NEW_PIXEL
)
1769 _mesa_update_state(ctx
);
1771 if (is_color_format(internalFormat
)) {
1772 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1775 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1776 postConvWidth
, 1, border
))
1779 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1780 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1781 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1783 texImage
= _mesa_alloc_texture_image();
1784 set_tex_image(texObj
, target
, level
, texImage
);
1786 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1790 else if (texImage
->Data
) {
1791 /* free the old texture data */
1792 FREE(texImage
->Data
);
1793 texImage
->Data
= NULL
;
1796 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1797 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1798 border
, internalFormat
);
1801 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1802 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1803 x
, y
, width
, border
);
1806 texObj
->Complete
= GL_FALSE
;
1807 ctx
->NewState
|= _NEW_TEXTURE
;
1813 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1814 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1817 struct gl_texture_unit
*texUnit
;
1818 struct gl_texture_object
*texObj
;
1819 struct gl_texture_image
*texImage
;
1820 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1821 GET_CURRENT_CONTEXT(ctx
);
1822 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1824 if (ctx
->NewState
& _NEW_PIXEL
)
1825 _mesa_update_state(ctx
);
1827 if (is_color_format(internalFormat
)) {
1828 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1832 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1833 postConvWidth
, postConvHeight
, border
))
1836 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1837 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1838 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1840 texImage
= _mesa_alloc_texture_image();
1841 set_tex_image(texObj
, target
, level
, texImage
);
1843 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1847 else if (texImage
->Data
) {
1848 /* free the old texture data */
1849 FREE(texImage
->Data
);
1850 texImage
->Data
= NULL
;
1853 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1854 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1855 border
, internalFormat
);
1857 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1858 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1859 x
, y
, width
, height
, border
);
1862 texObj
->Complete
= GL_FALSE
;
1863 ctx
->NewState
|= _NEW_TEXTURE
;
1869 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1870 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1872 GLsizei postConvWidth
= width
;
1873 GET_CURRENT_CONTEXT(ctx
);
1874 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1876 if (ctx
->NewState
& _NEW_PIXEL
)
1877 _mesa_update_state(ctx
);
1879 /* XXX should test internal format */
1880 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1882 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1883 xoffset
, 0, 0, postConvWidth
, 1))
1886 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1887 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1888 ctx
->NewState
|= _NEW_TEXTURE
;
1894 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1895 GLint xoffset
, GLint yoffset
,
1896 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1898 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1899 GET_CURRENT_CONTEXT(ctx
);
1900 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1902 if (ctx
->NewState
& _NEW_PIXEL
)
1903 _mesa_update_state(ctx
);
1905 /* XXX should test internal format */
1906 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1908 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1909 postConvWidth
, postConvHeight
))
1912 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1913 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1914 xoffset
, yoffset
, x
, y
, width
, height
);
1915 ctx
->NewState
|= _NEW_TEXTURE
;
1921 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1922 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1923 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1925 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1926 GET_CURRENT_CONTEXT(ctx
);
1927 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1929 if (ctx
->NewState
& _NEW_PIXEL
)
1930 _mesa_update_state(ctx
);
1932 /* XXX should test internal format */
1933 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1935 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1936 zoffset
, postConvWidth
, postConvHeight
))
1939 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1940 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1941 xoffset
, yoffset
, zoffset
,
1942 x
, y
, width
, height
);
1943 ctx
->NewState
|= _NEW_TEXTURE
;
1949 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
1950 GLenum internalFormat
, GLsizei width
,
1951 GLint border
, GLsizei imageSize
,
1954 GET_CURRENT_CONTEXT(ctx
);
1955 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1957 switch (internalFormat
) {
1958 case GL_COMPRESSED_ALPHA_ARB
:
1959 case GL_COMPRESSED_LUMINANCE_ARB
:
1960 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1961 case GL_COMPRESSED_INTENSITY_ARB
:
1962 case GL_COMPRESSED_RGB_ARB
:
1963 case GL_COMPRESSED_RGBA_ARB
:
1964 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
1967 /* silence compiler warning */
1971 if (target
== GL_TEXTURE_1D
) {
1972 struct gl_texture_unit
*texUnit
;
1973 struct gl_texture_object
*texObj
;
1974 struct gl_texture_image
*texImage
;
1976 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1977 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
1978 return; /* error in texture image was detected */
1981 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1982 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1983 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1986 texImage
= _mesa_alloc_texture_image();
1987 texObj
->Image
[level
] = texImage
;
1989 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
1993 else if (texImage
->Data
) {
1994 FREE(texImage
->Data
);
1995 texImage
->Data
= NULL
;
1998 init_teximage_fields(ctx
, texImage
, width
, 1, 1, border
, internalFormat
);
2000 if (ctx
->Extensions
.ARB_texture_compression
) {
2001 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2002 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2003 internalFormat
, width
, border
,
2006 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2010 texObj
->Complete
= GL_FALSE
;
2011 ctx
->NewState
|= _NEW_TEXTURE
;
2013 else if (target
== GL_PROXY_TEXTURE_1D
) {
2014 /* Proxy texture: check for errors and update proxy state */
2015 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2016 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2018 struct gl_texture_unit
*texUnit
;
2019 struct gl_texture_image
*texImage
;
2020 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2021 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2022 init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2023 border
, internalFormat
);
2024 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2025 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2026 internalFormat
, GL_NONE
, GL_NONE
,
2027 width
, 1, 1, border
);
2030 /* if error, clear all proxy texture image parameters */
2031 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2032 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2037 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2044 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2045 GLenum internalFormat
, GLsizei width
,
2046 GLsizei height
, GLint border
, GLsizei imageSize
,
2049 GET_CURRENT_CONTEXT(ctx
);
2050 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2052 switch (internalFormat
) {
2053 case GL_COMPRESSED_ALPHA_ARB
:
2054 case GL_COMPRESSED_LUMINANCE_ARB
:
2055 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2056 case GL_COMPRESSED_INTENSITY_ARB
:
2057 case GL_COMPRESSED_RGB_ARB
:
2058 case GL_COMPRESSED_RGBA_ARB
:
2059 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2062 /* silence compiler warning */
2066 if (target
== GL_TEXTURE_2D
||
2067 (ctx
->Extensions
.ARB_texture_cube_map
&&
2068 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2069 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2070 struct gl_texture_unit
*texUnit
;
2071 struct gl_texture_object
*texObj
;
2072 struct gl_texture_image
*texImage
;
2074 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2075 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2076 return; /* error in texture image was detected */
2079 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2080 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2081 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2084 texImage
= _mesa_alloc_texture_image();
2085 texObj
->Image
[level
] = texImage
;
2087 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2091 else if (texImage
->Data
) {
2092 FREE(texImage
->Data
);
2093 texImage
->Data
= NULL
;
2096 init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2099 if (ctx
->Extensions
.ARB_texture_compression
) {
2100 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2101 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2102 internalFormat
, width
, height
,
2103 border
, imageSize
, data
,
2105 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2109 texObj
->Complete
= GL_FALSE
;
2110 ctx
->NewState
|= _NEW_TEXTURE
;
2112 else if (target
== GL_PROXY_TEXTURE_2D
) {
2113 /* Proxy texture: check for errors and update proxy state */
2114 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2115 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2117 struct gl_texture_unit
*texUnit
;
2118 struct gl_texture_image
*texImage
;
2119 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2120 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2121 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2122 border
, internalFormat
);
2123 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2124 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2125 internalFormat
, GL_NONE
, GL_NONE
,
2126 width
, height
, 1, border
);
2129 /* if error, clear all proxy texture image parameters */
2130 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2131 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2136 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2143 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2144 GLenum internalFormat
, GLsizei width
,
2145 GLsizei height
, GLsizei depth
, GLint border
,
2146 GLsizei imageSize
, const GLvoid
*data
)
2148 GET_CURRENT_CONTEXT(ctx
);
2149 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2151 switch (internalFormat
) {
2152 case GL_COMPRESSED_ALPHA_ARB
:
2153 case GL_COMPRESSED_LUMINANCE_ARB
:
2154 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2155 case GL_COMPRESSED_INTENSITY_ARB
:
2156 case GL_COMPRESSED_RGB_ARB
:
2157 case GL_COMPRESSED_RGBA_ARB
:
2158 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2161 /* silence compiler warning */
2165 if (target
== GL_TEXTURE_3D
) {
2166 struct gl_texture_unit
*texUnit
;
2167 struct gl_texture_object
*texObj
;
2168 struct gl_texture_image
*texImage
;
2170 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2171 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2172 return; /* error in texture image was detected */
2175 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2176 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2177 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2180 texImage
= _mesa_alloc_texture_image();
2181 texObj
->Image
[level
] = texImage
;
2183 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2187 else if (texImage
->Data
) {
2188 FREE(texImage
->Data
);
2189 texImage
->Data
= NULL
;
2192 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2195 if (ctx
->Extensions
.ARB_texture_compression
) {
2196 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2197 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2199 width
, height
, depth
,
2200 border
, imageSize
, data
,
2202 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2206 texObj
->Complete
= GL_FALSE
;
2207 ctx
->NewState
|= _NEW_TEXTURE
;
2209 else if (target
== GL_PROXY_TEXTURE_3D
) {
2210 /* Proxy texture: check for errors and update proxy state */
2211 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2212 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2214 struct gl_texture_unit
*texUnit
;
2215 struct gl_texture_image
*texImage
;
2216 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2217 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2218 init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2219 border
, internalFormat
);
2220 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2221 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2222 internalFormat
, GL_NONE
, GL_NONE
,
2223 width
, height
, depth
, border
);
2226 /* if error, clear all proxy texture image parameters */
2227 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2228 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2233 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2240 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2241 GLsizei width
, GLenum format
,
2242 GLsizei imageSize
, const GLvoid
*data
)
2244 struct gl_texture_unit
*texUnit
;
2245 struct gl_texture_object
*texObj
;
2246 struct gl_texture_image
*texImage
;
2247 GET_CURRENT_CONTEXT(ctx
);
2248 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2250 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2251 width
, 1, 1, format
, GL_NONE
)) {
2252 return; /* error was detected */
2255 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2256 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2257 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2260 if (width
== 0 || !data
)
2261 return; /* no-op, not an error */
2263 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2264 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2266 format
, imageSize
, data
,
2269 ctx
->NewState
|= _NEW_TEXTURE
;
2274 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2275 GLint yoffset
, GLsizei width
, GLsizei height
,
2276 GLenum format
, GLsizei imageSize
,
2279 struct gl_texture_unit
*texUnit
;
2280 struct gl_texture_object
*texObj
;
2281 struct gl_texture_image
*texImage
;
2282 GET_CURRENT_CONTEXT(ctx
);
2283 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2285 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2286 width
, height
, 1, format
, GL_NONE
)) {
2287 return; /* error was detected */
2290 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2291 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2292 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2295 if (width
== 0 || height
== 0 || !data
)
2296 return; /* no-op, not an error */
2298 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2299 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2300 xoffset
, yoffset
, width
, height
,
2301 format
, imageSize
, data
,
2304 ctx
->NewState
|= _NEW_TEXTURE
;
2309 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2310 GLint yoffset
, GLint zoffset
, GLsizei width
,
2311 GLsizei height
, GLsizei depth
, GLenum format
,
2312 GLsizei imageSize
, const GLvoid
*data
)
2314 struct gl_texture_unit
*texUnit
;
2315 struct gl_texture_object
*texObj
;
2316 struct gl_texture_image
*texImage
;
2317 GET_CURRENT_CONTEXT(ctx
);
2318 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2320 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2321 width
, height
, depth
, format
, GL_NONE
)) {
2322 return; /* error was detected */
2325 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2326 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2327 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2330 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2331 return; /* no-op, not an error */
2333 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2334 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2335 xoffset
, yoffset
, zoffset
,
2336 width
, height
, depth
,
2337 format
, imageSize
, data
,
2340 ctx
->NewState
|= _NEW_TEXTURE
;
2345 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2347 const struct gl_texture_unit
*texUnit
;
2348 const struct gl_texture_object
*texObj
;
2349 struct gl_texture_image
*texImage
;
2350 GET_CURRENT_CONTEXT(ctx
);
2351 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2353 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2354 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2358 if (is_proxy_target(target
)) {
2359 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2363 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2364 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2365 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2368 /* invalid mipmap level */
2369 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2373 if (!texImage
->IsCompressed
) {
2374 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2381 if (ctx
->Extensions
.ARB_texture_compression
) {
2382 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2383 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,