1 /* $Id: teximage.c,v 1.92 2001/04/19 22:39:50 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.
111 * If n < 0 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 case GL_TEXTURE_CUBE_MAP_ARB
:
422 return ctx
->Extensions
.ARB_texture_cube_map
423 ? texUnit
->CurrentCubeMap
: NULL
;
424 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
425 return ctx
->Extensions
.ARB_texture_cube_map
426 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
428 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
435 * Return the texture image struct which corresponds to target and level
436 * for the given texture unit.
438 struct gl_texture_image
*
439 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
440 GLenum target
, GLint level
)
445 return texUnit
->Current1D
->Image
[level
];
446 case GL_PROXY_TEXTURE_1D
:
447 return ctx
->Texture
.Proxy1D
->Image
[level
];
449 return texUnit
->Current2D
->Image
[level
];
450 case GL_PROXY_TEXTURE_2D
:
451 return ctx
->Texture
.Proxy2D
->Image
[level
];
453 return texUnit
->Current3D
->Image
[level
];
454 case GL_PROXY_TEXTURE_3D
:
455 return ctx
->Texture
.Proxy3D
->Image
[level
];
456 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
457 if (ctx
->Extensions
.ARB_texture_cube_map
)
458 return texUnit
->CurrentCubeMap
->Image
[level
];
461 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
462 if (ctx
->Extensions
.ARB_texture_cube_map
)
463 return texUnit
->CurrentCubeMap
->NegX
[level
];
466 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
467 if (ctx
->Extensions
.ARB_texture_cube_map
)
468 return texUnit
->CurrentCubeMap
->PosY
[level
];
471 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
472 if (ctx
->Extensions
.ARB_texture_cube_map
)
473 return texUnit
->CurrentCubeMap
->NegY
[level
];
476 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
477 if (ctx
->Extensions
.ARB_texture_cube_map
)
478 return texUnit
->CurrentCubeMap
->PosZ
[level
];
481 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
482 if (ctx
->Extensions
.ARB_texture_cube_map
)
483 return texUnit
->CurrentCubeMap
->NegZ
[level
];
486 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
487 if (ctx
->Extensions
.ARB_texture_cube_map
)
488 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
492 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
500 * glTexImage[123]D can accept a NULL image pointer. In this case we
501 * create a texture image with unspecified image contents per the OpenGL
505 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
507 const GLint components
= _mesa_components_in_format(format
);
508 const GLint numPixels
= width
* height
* depth
;
509 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
512 * Let's see if anyone finds this. If glTexImage2D() is called with
513 * a NULL image pointer then load the texture image with something
514 * interesting instead of leaving it indeterminate.
517 static const char message
[8][32] = {
521 " X X XXXX XXX XXXXX ",
524 " X X XXXXX XXX X X ",
528 GLubyte
*imgPtr
= data
;
530 for (h
= 0; h
< depth
; h
++) {
531 for (i
= 0; i
< height
; i
++) {
532 GLint srcRow
= 7 - (i
% 8);
533 for (j
= 0; j
< width
; j
++) {
534 GLint srcCol
= j
% 32;
535 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
536 for (k
= 0; k
< components
; k
++) {
550 * Reset the fields of a gl_texture_image struct to zero.
551 * This is called when a proxy texture test fails, we set all the
552 * image members (except DriverData) to zero.
553 * It's also used in glTexImage[123]D as a safeguard to be sure all
554 * required fields get initialized properly by the Driver.TexImage[123]D
558 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
)
591 img
->Format
= _mesa_base_tex_format( ctx
, 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 !_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
);
763 /* if we get here, the parameters are OK */
770 * Test glTexSubImage[123]D() parameters for errors.
772 * dimensions - must be 1 or 2 or 3
773 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
776 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
777 GLenum target
, GLint level
,
778 GLint xoffset
, GLint yoffset
, GLint zoffset
,
779 GLint width
, GLint height
, GLint depth
,
780 GLenum format
, GLenum type
)
782 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
783 struct gl_texture_image
*destTex
;
785 if (dimensions
== 1) {
786 if (target
!= GL_TEXTURE_1D
) {
787 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
791 else if (dimensions
== 2) {
792 if (ctx
->Extensions
.ARB_texture_cube_map
) {
793 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
794 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
795 target
!= GL_TEXTURE_2D
) {
796 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
800 else if (target
!= GL_TEXTURE_2D
) {
801 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
805 else if (dimensions
== 3) {
806 if (target
!= GL_TEXTURE_3D
) {
807 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
812 _mesa_problem( ctx
, "bad dims in texture_error_check" );
816 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
818 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
819 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
825 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
826 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
829 if (height
< 0 && dimensions
> 1) {
831 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
832 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
835 if (depth
< 0 && dimensions
> 2) {
837 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
838 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
842 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
845 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
849 if (xoffset
< -((GLint
)destTex
->Border
)) {
850 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
853 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
854 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
857 if (dimensions
> 1) {
858 if (yoffset
< -((GLint
)destTex
->Border
)) {
859 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
862 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
863 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
867 if (dimensions
> 2) {
868 if (zoffset
< -((GLint
)destTex
->Border
)) {
869 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
872 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
873 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
878 if (!is_compressed_format(ctx
, destTex
->IntFormat
) &&
879 !_mesa_is_legal_format_and_type(format
, type
)) {
881 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
882 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
891 * Test glCopyTexImage[12]D() parameters for errors.
892 * Input: dimensions - must be 1 or 2 or 3
893 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
896 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
897 GLenum target
, GLint level
, GLint internalFormat
,
898 GLint width
, GLint height
, GLint border
)
902 if (dimensions
== 1) {
903 if (target
!= GL_TEXTURE_1D
) {
904 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
908 else if (dimensions
== 2) {
909 if (ctx
->Extensions
.ARB_texture_cube_map
) {
910 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
911 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
912 target
!= GL_TEXTURE_2D
) {
913 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
917 else if (target
!= GL_TEXTURE_2D
) {
918 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
924 if (border
!= 0 && border
!= 1) {
926 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
927 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
932 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
933 || logbase2( width
- 2 * border
) < 0) {
935 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
936 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
941 if (dimensions
>= 2) {
942 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
943 || logbase2( height
- 2 * border
) < 0) {
945 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
946 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
951 /* For cube map, width must equal height */
952 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
953 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
954 if (width
!= height
) {
955 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
961 if (level
< 0 || level
>=ctx
->Const
.MaxTextureLevels
) {
963 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
964 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
968 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
971 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
972 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
976 /* if we get here, the parameters are OK */
982 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
983 GLenum target
, GLint level
,
984 GLint xoffset
, GLint yoffset
, GLint zoffset
,
985 GLsizei width
, GLsizei height
)
987 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
988 struct gl_texture_image
*teximage
;
990 if (dimensions
== 1) {
991 if (target
!= GL_TEXTURE_1D
) {
992 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
996 else if (dimensions
== 2) {
997 if (ctx
->Extensions
.ARB_texture_cube_map
) {
998 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
999 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1000 target
!= GL_TEXTURE_2D
) {
1001 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1005 else if (target
!= GL_TEXTURE_2D
) {
1006 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1010 else if (dimensions
== 3) {
1011 if (target
!= GL_TEXTURE_3D
) {
1012 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1017 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1019 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1020 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1026 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1027 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1030 if (dimensions
> 1 && height
< 0) {
1032 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1033 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1037 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1040 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1041 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
1045 if (xoffset
< -((GLint
)teximage
->Border
)) {
1047 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1048 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1051 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1053 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1054 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1057 if (dimensions
> 1) {
1058 if (yoffset
< -((GLint
)teximage
->Border
)) {
1060 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1061 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1064 /* NOTE: we're adding the border here, not subtracting! */
1065 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1067 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1068 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1073 if (dimensions
> 2) {
1074 if (zoffset
< -((GLint
)teximage
->Border
)) {
1076 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1077 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1080 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1082 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1083 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1088 /* if we get here, the parameters are OK */
1095 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1096 GLenum type
, GLvoid
*pixels
)
1098 const struct gl_texture_unit
*texUnit
;
1099 const struct gl_texture_object
*texObj
;
1100 struct gl_texture_image
*texImage
;
1101 GET_CURRENT_CONTEXT(ctx
);
1102 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1104 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1105 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1109 if (_mesa_sizeof_type(type
) <= 0) {
1110 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1114 if (_mesa_components_in_format(format
) <= 0 ||
1115 format
== GL_STENCIL_INDEX
) {
1116 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1120 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1121 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1124 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1125 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1128 /* XXX what if format/type doesn't match texture format/type? */
1133 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1134 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1135 if (!texObj
|| is_proxy_target(target
)) {
1136 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1140 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1142 /* invalid mipmap level, not an error */
1146 if (!texImage
->Data
) {
1147 /* no image data, not an error */
1151 if (ctx
->NewState
& _NEW_PIXEL
)
1152 _mesa_update_state(ctx
);
1154 if (is_color_format(format
) &&
1155 ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
1156 /* convert texture image to GL_RGBA, GL_FLOAT */
1157 GLint width
= texImage
->Width
;
1158 GLint height
= texImage
->Height
;
1159 GLint depth
= texImage
->Depth
;
1161 GLfloat
*tmpImage
, *convImage
;
1162 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1164 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1167 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1170 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1174 for (img
= 0; img
< depth
; img
++) {
1175 GLint convWidth
, convHeight
;
1177 /* convert texture data to GLfloat/GL_RGBA */
1178 for (row
= 0; row
< height
; row
++) {
1179 GLchan texels
[1 << MAX_TEXTURE_LEVELS
][4];
1181 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
1182 for (col
= 0; col
< width
; col
++) {
1183 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1186 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
1187 GL_RGBA
, CHAN_TYPE
, texels
,
1188 &_mesa_native_packing
,
1189 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
1194 convHeight
= height
;
1197 if (target
== GL_TEXTURE_1D
) {
1198 if (ctx
->Pixel
.Convolution1DEnabled
) {
1199 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
1203 if (ctx
->Pixel
.Convolution2DEnabled
) {
1204 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
1205 tmpImage
, convImage
);
1207 else if (ctx
->Pixel
.Separable2DEnabled
) {
1208 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
1209 tmpImage
, convImage
);
1213 /* pack convolved image */
1214 for (row
= 0; row
< convHeight
; row
++) {
1215 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
1216 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
1217 convWidth
, convHeight
,
1218 format
, type
, img
, row
, 0);
1219 _mesa_pack_float_rgba_span(ctx
, convWidth
,
1220 (const GLfloat(*)[4]) src
,
1221 format
, type
, dest
, &ctx
->Pack
,
1222 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
1230 /* no convolution, or non-rgba image */
1231 GLint width
= texImage
->Width
;
1232 GLint height
= texImage
->Height
;
1233 GLint depth
= texImage
->Depth
;
1235 for (img
= 0; img
< depth
; img
++) {
1236 for (row
= 0; row
< height
; row
++) {
1237 /* compute destination address in client memory */
1238 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1239 width
, height
, format
, type
,
1243 if (format
== GL_COLOR_INDEX
) {
1244 GLuint indexRow
[MAX_WIDTH
];
1246 for (col
= 0; col
< width
; col
++) {
1247 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1248 (GLvoid
*) &indexRow
[col
]);
1250 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1251 indexRow
, &ctx
->Pack
,
1252 ctx
->_ImageTransferState
);
1254 else if (format
== GL_DEPTH_COMPONENT
) {
1255 GLfloat depthRow
[MAX_WIDTH
];
1257 for (col
= 0; col
< width
; col
++) {
1258 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1259 (GLvoid
*) &depthRow
[col
]);
1261 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1262 depthRow
, &ctx
->Pack
);
1265 /* general case: convert row to RGBA format */
1266 GLchan rgba
[MAX_WIDTH
][4];
1268 for (col
= 0; col
< width
; col
++) {
1269 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1270 (GLvoid
*) rgba
[col
]);
1272 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1273 format
, type
, dest
, &ctx
->Pack
,
1274 ctx
->_ImageTransferState
);
1284 * Called from the API. Note that width includes the border.
1287 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1288 GLsizei width
, GLint border
, GLenum format
,
1289 GLenum type
, const GLvoid
*pixels
)
1291 GLsizei postConvWidth
= width
;
1292 GET_CURRENT_CONTEXT(ctx
);
1293 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1295 if (is_color_format(internalFormat
)) {
1296 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1299 if (target
== GL_TEXTURE_1D
) {
1300 struct gl_texture_unit
*texUnit
;
1301 struct gl_texture_object
*texObj
;
1302 struct gl_texture_image
*texImage
;
1304 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1305 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1306 return; /* error was recorded */
1309 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1310 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1311 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1314 texImage
= _mesa_alloc_texture_image();
1315 texObj
->Image
[level
] = texImage
;
1317 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1321 else if (texImage
->Data
) {
1322 /* free the old texture data */
1323 FREE(texImage
->Data
);
1324 texImage
->Data
= NULL
;
1326 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1327 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1328 border
, internalFormat
);
1330 if (ctx
->NewState
& _NEW_PIXEL
)
1331 _mesa_update_state(ctx
);
1333 ASSERT(ctx
->Driver
.TexImage1D
);
1335 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1336 width
, border
, format
, type
, pixels
,
1337 &ctx
->Unpack
, texObj
, texImage
);
1340 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1342 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1344 format
, GL_UNSIGNED_BYTE
, dummy
,
1345 &_mesa_native_packing
, texObj
, texImage
);
1350 ASSERT(texImage
->TexFormat
);
1351 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1352 ASSERT(texImage
->FetchTexel
);
1355 texObj
->Complete
= GL_FALSE
;
1356 ctx
->NewState
|= _NEW_TEXTURE
;
1358 else if (target
== GL_PROXY_TEXTURE_1D
) {
1359 /* Proxy texture: check for errors and update proxy state */
1360 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1362 postConvWidth
, 1, 1, border
);
1364 struct gl_texture_unit
*texUnit
;
1365 struct gl_texture_image
*texImage
;
1366 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1367 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1368 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1369 border
, internalFormat
);
1370 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1371 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1372 internalFormat
, format
, type
,
1373 postConvWidth
, 1, 1, border
);
1376 /* if error, clear all proxy texture image parameters */
1377 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1378 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1383 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1390 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1391 GLsizei width
, GLsizei height
, GLint border
,
1392 GLenum format
, GLenum type
,
1393 const GLvoid
*pixels
)
1395 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1396 GET_CURRENT_CONTEXT(ctx
);
1397 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1399 if (is_color_format(internalFormat
)) {
1400 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1404 if (target
== GL_TEXTURE_2D
||
1405 (ctx
->Extensions
.ARB_texture_cube_map
&&
1406 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1407 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1408 /* non-proxy target */
1409 struct gl_texture_unit
*texUnit
;
1410 struct gl_texture_object
*texObj
;
1411 struct gl_texture_image
*texImage
;
1413 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1414 format
, type
, 2, postConvWidth
, postConvHeight
,
1416 return; /* error was recorded */
1419 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1420 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1421 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1424 texImage
= _mesa_alloc_texture_image();
1425 set_tex_image(texObj
, target
, level
, texImage
);
1427 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1431 else if (texImage
->Data
) {
1432 /* free the old texture data */
1433 FREE(texImage
->Data
);
1434 texImage
->Data
= NULL
;
1436 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1437 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1438 border
, internalFormat
);
1440 if (ctx
->NewState
& _NEW_PIXEL
)
1441 _mesa_update_state(ctx
);
1443 ASSERT(ctx
->Driver
.TexImage2D
);
1445 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1446 width
, height
, border
, format
, type
, pixels
,
1447 &ctx
->Unpack
, texObj
, texImage
);
1450 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1452 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1453 width
, height
, border
,
1454 format
, GL_UNSIGNED_BYTE
, dummy
,
1455 &_mesa_native_packing
, texObj
, texImage
);
1460 ASSERT(texImage
->TexFormat
);
1461 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1462 ASSERT(texImage
->FetchTexel
);
1465 texObj
->Complete
= GL_FALSE
;
1466 ctx
->NewState
|= _NEW_TEXTURE
;
1468 else if (target
== GL_PROXY_TEXTURE_2D
) {
1469 /* Proxy texture: check for errors and update proxy state */
1470 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1472 postConvWidth
, postConvHeight
, 1, border
);
1474 struct gl_texture_unit
*texUnit
;
1475 struct gl_texture_image
*texImage
;
1476 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1477 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1478 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1479 border
, internalFormat
);
1480 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1481 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1482 internalFormat
, format
, type
,
1483 postConvWidth
, postConvHeight
, 1, border
);
1486 /* if error, clear all proxy texture image parameters */
1487 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1488 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1493 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1500 * Called by the API or display list executor.
1501 * Note that width and height include the border.
1504 _mesa_TexImage3D( GLenum target
, GLint level
, GLenum internalFormat
,
1505 GLsizei width
, GLsizei height
, GLsizei depth
,
1506 GLint border
, GLenum format
, GLenum type
,
1507 const GLvoid
*pixels
)
1509 GET_CURRENT_CONTEXT(ctx
);
1510 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1512 if (target
== GL_TEXTURE_3D
) {
1513 struct gl_texture_unit
*texUnit
;
1514 struct gl_texture_object
*texObj
;
1515 struct gl_texture_image
*texImage
;
1517 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1518 format
, type
, 3, width
, height
, depth
, border
)) {
1519 return; /* error was recorded */
1522 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1523 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1524 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1527 texImage
= _mesa_alloc_texture_image();
1528 texObj
->Image
[level
] = texImage
;
1530 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1534 else if (texImage
->Data
) {
1535 FREE(texImage
->Data
);
1536 texImage
->Data
= NULL
;
1538 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1539 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
1542 if (ctx
->NewState
& _NEW_PIXEL
)
1543 _mesa_update_state(ctx
);
1545 ASSERT(ctx
->Driver
.TexImage3D
);
1547 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, (GLint
) internalFormat
,
1548 width
, height
, depth
, border
,
1549 format
, type
, pixels
,
1550 &ctx
->Unpack
, texObj
, texImage
);
1553 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1555 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
,
1556 (GLint
) internalFormat
,
1557 width
, height
, depth
, border
,
1558 format
, GL_UNSIGNED_BYTE
, dummy
,
1559 &_mesa_native_packing
, texObj
, texImage
);
1564 ASSERT(texImage
->TexFormat
);
1565 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1566 ASSERT(texImage
->FetchTexel
);
1569 texObj
->Complete
= GL_FALSE
;
1570 ctx
->NewState
|= _NEW_TEXTURE
;
1572 else if (target
== GL_PROXY_TEXTURE_3D
) {
1573 /* Proxy texture: check for errors and update proxy state */
1574 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1575 format
, type
, 3, width
, height
, depth
, border
);
1577 struct gl_texture_unit
*texUnit
;
1578 struct gl_texture_image
*texImage
;
1579 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1580 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1581 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
1582 border
, internalFormat
);
1583 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1584 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1585 internalFormat
, format
, type
,
1586 width
, height
, depth
, border
);
1589 /* if error, clear all proxy texture image parameters */
1590 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1591 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1596 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1603 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1604 GLsizei width
, GLsizei height
, GLsizei depth
,
1605 GLint border
, GLenum format
, GLenum type
,
1606 const GLvoid
*pixels
)
1608 _mesa_TexImage3D(target
, level
, internalFormat
, width
, height
,
1609 depth
, border
, format
, type
, pixels
);
1615 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1616 GLint xoffset
, GLsizei width
,
1617 GLenum format
, GLenum type
,
1618 const GLvoid
*pixels
)
1620 GLsizei postConvWidth
= width
;
1621 struct gl_texture_unit
*texUnit
;
1622 struct gl_texture_object
*texObj
;
1623 struct gl_texture_image
*texImage
;
1624 GET_CURRENT_CONTEXT(ctx
);
1625 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1627 if (ctx
->NewState
& _NEW_PIXEL
)
1628 _mesa_update_state(ctx
);
1630 /* XXX should test internal format */
1631 if (is_color_format(format
)) {
1632 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1635 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1636 postConvWidth
, 1, 1, format
, type
)) {
1637 return; /* error was detected */
1640 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1641 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1642 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1645 if (width
== 0 || !pixels
)
1646 return; /* no-op, not an error */
1648 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1649 xoffset
+= texImage
->Border
;
1651 ASSERT(ctx
->Driver
.TexSubImage1D
);
1652 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1653 format
, type
, pixels
, &ctx
->Unpack
,
1655 ctx
->NewState
|= _NEW_TEXTURE
;
1660 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1661 GLint xoffset
, GLint yoffset
,
1662 GLsizei width
, GLsizei height
,
1663 GLenum format
, GLenum type
,
1664 const GLvoid
*pixels
)
1666 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1667 struct gl_texture_unit
*texUnit
;
1668 struct gl_texture_object
*texObj
;
1669 struct gl_texture_image
*texImage
;
1670 GET_CURRENT_CONTEXT(ctx
);
1671 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1673 if (ctx
->NewState
& _NEW_PIXEL
)
1674 _mesa_update_state(ctx
);
1676 /* XXX should test internal format */
1677 if (is_color_format(format
)) {
1678 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1682 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1683 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1684 return; /* error was detected */
1687 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1688 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1689 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1692 if (width
== 0 || height
== 0 || !pixels
)
1693 return; /* no-op, not an error */
1695 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1696 xoffset
+= texImage
->Border
;
1697 yoffset
+= texImage
->Border
;
1699 ASSERT(ctx
->Driver
.TexSubImage2D
);
1700 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1701 width
, height
, format
, type
, pixels
,
1702 &ctx
->Unpack
, texObj
, texImage
);
1703 ctx
->NewState
|= _NEW_TEXTURE
;
1709 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1710 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1711 GLsizei width
, GLsizei height
, GLsizei depth
,
1712 GLenum format
, GLenum type
,
1713 const GLvoid
*pixels
)
1715 struct gl_texture_unit
*texUnit
;
1716 struct gl_texture_object
*texObj
;
1717 struct gl_texture_image
*texImage
;
1718 GET_CURRENT_CONTEXT(ctx
);
1719 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1721 if (ctx
->NewState
& _NEW_PIXEL
)
1722 _mesa_update_state(ctx
);
1724 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1725 width
, height
, depth
, format
, type
)) {
1726 return; /* error was detected */
1729 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1730 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1731 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1734 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1735 return; /* no-op, not an error */
1737 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1738 xoffset
+= texImage
->Border
;
1739 yoffset
+= texImage
->Border
;
1740 zoffset
+= texImage
->Border
;
1742 ASSERT(ctx
->Driver
.TexSubImage3D
);
1743 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1744 xoffset
, yoffset
, zoffset
,
1745 width
, height
, depth
,
1746 format
, type
, pixels
,
1747 &ctx
->Unpack
, texObj
, texImage
);
1748 ctx
->NewState
|= _NEW_TEXTURE
;
1754 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1755 GLenum internalFormat
,
1757 GLsizei width
, GLint border
)
1759 struct gl_texture_unit
*texUnit
;
1760 struct gl_texture_object
*texObj
;
1761 struct gl_texture_image
*texImage
;
1762 GLsizei postConvWidth
= width
;
1763 GET_CURRENT_CONTEXT(ctx
);
1764 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1766 if (ctx
->NewState
& _NEW_PIXEL
)
1767 _mesa_update_state(ctx
);
1769 if (is_color_format(internalFormat
)) {
1770 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1773 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1774 postConvWidth
, 1, border
))
1777 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1778 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1779 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1781 texImage
= _mesa_alloc_texture_image();
1782 set_tex_image(texObj
, target
, level
, texImage
);
1784 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1788 else if (texImage
->Data
) {
1789 /* free the old texture data */
1790 FREE(texImage
->Data
);
1791 texImage
->Data
= NULL
;
1794 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1795 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1796 border
, internalFormat
);
1799 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1800 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1801 x
, y
, width
, border
);
1803 ASSERT(texImage
->TexFormat
);
1804 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1805 ASSERT(texImage
->FetchTexel
);
1808 texObj
->Complete
= GL_FALSE
;
1809 ctx
->NewState
|= _NEW_TEXTURE
;
1815 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1816 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1819 struct gl_texture_unit
*texUnit
;
1820 struct gl_texture_object
*texObj
;
1821 struct gl_texture_image
*texImage
;
1822 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1823 GET_CURRENT_CONTEXT(ctx
);
1824 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1826 if (ctx
->NewState
& _NEW_PIXEL
)
1827 _mesa_update_state(ctx
);
1829 if (is_color_format(internalFormat
)) {
1830 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1834 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1835 postConvWidth
, postConvHeight
, border
))
1838 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1839 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1840 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1842 texImage
= _mesa_alloc_texture_image();
1843 set_tex_image(texObj
, target
, level
, texImage
);
1845 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1849 else if (texImage
->Data
) {
1850 /* free the old texture data */
1851 FREE(texImage
->Data
);
1852 texImage
->Data
= NULL
;
1855 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1856 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1857 border
, internalFormat
);
1859 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1860 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1861 x
, y
, width
, height
, border
);
1863 ASSERT(texImage
->TexFormat
);
1864 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1865 ASSERT(texImage
->FetchTexel
);
1868 texObj
->Complete
= GL_FALSE
;
1869 ctx
->NewState
|= _NEW_TEXTURE
;
1875 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1876 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1878 struct gl_texture_unit
*texUnit
;
1879 struct gl_texture_object
*texObj
;
1880 struct gl_texture_image
*texImage
;
1881 GLsizei postConvWidth
= width
;
1882 GET_CURRENT_CONTEXT(ctx
);
1883 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1885 if (ctx
->NewState
& _NEW_PIXEL
)
1886 _mesa_update_state(ctx
);
1888 /* XXX should test internal format */
1889 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1891 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1892 xoffset
, 0, 0, postConvWidth
, 1))
1895 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1896 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1897 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1899 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1900 xoffset
+= texImage
->Border
;
1902 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1903 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1904 ctx
->NewState
|= _NEW_TEXTURE
;
1910 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1911 GLint xoffset
, GLint yoffset
,
1912 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1914 struct gl_texture_unit
*texUnit
;
1915 struct gl_texture_object
*texObj
;
1916 struct gl_texture_image
*texImage
;
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 _mesa_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
, 2, target
, level
, xoffset
, yoffset
, 0,
1928 postConvWidth
, postConvHeight
))
1931 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1932 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1933 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1935 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1936 xoffset
+= texImage
->Border
;
1937 yoffset
+= texImage
->Border
;
1939 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1940 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1941 xoffset
, yoffset
, x
, y
, width
, height
);
1942 ctx
->NewState
|= _NEW_TEXTURE
;
1948 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1949 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1950 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1952 struct gl_texture_unit
*texUnit
;
1953 struct gl_texture_object
*texObj
;
1954 struct gl_texture_image
*texImage
;
1955 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1956 GET_CURRENT_CONTEXT(ctx
);
1957 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1959 if (ctx
->NewState
& _NEW_PIXEL
)
1960 _mesa_update_state(ctx
);
1962 /* XXX should test internal format */
1963 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1965 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1966 zoffset
, postConvWidth
, postConvHeight
))
1969 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1970 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1971 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1973 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1974 xoffset
+= texImage
->Border
;
1975 yoffset
+= texImage
->Border
;
1976 zoffset
+= texImage
->Border
;
1978 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1979 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1980 xoffset
, yoffset
, zoffset
,
1981 x
, y
, width
, height
);
1982 ctx
->NewState
|= _NEW_TEXTURE
;
1988 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
1989 GLenum internalFormat
, GLsizei width
,
1990 GLint border
, GLsizei imageSize
,
1993 GET_CURRENT_CONTEXT(ctx
);
1994 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1996 switch (internalFormat
) {
1997 case GL_COMPRESSED_ALPHA_ARB
:
1998 case GL_COMPRESSED_LUMINANCE_ARB
:
1999 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2000 case GL_COMPRESSED_INTENSITY_ARB
:
2001 case GL_COMPRESSED_RGB_ARB
:
2002 case GL_COMPRESSED_RGBA_ARB
:
2003 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2006 /* silence compiler warning */
2010 if (target
== GL_TEXTURE_1D
) {
2011 struct gl_texture_unit
*texUnit
;
2012 struct gl_texture_object
*texObj
;
2013 struct gl_texture_image
*texImage
;
2015 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2016 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2017 return; /* error in texture image was detected */
2020 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2021 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2022 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2025 texImage
= _mesa_alloc_texture_image();
2026 texObj
->Image
[level
] = texImage
;
2028 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2032 else if (texImage
->Data
) {
2033 FREE(texImage
->Data
);
2034 texImage
->Data
= NULL
;
2037 init_teximage_fields(ctx
, texImage
, width
, 1, 1, border
, internalFormat
);
2039 if (ctx
->Extensions
.ARB_texture_compression
) {
2040 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2041 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2042 internalFormat
, width
, border
,
2045 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2049 texObj
->Complete
= GL_FALSE
;
2050 ctx
->NewState
|= _NEW_TEXTURE
;
2052 else if (target
== GL_PROXY_TEXTURE_1D
) {
2053 /* Proxy texture: check for errors and update proxy state */
2054 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2055 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2057 struct gl_texture_unit
*texUnit
;
2058 struct gl_texture_image
*texImage
;
2059 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2060 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2061 init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2062 border
, internalFormat
);
2063 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2064 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2065 internalFormat
, GL_NONE
, GL_NONE
,
2066 width
, 1, 1, border
);
2069 /* if error, clear all proxy texture image parameters */
2070 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2071 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2076 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2083 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2084 GLenum internalFormat
, GLsizei width
,
2085 GLsizei height
, GLint border
, GLsizei imageSize
,
2088 GET_CURRENT_CONTEXT(ctx
);
2089 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2091 switch (internalFormat
) {
2092 case GL_COMPRESSED_ALPHA_ARB
:
2093 case GL_COMPRESSED_LUMINANCE_ARB
:
2094 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2095 case GL_COMPRESSED_INTENSITY_ARB
:
2096 case GL_COMPRESSED_RGB_ARB
:
2097 case GL_COMPRESSED_RGBA_ARB
:
2098 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2101 /* silence compiler warning */
2105 if (target
== GL_TEXTURE_2D
||
2106 (ctx
->Extensions
.ARB_texture_cube_map
&&
2107 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2108 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2109 struct gl_texture_unit
*texUnit
;
2110 struct gl_texture_object
*texObj
;
2111 struct gl_texture_image
*texImage
;
2113 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2114 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2115 return; /* error in texture image was detected */
2118 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2119 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2120 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2123 texImage
= _mesa_alloc_texture_image();
2124 texObj
->Image
[level
] = texImage
;
2126 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2130 else if (texImage
->Data
) {
2131 FREE(texImage
->Data
);
2132 texImage
->Data
= NULL
;
2135 init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2138 if (ctx
->Extensions
.ARB_texture_compression
) {
2139 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2140 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2141 internalFormat
, width
, height
,
2142 border
, imageSize
, data
,
2144 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2148 texObj
->Complete
= GL_FALSE
;
2149 ctx
->NewState
|= _NEW_TEXTURE
;
2151 else if (target
== GL_PROXY_TEXTURE_2D
) {
2152 /* Proxy texture: check for errors and update proxy state */
2153 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2154 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2156 struct gl_texture_unit
*texUnit
;
2157 struct gl_texture_image
*texImage
;
2158 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2159 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2160 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2161 border
, internalFormat
);
2162 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2163 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2164 internalFormat
, GL_NONE
, GL_NONE
,
2165 width
, height
, 1, border
);
2168 /* if error, clear all proxy texture image parameters */
2169 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2170 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2175 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2182 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2183 GLenum internalFormat
, GLsizei width
,
2184 GLsizei height
, GLsizei depth
, GLint border
,
2185 GLsizei imageSize
, const GLvoid
*data
)
2187 GET_CURRENT_CONTEXT(ctx
);
2188 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2190 switch (internalFormat
) {
2191 case GL_COMPRESSED_ALPHA_ARB
:
2192 case GL_COMPRESSED_LUMINANCE_ARB
:
2193 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2194 case GL_COMPRESSED_INTENSITY_ARB
:
2195 case GL_COMPRESSED_RGB_ARB
:
2196 case GL_COMPRESSED_RGBA_ARB
:
2197 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2200 /* silence compiler warning */
2204 if (target
== GL_TEXTURE_3D
) {
2205 struct gl_texture_unit
*texUnit
;
2206 struct gl_texture_object
*texObj
;
2207 struct gl_texture_image
*texImage
;
2209 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2210 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2211 return; /* error in texture image was detected */
2214 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2215 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2216 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2219 texImage
= _mesa_alloc_texture_image();
2220 texObj
->Image
[level
] = texImage
;
2222 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2226 else if (texImage
->Data
) {
2227 FREE(texImage
->Data
);
2228 texImage
->Data
= NULL
;
2231 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2234 if (ctx
->Extensions
.ARB_texture_compression
) {
2235 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2236 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2238 width
, height
, depth
,
2239 border
, imageSize
, data
,
2241 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2245 texObj
->Complete
= GL_FALSE
;
2246 ctx
->NewState
|= _NEW_TEXTURE
;
2248 else if (target
== GL_PROXY_TEXTURE_3D
) {
2249 /* Proxy texture: check for errors and update proxy state */
2250 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2251 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2253 struct gl_texture_unit
*texUnit
;
2254 struct gl_texture_image
*texImage
;
2255 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2256 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2257 init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2258 border
, internalFormat
);
2259 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2260 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2261 internalFormat
, GL_NONE
, GL_NONE
,
2262 width
, height
, depth
, border
);
2265 /* if error, clear all proxy texture image parameters */
2266 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2267 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2272 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2279 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2280 GLsizei width
, GLenum format
,
2281 GLsizei imageSize
, const GLvoid
*data
)
2283 struct gl_texture_unit
*texUnit
;
2284 struct gl_texture_object
*texObj
;
2285 struct gl_texture_image
*texImage
;
2286 GET_CURRENT_CONTEXT(ctx
);
2287 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2289 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2290 width
, 1, 1, format
, GL_NONE
)) {
2291 return; /* error was detected */
2294 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2295 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2296 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2299 if (width
== 0 || !data
)
2300 return; /* no-op, not an error */
2302 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2303 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2305 format
, imageSize
, data
,
2308 ctx
->NewState
|= _NEW_TEXTURE
;
2313 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2314 GLint yoffset
, GLsizei width
, GLsizei height
,
2315 GLenum format
, GLsizei imageSize
,
2318 struct gl_texture_unit
*texUnit
;
2319 struct gl_texture_object
*texObj
;
2320 struct gl_texture_image
*texImage
;
2321 GET_CURRENT_CONTEXT(ctx
);
2322 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2324 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2325 width
, height
, 1, format
, GL_NONE
)) {
2326 return; /* error was detected */
2329 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2330 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2331 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2334 if (width
== 0 || height
== 0 || !data
)
2335 return; /* no-op, not an error */
2337 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2338 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2339 xoffset
, yoffset
, width
, height
,
2340 format
, imageSize
, data
,
2343 ctx
->NewState
|= _NEW_TEXTURE
;
2348 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2349 GLint yoffset
, GLint zoffset
, GLsizei width
,
2350 GLsizei height
, GLsizei depth
, GLenum format
,
2351 GLsizei imageSize
, const GLvoid
*data
)
2353 struct gl_texture_unit
*texUnit
;
2354 struct gl_texture_object
*texObj
;
2355 struct gl_texture_image
*texImage
;
2356 GET_CURRENT_CONTEXT(ctx
);
2357 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2359 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2360 width
, height
, depth
, format
, GL_NONE
)) {
2361 return; /* error was detected */
2364 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2365 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2366 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2369 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2370 return; /* no-op, not an error */
2372 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2373 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2374 xoffset
, yoffset
, zoffset
,
2375 width
, height
, depth
,
2376 format
, imageSize
, data
,
2379 ctx
->NewState
|= _NEW_TEXTURE
;
2384 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2386 const struct gl_texture_unit
*texUnit
;
2387 const struct gl_texture_object
*texObj
;
2388 struct gl_texture_image
*texImage
;
2389 GET_CURRENT_CONTEXT(ctx
);
2390 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2392 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2393 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2397 if (is_proxy_target(target
)) {
2398 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2402 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2403 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2404 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2407 /* invalid mipmap level */
2408 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2412 if (!texImage
->IsCompressed
) {
2413 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2420 if (ctx
->Extensions
.ARB_texture_compression
) {
2421 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2422 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,