1 /* $Id: teximage.c,v 1.86 2001/03/19 02:25:35 keithw 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
, GLint 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
, 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
, 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
, internalFormat
,
1566 width
, height
, depth
, border
,
1567 format
, GL_UNSIGNED_BYTE
, dummy
,
1568 &_mesa_native_packing
, texObj
, texImage
);
1574 /* one of these has to be non-zero! */
1575 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1576 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1577 texImage
->DepthBits
);
1578 ASSERT(texImage
->FetchTexel
);
1582 texObj
->Complete
= GL_FALSE
;
1583 ctx
->NewState
|= _NEW_TEXTURE
;
1585 else if (target
== GL_PROXY_TEXTURE_3D
) {
1586 /* Proxy texture: check for errors and update proxy state */
1587 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1588 format
, type
, 3, width
, height
, depth
, border
);
1590 struct gl_texture_unit
*texUnit
;
1591 struct gl_texture_image
*texImage
;
1592 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1593 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1594 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
1595 border
, internalFormat
);
1596 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1597 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1598 internalFormat
, format
, type
,
1599 width
, height
, depth
, border
);
1602 /* if error, clear all proxy texture image parameters */
1603 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1604 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1609 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1616 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1617 GLsizei width
, GLsizei height
, GLsizei depth
,
1618 GLint border
, GLenum format
, GLenum type
,
1619 const GLvoid
*pixels
)
1621 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1622 depth
, border
, format
, type
, pixels
);
1628 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1629 GLint xoffset
, GLsizei width
,
1630 GLenum format
, GLenum type
,
1631 const GLvoid
*pixels
)
1633 GLsizei postConvWidth
= width
;
1634 struct gl_texture_unit
*texUnit
;
1635 struct gl_texture_object
*texObj
;
1636 struct gl_texture_image
*texImage
;
1637 GET_CURRENT_CONTEXT(ctx
);
1638 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1640 if (ctx
->NewState
& _NEW_PIXEL
)
1641 _mesa_update_state(ctx
);
1643 /* XXX should test internal format */
1644 if (is_color_format(format
)) {
1645 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1648 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1649 postConvWidth
, 1, 1, format
, type
)) {
1650 return; /* error was detected */
1653 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1654 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1655 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1658 if (width
== 0 || !pixels
)
1659 return; /* no-op, not an error */
1661 ASSERT(ctx
->Driver
.TexSubImage1D
);
1662 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1663 format
, type
, pixels
, &ctx
->Unpack
,
1665 ctx
->NewState
|= _NEW_TEXTURE
;
1670 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1671 GLint xoffset
, GLint yoffset
,
1672 GLsizei width
, GLsizei height
,
1673 GLenum format
, GLenum type
,
1674 const GLvoid
*pixels
)
1676 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1677 struct gl_texture_unit
*texUnit
;
1678 struct gl_texture_object
*texObj
;
1679 struct gl_texture_image
*texImage
;
1680 GET_CURRENT_CONTEXT(ctx
);
1681 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1683 if (ctx
->NewState
& _NEW_PIXEL
)
1684 _mesa_update_state(ctx
);
1686 /* XXX should test internal format */
1687 if (is_color_format(format
)) {
1688 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1692 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1693 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1694 return; /* error was detected */
1697 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1698 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1699 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1702 if (width
== 0 || height
== 0 || !pixels
)
1703 return; /* no-op, not an error */
1705 ASSERT(ctx
->Driver
.TexSubImage2D
);
1706 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1707 width
, height
, format
, type
, pixels
,
1708 &ctx
->Unpack
, texObj
, texImage
);
1709 ctx
->NewState
|= _NEW_TEXTURE
;
1715 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1716 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1717 GLsizei width
, GLsizei height
, GLsizei depth
,
1718 GLenum format
, GLenum type
,
1719 const GLvoid
*pixels
)
1721 struct gl_texture_unit
*texUnit
;
1722 struct gl_texture_object
*texObj
;
1723 struct gl_texture_image
*texImage
;
1724 GET_CURRENT_CONTEXT(ctx
);
1725 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1727 if (ctx
->NewState
& _NEW_PIXEL
)
1728 _mesa_update_state(ctx
);
1730 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1731 width
, height
, depth
, format
, type
)) {
1732 return; /* error was detected */
1735 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1736 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1737 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1740 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1741 return; /* no-op, not an error */
1743 ASSERT(ctx
->Driver
.TexSubImage3D
);
1744 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1745 xoffset
, yoffset
, zoffset
,
1746 width
, height
, depth
,
1747 format
, type
, pixels
,
1748 &ctx
->Unpack
, texObj
, texImage
);
1749 ctx
->NewState
|= _NEW_TEXTURE
;
1755 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1756 GLenum internalFormat
,
1758 GLsizei width
, GLint border
)
1760 struct gl_texture_unit
*texUnit
;
1761 struct gl_texture_object
*texObj
;
1762 struct gl_texture_image
*texImage
;
1763 GLsizei postConvWidth
= width
;
1764 GET_CURRENT_CONTEXT(ctx
);
1765 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1767 if (ctx
->NewState
& _NEW_PIXEL
)
1768 _mesa_update_state(ctx
);
1770 if (is_color_format(internalFormat
)) {
1771 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1774 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1775 postConvWidth
, 1, border
))
1778 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1779 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1780 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1782 texImage
= _mesa_alloc_texture_image();
1783 set_tex_image(texObj
, target
, level
, texImage
);
1785 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1789 else if (texImage
->Data
) {
1790 /* free the old texture data */
1791 FREE(texImage
->Data
);
1792 texImage
->Data
= NULL
;
1795 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1796 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1797 border
, internalFormat
);
1800 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1801 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1802 x
, y
, width
, border
);
1805 texObj
->Complete
= GL_FALSE
;
1806 ctx
->NewState
|= _NEW_TEXTURE
;
1812 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1813 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1816 struct gl_texture_unit
*texUnit
;
1817 struct gl_texture_object
*texObj
;
1818 struct gl_texture_image
*texImage
;
1819 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1820 GET_CURRENT_CONTEXT(ctx
);
1821 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1823 if (ctx
->NewState
& _NEW_PIXEL
)
1824 _mesa_update_state(ctx
);
1826 if (is_color_format(internalFormat
)) {
1827 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1831 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1832 postConvWidth
, postConvHeight
, border
))
1835 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1836 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1837 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1839 texImage
= _mesa_alloc_texture_image();
1840 set_tex_image(texObj
, target
, level
, texImage
);
1842 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1846 else if (texImage
->Data
) {
1847 /* free the old texture data */
1848 FREE(texImage
->Data
);
1849 texImage
->Data
= NULL
;
1852 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1853 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1854 border
, internalFormat
);
1856 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1857 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1858 x
, y
, width
, height
, border
);
1861 texObj
->Complete
= GL_FALSE
;
1862 ctx
->NewState
|= _NEW_TEXTURE
;
1868 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1869 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1871 GLsizei postConvWidth
= width
;
1872 GET_CURRENT_CONTEXT(ctx
);
1873 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1875 if (ctx
->NewState
& _NEW_PIXEL
)
1876 _mesa_update_state(ctx
);
1878 /* XXX should test internal format */
1879 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1881 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1882 xoffset
, 0, 0, postConvWidth
, 1))
1885 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1886 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1887 ctx
->NewState
|= _NEW_TEXTURE
;
1893 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1894 GLint xoffset
, GLint yoffset
,
1895 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1897 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1898 GET_CURRENT_CONTEXT(ctx
);
1899 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1901 if (ctx
->NewState
& _NEW_PIXEL
)
1902 _mesa_update_state(ctx
);
1904 /* XXX should test internal format */
1905 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1907 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1908 postConvWidth
, postConvHeight
))
1911 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1912 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1913 xoffset
, yoffset
, x
, y
, width
, height
);
1914 ctx
->NewState
|= _NEW_TEXTURE
;
1920 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1921 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1922 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1924 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1925 GET_CURRENT_CONTEXT(ctx
);
1926 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1928 if (ctx
->NewState
& _NEW_PIXEL
)
1929 _mesa_update_state(ctx
);
1931 /* XXX should test internal format */
1932 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1934 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1935 zoffset
, postConvWidth
, postConvHeight
))
1938 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1939 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1940 xoffset
, yoffset
, zoffset
,
1941 x
, y
, width
, height
);
1942 ctx
->NewState
|= _NEW_TEXTURE
;
1948 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
1949 GLenum internalFormat
, GLsizei width
,
1950 GLint border
, GLsizei imageSize
,
1953 GET_CURRENT_CONTEXT(ctx
);
1954 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1956 switch (internalFormat
) {
1957 case GL_COMPRESSED_ALPHA_ARB
:
1958 case GL_COMPRESSED_LUMINANCE_ARB
:
1959 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1960 case GL_COMPRESSED_INTENSITY_ARB
:
1961 case GL_COMPRESSED_RGB_ARB
:
1962 case GL_COMPRESSED_RGBA_ARB
:
1963 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
1966 /* silence compiler warning */
1970 if (target
== GL_TEXTURE_1D
) {
1971 struct gl_texture_unit
*texUnit
;
1972 struct gl_texture_object
*texObj
;
1973 struct gl_texture_image
*texImage
;
1975 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1976 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
1977 return; /* error in texture image was detected */
1980 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1981 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1982 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1985 texImage
= _mesa_alloc_texture_image();
1986 texObj
->Image
[level
] = texImage
;
1988 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
1992 else if (texImage
->Data
) {
1993 FREE(texImage
->Data
);
1994 texImage
->Data
= NULL
;
1997 init_teximage_fields(ctx
, texImage
, width
, 1, 1, border
, internalFormat
);
1999 if (ctx
->Extensions
.ARB_texture_compression
) {
2000 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2001 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2002 internalFormat
, width
, border
,
2005 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2009 texObj
->Complete
= GL_FALSE
;
2010 ctx
->NewState
|= _NEW_TEXTURE
;
2012 else if (target
== GL_PROXY_TEXTURE_1D
) {
2013 /* Proxy texture: check for errors and update proxy state */
2014 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2015 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2017 struct gl_texture_unit
*texUnit
;
2018 struct gl_texture_image
*texImage
;
2019 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2020 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2021 init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2022 border
, internalFormat
);
2023 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2024 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2025 internalFormat
, GL_NONE
, GL_NONE
,
2026 width
, 1, 1, border
);
2029 /* if error, clear all proxy texture image parameters */
2030 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2031 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2036 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2043 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2044 GLenum internalFormat
, GLsizei width
,
2045 GLsizei height
, GLint border
, GLsizei imageSize
,
2048 GET_CURRENT_CONTEXT(ctx
);
2049 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2051 switch (internalFormat
) {
2052 case GL_COMPRESSED_ALPHA_ARB
:
2053 case GL_COMPRESSED_LUMINANCE_ARB
:
2054 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2055 case GL_COMPRESSED_INTENSITY_ARB
:
2056 case GL_COMPRESSED_RGB_ARB
:
2057 case GL_COMPRESSED_RGBA_ARB
:
2058 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2061 /* silence compiler warning */
2065 if (target
== GL_TEXTURE_2D
||
2066 (ctx
->Extensions
.ARB_texture_cube_map
&&
2067 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2068 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2069 struct gl_texture_unit
*texUnit
;
2070 struct gl_texture_object
*texObj
;
2071 struct gl_texture_image
*texImage
;
2073 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2074 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2075 return; /* error in texture image was detected */
2078 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2079 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2080 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2083 texImage
= _mesa_alloc_texture_image();
2084 texObj
->Image
[level
] = texImage
;
2086 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2090 else if (texImage
->Data
) {
2091 FREE(texImage
->Data
);
2092 texImage
->Data
= NULL
;
2095 init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2098 if (ctx
->Extensions
.ARB_texture_compression
) {
2099 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2100 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2101 internalFormat
, width
, height
,
2102 border
, imageSize
, data
,
2104 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2108 texObj
->Complete
= GL_FALSE
;
2109 ctx
->NewState
|= _NEW_TEXTURE
;
2111 else if (target
== GL_PROXY_TEXTURE_2D
) {
2112 /* Proxy texture: check for errors and update proxy state */
2113 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2114 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2116 struct gl_texture_unit
*texUnit
;
2117 struct gl_texture_image
*texImage
;
2118 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2119 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2120 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2121 border
, internalFormat
);
2122 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2123 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2124 internalFormat
, GL_NONE
, GL_NONE
,
2125 width
, height
, 1, border
);
2128 /* if error, clear all proxy texture image parameters */
2129 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2130 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2135 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2142 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2143 GLenum internalFormat
, GLsizei width
,
2144 GLsizei height
, GLsizei depth
, GLint border
,
2145 GLsizei imageSize
, const GLvoid
*data
)
2147 GET_CURRENT_CONTEXT(ctx
);
2148 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2150 switch (internalFormat
) {
2151 case GL_COMPRESSED_ALPHA_ARB
:
2152 case GL_COMPRESSED_LUMINANCE_ARB
:
2153 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2154 case GL_COMPRESSED_INTENSITY_ARB
:
2155 case GL_COMPRESSED_RGB_ARB
:
2156 case GL_COMPRESSED_RGBA_ARB
:
2157 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2160 /* silence compiler warning */
2164 if (target
== GL_TEXTURE_3D
) {
2165 struct gl_texture_unit
*texUnit
;
2166 struct gl_texture_object
*texObj
;
2167 struct gl_texture_image
*texImage
;
2169 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2170 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2171 return; /* error in texture image was detected */
2174 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2175 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2176 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2179 texImage
= _mesa_alloc_texture_image();
2180 texObj
->Image
[level
] = texImage
;
2182 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2186 else if (texImage
->Data
) {
2187 FREE(texImage
->Data
);
2188 texImage
->Data
= NULL
;
2191 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2194 if (ctx
->Extensions
.ARB_texture_compression
) {
2195 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2196 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2198 width
, height
, depth
,
2199 border
, imageSize
, data
,
2201 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2205 texObj
->Complete
= GL_FALSE
;
2206 ctx
->NewState
|= _NEW_TEXTURE
;
2208 else if (target
== GL_PROXY_TEXTURE_3D
) {
2209 /* Proxy texture: check for errors and update proxy state */
2210 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2211 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2213 struct gl_texture_unit
*texUnit
;
2214 struct gl_texture_image
*texImage
;
2215 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2216 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2217 init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2218 border
, internalFormat
);
2219 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2220 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2221 internalFormat
, GL_NONE
, GL_NONE
,
2222 width
, height
, depth
, border
);
2225 /* if error, clear all proxy texture image parameters */
2226 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2227 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2232 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2239 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2240 GLsizei width
, GLenum format
,
2241 GLsizei imageSize
, const GLvoid
*data
)
2243 struct gl_texture_unit
*texUnit
;
2244 struct gl_texture_object
*texObj
;
2245 struct gl_texture_image
*texImage
;
2246 GET_CURRENT_CONTEXT(ctx
);
2247 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2249 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2250 width
, 1, 1, format
, GL_NONE
)) {
2251 return; /* error was detected */
2254 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2255 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2256 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2259 if (width
== 0 || !data
)
2260 return; /* no-op, not an error */
2262 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2263 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2265 format
, imageSize
, data
,
2268 ctx
->NewState
|= _NEW_TEXTURE
;
2273 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2274 GLint yoffset
, GLsizei width
, GLsizei height
,
2275 GLenum format
, GLsizei imageSize
,
2278 struct gl_texture_unit
*texUnit
;
2279 struct gl_texture_object
*texObj
;
2280 struct gl_texture_image
*texImage
;
2281 GET_CURRENT_CONTEXT(ctx
);
2282 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2284 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2285 width
, height
, 1, format
, GL_NONE
)) {
2286 return; /* error was detected */
2289 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2290 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2291 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2294 if (width
== 0 || height
== 0 || !data
)
2295 return; /* no-op, not an error */
2297 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2298 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2299 xoffset
, yoffset
, width
, height
,
2300 format
, imageSize
, data
,
2303 ctx
->NewState
|= _NEW_TEXTURE
;
2308 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2309 GLint yoffset
, GLint zoffset
, GLsizei width
,
2310 GLsizei height
, GLsizei depth
, GLenum format
,
2311 GLsizei imageSize
, const GLvoid
*data
)
2313 struct gl_texture_unit
*texUnit
;
2314 struct gl_texture_object
*texObj
;
2315 struct gl_texture_image
*texImage
;
2316 GET_CURRENT_CONTEXT(ctx
);
2317 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2319 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2320 width
, height
, depth
, format
, GL_NONE
)) {
2321 return; /* error was detected */
2324 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2325 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2326 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2329 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2330 return; /* no-op, not an error */
2332 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2333 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2334 xoffset
, yoffset
, zoffset
,
2335 width
, height
, depth
,
2336 format
, imageSize
, data
,
2339 ctx
->NewState
|= _NEW_TEXTURE
;
2344 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2346 const struct gl_texture_unit
*texUnit
;
2347 const struct gl_texture_object
*texObj
;
2348 struct gl_texture_image
*texImage
;
2349 GET_CURRENT_CONTEXT(ctx
);
2350 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2352 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2353 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2357 if (is_proxy_target(target
)) {
2358 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2362 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2363 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2364 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2367 /* invalid mipmap level */
2368 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2372 if (!texImage
->IsCompressed
) {
2373 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2380 if (ctx
->Extensions
.ARB_texture_compression
) {
2381 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2382 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,